- {shouldShowLink ? (
- renderSingleLink(links[0], formattedValue, getLinkStyle(styles, cellOptions))
- ) : shouldShowTooltip ? (
-
setTooltipCoords(undefined)}
- />
- ) : (
- formattedValue
- )}
+
+ {link == null ? formattedValue : renderSingleLink(link, formattedValue, getLinkStyle(styles, cellOptions))}
);
}
diff --git a/packages/grafana-ui/src/components/Table/TableNG/Cells/BarGaugeCell.tsx b/packages/grafana-ui/src/components/Table/TableNG/Cells/BarGaugeCell.tsx
index 710a8c65726..69ebfac671c 100644
--- a/packages/grafana-ui/src/components/Table/TableNG/Cells/BarGaugeCell.tsx
+++ b/packages/grafana-ui/src/components/Table/TableNG/Cells/BarGaugeCell.tsx
@@ -1,13 +1,11 @@
-import { useState } from 'react';
-
import { ThresholdsConfig, ThresholdsMode, VizOrientation, getFieldConfigWithMinMax } from '@grafana/data';
import { BarGaugeDisplayMode, BarGaugeValueMode, TableCellDisplayMode } from '@grafana/schema';
import { BarGauge } from '../../../BarGauge/BarGauge';
-import { DataLinksActionsTooltip, renderSingleLink } from '../../DataLinksActionsTooltip';
-import { tooltipOnClickHandler, DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils } from '../../utils';
+import { renderSingleLink } from '../../DataLinksActionsTooltip';
+import { useSingleLink } from '../hooks';
import { BarGaugeCellProps } from '../types';
-import { extractPixelValue, getCellOptions, getAlignmentFactor, getCellLinks } from '../utils';
+import { extractPixelValue, getCellOptions, getAlignmentFactor } from '../utils';
const defaultScale: ThresholdsConfig = {
mode: ThresholdsMode.Absolute,
@@ -23,7 +21,7 @@ const defaultScale: ThresholdsConfig = {
],
};
-export const BarGaugeCell = ({ value, field, theme, height, width, rowIdx, actions }: BarGaugeCellProps) => {
+export const BarGaugeCell = ({ value, field, theme, height, width, rowIdx }: BarGaugeCellProps) => {
const displayValue = field.display!(value);
const cellOptions = getCellOptions(field);
const heightOffset = extractPixelValue(theme.spacing(1));
@@ -48,51 +46,26 @@ export const BarGaugeCell = ({ value, field, theme, height, width, rowIdx, actio
}
const alignmentFactors = getAlignmentFactor(field, displayValue, rowIdx!);
- const links = getCellLinks(field, rowIdx) || [];
- const [tooltipCoords, setTooltipCoords] = useState();
- const { shouldShowLink, hasMultipleLinksOrActions } = getDataLinksActionsTooltipUtils(links, actions);
- const shouldShowTooltip = hasMultipleLinksOrActions && tooltipCoords !== undefined;
-
- const renderComponent = () => {
- return (
-
- );
- };
-
- return (
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
-
- {shouldShowLink ? (
- renderSingleLink(links[0], renderComponent())
- ) : shouldShowTooltip ? (
- setTooltipCoords(undefined)}
- />
- ) : (
- renderComponent()
- )}
-
+ const barGaugeComponent = (
+
);
+
+ const link = useSingleLink(field, rowIdx);
+
+ return link == null ? barGaugeComponent : renderSingleLink(link, barGaugeComponent);
};
diff --git a/packages/grafana-ui/src/components/Table/TableNG/Cells/ImageCell.tsx b/packages/grafana-ui/src/components/Table/TableNG/Cells/ImageCell.tsx
index bc62e266b12..e0c1050396a 100644
--- a/packages/grafana-ui/src/components/Table/TableNG/Cells/ImageCell.tsx
+++ b/packages/grafana-ui/src/components/Table/TableNG/Cells/ImageCell.tsx
@@ -1,55 +1,28 @@
import { css } from '@emotion/css';
import { Property } from 'csstype';
-import { useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../../../themes/ThemeContext';
-import { DataLinksActionsTooltip, renderSingleLink } from '../../DataLinksActionsTooltip';
+import { renderSingleLink } from '../../DataLinksActionsTooltip';
import { TableCellDisplayMode } from '../../types';
-import { DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils, tooltipOnClickHandler } from '../../utils';
+import { useSingleLink } from '../hooks';
import { ImageCellProps } from '../types';
-import { getCellLinks } from '../utils';
const DATALINKS_HEIGHT_OFFSET = 10;
-export const ImageCell = ({ cellOptions, field, height, justifyContent, value, rowIdx, actions }: ImageCellProps) => {
+export const ImageCell = ({ cellOptions, field, height, justifyContent, value, rowIdx }: ImageCellProps) => {
const calculatedHeight = height - DATALINKS_HEIGHT_OFFSET;
const styles = useStyles2(getStyles, calculatedHeight, justifyContent);
- const links = getCellLinks(field, rowIdx) || [];
-
- const [tooltipCoords, setTooltipCoords] = useState();
- const { shouldShowLink, hasMultipleLinksOrActions } = getDataLinksActionsTooltipUtils(links, actions);
- const shouldShowTooltip = hasMultipleLinksOrActions && tooltipCoords !== undefined;
const { text } = field.display!(value);
const { alt, title } =
cellOptions.type === TableCellDisplayMode.Image ? cellOptions : { alt: undefined, title: undefined };
const img = ;
+ const link = useSingleLink(field, rowIdx);
- return (
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
-
- {shouldShowLink ? (
- renderSingleLink(links[0], img)
- ) : shouldShowTooltip ? (
- setTooltipCoords(undefined)}
- />
- ) : (
- img
- )}
-
- );
+ return {link == null ? img : renderSingleLink(link, img)}
;
};
const getStyles = (theme: GrafanaTheme2, height: number, justifyContent: Property.JustifyContent) => ({
diff --git a/packages/grafana-ui/src/components/Table/TableNG/Cells/JSONCell.tsx b/packages/grafana-ui/src/components/Table/TableNG/Cells/JSONCell.tsx
index 2506255cb03..dc195cbcd67 100644
--- a/packages/grafana-ui/src/components/Table/TableNG/Cells/JSONCell.tsx
+++ b/packages/grafana-ui/src/components/Table/TableNG/Cells/JSONCell.tsx
@@ -1,16 +1,14 @@
import { css } from '@emotion/css';
import { Property } from 'csstype';
-import { useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../../../themes/ThemeContext';
-import { DataLinksActionsTooltip, renderSingleLink } from '../../DataLinksActionsTooltip';
-import { tooltipOnClickHandler, DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils } from '../../utils';
+import { renderSingleLink } from '../../DataLinksActionsTooltip';
+import { useSingleLink } from '../hooks';
import { JSONCellProps } from '../types';
-import { getCellLinks } from '../utils';
-export const JSONCell = ({ value, justifyContent, field, rowIdx, actions }: JSONCellProps) => {
+export const JSONCell = ({ value, justifyContent, field, rowIdx }: JSONCellProps) => {
const styles = useStyles2(getStyles, justifyContent);
let displayValue = value;
@@ -33,34 +31,9 @@ export const JSONCell = ({ value, justifyContent, field, rowIdx, actions }: JSON
}
}
- const links = getCellLinks(field, rowIdx) || [];
+ const link = useSingleLink(field, rowIdx);
- const [tooltipCoords, setTooltipCoords] = useState();
- const { shouldShowLink, hasMultipleLinksOrActions } = getDataLinksActionsTooltipUtils(links, actions);
- const shouldShowTooltip = hasMultipleLinksOrActions && tooltipCoords !== undefined;
-
- return (
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
-
- {shouldShowLink ? (
- renderSingleLink(links[0], displayValue)
- ) : shouldShowTooltip ? (
- setTooltipCoords(undefined)}
- />
- ) : (
- displayValue
- )}
-
- );
+ return {link == null ? displayValue : renderSingleLink(link, displayValue)}
;
};
const getStyles = (theme: GrafanaTheme2, justifyContent: Property.JustifyContent) => ({
diff --git a/packages/grafana-ui/src/components/Table/TableNG/Cells/PillCell.test.tsx b/packages/grafana-ui/src/components/Table/TableNG/Cells/PillCell.test.tsx
new file mode 100644
index 00000000000..a216a9221d1
--- /dev/null
+++ b/packages/grafana-ui/src/components/Table/TableNG/Cells/PillCell.test.tsx
@@ -0,0 +1,219 @@
+import { render, screen } from '@testing-library/react';
+
+import { DataFrame, Field, FieldType, GrafanaTheme2, MappingType, createTheme } from '@grafana/data';
+import { TableCellDisplayMode, TablePillCellOptions } from '@grafana/schema';
+
+import { mockThemeContext } from '../../../../themes/ThemeContext';
+
+import { PillCell, inferPills } from './PillCell';
+
+describe('PillCell', () => {
+ let restoreThemeContext: () => void;
+
+ beforeEach(() => {
+ restoreThemeContext = mockThemeContext(createTheme());
+ });
+
+ afterEach(() => {
+ restoreThemeContext();
+ });
+
+ const mockCellOptions: TablePillCellOptions = {
+ type: TableCellDisplayMode.Pill,
+ colorMode: 'auto',
+ };
+
+ const mockField: Field = {
+ name: 'test',
+ type: FieldType.string,
+ values: [],
+ config: {},
+ };
+
+ const mockFrame: DataFrame = {
+ name: 'test',
+ fields: [mockField],
+ length: 1,
+ };
+
+ const defaultProps = {
+ value: 'test-value',
+ field: mockField,
+ justifyContent: 'flex-start' as const,
+ cellOptions: mockCellOptions,
+ rowIdx: 0,
+ frame: mockFrame,
+ height: 30,
+ width: 100,
+ theme: {} as GrafanaTheme2,
+ cellInspect: false,
+ showFilters: false,
+ };
+
+ describe('pill parsing', () => {
+ it('should render pills for single values', () => {
+ render( );
+ expect(screen.getByText('test-value')).toBeInTheDocument();
+ });
+
+ it('should render pills for CSV values', () => {
+ render( );
+ expect(screen.getByText('value1')).toBeInTheDocument();
+ expect(screen.getByText('value2')).toBeInTheDocument();
+ expect(screen.getByText('value3')).toBeInTheDocument();
+ });
+
+ it('should render pills for JSON array values', () => {
+ render( );
+ expect(screen.getByText('item1')).toBeInTheDocument();
+ expect(screen.getByText('item2')).toBeInTheDocument();
+ expect(screen.getByText('item3')).toBeInTheDocument();
+ });
+
+ it('should show dash for empty values', () => {
+ render( );
+ expect(screen.getByText('-')).toBeInTheDocument();
+ });
+
+ it('should show dash for null values', () => {
+ render( );
+ expect(screen.getByText('-')).toBeInTheDocument();
+ });
+ });
+
+ describe('color mapping', () => {
+ // These tests primarily ensure the color logic executes without throwing.
+ // For true color verification, visual regression tests would be needed.
+
+ it('should use mapped colors when colorMode is mapped', () => {
+ const mappedOptions: TablePillCellOptions = {
+ type: TableCellDisplayMode.Pill,
+ colorMode: 'mapped',
+ };
+
+ render( );
+
+ const successPill = screen.getByText('success');
+ const errorPill = screen.getByText('error');
+ const warningPill = screen.getByText('warning');
+ const unknownPill = screen.getByText('unknown');
+
+ expect(successPill).toBeInTheDocument();
+ expect(errorPill).toBeInTheDocument();
+ expect(warningPill).toBeInTheDocument();
+ expect(unknownPill).toBeInTheDocument();
+ });
+
+ it('should use field-level value mappings when available', () => {
+ const mappedOptions: TablePillCellOptions = {
+ type: TableCellDisplayMode.Pill,
+ colorMode: 'mapped',
+ };
+
+ // Mock field with value mappings
+ const fieldWithMappings: Field = {
+ ...mockField,
+ config: {
+ ...mockField.config,
+ mappings: [
+ {
+ type: MappingType.ValueToText,
+ options: {
+ success: { color: '#00FF00' },
+ error: { color: '#FF0000' },
+ warning: { color: '#FFFF00' },
+ },
+ },
+ ],
+ },
+ display: (value: unknown) => ({
+ text: String(value),
+ color:
+ String(value) === 'success'
+ ? '#00FF00'
+ : String(value) === 'error'
+ ? '#FF0000'
+ : String(value) === 'warning'
+ ? '#FFFF00'
+ : '#FF780A',
+ numeric: 0,
+ }),
+ };
+
+ render(
+
+ );
+
+ const successPill = screen.getByText('success');
+ const errorPill = screen.getByText('error');
+ const warningPill = screen.getByText('warning');
+ const unknownPill = screen.getByText('unknown');
+
+ expect(successPill).toBeInTheDocument();
+ expect(errorPill).toBeInTheDocument();
+ expect(warningPill).toBeInTheDocument();
+ expect(unknownPill).toBeInTheDocument();
+ });
+
+ it('should use fixed color when colorMode is fixed', () => {
+ const fixedOptions: TablePillCellOptions = {
+ type: TableCellDisplayMode.Pill,
+ colorMode: 'fixed',
+ color: '#FF00FF',
+ };
+
+ render( );
+ expect(screen.getByText('test-value')).toBeInTheDocument();
+ });
+
+ it('should use auto color when colorMode is auto', () => {
+ const autoOptions: TablePillCellOptions = {
+ type: TableCellDisplayMode.Pill,
+ colorMode: 'auto',
+ };
+
+ render( );
+ expect(screen.getByText('test-value')).toBeInTheDocument();
+ });
+ });
+});
+
+describe('inferPills', () => {
+ // These tests verify the pill parsing logic handles various input formats correctly.
+ // They ensure the function can extract pill values from different data structures.
+
+ it('should return empty array for null/undefined values', () => {
+ expect(inferPills(null)).toEqual([]);
+ expect(inferPills(undefined)).toEqual([]);
+ expect(inferPills('')).toEqual([]);
+ });
+
+ it('should parse single values', () => {
+ expect(inferPills('test')).toEqual(['test']);
+ expect(inferPills('"quoted"')).toEqual(['quoted']);
+ expect(inferPills("'quoted'")).toEqual(['quoted']);
+ });
+
+ it('should parse CSV strings', () => {
+ expect(inferPills('value1,value2,value3')).toEqual(['value1', 'value2', 'value3']);
+ expect(inferPills(' value1 , value2 , value3 ')).toEqual(['value1', 'value2', 'value3']);
+ expect(inferPills('value1, ,value3')).toEqual(['value1', 'value3']);
+ });
+
+ it('should parse JSON arrays', () => {
+ expect(inferPills('["item1","item2","item3"]')).toEqual(['item1', 'item2', 'item3']);
+ expect(inferPills('["item1", "item2", "item3"]')).toEqual(['item1', 'item2', 'item3']);
+ expect(inferPills('["item1", null, "item3"]')).toEqual(['item1', 'item3']);
+ });
+
+ it('should handle mixed content', () => {
+ // When JSON parsing fails, it falls back to CSV parsing
+ expect(inferPills('["item1", "item2"],extra')).toEqual(['["item1"', '"item2"]', 'extra']);
+ expect(inferPills('not-json,value')).toEqual(['not-json', 'value']);
+ });
+});
diff --git a/packages/grafana-ui/src/components/Table/TableNG/Cells/PillCell.tsx b/packages/grafana-ui/src/components/Table/TableNG/Cells/PillCell.tsx
new file mode 100644
index 00000000000..aaa103c3dc7
--- /dev/null
+++ b/packages/grafana-ui/src/components/Table/TableNG/Cells/PillCell.tsx
@@ -0,0 +1,185 @@
+import { css } from '@emotion/css';
+import { Property } from 'csstype';
+import { useMemo } from 'react';
+
+import { GrafanaTheme2, isDataFrame, classicColors, colorManipulator, Field } from '@grafana/data';
+import { TablePillCellOptions } from '@grafana/schema';
+
+import { useStyles2 } from '../../../../themes/ThemeContext';
+import { TableCellRendererProps } from '../types';
+
+const DEFAULT_PILL_BG_COLOR = '#FF780A';
+
+interface Pill {
+ value: string;
+ key: string;
+ bgColor: string;
+ color: string;
+}
+
+function createPills(pillValues: string[], cellOptions: TableCellRendererProps['cellOptions'], field: Field): Pill[] {
+ return pillValues.map((pill, index) => {
+ const bgColor = getPillColor(pill, cellOptions, field);
+ const textColor = colorManipulator.getContrastRatio('#FFFFFF', bgColor) >= 4.5 ? '#FFFFFF' : '#000000';
+ return {
+ value: pill,
+ key: `${pill}-${index}`,
+ bgColor,
+ color: textColor,
+ };
+ });
+}
+
+export function PillCell({ value, field, justifyContent, cellOptions }: TableCellRendererProps) {
+ const styles = useStyles2(getStyles, justifyContent);
+
+ const pills: Pill[] = useMemo(() => {
+ const pillValues = inferPills(value);
+ return createPills(pillValues, cellOptions, field);
+ }, [value, cellOptions, field]);
+
+ if (pills.length === 0) {
+ return -
;
+ }
+
+ return (
+
+
+ {pills.map((pill) => (
+
+ {pill.value}
+
+ ))}
+
+
+ );
+}
+
+export function inferPills(value: unknown): string[] {
+ if (!value) {
+ return [];
+ }
+
+ // Handle DataFrame - not supported for pills
+ if (isDataFrame(value)) {
+ return [];
+ }
+
+ // Handle different value types
+ const stringValue = String(value);
+
+ // Try to parse as JSON first
+ try {
+ const parsed = JSON.parse(stringValue);
+ if (Array.isArray(parsed)) {
+ // JSON array of strings
+ return parsed
+ .filter((item) => item != null && item !== '')
+ .map(String)
+ .map((text) => text.trim())
+ .filter((item) => item !== '');
+ }
+ } catch {
+ // Not valid JSON, continue with other parsing
+ }
+
+ // Handle CSV string
+ if (stringValue.includes(',')) {
+ return stringValue
+ .split(',')
+ .map((text) => text.trim())
+ .filter((item) => item !== '');
+ }
+
+ // Single value - strip quotes
+ return [stringValue.replace(/["'`]/g, '').trim()];
+}
+
+function isPillCellOptions(cellOptions: TableCellRendererProps['cellOptions']): cellOptions is TablePillCellOptions {
+ return cellOptions?.type === 'pill';
+}
+
+function getPillColor(pill: string, cellOptions: TableCellRendererProps['cellOptions'], field: Field): string {
+ if (!isPillCellOptions(cellOptions)) {
+ return getDeterministicColor(pill);
+ }
+
+ const colorMode = cellOptions.colorMode || 'auto';
+
+ // Fixed color mode (highest priority)
+ if (colorMode === 'fixed' && cellOptions.color) {
+ return cellOptions.color;
+ }
+
+ // Mapped color mode - use field's value mappings
+ if (colorMode === 'mapped') {
+ // Check if field has value mappings
+ if (field.config.mappings && field.config.mappings.length > 0) {
+ // Use the field's display processor to get the mapped value
+ const displayValue = field.display!(pill);
+ if (displayValue.color) {
+ return displayValue.color;
+ }
+ }
+ // Fallback to default color for unmapped values
+ return cellOptions.color || DEFAULT_PILL_BG_COLOR;
+ }
+
+ // Auto mode - deterministic color assignment based on string hash
+ if (colorMode === 'auto') {
+ return getDeterministicColor(pill);
+ }
+
+ // Default color for unknown values or fallback
+ return DEFAULT_PILL_BG_COLOR;
+}
+
+function getDeterministicColor(text: string): string {
+ // Create a simple hash of the string to get consistent colors
+ let hash = 0;
+ for (let i = 0; i < text.length; i++) {
+ const char = text.charCodeAt(i);
+ hash = (hash << 5) - hash + char;
+ hash = hash & hash; // Convert to 32-bit integer
+ }
+
+ // Use absolute value and modulo to get a consistent index
+ const colorValues = Object.values(classicColors);
+ const index = Math.abs(hash) % colorValues.length;
+
+ return colorValues[index];
+}
+
+const getStyles = (theme: GrafanaTheme2, justifyContent: Property.JustifyContent | undefined) => ({
+ cell: css({
+ display: 'flex',
+ justifyContent: justifyContent || 'flex-start',
+ alignItems: 'center',
+ height: '100%',
+ padding: theme.spacing(0.5),
+ }),
+ pillsContainer: css({
+ display: 'flex',
+ flexWrap: 'wrap',
+ gap: theme.spacing(0.5),
+ maxWidth: '100%',
+ }),
+ pill: css({
+ display: 'inline-block',
+ padding: theme.spacing(0.25, 0.75),
+ borderRadius: theme.shape.radius.default,
+ fontSize: theme.typography.bodySmall.fontSize,
+ lineHeight: theme.typography.bodySmall.lineHeight,
+ fontWeight: theme.typography.fontWeightMedium,
+ whiteSpace: 'nowrap',
+ textAlign: 'center',
+ minWidth: 'fit-content',
+ }),
+});
diff --git a/packages/grafana-ui/src/components/Table/TableNG/Cells/TableCellActions.tsx b/packages/grafana-ui/src/components/Table/TableNG/Cells/TableCellActions.tsx
index eb67a369cb2..558d1c7978d 100644
--- a/packages/grafana-ui/src/components/Table/TableNG/Cells/TableCellActions.tsx
+++ b/packages/grafana-ui/src/components/Table/TableNG/Cells/TableCellActions.tsx
@@ -24,7 +24,10 @@ export function TableCellActions(props: TableCellActionsProps) {
} = props;
return (
-
+ // stopping propagation to prevent clicks within the actions menu from triggering the cell click events
+ // for things like the data links tooltip.
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
+
ev.stopPropagation()}>
{cellInspect && (
ReactNode;
@@ -24,7 +25,6 @@ const GAUGE_RENDERER: TableCellRenderer = (props) => (
height={props.height}
width={props.width}
rowIdx={props.rowIdx}
- actions={props.actions}
/>
);
@@ -35,7 +35,6 @@ const AUTO_RENDERER: TableCellRenderer = (props) => (
justifyContent={props.justifyContent}
rowIdx={props.rowIdx}
cellOptions={props.cellOptions}
- actions={props.actions}
/>
);
@@ -52,13 +51,7 @@ const SPARKLINE_RENDERER: TableCellRenderer = (props) => (
);
const JSON_RENDERER: TableCellRenderer = (props) => (
-
+
);
const GEO_RENDERER: TableCellRenderer = (props) => (
@@ -73,13 +66,16 @@ const IMAGE_RENDERER: TableCellRenderer = (props) => (
justifyContent={props.justifyContent}
value={props.value}
rowIdx={props.rowIdx}
- actions={props.actions}
/>
);
const DATA_LINKS_RENDERER: TableCellRenderer = (props) => ;
-const ACTIONS_RENDERER: TableCellRenderer = (props) => ;
+const ACTIONS_RENDERER: TableCellRenderer = ({ field, rowIdx, getActions = () => [] }) => (
+
+);
+
+const PILL_RENDERER: TableCellRenderer = (props) => ;
function isCustomCellOptions(options: TableCellOptions): options is TableCustomCellOptions {
return options.type === TableCellDisplayMode.Custom;
@@ -104,6 +100,7 @@ const CELL_RENDERERS: Record = {
[TableCellDisplayMode.ColorText]: AUTO_RENDERER,
[TableCellDisplayMode.ColorBackground]: AUTO_RENDERER,
[TableCellDisplayMode.Auto]: AUTO_RENDERER,
+ [TableCellDisplayMode.Pill]: PILL_RENDERER,
};
/** @internal */
diff --git a/packages/grafana-ui/src/components/Table/TableNG/TableNG.test.tsx b/packages/grafana-ui/src/components/Table/TableNG/TableNG.test.tsx
index dd1d4364128..9dfe1a2719b 100644
--- a/packages/grafana-ui/src/components/Table/TableNG/TableNG.test.tsx
+++ b/packages/grafana-ui/src/components/Table/TableNG/TableNG.test.tsx
@@ -1,7 +1,17 @@
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { applyFieldOverrides, createTheme, DataFrame, EventBus, FieldType, toDataFrame } from '@grafana/data';
+import {
+ applyFieldOverrides,
+ createTheme,
+ DataFrame,
+ DataLink,
+ EventBus,
+ FieldType,
+ LinkModel,
+ toDataFrame,
+} from '@grafana/data';
+import { selectors } from '@grafana/e2e-selectors';
import { TableCellBackgroundDisplayMode } from '@grafana/schema';
import { PanelContext, PanelContextProvider } from '../../../components/PanelChrome';
@@ -1682,4 +1692,55 @@ describe('TableNG', () => {
expect(mockEventBus.publish).not.toHaveBeenCalled();
});
});
+
+ describe('Displays data Links', () => {
+ function toLinkModel(link: DataLink): LinkModel {
+ return {
+ href: link.url,
+ title: link.title,
+ target: link.targetBlank ? '_blank' : '_self',
+ origin: link.origin || 'panel',
+ };
+ }
+
+ it('shows multiple datalinks in the tooltip', async () => {
+ const dataFrame = createBasicDataFrame();
+ const links: DataLink[] = [
+ { url: 'http://asdasd.com', title: 'Test Title' },
+ { url: 'http://asdasd2.com', title: 'Test Title2' },
+ ];
+
+ dataFrame.fields[0].config.links = links;
+ dataFrame.fields[0].getLinks = () => links.map(toLinkModel);
+
+ render( );
+
+ const cell = screen.getByText('A1');
+ await userEvent.click(cell);
+
+ const tooltip = screen.getByTestId(selectors.components.DataLinksActionsTooltip.tooltipWrapper);
+ expect(tooltip).toBeInTheDocument();
+
+ expect(screen.getByText('Test Title')).toBeInTheDocument();
+ expect(screen.getByText('Test Title2')).toBeInTheDocument();
+ });
+
+ it('does not show tooltip for a single link', async () => {
+ const dataFrame = createBasicDataFrame();
+
+ const links: DataLink[] = [{ url: 'http://asdasd.com', title: 'Test Title' }];
+
+ dataFrame.fields[0].config.links = links;
+ dataFrame.fields[0].getLinks = () => links.map(toLinkModel);
+
+ render( );
+
+ const cell = screen.getByText('A1');
+
+ // we need to click the parent since the cell itself is a link.
+ await userEvent.click(cell.parentElement!);
+
+ expect(screen.queryByTestId(selectors.components.DataLinksActionsTooltip.tooltipWrapper)).not.toBeInTheDocument();
+ });
+ });
});
diff --git a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx
index 5a0a2fdc036..aa35b99ae9c 100644
--- a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx
+++ b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx
@@ -1,7 +1,7 @@
import 'react-data-grid/lib/styles.css';
import { css, cx } from '@emotion/css';
import { Property } from 'csstype';
-import { Key, ReactNode, useLayoutEffect, useMemo, useState } from 'react';
+import { Key, ReactNode, useCallback, useLayoutEffect, useMemo, useState } from 'react';
import {
Cell,
CellRendererProps,
@@ -22,8 +22,10 @@ import { ContextMenu } from '../../ContextMenu/ContextMenu';
import { MenuItem } from '../../Menu/MenuItem';
import { Pagination } from '../../Pagination/Pagination';
import { PanelContext, usePanelContext } from '../../PanelChrome';
+import { DataLinksActionsTooltip } from '../DataLinksActionsTooltip';
import { TableCellInspector, TableCellInspectorMode } from '../TableCellInspector';
import { CellColors, TableCellDisplayMode } from '../types';
+import { DataLinksActionsTooltipState } from '../utils';
import { HeaderCell } from './Cells/HeaderCell';
import { RowExpander } from './Cells/RowExpander';
@@ -56,6 +58,8 @@ import {
getCellOptions,
shouldTextWrap,
isCellInspectEnabled,
+ getCellLinks,
+ withDataLinksActionsTooltip,
} from './utils';
type CellRootRenderer = (key: React.Key, props: CellRendererProps) => React.ReactNode;
@@ -68,14 +72,13 @@ export function TableNG(props: TableNGProps) {
enableSharedCrosshair = false,
enableVirtualization,
footerOptions,
- getActions,
+ getActions = () => [],
height,
initialSortBy,
noHeader,
onCellFilterAdded,
onColumnResize,
onSortByChange,
- replaceVariables,
showTypeIcons,
structureRev,
width,
@@ -88,6 +91,11 @@ export function TableNG(props: TableNGProps) {
});
const panelContext = usePanelContext();
+ const getCellActions = useCallback(
+ (field: Field, rowIdx: number) => getActions(data, field, rowIdx),
+ [getActions, data]
+ );
+
const hasHeader = !noHeader;
const hasFooter = Boolean(footerOptions?.show && footerOptions.reducer?.length);
const isCountRowsSet = Boolean(
@@ -256,13 +264,15 @@ export function TableNG(props: TableNGProps) {
interface Schema {
columns: TableColumn[];
cellRootRenderers: Record;
+ colsWithTooltip: Record;
}
- const { columns, cellRootRenderers } = useMemo(() => {
+ const { columns, cellRootRenderers, colsWithTooltip } = useMemo(() => {
const fromFields = (f: Field[], widths: number[]) => {
const result: Schema = {
columns: [],
cellRootRenderers: {},
+ colsWithTooltip: {},
};
let lastRowIdx = -1;
@@ -280,7 +290,6 @@ export function TableNG(props: TableNGProps) {
const showFilters = Boolean(field.config.filterable && onCellFilterAdded != null);
const showActions = cellInspect || showFilters;
const width = widths[i];
- const frame = data;
// helps us avoid string cx and emotion per-cell
const cellActionClassName = showActions
@@ -294,6 +303,9 @@ export function TableNG(props: TableNGProps) {
const cellType = cellOptions.type;
const shouldOverflow = shouldTextOverflow(field);
const shouldWrap = shouldTextWrap(field);
+ const withTooltip = withDataLinksActionsTooltip(field, cellType);
+
+ result.colsWithTooltip[displayName] = withTooltip;
// this fires first
const renderCellRoot = (key: Key, props: CellRendererProps): ReactNode => {
@@ -317,7 +329,7 @@ export function TableNG(props: TableNGProps) {
colors = {};
}
- const cellStyle = getCellStyles(theme, field, _rowHeight, shouldWrap, shouldOverflow, colors);
+ const cellStyle = getCellStyles(theme, field, _rowHeight, shouldWrap, shouldOverflow, withTooltip, colors);
return (
): JSX.Element => {
const rowIdx = props.row.__index;
const value = props.row[props.column.key];
-
- // TODO: defer until click?
- const actions = getActions?.(frame, field, props.row.__index, replaceVariables);
+ const frame = data;
return (
<>
{renderFieldCell({
- actions,
cellOptions,
frame,
field,
@@ -354,6 +363,7 @@ export function TableNG(props: TableNGProps) {
width,
cellInspect,
showFilters,
+ getActions: getCellActions,
})}
{showActions && (
();
+
return (
<>
@@ -541,6 +552,24 @@ export function TableNG(props: TableNGProps) {
className={styles.grid}
columns={structureRevColumns}
rows={paginatedRows}
+ onCellClick={({ column, row }, { clientX, clientY, preventGridDefault }) => {
+ // Note: could be column.field; JS says yes, but TS says no!
+ const field = columns[column.idx].field;
+
+ if (colsWithTooltip[getDisplayName(field)]) {
+ const rowIdx = row.__index;
+ setTooltipState({
+ coords: {
+ clientX,
+ clientY,
+ },
+ links: getCellLinks(field, rowIdx),
+ actions: getCellActions(field, rowIdx),
+ });
+
+ preventGridDefault();
+ }
+ }}
onCellKeyDown={
hasNestedFrames
? (_, event) => {
@@ -577,6 +606,15 @@ export function TableNG(props: TableNGProps) {
|
)}
+ {tooltipState && (
+
setTooltipState(undefined)}
+ />
+ )}
+
{isContextMenuOpen && (
({
- cell: css({
- textOverflow: 'initial',
- background: colors.bgColor ?? 'inherit',
- alignContent: 'center',
- justifyContent: getTextAlign(field),
- paddingInline: TABLE.CELL_PADDING,
- height: '100%',
- minHeight: rowHeight, // min height interacts with the fit-content property on the overflow container
- ...(shouldWrap && { whiteSpace: 'pre-line' }),
- '&:last-child': {
- borderInlineEnd: 'none',
- },
- '&:hover': {
- background: colors.bgHoverColor,
- '.table-cell-actions': {
- display: 'flex',
+) => {
+ return {
+ cell: css({
+ textOverflow: 'initial',
+ background: colors.bgColor ?? 'inherit',
+ alignContent: 'center',
+ justifyContent: getTextAlign(field),
+ paddingInline: TABLE.CELL_PADDING,
+ height: '100%',
+ minHeight: rowHeight, // min height interacts with the fit-content property on the overflow container
+ ...(shouldWrap && { whiteSpace: 'pre-line' }),
+ ...(hasTooltip && { cursor: 'pointer' }),
+ '&:last-child': {
+ borderInlineEnd: 'none',
},
- ...(shouldOverflow && {
- zIndex: theme.zIndex.tooltip - 2,
- whiteSpace: 'pre-line',
- height: 'fit-content',
- minWidth: 'fit-content',
- }),
- },
- }),
-});
+ '&:hover': {
+ background: colors.bgHoverColor,
+ '.table-cell-actions': {
+ display: 'flex',
+ },
+ ...(shouldOverflow && {
+ zIndex: theme.zIndex.tooltip - 2,
+ whiteSpace: 'pre-line',
+ height: 'fit-content',
+ minWidth: 'fit-content',
+ }),
+ },
+ }),
+ };
+};
diff --git a/packages/grafana-ui/src/components/Table/TableNG/hooks.ts b/packages/grafana-ui/src/components/Table/TableNG/hooks.ts
index 1540d1e0383..33c89162939 100644
--- a/packages/grafana-ui/src/components/Table/TableNG/hooks.ts
+++ b/packages/grafana-ui/src/components/Table/TableNG/hooks.ts
@@ -2,7 +2,7 @@ import { useState, useMemo, useEffect, useCallback, useRef, useLayoutEffect } fr
import { Column, DataGridProps, SortColumn } from 'react-data-grid';
import { varPreLine } from 'uwrap';
-import { Field, fieldReducers, FieldType, formattedValueToString, reduceField } from '@grafana/data';
+import { Field, fieldReducers, FieldType, formattedValueToString, LinkModel, reduceField } from '@grafana/data';
import { useTheme2 } from '../../../themes/ThemeContext';
import { TableCellDisplayMode, TableColumnResizeActionCallback } from '../types';
@@ -17,6 +17,7 @@ import {
getColumnTypes,
GetMaxWrapCellOptions,
getMaxWrapCell,
+ getCellLinks,
} from './utils';
// Helper function to get displayed value
@@ -597,3 +598,10 @@ export function useColumnResize(
return dataGridResizeHandler;
}
+
+export function useSingleLink(field: Field, rowIdx: number): LinkModel | undefined {
+ const linksCount = field.config.links?.length ?? 0;
+ const actionsCount = field.config.actions?.length ?? 0;
+ const shouldShowLink = linksCount === 1 && actionsCount === 0;
+ return useMemo(() => (shouldShowLink ? (getCellLinks(field, rowIdx) ?? []) : [])[0], [field, shouldShowLink, rowIdx]);
+}
diff --git a/packages/grafana-ui/src/components/Table/TableNG/types.ts b/packages/grafana-ui/src/components/Table/TableNG/types.ts
index 2946923db8f..04caa62c85c 100644
--- a/packages/grafana-ui/src/components/Table/TableNG/types.ts
+++ b/packages/grafana-ui/src/components/Table/TableNG/types.ts
@@ -10,7 +10,6 @@ import {
TimeRange,
FieldConfigSource,
ActionModel,
- InterpolateFunction,
FieldType,
DataFrameWithValue,
SelectableValue,
@@ -30,12 +29,9 @@ export type TableColumnResizeActionCallback = (fieldDisplayName: string, width:
export type TableSortByActionCallback = (state: TableSortByFieldState[]) => void;
export type FooterItem = Array> | string | undefined;
-export type GetActionsFunction = (
- frame: DataFrame,
- field: Field,
- rowIndex: number,
- replaceVariables?: InterpolateFunction
-) => ActionModel[];
+export type GetActionsFunction = (frame: DataFrame, field: Field, rowIndex: number) => ActionModel[];
+
+export type GetActionsFunctionLocal = (field: Field, rowIndex: number) => ActionModel[];
export type TableFieldOptionsType = Omit & {
cellOptions: TableCellOptions;
@@ -142,7 +138,6 @@ export interface BaseTableProps {
initialRowIndex?: number;
fieldConfig?: FieldConfigSource;
getActions?: GetActionsFunction;
- replaceVariables?: InterpolateFunction;
// Used solely for testing as RTL can't correctly render the table otherwise
enableVirtualization?: boolean;
}
@@ -151,7 +146,6 @@ export interface BaseTableProps {
export interface TableNGProps extends BaseTableProps {}
export interface TableCellRendererProps {
- actions?: ActionModel[];
rowIdx: number;
frame: DataFrame;
timeRange?: TimeRange;
@@ -165,6 +159,7 @@ export interface TableCellRendererProps {
cellInspect: boolean;
showFilters: boolean;
justifyContent: Property.JustifyContent;
+ getActions?: GetActionsFunctionLocal;
}
export type ContextMenuProps = {
@@ -205,7 +200,7 @@ export interface SparklineCellProps {
width: number;
}
-export interface BarGaugeCellProps extends ActionCellProps {
+export interface BarGaugeCellProps {
field: Field;
height: number;
rowIdx: number;
@@ -214,7 +209,7 @@ export interface BarGaugeCellProps extends ActionCellProps {
width: number;
}
-export interface ImageCellProps extends ActionCellProps {
+export interface ImageCellProps {
cellOptions: TableCellOptions;
field: Field;
height: number;
@@ -223,7 +218,7 @@ export interface ImageCellProps extends ActionCellProps {
rowIdx: number;
}
-export interface JSONCellProps extends ActionCellProps {
+export interface JSONCellProps {
justifyContent: Property.JustifyContent;
value: TableCellValue;
field: Field;
@@ -241,24 +236,26 @@ export interface GeoCellProps {
height: number;
}
-export interface ActionCellProps {
- actions?: ActionModel[];
-}
-
export interface CellColors {
textColor?: string;
bgColor?: string;
bgHoverColor?: string;
}
-export interface AutoCellProps extends ActionCellProps {
- value: TableCellValue;
+export interface AutoCellProps {
field: Field;
+ value: TableCellValue;
justifyContent: Property.JustifyContent;
rowIdx: number;
cellOptions: TableCellOptions;
}
+export interface ActionCellProps {
+ field: Field;
+ rowIdx: number;
+ getActions: GetActionsFunctionLocal;
+}
+
// Comparator for sorting table values
export type Comparator = (a: TableCellValue, b: TableCellValue) => number;
diff --git a/packages/grafana-ui/src/components/Table/TableNG/utils.ts b/packages/grafana-ui/src/components/Table/TableNG/utils.ts
index 78f5442f234..90004837874 100644
--- a/packages/grafana-ui/src/components/Table/TableNG/utils.ts
+++ b/packages/grafana-ui/src/components/Table/TableNG/utils.ts
@@ -172,6 +172,7 @@ const DEFAULT_CELL_OPTIONS = { type: TableCellDisplayMode.Auto } as const;
/**
* @internal
* Returns the cell options for a field, migrating from legacy displayMode if necessary.
+ * TODO: remove live migration in favor of doing it in dashboard or panel migrator
*/
export function getCellOptions(field: Field): TableCellOptions {
if (field.config.custom?.displayMode) {
@@ -613,3 +614,12 @@ export function getApplyToRowBgFn(fields: Field[], theme: GrafanaTheme2): ((rowI
}
}
}
+
+/** @internal */
+export function withDataLinksActionsTooltip(field: Field, cellType: TableCellDisplayMode) {
+ return (
+ cellType !== TableCellDisplayMode.DataLinks &&
+ cellType !== TableCellDisplayMode.Actions &&
+ (field.config.links?.length ?? 0) + (field.config.actions?.length ?? 0) > 1
+ );
+}
diff --git a/packages/grafana-ui/src/components/Table/types.ts b/packages/grafana-ui/src/components/Table/types.ts
index e2c5b5b8099..1d029ae7099 100644
--- a/packages/grafana-ui/src/components/Table/types.ts
+++ b/packages/grafana-ui/src/components/Table/types.ts
@@ -57,7 +57,7 @@ export interface TableCellProps extends CellProps {
onCellFilterAdded?: TableFilterActionCallback;
innerWidth: number;
frame: DataFrame;
- actions?: ActionModel[];
+ actions?: ActionModel[]; // unused in NG
setInspectCell?: TableInspectCellCallback;
}
diff --git a/packages/grafana-ui/src/components/Table/utils.ts b/packages/grafana-ui/src/components/Table/utils.ts
index f4c9b072b16..77dc0cec078 100644
--- a/packages/grafana-ui/src/components/Table/utils.ts
+++ b/packages/grafana-ui/src/components/Table/utils.ts
@@ -196,6 +196,8 @@ export function getCellComponent(displayMode: TableCellDisplayMode, field: Field
return DataLinksCell;
case TableCellDisplayMode.Actions:
return ActionsCell;
+ case TableCellDisplayMode.Pill:
+ return DefaultCell; // Legacy table doesn't support pill cells, fallback to default
}
if (field.type === FieldType.geo) {
@@ -764,10 +766,16 @@ export function guessLongestField(fieldConfig: FieldConfigSource, data: DataFram
return longestField;
}
-export type DataLinksActionsTooltipCoords = {
+export interface DataLinksActionsTooltipState {
+ coords: DataLinksActionsTooltipCoords;
+ links?: LinkModel[];
+ actions?: ActionModel[];
+}
+
+export interface DataLinksActionsTooltipCoords {
clientX: number;
clientY: number;
-};
+}
export const getDataLinksActionsTooltipUtils = (links: LinkModel[], actions?: ActionModel[]) => {
const hasMultipleLinksOrActions = links.length > 1 || Boolean(actions?.length);
diff --git a/pkg/login/social/connectors/generic_oauth.go b/pkg/login/social/connectors/generic_oauth.go
index 7d1d5842a47..02b93285e93 100644
--- a/pkg/login/social/connectors/generic_oauth.go
+++ b/pkg/login/social/connectors/generic_oauth.go
@@ -245,78 +245,136 @@ func (s *SocialGenericOAuth) UserInfo(ctx context.Context, client *http.Client,
defer s.reloadMutex.RUnlock()
s.log.Debug("Getting user info")
- toCheck := make([]*UserInfoJson, 0, 2)
- if tokenData := s.extractFromToken(token); tokenData != nil {
- toCheck = append(toCheck, tokenData)
+ // 1. Collect user info data from various sources
+ dataSources := s.collectUserInfoData(ctx, client, token)
+
+ // 2. Build user info from collected data
+ userInfo, externalOrgs, err := s.buildUserInfo(dataSources)
+ if err != nil {
+ return nil, err
+ }
+
+ // 3. Post-process user info
+ err = s.postProcessUserInfo(ctx, client, userInfo, externalOrgs)
+ if err != nil {
+ return nil, err
+ }
+
+ // 4. Validate user access
+ err = s.validateUserAccess(ctx, client, userInfo)
+ if err != nil {
+ return nil, err
+ }
+
+ s.log.Debug("User info result", "result", userInfo)
+ return userInfo, nil
+}
+
+// collectUserInfoData gathers user information from ID token, API, and access token
+func (s *SocialGenericOAuth) collectUserInfoData(ctx context.Context, client *http.Client, token *oauth2.Token) []*UserInfoJson {
+ dataSources := make([]*UserInfoJson, 0, 3)
+
+ if idTokenData := s.extractFromIDToken(token); idTokenData != nil {
+ dataSources = append(dataSources, idTokenData)
}
if apiData := s.extractFromAPI(ctx, client); apiData != nil {
- toCheck = append(toCheck, apiData)
+ dataSources = append(dataSources, apiData)
+ }
+ if accessTokenData := s.extractFromAccessToken(token); accessTokenData != nil {
+ dataSources = append(dataSources, accessTokenData)
}
+ return dataSources
+}
+
+// buildUserInfo constructs BasicUserInfo from collected data sources
+func (s *SocialGenericOAuth) buildUserInfo(dataSources []*UserInfoJson) (*social.BasicUserInfo, []string, error) {
userInfo := &social.BasicUserInfo{}
var externalOrgs []string
- for _, data := range toCheck {
+
+ for _, data := range dataSources {
s.log.Debug("Processing external user info", "source", data.source, "data", data)
- if userInfo.Id == "" {
- userInfo.Id = data.Sub
+ s.extractBasicUserFields(userInfo, data)
+
+ if err := s.extractRoleAndOrgs(userInfo, &externalOrgs, data); err != nil {
+ return nil, nil, err
}
- if userInfo.Name == "" {
- userInfo.Name = s.extractUserName(data)
- }
+ s.extractUserGroups(userInfo, data)
+ }
- if userInfo.Login == "" {
- userInfo.Login = s.extractLogin(data)
- }
+ return userInfo, externalOrgs, nil
+}
- if userInfo.Email == "" {
- userInfo.Email = s.extractEmail(data)
- if userInfo.Email != "" {
- s.log.Debug("Set user info email from extracted email", "email", userInfo.Email)
- }
- }
+// extractBasicUserFields extracts basic user fields (ID, Name, Login, Email) from data
+func (s *SocialGenericOAuth) extractBasicUserFields(userInfo *social.BasicUserInfo, data *UserInfoJson) {
+ if userInfo.Id == "" {
+ userInfo.Id = data.Sub
+ }
- if userInfo.Role == "" && !s.info.SkipOrgRoleSync {
- role, grafanaAdmin, err := s.extractRoleAndAdminOptional(data.rawJSON, []string{})
- if err != nil {
- s.log.Warn("Failed to extract role", "err", err)
- } else {
- userInfo.Role = role
- if s.info.AllowAssignGrafanaAdmin {
- userInfo.IsGrafanaAdmin = &grafanaAdmin
- }
- }
- }
+ if userInfo.Name == "" {
+ userInfo.Name = s.extractUserName(data)
+ }
- if len(externalOrgs) == 0 && !s.info.SkipOrgRoleSync {
- var err error
- externalOrgs, err = s.extractOrgs(data.rawJSON)
- if err != nil {
- s.log.Warn("Failed to extract orgs", "err", err)
- return nil, err
- }
- }
+ if userInfo.Login == "" {
+ userInfo.Login = s.extractLogin(data)
+ }
- if len(userInfo.Groups) == 0 {
- groups, err := s.extractGroups(data)
- if err != nil {
- s.log.Warn("Failed to extract groups", "err", err)
- } else if len(groups) > 0 {
- s.log.Debug("Setting user info groups from extracted groups")
- userInfo.Groups = groups
+ if userInfo.Email == "" {
+ userInfo.Email = s.extractEmail(data)
+ if userInfo.Email != "" {
+ s.log.Debug("Set user info email from extracted email", "email", userInfo.Email)
+ }
+ }
+}
+
+// extractRoleAndOrgs extracts role and organization information from data
+func (s *SocialGenericOAuth) extractRoleAndOrgs(userInfo *social.BasicUserInfo, externalOrgs *[]string, data *UserInfoJson) error {
+ if userInfo.Role == "" && !s.info.SkipOrgRoleSync {
+ role, grafanaAdmin, err := s.extractRoleAndAdminOptional(data.rawJSON, []string{})
+ if err != nil {
+ s.log.Warn("Failed to extract role", "err", err)
+ } else {
+ userInfo.Role = role
+ if s.info.AllowAssignGrafanaAdmin {
+ userInfo.IsGrafanaAdmin = &grafanaAdmin
}
}
}
+ if len(*externalOrgs) == 0 && !s.info.SkipOrgRoleSync {
+ orgs, err := s.extractOrgs(data.rawJSON)
+ if err != nil {
+ s.log.Warn("Failed to extract orgs", "err", err)
+ return err
+ }
+ *externalOrgs = orgs
+ }
+
+ return nil
+}
+
+// extractUserGroups extracts group information from data
+func (s *SocialGenericOAuth) extractUserGroups(userInfo *social.BasicUserInfo, data *UserInfoJson) {
+ if len(userInfo.Groups) == 0 {
+ groups, err := s.extractGroups(data)
+ if err != nil {
+ s.log.Warn("Failed to extract groups", "err", err)
+ } else if len(groups) > 0 {
+ s.log.Debug("Setting user info groups from extracted groups")
+ userInfo.Groups = groups
+ }
+ }
+}
+
+// postProcessUserInfo handles post-processing of user info (org roles, private email, etc.)
+func (s *SocialGenericOAuth) postProcessUserInfo(ctx context.Context, client *http.Client, userInfo *social.BasicUserInfo, externalOrgs []string) error {
if !s.info.SkipOrgRoleSync {
userInfo.OrgRoles = s.orgRoleMapper.MapOrgRoles(s.orgMappingCfg, externalOrgs, userInfo.Role)
if s.info.RoleAttributeStrict && len(userInfo.OrgRoles) == 0 {
- // If no roles are found and role_attribute_strict is set, return an error.
- // The s.info.RoleAttributeStrict is necessary, because there is a case when len(userInfo.OrgRoles) == 0,
- // but strict role mapping is not enabled (when getAllOrgs fails).
- return nil, errRoleAttributeStrictViolation.Errorf("could not evaluate any valid roles using IdP provided data")
+ return errRoleAttributeStrictViolation.Errorf("could not evaluate any valid roles using IdP provided data")
}
}
@@ -325,11 +383,11 @@ func (s *SocialGenericOAuth) UserInfo(ctx context.Context, client *http.Client,
}
if s.canFetchPrivateEmail(userInfo) {
- var err error
- userInfo.Email, err = s.fetchPrivateEmail(ctx, client)
+ email, err := s.fetchPrivateEmail(ctx, client)
if err != nil {
- return nil, err
+ return err
}
+ userInfo.Email = email
s.log.Debug("Setting email from fetched private email", "email", userInfo.Email)
}
@@ -338,28 +396,32 @@ func (s *SocialGenericOAuth) UserInfo(ctx context.Context, client *http.Client,
userInfo.Login = userInfo.Email
}
+ return nil
+}
+
+// validateUserAccess validates user access based on team, organization, and group membership
+func (s *SocialGenericOAuth) validateUserAccess(ctx context.Context, client *http.Client, userInfo *social.BasicUserInfo) error {
if !s.isTeamMember(ctx, client) {
- return nil, &SocialError{"User not a member of one of the required teams"}
+ return &SocialError{"User not a member of one of the required teams"}
}
if !s.isOrganizationMember(ctx, client) {
- return nil, &SocialError{"User not a member of one of the required organizations"}
+ return &SocialError{"User not a member of one of the required organizations"}
}
if !s.isGroupMember(userInfo.Groups) {
- return nil, errMissingGroupMembership
+ return errMissingGroupMembership
}
- s.log.Debug("User info result", "result", userInfo)
- return userInfo, nil
+ return nil
}
func (s *SocialGenericOAuth) canFetchPrivateEmail(userinfo *social.BasicUserInfo) bool {
return s.info.ApiUrl != "" && userinfo.Email == ""
}
-func (s *SocialGenericOAuth) extractFromToken(token *oauth2.Token) *UserInfoJson {
- s.log.Debug("Extracting user info from OAuth token")
+func (s *SocialGenericOAuth) extractFromIDToken(token *oauth2.Token) *UserInfoJson {
+ s.log.Debug("Extracting user info from OAuth ID token")
idTokenAttribute := "id_token"
if s.idTokenAttributeName != "" {
@@ -373,21 +435,44 @@ func (s *SocialGenericOAuth) extractFromToken(token *oauth2.Token) *UserInfoJson
return nil
}
- rawJSON, err := s.retrieveRawIDToken(idToken)
+ rawJSON, err := s.retrieveRawJWTPayload(idToken)
if err != nil {
- s.log.Warn("Error retrieving id_token", "error", err, "token", fmt.Sprintf("%+v", token))
+ s.log.Warn("Error retrieving id_token payload", "error", err, "token", fmt.Sprintf("%+v", token))
return nil
}
+ return s.parseUserInfoFromJSON(rawJSON, "id_token")
+}
+
+func (s *SocialGenericOAuth) extractFromAccessToken(token *oauth2.Token) *UserInfoJson {
+ s.log.Debug("Extracting user info from OAuth access token")
+
+ accessToken := token.AccessToken
+ if accessToken == "" {
+ s.log.Debug("No access token found")
+ return nil
+ }
+
+ rawJSON, err := s.retrieveRawJWTPayload(accessToken)
+ if err != nil {
+ s.log.Warn("Error retrieving access token payload", "error", err)
+ return nil
+ }
+
+ return s.parseUserInfoFromJSON(rawJSON, "access_token")
+}
+
+// parseUserInfoFromJSON is a helper method to parse UserInfoJson from raw JSON and source
+func (s *SocialGenericOAuth) parseUserInfoFromJSON(rawJSON []byte, source string) *UserInfoJson {
var data UserInfoJson
if err := json.Unmarshal(rawJSON, &data); err != nil {
- s.log.Error("Error decoding id_token JSON", "raw_json", string(rawJSON), "error", err)
+ s.log.Error("Error decoding user info JSON", "raw_json", string(rawJSON), "error", err, "source", source)
return nil
}
data.rawJSON = rawJSON
- data.source = "token"
- s.log.Debug("Received id_token", "raw_json", string(data.rawJSON), "data", data.String())
+ data.source = source
+ s.log.Debug("Parsed user info from JSON", "raw_json", string(rawJSON), "data", data.String(), "source", source)
return &data
}
@@ -404,18 +489,7 @@ func (s *SocialGenericOAuth) extractFromAPI(ctx context.Context, client *http.Cl
return nil
}
- rawJSON := rawUserInfoResponse.Body
-
- var data UserInfoJson
- if err := json.Unmarshal(rawJSON, &data); err != nil {
- s.log.Error("Error decoding user info response", "raw_json", rawJSON, "error", err)
- return nil
- }
-
- data.rawJSON = rawJSON
- data.source = "API"
- s.log.Debug("Received user info response from API", "raw_json", string(rawJSON), "data", data.String())
- return &data
+ return s.parseUserInfoFromJSON(rawUserInfoResponse.Body, "API")
}
func (s *SocialGenericOAuth) extractEmail(data *UserInfoJson) string {
diff --git a/pkg/login/social/connectors/generic_oauth_test.go b/pkg/login/social/connectors/generic_oauth_test.go
index 881ed9fd541..b4b7469cc05 100644
--- a/pkg/login/social/connectors/generic_oauth_test.go
+++ b/pkg/login/social/connectors/generic_oauth_test.go
@@ -31,6 +31,7 @@ func TestUserInfoSearchesForEmailAndOrgRoles(t *testing.T) {
AllowAssignGrafanaAdmin bool
ResponseBody any
OAuth2Extra any
+ AccessToken string
Setup func(*orgtest.FakeOrgService)
RoleAttributePath string
RoleAttributeStrict bool
@@ -440,6 +441,62 @@ func TestUserInfoSearchesForEmailAndOrgRoles(t *testing.T) {
ExpectedEmail: "john.doe@example.com",
ExpectedOrgRoles: map[int64]org.RoleType{2: org.RoleViewer},
},
+ // Access Token Test Cases
+ {
+ Name: "Given a valid access token with role, no ID token, no API response, use access token",
+ ResponseBody: map[string]any{},
+ OAuth2Extra: map[string]any{},
+ AccessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiRWRpdG9yIiwiZW1haWwiOiJhY2Nlc3MudG9rZW5AZXhhbXBsZS5jb20ifQ.oVEMSJVqBwrGXOcwGgXL_8J-CZhgFVPjXXSqzPJQ5JU", // { "role": "Editor", "email": "access.token@example.com" }
+ RoleAttributePath: "role",
+ ExpectedEmail: "access.token@example.com",
+ ExpectedOrgRoles: map[int64]org.RoleType{2: org.RoleEditor},
+ },
+ {
+ Name: "Given a valid access token with org roles, no ID token, no API response, use access token",
+ ResponseBody: map[string]any{},
+ OAuth2Extra: map[string]any{},
+ AccessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiVmlld2VyIiwiZW1haWwiOiJhY2Nlc3MudG9rZW5AZXhhbXBsZS5jb20iLCJpbmZvIjp7InJvbGVzIjpbImFjY2Vzcy1kZXYiLCJhY2Nlc3Mtb3BzIl19fQ.g8-mNJQDL9CJWgRTFdKBRRKbsHZfFhJrzPYQGXfxGIE", // { "role": "Viewer", "email": "access.token@example.com", "info": { "roles": [ "access-dev", "access-ops" ] }}
+ RoleAttributePath: "role",
+ OrgAttributePath: "info.roles",
+ OrgMapping: []string{"access-dev:org_dev:Admin", "access-ops:org_engineering:Editor"},
+ ExpectedEmail: "access.token@example.com",
+ ExpectedOrgRoles: map[int64]org.RoleType{4: org.RoleAdmin, 5: org.RoleEditor},
+ },
+ {
+ Name: "Given a valid access token and ID token, prefer ID token",
+ ResponseBody: map[string]any{},
+ OAuth2Extra: map[string]any{
+ // { "role": "Admin", "email": "id.token@example.com" }
+ "id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiQWRtaW4iLCJlbWFpbCI6ImlkLnRva2VuQGV4YW1wbGUuY29tIn0.T8wcoOOPQ_av9VsOFoYJZGNFGJgG0d3LPDvtxvgODkU",
+ },
+ AccessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiRWRpdG9yIiwiZW1haWwiOiJhY2Nlc3MudG9rZW5AZXhhbXBsZS5jb20ifQ.oVEMSJVqBwrGXOcwGgXL_8J-CZhgFVPjXXSqzPJQ5JU", // { "role": "Editor", "email": "access.token@example.com" }
+ RoleAttributePath: "role",
+ ExpectedEmail: "id.token@example.com",
+ ExpectedOrgRoles: map[int64]org.RoleType{2: org.RoleAdmin},
+ },
+ {
+ Name: "Given a valid access token with no email, ID token with no role, API response with no data, merge",
+ ResponseBody: map[string]any{},
+ OAuth2Extra: map[string]any{
+ // { "email": "id.token@example.com" }
+ "id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImlkLnRva2VuQGV4YW1wbGUuY29tIn0.k5GwPcZvGe2BE_jgwN0ntz0nz4KlYhEd0hRRLApkTJ4",
+ },
+ AccessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiRWRpdG9yIn0.gfnKWZKNFNqrILhHFzabBVEWnJJIZBmQSBwLPCHhLUY", // { "role": "Editor" }
+ RoleAttributePath: "role",
+ ExpectedEmail: "id.token@example.com",
+ ExpectedOrgRoles: map[int64]org.RoleType{2: org.RoleEditor},
+ },
+ {
+ Name: "Given a valid access token with GrafanaAdmin role and AssignGrafanaAdmin enabled",
+ AllowAssignGrafanaAdmin: true,
+ ResponseBody: map[string]any{},
+ OAuth2Extra: map[string]any{},
+ AccessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiR3JhZmFuYUFkbWluIiwiZW1haWwiOiJhY2Nlc3MudG9rZW5AZXhhbXBsZS5jb20ifQ.fJPjMgZW9bOYXOLgOUekNQmNrVbUNhU1iqQJwqFWzUY", // { "role": "GrafanaAdmin", "email": "access.token@example.com" }
+ RoleAttributePath: "role",
+ ExpectedEmail: "access.token@example.com",
+ ExpectedGrafanaAdmin: trueBoolPtr(),
+ ExpectedOrgRoles: map[int64]org.RoleType{2: org.RoleAdmin},
+ },
}
cfg := &setting.Cfg{
@@ -479,8 +536,9 @@ func TestUserInfoSearchesForEmailAndOrgRoles(t *testing.T) {
require.NoError(t, err)
}))
provider.info.ApiUrl = ts.URL
+
staticToken := oauth2.Token{
- AccessToken: "",
+ AccessToken: tc.AccessToken,
TokenType: "",
RefreshToken: "",
Expiry: time.Now(),
@@ -853,7 +911,7 @@ func TestPayloadCompression(t *testing.T) {
}
token := staticToken.WithExtra(test.OAuth2Extra)
- userInfo := provider.extractFromToken(token)
+ userInfo := provider.extractFromIDToken(token)
if test.ExpectedEmail == "" {
require.Nil(t, userInfo, "Testing case %q", test.Name)
diff --git a/pkg/login/social/connectors/gitlab_oauth.go b/pkg/login/social/connectors/gitlab_oauth.go
index 917a4503218..2a2d2b7100b 100644
--- a/pkg/login/social/connectors/gitlab_oauth.go
+++ b/pkg/login/social/connectors/gitlab_oauth.go
@@ -275,7 +275,7 @@ func (s *SocialGitlab) extractFromToken(ctx context.Context, client *http.Client
return nil, nil
}
- rawJSON, err := s.retrieveRawIDToken(idToken)
+ rawJSON, err := s.retrieveRawJWTPayload(idToken)
if err != nil {
s.log.Warn("Error retrieving id_token", "error", err, "token", fmt.Sprintf("%+v", idToken))
return nil, nil
diff --git a/pkg/login/social/connectors/google_oauth.go b/pkg/login/social/connectors/google_oauth.go
index 2191a2c01e8..4e5d7a3f8f8 100644
--- a/pkg/login/social/connectors/google_oauth.go
+++ b/pkg/login/social/connectors/google_oauth.go
@@ -236,7 +236,7 @@ func (s *SocialGoogle) extractFromToken(_ context.Context, _ *http.Client, token
return nil, nil
}
- rawJSON, err := s.retrieveRawIDToken(idToken)
+ rawJSON, err := s.retrieveRawJWTPayload(idToken)
if err != nil {
s.log.Warn("Error retrieving id_token", "error", err, "token", fmt.Sprintf("%+v", idToken))
return nil, nil
diff --git a/pkg/login/social/connectors/social_base.go b/pkg/login/social/connectors/social_base.go
index 35bc67004c5..e6bda1c4f81 100644
--- a/pkg/login/social/connectors/social_base.go
+++ b/pkg/login/social/connectors/social_base.go
@@ -196,21 +196,21 @@ func (s *SocialBase) isGroupMember(groups []string) bool {
return false
}
-func (s *SocialBase) retrieveRawIDToken(idToken any) ([]byte, error) {
- tokenString, ok := idToken.(string)
+func (s *SocialBase) retrieveRawJWTPayload(token any) ([]byte, error) {
+ tokenString, ok := token.(string)
if !ok {
- return nil, fmt.Errorf("id_token is not a string: %v", idToken)
+ return nil, fmt.Errorf("token is not a string: %v", token)
}
jwtRegexp := regexp.MustCompile("^([-_a-zA-Z0-9=]+)[.]([-_a-zA-Z0-9=]+)[.]([-_a-zA-Z0-9=]+)$")
matched := jwtRegexp.FindStringSubmatch(tokenString)
if matched == nil {
- return nil, fmt.Errorf("id_token is not in JWT format: %s", tokenString)
+ return nil, fmt.Errorf("token is not in JWT format: %s", tokenString)
}
rawJSON, err := base64.RawURLEncoding.DecodeString(matched[2])
if err != nil {
- return nil, fmt.Errorf("error base64 decoding id_token: %w", err)
+ return nil, fmt.Errorf("error base64 decoding token payload: %w", err)
}
headerBytes, err := base64.RawURLEncoding.DecodeString(matched[1])
diff --git a/pkg/services/authn/clients/jwt.go b/pkg/services/authn/clients/jwt.go
index 82323e21bfe..93036b87915 100644
--- a/pkg/services/authn/clients/jwt.go
+++ b/pkg/services/authn/clients/jwt.go
@@ -114,9 +114,6 @@ func (s *JWT) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identi
if !s.cfg.JWTAuth.SkipOrgRoleSync {
role, grafanaAdmin := s.extractRoleAndAdmin(claims)
- if err != nil {
- s.log.Warn("Failed to extract role", "err", err)
- }
if s.cfg.JWTAuth.AllowAssignGrafanaAdmin {
id.IsGrafanaAdmin = &grafanaAdmin
diff --git a/pkg/tests/apis/folder/folders_test.go b/pkg/tests/apis/folder/folders_test.go
index 35722cbc964..24459c08963 100644
--- a/pkg/tests/apis/folder/folders_test.go
+++ b/pkg/tests/apis/folder/folders_test.go
@@ -861,7 +861,7 @@ func TestIntegrationFolderGetPermissions(t *testing.T) {
}
// TestFoldersCreateAPIEndpointK8S is the counterpart of pkg/api/folder_test.go TestFoldersCreateAPIEndpoint
-func TestFoldersCreateAPIEndpointK8S(t *testing.T) {
+func TestIntegrationFoldersCreateAPIEndpointK8S(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
@@ -902,7 +902,7 @@ func TestFoldersCreateAPIEndpointK8S(t *testing.T) {
description: "folder creation fails without permissions to create a folder",
input: folderWithoutParentInput,
expectedCode: http.StatusForbidden,
- expectedMessage: dashboards.ErrFolderAccessDenied.Error(),
+ expectedMessage: fmt.Sprintf("You'll need additional permissions to perform this action. Permissions needed: %s", "folders:create"),
permissions: []resourcepermissions.SetResourcePermissionCommand{},
},
{
@@ -1022,7 +1022,7 @@ func testDescription(description string, expectedErr error) string {
}
// There are no counterpart of TestFoldersGetAPIEndpointK8S in pkg/api/folder_test.go
-func TestFoldersGetAPIEndpointK8S(t *testing.T) {
+func TestIntegrationFoldersGetAPIEndpointK8S(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
@@ -1062,6 +1062,7 @@ func TestFoldersGetAPIEndpointK8S(t *testing.T) {
expectedOutput: []dtos.FolderSearchHit{
{UID: "foo", Title: "Folder 1"},
{UID: "qux", Title: "Folder 3"},
+ {UID: folder.SharedWithMeFolder.UID, Title: folder.SharedWithMeFolder.Title},
},
permissions: folderReadAndCreatePermission,
},
@@ -1107,7 +1108,7 @@ func TestFoldersGetAPIEndpointK8S(t *testing.T) {
}
// test on all dualwriter modes
- for mode := 1; mode <= 4; mode++ {
+ for mode := 0; mode <= 4; mode++ {
for _, tc := range tcs {
t.Run(fmt.Sprintf("Mode: %d, %s", mode, tc.description), func(t *testing.T) {
modeDw := grafanarest.DualWriterMode(mode)
@@ -1123,6 +1124,7 @@ func TestFoldersGetAPIEndpointK8S(t *testing.T) {
},
EnableFeatureToggles: []string{
featuremgmt.FlagNestedFolders,
+ featuremgmt.FlagUnifiedStorageSearch,
featuremgmt.FlagKubernetesClientDashboardsFolders,
},
})
diff --git a/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx b/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx
index 10a9e429099..291696baeeb 100644
--- a/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx
+++ b/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx
@@ -210,7 +210,7 @@ export function NewProvisionedFolderForm({ parentFolder, onDismiss }: Props) {
const { workflowOptions, isGitHub, repository, folder, initialValues } = useProvisionedFolderFormData({
folderUid: parentFolder?.uid,
action: 'create',
- title: parentFolder?.title,
+ title: '', // Empty title for new folders
});
if (!initialValues) {
diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx
index f1660b56772..19a1e3af6c5 100644
--- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx
+++ b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx
@@ -18,6 +18,9 @@ import { addQuery } from 'app/core/utils/query';
import { getLastUsedDatasourceFromStorage } from 'app/features/dashboard/utils/dashboard';
import { storeLastUsedDataSourceInLocalStorage } from 'app/features/datasources/components/picker/utils';
import { dataSource as expressionDatasource } from 'app/features/expressions/ExpressionDatasource';
+import { ExpressionTypeDropdown } from 'app/features/expressions/components/ExpressionTypeDropdown';
+import { ExpressionQueryType } from 'app/features/expressions/types';
+import { getDefaults } from 'app/features/expressions/utils/expressionTypes';
import { GroupActionComponents } from 'app/features/query/components/QueryActionComponent';
import { QueryEditorRows } from 'app/features/query/components/QueryEditorRows';
import { QueryGroupTopSection } from 'app/features/query/components/QueryGroup';
@@ -286,9 +289,15 @@ export class PanelDataQueriesTab extends SceneObjectBase {
+ public onAddExpressionOfType = (type: ExpressionQueryType) => {
const queries = this.getQueries();
- this.onQueriesChange(addQuery(queries, expressionDatasource.newQuery()));
+ // Create base expression query with the specified type
+ const baseQuery = expressionDatasource.newQuery();
+ const queryWithType = { ...baseQuery, type };
+ // Apply defaults specific to the expression type
+ const queryWithDefaults = getDefaults(queryWithType);
+
+ this.onQueriesChange(addQuery(queries, queryWithDefaults));
};
public renderExtraActions() {
@@ -316,6 +325,7 @@ export function PanelDataQueriesTabRendered({ model }: SceneComponentProps {
// ensure all queries explicitly define a datasource
@@ -394,16 +404,11 @@ export function PanelDataQueriesTabRendered({ model }: SceneComponentProps
)}
{config.expressionsEnabled && model.isExpressionsSupported(dsSettings) && (
-
-
+
+
Expression
-
-
+
+
)}
{model.renderExtraActions()}
diff --git a/public/app/features/expressions/ExpressionQueryEditor.tsx b/public/app/features/expressions/ExpressionQueryEditor.tsx
index 75261904c60..b1f07c253bb 100644
--- a/public/app/features/expressions/ExpressionQueryEditor.tsx
+++ b/public/app/features/expressions/ExpressionQueryEditor.tsx
@@ -1,10 +1,12 @@
+import { css } from '@emotion/css';
import { useCallback, useEffect, useRef } from 'react';
-import { DataSourceApi, QueryEditorProps, SelectableValue } from '@grafana/data';
-import { t } from '@grafana/i18n';
-import { InlineField, Select } from '@grafana/ui';
+import { DataSourceApi, GrafanaTheme2, QueryEditorProps } from '@grafana/data';
+import { t, Trans } from '@grafana/i18n';
+import { Button, IconButton, InlineField, PopoverContent, useStyles2 } from '@grafana/ui';
import { ClassicConditions } from './components/ClassicConditions';
+import { ExpressionTypeDropdown } from './components/ExpressionTypeDropdown';
import { Math } from './components/Math';
import { Reduce } from './components/Reduce';
import { Resample } from './components/Resample';
@@ -20,6 +22,24 @@ const labelWidth = 15;
type NonClassicExpressionType = Exclude;
type ExpressionTypeConfigStorage = Partial>;
+// Help text for each expression type - can be expanded with more detailed content
+const getExpressionHelpText = (type: ExpressionQueryType): PopoverContent | string => {
+ const description = expressionTypes.find(({ value }) => value === type)?.description;
+
+ switch (type) {
+ case ExpressionQueryType.sql:
+ return (
+
+ Run MySQL-dialect SQL against the tables returned from your data sources. Data source queries (ie "A", "B")
+ are available as tables and referenced by query-name. Fields are available as columns, as returned from the
+ data source.
+
+ );
+ default:
+ return description ?? '';
+ }
+};
+
function useExpressionsCache() {
const expressionCache = useRef({});
@@ -62,14 +82,16 @@ export function ExpressionQueryEditor(props: Props) {
const { query, queries, onRunQuery, onChange, app } = props;
const { getCachedExpression, setCachedExpression } = useExpressionsCache();
+ const styles = useStyles2(getStyles);
+
useEffect(() => {
setCachedExpression(query.type, query.expression);
}, [query.expression, query.type, setCachedExpression]);
const onSelectExpressionType = useCallback(
- (item: SelectableValue) => {
- const cachedExpression = getCachedExpression(item.value!);
- const defaults = getDefaults({ ...query, type: item.value! });
+ (value: ExpressionQueryType) => {
+ const cachedExpression = getCachedExpression(value!);
+ const defaults = getDefaults({ ...query, type: value! });
onChange({ ...defaults, expression: cachedExpression ?? defaults.expression });
},
@@ -100,17 +122,35 @@ export function ExpressionQueryEditor(props: Props) {
}
};
- const selected = expressionTypes.find((o) => o.value === query.type);
+ const helperText = getExpressionHelpText(query.type);
return (
-
-
-
+
+
+
+
+ {expressionTypes.find(({ value }) => value === query.type)?.label}
+
+
+
+ {helperText && }
+
{renderExpressionType()}
);
}
+
+const getStyles = (theme: GrafanaTheme2) => ({
+ operationRow: css({
+ display: 'flex',
+ alignItems: 'center',
+ gap: theme.spacing(1),
+ }),
+ infoIcon: css({
+ marginBottom: theme.spacing(0.5), // Align with the select field
+ }),
+});
diff --git a/public/app/features/expressions/components/ExpressionTypeDropdown.tsx b/public/app/features/expressions/components/ExpressionTypeDropdown.tsx
new file mode 100644
index 00000000000..2fc78ba53d2
--- /dev/null
+++ b/public/app/features/expressions/components/ExpressionTypeDropdown.tsx
@@ -0,0 +1,100 @@
+import { css } from '@emotion/css';
+import { ReactElement, useCallback, useMemo, memo } from 'react';
+
+import { FeatureState, GrafanaTheme2, SelectableValue } from '@grafana/data';
+import { Dropdown, FeatureBadge, Icon, Menu, Tooltip, useStyles2 } from '@grafana/ui';
+import { ExpressionQueryType, expressionTypes } from 'app/features/expressions/types';
+
+const EXPRESSION_ICON_MAP = {
+ [ExpressionQueryType.math]: 'calculator-alt',
+ [ExpressionQueryType.reduce]: 'compress-arrows',
+ [ExpressionQueryType.resample]: 'sync',
+ [ExpressionQueryType.classic]: 'cog',
+ [ExpressionQueryType.threshold]: 'sliders-v-alt',
+ [ExpressionQueryType.sql]: 'database',
+} as const satisfies Record;
+
+interface ExpressionTypeDropdownProps {
+ children: ReactElement;
+ handleOnSelect: (value: ExpressionQueryType) => void;
+}
+
+interface ExpressionMenuItemProps {
+ item: SelectableValue;
+ onSelect: (value: ExpressionQueryType) => void;
+}
+
+const ExpressionMenuItem = memo(({ item, onSelect }) => {
+ const { value, label, description } = item;
+ const styles = useStyles2(getStyles);
+
+ const handleClick = useCallback(() => onSelect(value!), [value, onSelect]);
+
+ return (
+ (
+
+
+
+ {label}
+ {value === ExpressionQueryType.sql && }
+
+
+
+
+
+ )}
+ key={value}
+ label=""
+ onClick={handleClick}
+ />
+ );
+});
+
+ExpressionMenuItem.displayName = 'ExpressionMenuItem';
+
+export const ExpressionTypeDropdown = memo(({ handleOnSelect, children }) => {
+ const menuItems = useMemo(
+ () => expressionTypes.map((item) => ),
+ [handleOnSelect]
+ );
+
+ const menuOverlay = useMemo(() => {menuItems} , [menuItems]);
+
+ return (
+
+ {children}
+
+ );
+});
+
+ExpressionTypeDropdown.displayName = 'ExpressionTypeDropdown';
+
+const getStyles = (theme: GrafanaTheme2) => {
+ return {
+ expressionTypeItem: css({
+ width: '100%',
+ display: 'flex',
+ alignItems: 'center',
+ gap: theme.spacing(1),
+ }),
+
+ expressionTypeItemContent: css({
+ flexGrow: 1,
+ display: 'flex',
+ alignItems: 'center',
+ gap: theme.spacing(1),
+ }),
+
+ icon: css({
+ color: theme.colors.text.secondary,
+ flexShrink: 0,
+ }),
+
+ infoIcon: css({
+ opacity: 0.7,
+ color: theme.colors.text.secondary,
+ flexShrink: 0,
+ }),
+ };
+};
diff --git a/public/app/features/expressions/components/SqlExpr.tsx b/public/app/features/expressions/components/SqlExpr.tsx
index 09c43551de4..1f61a558471 100644
--- a/public/app/features/expressions/components/SqlExpr.tsx
+++ b/public/app/features/expressions/components/SqlExpr.tsx
@@ -30,12 +30,10 @@ interface Props {
export const SqlExpr = ({ onChange, refIds, query, alerting = false }: Props) => {
const vars = useMemo(() => refIds.map((v) => v.value!), [refIds]);
- const initialQuery = `-- Run MySQL-dialect SQL against the tables returned from your data sources.
--- Data source queries (ie "${vars[0]}") are available as tables and referenced by query-name
--- Fields are available as columns, as returned from the data source.
-SELECT *
-FROM ${vars[0]}
-LIMIT 10`;
+ const initialQuery = `SELECT *
+ FROM ${vars[0]}
+ LIMIT 10`;
+
const styles = useStyles2(getStyles);
const containerRef = useRef(null);
const [dimensions, setDimensions] = useState({ height: 0 });
diff --git a/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx b/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx
index 9508dfee1e7..7345c031eac 100644
--- a/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx
+++ b/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx
@@ -51,7 +51,7 @@ export const ConvertFieldTypeTransformerEditor = ({
const onSelectField = useCallback(
(idx: number) => (value: string | undefined) => {
- const conversions = options.conversions;
+ const conversions = [...options.conversions];
conversions[idx] = { ...conversions[idx], targetField: value ?? '', dateFormat: undefined };
onChange({
...options,
diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.test.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.test.tsx
index db5f9172a67..9e72fbb491e 100644
--- a/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.test.tsx
+++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.test.tsx
@@ -36,55 +36,55 @@ describe('UrlAndAuthenticationSection', () => {
expect(onOptionsChangeMock).toHaveBeenCalled();
});
- it('renders DRBP warning for InfluxDB OSS 1.x and InfluxQL', () => {
- const props = {
- ...defaultProps,
- options: {
- ...defaultProps.options,
- jsonData: { product: 'InfluxDB OSS 1.x', version: InfluxVersion.InfluxQL },
- },
- };
+ const productsRequiringDBRP = [
+ 'InfluxDB OSS 1.x',
+ 'InfluxDB OSS 2.x',
+ 'InfluxDB Enterprise 1.x',
+ 'InfluxDB Cloud (TSM)',
+ 'InfluxDB Cloud Serverless',
+ ];
- render( );
- expect(screen.getByText(/requires DRBP mapping/i)).toBeInTheDocument();
+ describe('UrlAndAuthenticationSection', () => {
+ it.each(productsRequiringDBRP)('renders DBRP warning for %s and InfluxQL', (product) => {
+ const props = {
+ ...defaultProps,
+ options: {
+ ...defaultProps.options,
+ jsonData: {
+ product,
+ version: InfluxVersion.InfluxQL,
+ },
+ },
+ };
+
+ render( );
+ expect(screen.getByText(/requires DBRP mapping/i)).toBeInTheDocument();
+ });
});
- it('renders DRBP warning for InfluxDB OSS 2.x and InfluxQL', () => {
+ it('does not render DBRP warning for SQL', () => {
const props = {
...defaultProps,
options: {
...defaultProps.options,
- jsonData: { product: 'InfluxDB OSS 2.x', version: InfluxVersion.InfluxQL },
+ jsonData: { version: InfluxVersion.SQL },
},
};
render( );
- expect(screen.getByText(/requires DRBP mapping/i)).toBeInTheDocument();
+ expect(screen.queryByText(/requires DBRP mapping/i)).not.toBeInTheDocument();
});
- it('does not render DRBP warning for InfluxDB OSS 1.x and Flux', () => {
+ it('does not render DBRP warning for Flux', () => {
const props = {
...defaultProps,
options: {
...defaultProps.options,
- jsonData: { product: 'InfluxDB OSS 1.x', version: InfluxVersion.Flux },
+ jsonData: { version: InfluxVersion.Flux },
},
};
render( );
- expect(screen.queryByText(/requires DRBP mapping/i)).not.toBeInTheDocument();
- });
-
- it('does not render DRBP warning for InfluxDB OSS 2.x and Flux', () => {
- const props = {
- ...defaultProps,
- options: {
- ...defaultProps.options,
- jsonData: { product: 'InfluxDB OSS 2.x', version: InfluxVersion.Flux },
- },
- };
-
- render( );
- expect(screen.queryByText(/requires DRBP mapping/i)).not.toBeInTheDocument();
+ expect(screen.queryByText(/requires DBRP mapping/i)).not.toBeInTheDocument();
});
});
diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.tsx
index 7b0ff3fcd69..263e0b45865 100644
--- a/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.tsx
+++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.tsx
@@ -38,10 +38,16 @@ export const UrlAndAuthenticationSection = (props: Props) => {
typeof v === 'string' && (v === InfluxVersion.Flux || v === InfluxVersion.InfluxQL || v === InfluxVersion.SQL);
// Database + Retention Policy (DBRP) mapping is required for InfluxDB OSS 1.x and 2.x when using InfluxQL
- const requiresDrbpMapping =
+ const requiresDbrpMapping =
options.jsonData.product &&
options.jsonData.version === InfluxVersion.InfluxQL &&
- ['InfluxDB OSS 1.x', 'InfluxDB OSS 2.x'].includes(options.jsonData.product);
+ [
+ 'InfluxDB OSS 1.x',
+ 'InfluxDB OSS 2.x',
+ 'InfluxDB Enterprise 1.x',
+ 'InfluxDB Cloud (TSM)',
+ 'InfluxDB Cloud Serverless',
+ ].includes(options.jsonData.product);
const onProductChange = ({ value }: ComboboxOption) => {
trackInfluxDBConfigV2ProductSelected({ product: value });
@@ -113,8 +119,8 @@ export const UrlAndAuthenticationSection = (props: Props) => {
- {requiresDrbpMapping && (
-
+ {requiresDbrpMapping && (
+
InfluxDB OSS 1.x and 2.x users must configure a Database + Retention Policy (DBRP) mapping via the CLI or
API before data can be queried.{' '}
diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/constants.ts b/public/app/plugins/datasource/influxdb/components/editor/config-v2/constants.ts
index 3ae3122bffd..07b4b3fc35e 100644
--- a/public/app/plugins/datasource/influxdb/components/editor/config-v2/constants.ts
+++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/constants.ts
@@ -30,8 +30,8 @@ export const CONFIG_SECTION_HEADERS_WITH_PDC = [
];
export const HTTP_MODES: ComboboxOption[] = [
- { label: 'GET', value: 'GET' },
{ label: 'POST', value: 'POST' },
+ { label: 'GET', value: 'GET' },
];
export const getInlineLabelStyles = (theme: GrafanaTheme2, transparent = false, width?: number | 'auto') => {
diff --git a/public/app/plugins/datasource/loki/package.json b/public/app/plugins/datasource/loki/package.json
index 0b4be6cada6..0fe5fbfdd7b 100644
--- a/public/app/plugins/datasource/loki/package.json
+++ b/public/app/plugins/datasource/loki/package.json
@@ -6,7 +6,7 @@
"dependencies": {
"@emotion/css": "11.13.5",
"@grafana/data": "12.1.0-pre",
- "@grafana/lezer-logql": "0.2.7",
+ "@grafana/lezer-logql": "0.2.8",
"@grafana/llm": "0.22.1",
"@grafana/monaco-logql": "^0.0.8",
"@grafana/runtime": "12.1.0-pre",
diff --git a/public/app/plugins/panel/table/table-new/TableCellOptionEditor.tsx b/public/app/plugins/panel/table/table-new/TableCellOptionEditor.tsx
index ad5d9e400be..d8752c8e503 100644
--- a/public/app/plugins/panel/table/table-new/TableCellOptionEditor.tsx
+++ b/public/app/plugins/panel/table/table-new/TableCellOptionEditor.tsx
@@ -10,6 +10,7 @@ import { AutoCellOptionsEditor } from './cells/AutoCellOptionsEditor';
import { BarGaugeCellOptionsEditor } from './cells/BarGaugeCellOptionsEditor';
import { ColorBackgroundCellOptionsEditor } from './cells/ColorBackgroundCellOptionsEditor';
import { ImageCellOptionsEditor } from './cells/ImageCellOptionsEditor';
+import { PillCellOptionsEditor } from './cells/PillCellOptionsEditor';
import { SparklineCellOptionsEditor } from './cells/SparklineCellOptionsEditor';
// The props that any cell type editor are expected
@@ -77,6 +78,9 @@ export const TableCellOptionEditor = ({ value, onChange }: Props) => {
{cellType === TableCellDisplayMode.Image && (
)}
+ {cellType === TableCellDisplayMode.Pill && (
+
+ )}
);
};
@@ -91,6 +95,7 @@ let cellDisplayModeOptions: Array> = [
{ value: { type: TableCellDisplayMode.JSONView }, label: 'JSON View' },
{ value: { type: TableCellDisplayMode.Image }, label: 'Image' },
{ value: { type: TableCellDisplayMode.Actions }, label: 'Actions' },
+ { value: { type: TableCellDisplayMode.Pill }, label: 'Pill' },
];
const getStyles = (theme: GrafanaTheme2) => ({
diff --git a/public/app/plugins/panel/table/table-new/TablePanel.tsx b/public/app/plugins/panel/table/table-new/TablePanel.tsx
index 903a74f65c3..d5bf34dd869 100644
--- a/public/app/plugins/panel/table/table-new/TablePanel.tsx
+++ b/public/app/plugins/panel/table/table-new/TablePanel.tsx
@@ -1,5 +1,5 @@
import { css } from '@emotion/css';
-import { useMemo } from 'react';
+import { useCallback, useMemo } from 'react';
import {
ActionModel,
@@ -57,6 +57,11 @@ export function TablePanel(props: Props) {
const enableSharedCrosshair = panelContext.sync && panelContext.sync() !== DashboardCursorSync.Off;
+ const _getActions = useCallback(
+ (frame: DataFrame, field: Field, rowIndex: number) => getCellActions(frame, field, rowIndex, replaceVariables),
+ [replaceVariables]
+ );
+
const tableElement = (
);
@@ -159,28 +163,39 @@ const getCellActions = (
field: Field,
rowIndex: number,
replaceVariables: InterpolateFunction | undefined
-) => {
- const actions: Array> = [];
- const actionLookup = new Set();
+): Array> => {
+ const numActions = field.config.actions?.length ?? 0;
- const actionsModel = getActions(
- dataFrame,
- field,
- field.state!.scopedVars!,
- replaceVariables ?? replaceVars,
- field.config.actions ?? [],
- { valueRowIndex: rowIndex }
- );
+ if (numActions > 0) {
+ const actions = getActions(
+ dataFrame,
+ field,
+ field.state!.scopedVars!,
+ replaceVariables ?? replaceVars,
+ field.config.actions ?? [],
+ { valueRowIndex: rowIndex }
+ );
- actionsModel.forEach((action) => {
- const key = `${action.title}`;
- if (!actionLookup.has(key)) {
- actions.push(action);
- actionLookup.add(key);
+ if (actions.length === 1) {
+ return actions;
+ } else {
+ const actionsOut: Array> = [];
+ const actionLookup = new Set();
+
+ actions.forEach((action) => {
+ const key = action.title;
+
+ if (!actionLookup.has(key)) {
+ actionsOut.push(action);
+ actionLookup.add(key);
+ }
+ });
+
+ return actionsOut;
}
- });
+ }
- return actions;
+ return [];
};
const tableStyles = {
diff --git a/public/app/plugins/panel/table/table-new/cells/PillCellOptionsEditor.tsx b/public/app/plugins/panel/table/table-new/cells/PillCellOptionsEditor.tsx
new file mode 100644
index 00000000000..0ff38f33ea9
--- /dev/null
+++ b/public/app/plugins/panel/table/table-new/cells/PillCellOptionsEditor.tsx
@@ -0,0 +1,66 @@
+import { t } from '@grafana/i18n';
+import { TablePillCellOptions } from '@grafana/schema';
+import { Field, ColorPicker, RadioButtonGroup, Stack } from '@grafana/ui';
+
+import { TableCellEditorProps } from '../TableCellOptionEditor';
+
+const colorModeOptions: Array<{ value: 'auto' | 'fixed' | 'mapped'; label: string }> = [
+ { value: 'auto', label: 'Auto' },
+ { value: 'fixed', label: 'Fixed color' },
+ { value: 'mapped', label: 'Value mapping' },
+];
+
+export const PillCellOptionsEditor = ({ cellOptions, onChange }: TableCellEditorProps) => {
+ const colorMode = cellOptions.colorMode || 'auto';
+
+ const onColorModeChange = (mode: 'auto' | 'fixed' | 'mapped') => {
+ const updatedOptions = { ...cellOptions, colorMode: mode };
+ onChange(updatedOptions);
+ };
+
+ const onColorChange = (color: string) => {
+ const updatedOptions = { ...cellOptions, color };
+ onChange(updatedOptions);
+ };
+
+ return (
+
+
+
+
+
+ {colorMode === 'fixed' && (
+
+
+
+ )}
+
+ {colorMode === 'mapped' && (
+
+
+
+ )}
+
+ );
+};
diff --git a/public/locales/cs-CZ/grafana.json b/public/locales/cs-CZ/grafana.json
index e6027d7ec7c..70d397d444a 100644
--- a/public/locales/cs-CZ/grafana.json
+++ b/public/locales/cs-CZ/grafana.json
@@ -4435,7 +4435,6 @@
}
},
"render-left-actions": {
- "text-public": "Veřejná",
"tooltip-view-as-scene": "Zobrazit jako scénu"
}
},
@@ -5211,7 +5210,6 @@
"playlist-next": "Přejít na další nástěnku",
"playlist-previous": "Přejít na předchozí nástěnku",
"playlist-stop": "Zastavit playlist",
- "public-dashboard": "Veřejná",
"refresh": "Obnovit nástěnku",
"save": "Uložit nástěnku",
"save-dashboard": {
@@ -5512,15 +5510,9 @@
"type": "Typ"
},
"dashboard-preview-banner": {
- "not-saved": "Hodnota ještě není uložena v databázi Grafany",
"not-yet-saved": "Hodnota není uložena v databázi Grafany",
- "open-pull-request-in-git-hub": "Otevřít pull request v GitHubu",
- "title-dashboard-loaded-branch-git-hub": "Tato nástěnka je načtena z větve na GitHubu.",
"title-dashboard-loaded-external-repository": "Tato nástěnka je načtena z externího úložiště",
- "title-dashboard-loaded-request-git-hub": "Tato nástěnka je načtena z pull request na GitHubu.",
- "title-error-loading-dashboard": "Chyba při načítání nástěnky",
- "value-not-saved": "Hodnota ještě není uložena v databázi Grafany",
- "view-pull-request-in-git-hub": "Zobrazit pull request v GitHubu"
+ "title-error-loading-dashboard": "Chyba při načítání nástěnky"
},
"dashboard-scene": {
"text": {
@@ -7259,6 +7251,7 @@
"when": "KDY"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Činnost"
},
"math": {
@@ -8551,7 +8544,7 @@
"usage-count_other": "Použito na {{count}} nástěnkách"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Hledat podle názvu nebo popisu"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Načítání panelu knihovny…"
@@ -8696,12 +8689,18 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_few": "",
+ "indexed-label_many": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_few": "",
+ "parsedl-label_many": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_few": "",
+ "structured-metadata_many": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8758,6 +8757,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8771,9 +8771,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10369,6 +10371,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Tato funkce je v současné době v aktivním vývoji. Pro nejlepší zážitek a nejnovější vylepšení doporučujeme použít <2>noční sestavení2> Grafany."
@@ -11834,6 +11847,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/de-DE/grafana.json b/public/locales/de-DE/grafana.json
index df7913debc3..e0995ddb557 100644
--- a/public/locales/de-DE/grafana.json
+++ b/public/locales/de-DE/grafana.json
@@ -4399,7 +4399,6 @@
}
},
"render-left-actions": {
- "text-public": "Öffentlich",
"tooltip-view-as-scene": "Als Szene anzeigen"
}
},
@@ -5173,7 +5172,6 @@
"playlist-next": "Zum nächsten Dashboard",
"playlist-previous": "Zum vorherigen Dashboard",
"playlist-stop": "Wiedergabeliste stoppen",
- "public-dashboard": "Öffentlich",
"refresh": "Dashboard aktualisieren",
"save": "Dashboard speichern",
"save-dashboard": {
@@ -5474,15 +5472,9 @@
"type": "Typ"
},
"dashboard-preview-banner": {
- "not-saved": "Der Wert ist noch nicht in der Grafana-Datenbank gespeichert",
"not-yet-saved": "Der Wert wird nicht in der Grafana-Datenbank gespeichert",
- "open-pull-request-in-git-hub": "Pull-Anfrage in GitHub öffnen",
- "title-dashboard-loaded-branch-git-hub": "Dieses Dashboard wird von einem Branch in GitHub geladen.",
"title-dashboard-loaded-external-repository": "Dieses Dashboard wird von einem externen Repository geladen",
- "title-dashboard-loaded-request-git-hub": "Dieses Dashboard wird von einer Pull-Anfrage in GitHub geladen.",
- "title-error-loading-dashboard": "Fehler beim Laden des Dashboards",
- "value-not-saved": "Der Wert ist noch nicht in der Grafana-Datenbank gespeichert",
- "view-pull-request-in-git-hub": "Pull-Anfrage in GitHub anzeigen"
+ "title-error-loading-dashboard": "Fehler beim Laden des Dashboards"
},
"dashboard-scene": {
"text": {
@@ -7217,6 +7209,7 @@
"when": "WANN"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Operation"
},
"math": {
@@ -8503,7 +8496,7 @@
"usage-count_other": "Verwendet bei {{count}} Dashboards"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Suche nach Name oder Beschreibung"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Bibliotheks-Panel wird geladen ..."
@@ -8644,12 +8637,12 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8706,6 +8699,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8719,9 +8713,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10311,6 +10307,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Diese Funktion befindet sich momentan in der aktiven Entwicklung. Für die bestmögliche Nutzererfahrung und die neuesten Verbesserungen empfehlen wir die Nutzung von <2>Nightly Build2> von Grafana."
@@ -11762,6 +11769,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json
index 4f517a706ed..f13ec825abf 100644
--- a/public/locales/en-US/grafana.json
+++ b/public/locales/en-US/grafana.json
@@ -7209,6 +7209,7 @@
"when": "WHEN"
},
"expression-query-editor": {
+ "helper-text-sql": "Run MySQL-dialect SQL against the tables returned from your data sources. Data source queries (ie \"A\", \"B\") are available as tables and referenced by query-name. Fields are available as columns, as returned from the data source.",
"label-operation": "Operation"
},
"math": {
@@ -11768,6 +11769,14 @@
"name-show-table-footer": "Show table footer",
"name-show-table-header": "Show table header",
"name-wrap-header-text": "Wrap header text",
+ "pill-cell-options-editor": {
+ "description-color-mode": "Choose how colors are assigned to pills",
+ "description-fixed-color": "All pills in this column will use this color",
+ "description-value-mappings-info": "For Value Mappings either use the global table Value Mappings or the Field overrides Value Mappings. The default will fall back to the Color Scheme. ",
+ "label-color-mode": "Color Mode",
+ "label-fixed-color": "Fixed Color",
+ "label-value-mappings-info": "Value Mappings"
+ },
"placeholder-column-width": "auto",
"placeholder-fields": "All Numeric Fields"
},
diff --git a/public/locales/es-ES/grafana.json b/public/locales/es-ES/grafana.json
index be14e14cfee..2f6067d59ad 100644
--- a/public/locales/es-ES/grafana.json
+++ b/public/locales/es-ES/grafana.json
@@ -4399,7 +4399,6 @@
}
},
"render-left-actions": {
- "text-public": "Pública",
"tooltip-view-as-scene": "Ver como escena"
}
},
@@ -5173,7 +5172,6 @@
"playlist-next": "Ir al siguiente panel de control",
"playlist-previous": "Ir al panel de control anterior",
"playlist-stop": "Detener la lista de reproducción",
- "public-dashboard": "Pública",
"refresh": "Actualizar panel de control",
"save": "Guardar panel de control",
"save-dashboard": {
@@ -5474,15 +5472,9 @@
"type": "Tipo"
},
"dashboard-preview-banner": {
- "not-saved": "El valor aún no se ha guardado en la base de datos de Grafana",
"not-yet-saved": "El valor no se ha guardado en la base de datos de Grafana",
- "open-pull-request-in-git-hub": "Abrir solicitud de extracción en GitHub",
- "title-dashboard-loaded-branch-git-hub": "Este panel de control se carga desde una rama en GitHub.",
"title-dashboard-loaded-external-repository": "Este panel de control se carga desde un repositorio externo",
- "title-dashboard-loaded-request-git-hub": "Este panel de control se carga desde una solicitud de extracción en GitHub.",
- "title-error-loading-dashboard": "Error al cargar el panel de control",
- "value-not-saved": "El valor aún no se ha guardado en la base de datos de Grafana",
- "view-pull-request-in-git-hub": "Ver solicitud de extracción en GitHub"
+ "title-error-loading-dashboard": "Error al cargar el panel de control"
},
"dashboard-scene": {
"text": {
@@ -7217,6 +7209,7 @@
"when": "CUÁNDO"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Operación"
},
"math": {
@@ -8503,7 +8496,7 @@
"usage-count_other": "Utilizado en {{count}} dashboards"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Buscar por nombre o descripción"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Cargando panel de la librería..."
@@ -8644,12 +8637,12 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8706,6 +8699,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8719,9 +8713,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10311,6 +10307,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Esta función se encuentra actualmente en desarrollo activo. Para obtener la mejor experiencia y las últimas mejoras, recomendamos utilizar la <2>compilación nocturna2> de Grafana."
@@ -11762,6 +11769,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/fr-FR/grafana.json b/public/locales/fr-FR/grafana.json
index e90b9bfca6e..db2ff959b42 100644
--- a/public/locales/fr-FR/grafana.json
+++ b/public/locales/fr-FR/grafana.json
@@ -4399,7 +4399,6 @@
}
},
"render-left-actions": {
- "text-public": "Public",
"tooltip-view-as-scene": "Afficher en tant que scène"
}
},
@@ -5173,7 +5172,6 @@
"playlist-next": "Accéder au tableau de bord suivant",
"playlist-previous": "Accéder au tableau de bord précédent",
"playlist-stop": "Arrêter la liste de lecture",
- "public-dashboard": "Public",
"refresh": "Actualiser le tableau de bord",
"save": "Enregistrer le tableau de bord",
"save-dashboard": {
@@ -5474,15 +5472,9 @@
"type": "Type"
},
"dashboard-preview-banner": {
- "not-saved": "La valeur n'est pas encore enregistrée dans la base de données Grafana",
"not-yet-saved": "La valeur n'est pas enregistrée dans la base de données Grafana",
- "open-pull-request-in-git-hub": "Ouvrir la demande de fusion dans GitHub",
- "title-dashboard-loaded-branch-git-hub": "Ce tableau de bord est chargé à partir d'une branche dans GitHub.",
"title-dashboard-loaded-external-repository": "Ce tableau de bord est chargé à partir d'un référentiel externe",
- "title-dashboard-loaded-request-git-hub": "Ce tableau de bord est chargé à partir d'une demande de fusion dans GitHub.",
- "title-error-loading-dashboard": "Erreur lors du chargement du tableau de bord",
- "value-not-saved": "La valeur n'est pas encore enregistrée dans la base de données Grafana",
- "view-pull-request-in-git-hub": "Afficher la demande de fusion dans GitHub"
+ "title-error-loading-dashboard": "Erreur lors du chargement du tableau de bord"
},
"dashboard-scene": {
"text": {
@@ -7217,6 +7209,7 @@
"when": "QUAND"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Opération"
},
"math": {
@@ -8503,7 +8496,7 @@
"usage-count_other": "Utilisé sur {{count}} tableaux de bord"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Rechercher par nom ou par description"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Chargement du panneau de la bibliothèque..."
@@ -8644,12 +8637,12 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8706,6 +8699,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8719,9 +8713,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10311,6 +10307,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Cette fonctionnalité est actuellement en cours de développement. Pour une expérience optimale et les dernières améliorations, nous vous recommandons d’utiliser la <2>compilation nocturne2> de Grafana."
@@ -11762,6 +11769,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/hu-HU/grafana.json b/public/locales/hu-HU/grafana.json
index b928b853b78..3339a1cb0ae 100644
--- a/public/locales/hu-HU/grafana.json
+++ b/public/locales/hu-HU/grafana.json
@@ -4399,7 +4399,6 @@
}
},
"render-left-actions": {
- "text-public": "Nyilvános",
"tooltip-view-as-scene": "Megtekintés jelenetként"
}
},
@@ -5173,7 +5172,6 @@
"playlist-next": "Ugrás a következő irányítópulthoz",
"playlist-previous": "Ugrás az előző irányítópulthoz",
"playlist-stop": "Lejátszási lista leállítása",
- "public-dashboard": "Nyilvános",
"refresh": "Irányítópult frissítése",
"save": "Irányítópult mentése",
"save-dashboard": {
@@ -5474,15 +5472,9 @@
"type": "Típus"
},
"dashboard-preview-banner": {
- "not-saved": "Az érték még nincs mentve a Grafana-adatbázisban",
"not-yet-saved": "Az érték nincs mentve a Grafana-adatbázisban",
- "open-pull-request-in-git-hub": "Összefésülési kérelem megnyitása a GitHubon",
- "title-dashboard-loaded-branch-git-hub": "Ez az irányítópult a GitHub egyik ágából töltődik be.",
"title-dashboard-loaded-external-repository": "Ez az irányítópult külső adattárból töltődik be",
- "title-dashboard-loaded-request-git-hub": "Ez az irányítópult a GitHub egyik összefésülési kérelméből töltődik be.",
- "title-error-loading-dashboard": "Hiba történt az irányítópult betöltésekor",
- "value-not-saved": "Az érték még nincs mentve a Grafana-adatbázisban",
- "view-pull-request-in-git-hub": "Összefésülési kérelem megtekintése a GitHubon"
+ "title-error-loading-dashboard": "Hiba történt az irányítópult betöltésekor"
},
"dashboard-scene": {
"text": {
@@ -7217,6 +7209,7 @@
"when": "WHEN"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Művelet"
},
"math": {
@@ -8503,7 +8496,7 @@
"usage-count_other": "{{count}} irányítópulton használatos"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Keresés név vagy leírás alapján"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Könyvtárpanel betöltése…"
@@ -8644,12 +8637,12 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8706,6 +8699,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8719,9 +8713,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10311,6 +10307,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Ez a funkció jelenleg aktív fejlesztés alatt áll. A legjobb élmény és a legújabb fejlesztések érdekében javasoljuk a Grafana <2>éjszakai buildjének2> használatát."
@@ -11762,6 +11769,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/id-ID/grafana.json b/public/locales/id-ID/grafana.json
index e6b6a904801..534eb42f74d 100644
--- a/public/locales/id-ID/grafana.json
+++ b/public/locales/id-ID/grafana.json
@@ -4381,7 +4381,6 @@
}
},
"render-left-actions": {
- "text-public": "Publik",
"tooltip-view-as-scene": "Tampilkan sebagai Scene"
}
},
@@ -5154,7 +5153,6 @@
"playlist-next": "Buka dasbor berikutnya",
"playlist-previous": "Buka dasbor sebelumnya",
"playlist-stop": "Hentikan daftar putar",
- "public-dashboard": "Publik",
"refresh": "Muat ulang dasbor",
"save": "Simpan dasbor",
"save-dashboard": {
@@ -5455,15 +5453,9 @@
"type": "Jenis"
},
"dashboard-preview-banner": {
- "not-saved": "Nilai belum disimpan dalam database Grafana",
"not-yet-saved": "Nilai tidak disimpan dalam database Grafana",
- "open-pull-request-in-git-hub": "Buka permintaan penggabungan di GitHub",
- "title-dashboard-loaded-branch-git-hub": "Dasbor ini dimuat dari cabang di GitHub.",
"title-dashboard-loaded-external-repository": "Dasbor ini dimuat dari repositori eksternal",
- "title-dashboard-loaded-request-git-hub": "Dasbor ini dimuat dari permintaan penggabungan di GitHub.",
- "title-error-loading-dashboard": "Kesalahan saat memuat dasbor",
- "value-not-saved": "Nilai belum disimpan dalam database Grafana",
- "view-pull-request-in-git-hub": "Lihat permintaan penggabungan di GitHub"
+ "title-error-loading-dashboard": "Kesalahan saat memuat dasbor"
},
"dashboard-scene": {
"text": {
@@ -7196,6 +7188,7 @@
"when": "KAPAN"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Pengoperasian"
},
"math": {
@@ -8479,7 +8472,7 @@
"usage-count_other": "Digunakan pada {{count}} dasbor"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Cari berdasarkan nama atau deskripsi"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Memuat panel pustaka..."
@@ -8618,12 +8611,9 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_other": "",
+ "parsedl-label_other": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8680,6 +8670,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8693,9 +8684,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10282,6 +10275,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Fitur ini saat ini sedang dalam pengembangan aktif. Untuk pengalaman terbaik dan peningkatan terbaru, kami merekomendasikan Anda untuk menggunakan <2>versi nightly 2> Grafana."
@@ -11726,6 +11730,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/it-IT/grafana.json b/public/locales/it-IT/grafana.json
index 836d52d7fbb..cad6a896611 100644
--- a/public/locales/it-IT/grafana.json
+++ b/public/locales/it-IT/grafana.json
@@ -4399,7 +4399,6 @@
}
},
"render-left-actions": {
- "text-public": "Pubblico",
"tooltip-view-as-scene": "Visualizza come Scena"
}
},
@@ -5173,7 +5172,6 @@
"playlist-next": "Vai al dashboard successivo",
"playlist-previous": "Vai al dashboard precedente",
"playlist-stop": "Interrompi playlist",
- "public-dashboard": "Pubblico",
"refresh": "Aggiorna dashboard",
"save": "Salva dashboard",
"save-dashboard": {
@@ -5474,15 +5472,9 @@
"type": "Tipo"
},
"dashboard-preview-banner": {
- "not-saved": "Il valore non è ancora stato salvato nel database di Grafana",
"not-yet-saved": "Il valore non è stato salvato nel database di Grafana",
- "open-pull-request-in-git-hub": "Apri richiesta pull in GitHub",
- "title-dashboard-loaded-branch-git-hub": "Questo dashboard viene caricato da un ramo in GitHub.",
"title-dashboard-loaded-external-repository": "Questo dashboard viene caricato da un repository esterno",
- "title-dashboard-loaded-request-git-hub": "Questo dashboard viene caricato da una richiesta pull in GitHub.",
- "title-error-loading-dashboard": "Errore durante il caricamento del dashboard",
- "value-not-saved": "Il valore non è ancora stato salvato nel database di Grafana",
- "view-pull-request-in-git-hub": "Visualizza richiesta pull in GitHub"
+ "title-error-loading-dashboard": "Errore durante il caricamento del dashboard"
},
"dashboard-scene": {
"text": {
@@ -7217,6 +7209,7 @@
"when": "QUANDO"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Operazione"
},
"math": {
@@ -8503,7 +8496,7 @@
"usage-count_other": "Utilizzato su {{count}} dashboard"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Cerca per nome o descrizione"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Caricamento del pannello della libreria in corso..."
@@ -8644,12 +8637,12 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8706,6 +8699,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8719,9 +8713,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10311,6 +10307,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Questa funzione è attualmente in fase di sviluppo attivo. Per un'esperienza ottimale e gli ultimi miglioramenti, consigliamo di utilizzare la <2>nightly build2> di Grafana."
@@ -11762,6 +11769,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/ja-JP/grafana.json b/public/locales/ja-JP/grafana.json
index e7b17865a55..e1b74857c3e 100644
--- a/public/locales/ja-JP/grafana.json
+++ b/public/locales/ja-JP/grafana.json
@@ -4381,7 +4381,6 @@
}
},
"render-left-actions": {
- "text-public": "パブリック",
"tooltip-view-as-scene": "シーンとして表示"
}
},
@@ -5154,7 +5153,6 @@
"playlist-next": "次のダッシュボードに移動",
"playlist-previous": "前のダッシュボードに戻る",
"playlist-stop": "プレイリストを停止",
- "public-dashboard": "パブリック",
"refresh": "ダッシュボードを更新",
"save": "ダッシュボードを保存",
"save-dashboard": {
@@ -5455,15 +5453,9 @@
"type": "タイプ"
},
"dashboard-preview-banner": {
- "not-saved": "値はまだGrafanaデータベースに保存されていません",
"not-yet-saved": "値はGrafanaデータベースに保存されていません",
- "open-pull-request-in-git-hub": "GitHubでプルリクエストを開く",
- "title-dashboard-loaded-branch-git-hub": "このダッシュボードはGitHubのブランチから読み込まれます。",
"title-dashboard-loaded-external-repository": "このダッシュボードは外部リポジトリから読み込まれます",
- "title-dashboard-loaded-request-git-hub": "このダッシュボードは、GitHubのプルリクエストから読み込まれます。",
- "title-error-loading-dashboard": "ダッシュボードの読み込み中にエラーが発生しました",
- "value-not-saved": "値はまだGrafanaデータベースに保存されていません",
- "view-pull-request-in-git-hub": "GitHubでプルリクエストを表示する"
+ "title-error-loading-dashboard": "ダッシュボードの読み込み中にエラーが発生しました"
},
"dashboard-scene": {
"text": {
@@ -7196,6 +7188,7 @@
"when": "条件"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "操作"
},
"math": {
@@ -8479,7 +8472,7 @@
"usage-count_other": "{{count}}件のダッシュボードで使用中"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "名前と詳細で検索"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "ライブラリパネル読み込み中..."
@@ -8618,12 +8611,9 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_other": "",
+ "parsedl-label_other": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8680,6 +8670,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8693,9 +8684,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10282,6 +10275,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "この機能は現在開発中です。最高の体験と最新の改善を利用するには、Grafanaの<2>ナイトリービルド2>の使用をお勧めします。"
@@ -11726,6 +11730,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/ko-KR/grafana.json b/public/locales/ko-KR/grafana.json
index 5ffed66f289..a54baf4b8a7 100644
--- a/public/locales/ko-KR/grafana.json
+++ b/public/locales/ko-KR/grafana.json
@@ -4381,7 +4381,6 @@
}
},
"render-left-actions": {
- "text-public": "공개",
"tooltip-view-as-scene": "씬으로 보기"
}
},
@@ -5154,7 +5153,6 @@
"playlist-next": "다음 대시보드로 이동",
"playlist-previous": "이전 대시보드로 이동",
"playlist-stop": "플레이리스트 중지",
- "public-dashboard": "공개",
"refresh": "대시보드 새로 고침",
"save": "대시보드 저장",
"save-dashboard": {
@@ -5455,15 +5453,9 @@
"type": "유형"
},
"dashboard-preview-banner": {
- "not-saved": "값이 아직 Grafana 데이터베이스에 저장되지 않았습니다.",
"not-yet-saved": "값이 Grafana 데이터베이스에 저장되지 않았습니다.",
- "open-pull-request-in-git-hub": "GitHub에서 풀 요청 열기",
- "title-dashboard-loaded-branch-git-hub": "이 대시보드는 GitHub의 브랜치에서 로딩됩니다.",
"title-dashboard-loaded-external-repository": "이 대시보드는 외부 리포지토리에서 로딩됩니다.",
- "title-dashboard-loaded-request-git-hub": "이 대시보드는 GitHub의 풀 요청에서 로딩됩니다.",
- "title-error-loading-dashboard": "대시보드 로딩 중 오류 발생",
- "value-not-saved": "값이 아직 Grafana 데이터베이스에 저장되지 않았습니다.",
- "view-pull-request-in-git-hub": "GitHub에서 풀 요청 보기"
+ "title-error-loading-dashboard": "대시보드 로딩 중 오류 발생"
},
"dashboard-scene": {
"text": {
@@ -7196,6 +7188,7 @@
"when": "다음과 같은 때"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "연산"
},
"math": {
@@ -8479,7 +8472,7 @@
"usage-count_other": "{{count}}개의 대시보드에서 사용됨"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "이름 또는 설명으로 검색"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "라이브러리 패널 로딩 중..."
@@ -8618,12 +8611,9 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_other": "",
+ "parsedl-label_other": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8680,6 +8670,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8693,9 +8684,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10282,6 +10275,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "이 기능은 현재 적극적으로 개발 중입니다. 최상의 경험과 최신 개선 사항 적용을 위해 Grafana의 <2>야간 빌드2>를 사용하는 것이 좋습니다."
@@ -11726,6 +11730,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/nl-NL/grafana.json b/public/locales/nl-NL/grafana.json
index ae3b81983b0..d434ca6ae53 100644
--- a/public/locales/nl-NL/grafana.json
+++ b/public/locales/nl-NL/grafana.json
@@ -4399,7 +4399,6 @@
}
},
"render-left-actions": {
- "text-public": "Openbaar",
"tooltip-view-as-scene": "Weergeven als scène"
}
},
@@ -5173,7 +5172,6 @@
"playlist-next": "Naar het volgende dashboard",
"playlist-previous": "Naar het vorige dashboard",
"playlist-stop": "Afspeellijst stoppen",
- "public-dashboard": "Openbaar",
"refresh": "Dashboard vernieuwen",
"save": "Dashboard opslaan",
"save-dashboard": {
@@ -5474,15 +5472,9 @@
"type": "Type"
},
"dashboard-preview-banner": {
- "not-saved": "De waarde is nog niet opgeslagen in de Grafana-database",
"not-yet-saved": "De waarde is niet opgeslagen in de Grafana-database",
- "open-pull-request-in-git-hub": "Pull-verzoek openen in GitHub",
- "title-dashboard-loaded-branch-git-hub": "Dit dashboard wordt geladen vanuit een filiaal in GitHub.",
"title-dashboard-loaded-external-repository": "Dit dashboard wordt geladen vanuit een externe repository",
- "title-dashboard-loaded-request-git-hub": "Dit dashboard wordt geladen vanuit een pull-verzoek in GitHub.",
- "title-error-loading-dashboard": "Er is een fout opgetreden bij het laden van het dashboard",
- "value-not-saved": "De waarde is nog niet opgeslagen in de Grafana-database",
- "view-pull-request-in-git-hub": "Pull-verzoek bekijken in GitHub"
+ "title-error-loading-dashboard": "Er is een fout opgetreden bij het laden van het dashboard"
},
"dashboard-scene": {
"text": {
@@ -7217,6 +7209,7 @@
"when": "WANNEER"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Werking"
},
"math": {
@@ -8503,7 +8496,7 @@
"usage-count_other": "Gebruikt op {{count}} dashboards"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Zoeken op naam of beschrijving"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Bibliotheekpaneel laden..."
@@ -8644,12 +8637,12 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8706,6 +8699,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8719,9 +8713,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10311,6 +10307,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Er wordt momenteel actief gewerkt aan de ontwikkeling van deze functie. Voor de beste ervaring en de nieuwste verbeteringen raden we je aan om de <2>nachtelijke versie2> van Grafana te gebruiken."
@@ -11762,6 +11769,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/pl-PL/grafana.json b/public/locales/pl-PL/grafana.json
index 64f0653bbb3..1e636f38c03 100644
--- a/public/locales/pl-PL/grafana.json
+++ b/public/locales/pl-PL/grafana.json
@@ -4435,7 +4435,6 @@
}
},
"render-left-actions": {
- "text-public": "Publiczny",
"tooltip-view-as-scene": "Wyświetl jako scenę"
}
},
@@ -5211,7 +5210,6 @@
"playlist-next": "Przejdź do następnego pulpitu",
"playlist-previous": "Przejdź do poprzedniego pulpitu",
"playlist-stop": "Zatrzymaj autoodtwarzanie",
- "public-dashboard": "Publiczny",
"refresh": "Odśwież pulpit",
"save": "Zapisz pulpit",
"save-dashboard": {
@@ -5512,15 +5510,9 @@
"type": "Typ"
},
"dashboard-preview-banner": {
- "not-saved": "Wartość nie została jeszcze zapisana w bazie danych Grafana",
"not-yet-saved": "Wartość nie została zapisana w bazie danych Grafana",
- "open-pull-request-in-git-hub": "Otwórz pull request w GitHub",
- "title-dashboard-loaded-branch-git-hub": "Ten pulpit nawigacyjny jest ładowany z gałęzi w GitHub.",
"title-dashboard-loaded-external-repository": "Ten pulpit nawigacyjny jest ładowany z zewnętrznego repozytorium",
- "title-dashboard-loaded-request-git-hub": "Ten pulpit nawigacyjny jest ładowany z pull request w GitHub.",
- "title-error-loading-dashboard": "Błąd wczytywania pulpitu",
- "value-not-saved": "Wartość nie została jeszcze zapisana w bazie danych Grafana",
- "view-pull-request-in-git-hub": "Wyświetl pull request w GitHub"
+ "title-error-loading-dashboard": "Błąd wczytywania pulpitu"
},
"dashboard-scene": {
"text": {
@@ -7259,6 +7251,7 @@
"when": "KIEDY"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Operacja"
},
"math": {
@@ -8551,7 +8544,7 @@
"usage-count_other": "Używane na {{count}} pulpitu"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Szukaj według nazwy lub opisu"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Wczytywanie panelu biblioteki…"
@@ -8696,12 +8689,18 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_few": "",
+ "indexed-label_many": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_few": "",
+ "parsedl-label_many": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_few": "",
+ "structured-metadata_many": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8758,6 +8757,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8771,9 +8771,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10369,6 +10371,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Ta funkcja jest obecnie aktywnie rozwijana. Aby uzyskać najlepsze wrażenia i najnowsze ulepszenia, zalecamy korzystanie z <2>nocnej kompilacji2> aplikacji Grafana."
@@ -11834,6 +11847,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/pt-BR/grafana.json b/public/locales/pt-BR/grafana.json
index 30874326182..846cdd69fa0 100644
--- a/public/locales/pt-BR/grafana.json
+++ b/public/locales/pt-BR/grafana.json
@@ -4399,7 +4399,6 @@
}
},
"render-left-actions": {
- "text-public": "Pública",
"tooltip-view-as-scene": "Visualizar como cena"
}
},
@@ -5173,7 +5172,6 @@
"playlist-next": "Ir para o próximo painel de controle",
"playlist-previous": "Ir para o painel de controle anterior",
"playlist-stop": "Parar lista de reprodução",
- "public-dashboard": "Público",
"refresh": "Atualizar painel de controle",
"save": "Salvar painel de controle",
"save-dashboard": {
@@ -5474,15 +5472,9 @@
"type": "Tipo"
},
"dashboard-preview-banner": {
- "not-saved": "O valor ainda não está salvo no banco de dados da Grafana",
"not-yet-saved": "O valor não está salvo no banco de dados da Grafana",
- "open-pull-request-in-git-hub": "Abrir solicitação de pull no GitHub",
- "title-dashboard-loaded-branch-git-hub": "Este painel de controle é carregado a partir de um branch no GitHub.",
"title-dashboard-loaded-external-repository": "Este painel de controle é carregado a partir de um repositório externo",
- "title-dashboard-loaded-request-git-hub": "Este painel de controle é carregado a partir de uma solicitação de pull no GitHub.",
- "title-error-loading-dashboard": "Erro ao carregar o painel de controle",
- "value-not-saved": "O valor ainda não está salvo no banco de dados da Grafana",
- "view-pull-request-in-git-hub": "Ver solicitação de pull no GitHub"
+ "title-error-loading-dashboard": "Erro ao carregar o painel de controle"
},
"dashboard-scene": {
"text": {
@@ -7217,6 +7209,7 @@
"when": "QUANDO"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Operação"
},
"math": {
@@ -8503,7 +8496,7 @@
"usage-count_other": "Usado em {{count}} painéis"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Pesquisar por nome ou descrição"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Carregando painel da biblioteca…"
@@ -8644,12 +8637,12 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8706,6 +8699,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8719,9 +8713,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10311,6 +10307,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Este recurso está em desenvolvimento ativo no momento. Para ter uma melhor experiência e conferir as melhorias mais recentes, recomendamos usar a <2>compilação noturna2> da Grafana."
@@ -11762,6 +11769,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/pt-PT/grafana.json b/public/locales/pt-PT/grafana.json
index 24b4f9ad50f..946b1e08c05 100644
--- a/public/locales/pt-PT/grafana.json
+++ b/public/locales/pt-PT/grafana.json
@@ -4399,7 +4399,6 @@
}
},
"render-left-actions": {
- "text-public": "Público",
"tooltip-view-as-scene": "Ver como cena"
}
},
@@ -5173,7 +5172,6 @@
"playlist-next": "Ir para o próximo painel de controlo",
"playlist-previous": "Ir para o painel de controlo anterior",
"playlist-stop": "Parar a lista de reprodução",
- "public-dashboard": "Público",
"refresh": "Atualizar o painel de controlo",
"save": "Guardar o painel de controlo",
"save-dashboard": {
@@ -5474,15 +5472,9 @@
"type": "Tipo"
},
"dashboard-preview-banner": {
- "not-saved": "O valor ainda não está guardado na base de dados da Grafana",
"not-yet-saved": "O valor não está guardado na base de dados da Grafana",
- "open-pull-request-in-git-hub": "Abrir pedido pull no GitHub",
- "title-dashboard-loaded-branch-git-hub": "Este painel de controlo é carregado a partir de um ramo no GitHub.",
"title-dashboard-loaded-external-repository": "Este painel de controlo é carregado a partir de um repositório externo",
- "title-dashboard-loaded-request-git-hub": "Este painel de controlo é carregado a partir de um pedido pull no GitHub.",
- "title-error-loading-dashboard": "Erro ao carregar o painel de controlo",
- "value-not-saved": "O valor ainda não está guardado na base de dados da Grafana",
- "view-pull-request-in-git-hub": "Visualizar pedido pull no GitHub"
+ "title-error-loading-dashboard": "Erro ao carregar o painel de controlo"
},
"dashboard-scene": {
"text": {
@@ -7217,6 +7209,7 @@
"when": "QUANDO"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Funcionamento"
},
"math": {
@@ -8503,7 +8496,7 @@
"usage-count_other": "Utilizado em {{count}} painéis de controlo"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Pesquisar por nome ou descrição"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "A carregar painel de biblioteca..."
@@ -8644,12 +8637,12 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8706,6 +8699,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8719,9 +8713,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10311,6 +10307,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Esta funcionalidade está atualmente em desenvolvimento ativo. Para a melhor experiência e as melhorias mais recentes, recomendamos a utilização da <2>compilação noturna2> da Grafana."
@@ -11762,6 +11769,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/ru-RU/grafana.json b/public/locales/ru-RU/grafana.json
index d5eb61aad8f..bbed7d87c55 100644
--- a/public/locales/ru-RU/grafana.json
+++ b/public/locales/ru-RU/grafana.json
@@ -4435,7 +4435,6 @@
}
},
"render-left-actions": {
- "text-public": "Общедоступный",
"tooltip-view-as-scene": "Просмотр в виде сцены"
}
},
@@ -5211,7 +5210,6 @@
"playlist-next": "Перейти к следующему дашборду",
"playlist-previous": "Перейти к предыдущему дашборду",
"playlist-stop": "Остановить плейлист",
- "public-dashboard": "Общедоступный",
"refresh": "Обновить дашборд",
"save": "Сохранить дашборд",
"save-dashboard": {
@@ -5512,15 +5510,9 @@
"type": "Тип"
},
"dashboard-preview-banner": {
- "not-saved": "Значение еще не сохранено в базе данных Grafana",
"not-yet-saved": "Значение не сохранено в базе данных Grafana",
- "open-pull-request-in-git-hub": "Открыть запрос на включение изменений в GitHub",
- "title-dashboard-loaded-branch-git-hub": "Дашборд загружается из ветви в GitHub.",
"title-dashboard-loaded-external-repository": "Дашборд загружается из внешнего репозитория",
- "title-dashboard-loaded-request-git-hub": "Дашборд загружается из запроса на включение изменений в GitHub.",
- "title-error-loading-dashboard": "Ошибка при загрузке дашборда",
- "value-not-saved": "Значение еще не сохранено в базе данных Grafana",
- "view-pull-request-in-git-hub": "Просмотр запроса на включение изменений в GitHub"
+ "title-error-loading-dashboard": "Ошибка при загрузке дашборда"
},
"dashboard-scene": {
"text": {
@@ -7259,6 +7251,7 @@
"when": "КОГДА"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Операция"
},
"math": {
@@ -8551,7 +8544,7 @@
"usage-count_other": "Используется на {{count}} дашборда"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Поиск по названию или описанию"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Загрузка панели библиотеки..."
@@ -8696,12 +8689,18 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_few": "",
+ "indexed-label_many": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_few": "",
+ "parsedl-label_many": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_few": "",
+ "structured-metadata_many": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8758,6 +8757,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8771,9 +8771,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10369,6 +10371,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "В настоящее время эта функция находится в стадии активной разработки. Чтобы обеспечить максимальное удобство пользования и получить доступ к последним улучшениям, рекомендуем использовать <2>ночную сборку2> Grafana."
@@ -11834,6 +11847,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/sv-SE/grafana.json b/public/locales/sv-SE/grafana.json
index 4f7bb6d9dec..a1e6c576658 100644
--- a/public/locales/sv-SE/grafana.json
+++ b/public/locales/sv-SE/grafana.json
@@ -4399,7 +4399,6 @@
}
},
"render-left-actions": {
- "text-public": "Offentlig",
"tooltip-view-as-scene": "Visa som scen"
}
},
@@ -5173,7 +5172,6 @@
"playlist-next": "Gå till nästa instrumentpanel",
"playlist-previous": "Gå till föregående instrumentpanel",
"playlist-stop": "Stoppa spellista",
- "public-dashboard": "Offentlig",
"refresh": "Uppdatera instrumentpanel",
"save": "Spara instrumentpanel",
"save-dashboard": {
@@ -5474,15 +5472,9 @@
"type": "Typ"
},
"dashboard-preview-banner": {
- "not-saved": "Värdet har ännu inte sparats i Grafana-databasen",
"not-yet-saved": "Värdet sparades inte i Grafana-databasen",
- "open-pull-request-in-git-hub": "Öppna pull-begäran i GitHub",
- "title-dashboard-loaded-branch-git-hub": "Den här instrumentpanelen laddas från en gren i GitHub.",
"title-dashboard-loaded-external-repository": "Den här instrumentpanelen laddas från ett externt arkiv",
- "title-dashboard-loaded-request-git-hub": "Den här instrumentpanelen laddas från en pull-begäran i GitHub.",
- "title-error-loading-dashboard": "Fel vid laddning av instrumentpanel",
- "value-not-saved": "Värdet har ännu inte sparats i Grafana-databasen",
- "view-pull-request-in-git-hub": "Visa pull-begäran i GitHub"
+ "title-error-loading-dashboard": "Fel vid laddning av instrumentpanel"
},
"dashboard-scene": {
"text": {
@@ -7217,6 +7209,7 @@
"when": "NÄR"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Drift"
},
"math": {
@@ -8503,7 +8496,7 @@
"usage-count_other": "Används på {{count}} instrumentpaneler"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Sök efter namn eller beskrivning"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Laddar bibliotekspanel …"
@@ -8644,12 +8637,12 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8706,6 +8699,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8719,9 +8713,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10311,6 +10307,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Den här funktionen är för närvarande under aktiv utveckling. För den bästa upplevelsen och de senaste förbättringarna rekommenderar vi att du använder <2> nightly-versionen2> av Grafana."
@@ -11762,6 +11769,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/tr-TR/grafana.json b/public/locales/tr-TR/grafana.json
index c8e93d19834..729e7089dd2 100644
--- a/public/locales/tr-TR/grafana.json
+++ b/public/locales/tr-TR/grafana.json
@@ -4399,7 +4399,6 @@
}
},
"render-left-actions": {
- "text-public": "Herkese açık",
"tooltip-view-as-scene": "Sahne olarak görüntüle"
}
},
@@ -5173,7 +5172,6 @@
"playlist-next": "Sonraki panoya git",
"playlist-previous": "Önceki panoya git",
"playlist-stop": "Oynatma listesini durdur",
- "public-dashboard": "Herkese açık",
"refresh": "Panoyu yenile",
"save": "Panoyu kaydet",
"save-dashboard": {
@@ -5474,15 +5472,9 @@
"type": "Tür"
},
"dashboard-preview-banner": {
- "not-saved": "Değer henüz Grafana veri tabanına kaydedilmedi",
"not-yet-saved": "Değer Grafana veri tabanına kaydedilmedi",
- "open-pull-request-in-git-hub": "GitHub'da çekme isteği aç",
- "title-dashboard-loaded-branch-git-hub": "Bu pano, GitHub'daki bir daldan yüklendi.",
"title-dashboard-loaded-external-repository": "Bu pano, haricî bir depodan yüklendi.",
- "title-dashboard-loaded-request-git-hub": "Bu pano, GitHub'daki bir çekme isteğinden yüklendi.",
- "title-error-loading-dashboard": "Pano yüklenirken hata oluştu",
- "value-not-saved": "Değer henüz Grafana veri tabanına kaydedilmedi",
- "view-pull-request-in-git-hub": "GitHub'da çekme isteğini görüntüle"
+ "title-error-loading-dashboard": "Pano yüklenirken hata oluştu"
},
"dashboard-scene": {
"text": {
@@ -7217,6 +7209,7 @@
"when": "NE ZAMAN"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "Çalıştırma"
},
"math": {
@@ -8503,7 +8496,7 @@
"usage-count_other": "{{count}} panoda kullanılıyor"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "Ada veya açıklamaya göre ara"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "Kütüphane paneli yükleniyor..."
@@ -8644,12 +8637,12 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_one": "",
+ "indexed-label_other": "",
+ "parsedl-label_one": "",
+ "parsedl-label_other": "",
+ "structured-metadata_one": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8706,6 +8699,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8719,9 +8713,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10311,6 +10307,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "Bu özellik şu anda aktif geliştirme aşamasındadır. En iyi deneyim ve en yeni geliştirmeler için Grafana'nın <2>gecelik derleme2> sürümünü kullanmanızı öneririz."
@@ -11762,6 +11769,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/zh-Hans/grafana.json b/public/locales/zh-Hans/grafana.json
index 0d0c16a9ff1..09902858965 100644
--- a/public/locales/zh-Hans/grafana.json
+++ b/public/locales/zh-Hans/grafana.json
@@ -4381,7 +4381,6 @@
}
},
"render-left-actions": {
- "text-public": "公开",
"tooltip-view-as-scene": "作为场景查看"
}
},
@@ -5154,7 +5153,6 @@
"playlist-next": "前往下一个仪表板",
"playlist-previous": "前往上一个仪表板",
"playlist-stop": "停止播放列表",
- "public-dashboard": "公开",
"refresh": "刷新仪表板",
"save": "保存仪表板",
"save-dashboard": {
@@ -5455,15 +5453,9 @@
"type": "类型"
},
"dashboard-preview-banner": {
- "not-saved": "该值尚未保存在 Grafana 数据库中",
"not-yet-saved": "该值未保存在 Grafana 数据库中",
- "open-pull-request-in-git-hub": "在 GitHub 中打开拉取请求",
- "title-dashboard-loaded-branch-git-hub": "此数据面板从 GitHub 的分支加载。",
"title-dashboard-loaded-external-repository": "此数据面板从外部存储库加载",
- "title-dashboard-loaded-request-git-hub": "此数据面板从 GitHub 的拉取请求加载。",
- "title-error-loading-dashboard": "加载数据面板时出错",
- "value-not-saved": "该值尚未保存在 Grafana 数据库中",
- "view-pull-request-in-git-hub": "在 GitHub 中查看拉取请求"
+ "title-error-loading-dashboard": "加载数据面板时出错"
},
"dashboard-scene": {
"text": {
@@ -7196,6 +7188,7 @@
"when": "满足以下条件时"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "运算"
},
"math": {
@@ -8479,7 +8472,7 @@
"usage-count_other": "用于 {{count}} 个数据面板"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "按名称或描述搜索"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "正在加载库面板..."
@@ -8618,12 +8611,9 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_other": "",
+ "parsedl-label_other": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8680,6 +8670,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8693,9 +8684,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10282,6 +10275,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "此功能目前正在积极开发中。为了获得最佳体验和最新改进,我们建议您使用 Grafana 的<2>夜间版本2>。"
@@ -11726,6 +11730,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/public/locales/zh-Hant/grafana.json b/public/locales/zh-Hant/grafana.json
index 52210f14da4..b0655b9c6ca 100644
--- a/public/locales/zh-Hant/grafana.json
+++ b/public/locales/zh-Hant/grafana.json
@@ -4381,7 +4381,6 @@
}
},
"render-left-actions": {
- "text-public": "公共",
"tooltip-view-as-scene": "以場景形式檢視"
}
},
@@ -5154,7 +5153,6 @@
"playlist-next": "前往下一個儀表板",
"playlist-previous": "前往上一個儀表板",
"playlist-stop": "停止播放清單",
- "public-dashboard": "公共",
"refresh": "重新整理儀表板",
"save": "儲存儀表板",
"save-dashboard": {
@@ -5455,15 +5453,9 @@
"type": "類型"
},
"dashboard-preview-banner": {
- "not-saved": "該數值尚未儲存在 Grafana 資料庫中",
"not-yet-saved": "該數值未儲存在 Grafana 資料庫中",
- "open-pull-request-in-git-hub": "在 GitHub 中開啟拉取請求",
- "title-dashboard-loaded-branch-git-hub": "此儀表板是從 GitHub 的分支載入。",
"title-dashboard-loaded-external-repository": "此儀表板是從外部存放庫載入",
- "title-dashboard-loaded-request-git-hub": "此儀表板是從 GitHub 的拉取請求載入。",
- "title-error-loading-dashboard": "載入控制面板發生錯誤",
- "value-not-saved": "該數值尚未儲存在 Grafana 資料庫中",
- "view-pull-request-in-git-hub": "在 GitHub 中檢視拉取請求"
+ "title-error-loading-dashboard": "載入控制面板發生錯誤"
},
"dashboard-scene": {
"text": {
@@ -7196,6 +7188,7 @@
"when": "當"
},
"expression-query-editor": {
+ "helper-text-sql": "",
"label-operation": "操作"
},
"math": {
@@ -8479,7 +8472,7 @@
"usage-count_other": "用於 {{count}} 個儀表板"
},
"library-panels-search": {
- "placeholder-search-by-name-or-description": "按名稱或描述搜尋"
+ "placeholder-search-by-name-or-description": ""
},
"loading-indicator": {
"loading-library-panel": "正在載入資料庫面板…"
@@ -8618,12 +8611,9 @@
"fields": {
"type": {
"loki": {
- "indexed-label": "",
- "indexed-label-plural": "",
- "parsed-label-plural": "",
- "parsedl-label": "",
- "structured-metadata": "",
- "structured-metadata-plural": ""
+ "indexed-label_other": "",
+ "parsedl-label_other": "",
+ "structured-metadata_other": ""
}
}
},
@@ -8680,6 +8670,7 @@
"close": "",
"copy-shortlink": "",
"copy-to-clipboard": "",
+ "displayed-fields-section": "",
"fields": {
"adhoc-statistics": "",
"copy-value-to-clipboard": "",
@@ -8693,9 +8684,11 @@
"fields-section": "",
"hide-log-line": "",
"links-section": "",
+ "log-line-field": "",
"log-line-section": "",
"no-details": "",
"pin-line": "",
+ "remove-displayed-field": "",
"search": {
"no-results": ""
},
@@ -10282,6 +10275,17 @@
"label-workflow": ""
}
},
+ "provisioned-resource-preview-banner": {
+ "preview-banner": {
+ "not-saved": "",
+ "open-pull-request-in-git-hub": "",
+ "view-pull-request-in-git-hub": ""
+ },
+ "title-dashboard-loaded-branch-git-hub": "",
+ "title-dashboard-loaded-pull-request-git-hub": "",
+ "title-folder-created-branch-git-hub": "",
+ "title-folder-created-pull-request-git-hub": ""
+ },
"provisioning": {
"banner": {
"message": "此功能目前正在積極開發中。為了獲得最佳體驗和最新改進版本,建議使用 Grafana 的<2>夜間版本2>。"
@@ -11726,6 +11730,14 @@
"name-show-table-footer": "",
"name-show-table-header": "",
"name-wrap-header-text": "",
+ "pill-cell-options-editor": {
+ "description-color-mode": "",
+ "description-fixed-color": "",
+ "description-value-mappings-info": "",
+ "label-color-mode": "",
+ "label-fixed-color": "",
+ "label-value-mappings-info": ""
+ },
"placeholder-column-width": "",
"placeholder-fields": ""
},
diff --git a/yarn.lock b/yarn.lock
index 4039baa5714..6f8069078d2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2720,7 +2720,7 @@ __metadata:
"@emotion/css": "npm:11.13.5"
"@grafana/data": "npm:12.1.0-pre"
"@grafana/e2e-selectors": "npm:12.1.0-pre"
- "@grafana/lezer-logql": "npm:0.2.7"
+ "@grafana/lezer-logql": "npm:0.2.8"
"@grafana/llm": "npm:0.22.1"
"@grafana/monaco-logql": "npm:^0.0.8"
"@grafana/plugin-configs": "npm:12.1.0-pre"
@@ -3283,12 +3283,12 @@ __metadata:
languageName: unknown
linkType: soft
-"@grafana/lezer-logql@npm:0.2.7":
- version: 0.2.7
- resolution: "@grafana/lezer-logql@npm:0.2.7"
+"@grafana/lezer-logql@npm:0.2.8":
+ version: 0.2.8
+ resolution: "@grafana/lezer-logql@npm:0.2.8"
peerDependencies:
"@lezer/lr": ^1.0.0
- checksum: 10/606a9dc77b3b3751e1f325d6b1a8994b1bafef7fe0f6f3980ee7d184244b373f828960f46a748746e765615352ed8928d10f22ff06cede588fcc9d32e70a68d8
+ checksum: 10/56b31f9479037201b07d27602c023a2c2373758f232b02a4e5c501dbfabe6f708ddd2a4f8d059b5aad576297137bc2836ed3f520eceee6ffcd3001ad53c73f5c
languageName: node
linkType: hard
@@ -3714,7 +3714,7 @@ __metadata:
"@testing-library/jest-dom": "npm:6.6.3"
"@testing-library/react": "npm:16.2.0"
"@testing-library/user-event": "npm:14.6.1"
- "@types/chance": "npm:1.1.6"
+ "@types/chance": "npm:^1.1.7"
"@types/common-tags": "npm:^1.8.0"
"@types/d3": "npm:7.4.3"
"@types/hoist-non-react-statics": "npm:3.3.6"
@@ -3738,7 +3738,7 @@ __metadata:
"@types/tinycolor2": "npm:1.4.6"
"@types/uuid": "npm:10.0.0"
calculate-size: "npm:1.1.1"
- chance: "npm:1.1.12"
+ chance: "npm:^1.1.13"
classnames: "npm:2.5.1"
common-tags: "npm:1.8.2"
core-js: "npm:3.40.0"
@@ -8902,10 +8902,10 @@ __metadata:
languageName: node
linkType: hard
-"@types/chance@npm:1.1.6, @types/chance@npm:^1.1.3":
- version: 1.1.6
- resolution: "@types/chance@npm:1.1.6"
- checksum: 10/f4366f1b3144d143af3e6f0fad2ed1db7b9bdfa7d82d40944e9619d57fe7e6b60e8c1452f47a8ededa6b2188932879518628ecd9aac81c40384ded39c26338ba
+"@types/chance@npm:^1.1.7":
+ version: 1.1.7
+ resolution: "@types/chance@npm:1.1.7"
+ checksum: 10/5b3bf4ef0b7a2f6554f7767d7f081b4f613b45e74e74450d4da9c10cd12162420fc6ff5bb0abea143d6f7c43b62776b7a0e75d242cbe25c729fe020a1735e16f
languageName: node
linkType: hard
@@ -11726,21 +11726,21 @@ __metadata:
languageName: node
linkType: hard
-"autoprefixer@npm:10.4.20":
- version: 10.4.20
- resolution: "autoprefixer@npm:10.4.20"
+"autoprefixer@npm:10.4.21":
+ version: 10.4.21
+ resolution: "autoprefixer@npm:10.4.21"
dependencies:
- browserslist: "npm:^4.23.3"
- caniuse-lite: "npm:^1.0.30001646"
+ browserslist: "npm:^4.24.4"
+ caniuse-lite: "npm:^1.0.30001702"
fraction.js: "npm:^4.3.7"
normalize-range: "npm:^0.1.2"
- picocolors: "npm:^1.0.1"
+ picocolors: "npm:^1.1.1"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
postcss: ^8.1.0
bin:
autoprefixer: bin/autoprefixer
- checksum: 10/d3c4b562fc4af2393623a0207cc336f5b9f94c4264ae1c316376904c279702ce2b12dc3f27205f491195d1e29bb52ffc269970ceb0f271f035fadee128a273f7
+ checksum: 10/5d7aeee78ef362a6838e12312908516a8ac5364414175273e5cff83bbff67612755b93d567f3aa01ce318342df48aeab4b291847b5800c780e58c458f61a98a6
languageName: node
linkType: hard
@@ -12287,17 +12287,17 @@ __metadata:
languageName: node
linkType: hard
-"browserslist@npm:^4.0.0, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.23.3, browserslist@npm:^4.24.0, browserslist@npm:^4.24.3":
- version: 4.25.0
- resolution: "browserslist@npm:4.25.0"
+"browserslist@npm:^4.0.0, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.24.0, browserslist@npm:^4.24.3, browserslist@npm:^4.24.4, browserslist@npm:^4.24.5":
+ version: 4.25.1
+ resolution: "browserslist@npm:4.25.1"
dependencies:
- caniuse-lite: "npm:^1.0.30001718"
- electron-to-chromium: "npm:^1.5.160"
+ caniuse-lite: "npm:^1.0.30001726"
+ electron-to-chromium: "npm:^1.5.173"
node-releases: "npm:^2.0.19"
update-browserslist-db: "npm:^1.1.3"
bin:
browserslist: cli.js
- checksum: 10/4a5442b1a0d09c4c64454f184b8fed17d8c3e202034bf39de28f74497d7bd28dddee121b2bab4e34825fe0ed4c166d84e32a39f576c76fce73c1f8f05e4b6ee6
+ checksum: 10/bfb5511b425886279bbe2ea44d10e340c8aea85866c9d45083c13491d049b6362e254018c0afbf56d41ceeb64f994957ea8ae98dbba74ef1e54ef901c8732987
languageName: node
linkType: hard
@@ -12567,10 +12567,10 @@ __metadata:
languageName: node
linkType: hard
-"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001646, caniuse-lite@npm:^1.0.30001718":
- version: 1.0.30001723
- resolution: "caniuse-lite@npm:1.0.30001723"
- checksum: 10/edab89e84a2b257cf640f0bac1f25f92c699ade86143b2affc73403468f894023416a9f4a99e5345c933956990b005a2facfb87ac4517c8ccb588819bb62453b
+"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001726":
+ version: 1.0.30001727
+ resolution: "caniuse-lite@npm:1.0.30001727"
+ checksum: 10/6155a4141332c337d6317325bea58a09036a65f45bd9bd834ec38978b40c27d214baa04d25b21a5661664f3fbd00cb830e2bdb7eee8df09970bdd98a71f4dabf
languageName: node
linkType: hard
@@ -12677,10 +12677,10 @@ __metadata:
languageName: node
linkType: hard
-"chance@npm:1.1.12, chance@npm:^1.0.10":
- version: 1.1.12
- resolution: "chance@npm:1.1.12"
- checksum: 10/8700d5a66e27b47f4bdcf68f48489e1a490f39cd8bc8e39cac67c089b3f8d04b4bbc6710db0e85e802ad698cf3440d92784861208d2c248820355404b85b3f30
+"chance@npm:^1.1.13":
+ version: 1.1.13
+ resolution: "chance@npm:1.1.13"
+ checksum: 10/968e31ce9b8ce554c8a84fb66d85f6d06a33517bf21355ab760e347a0aaaece0652a23c791406826d4efe619b1aa4e7b66fb42acbd07859ba36ec2498a167b8c
languageName: node
linkType: hard
@@ -12849,15 +12849,15 @@ __metadata:
languageName: node
linkType: hard
-"chrome-remote-interface@npm:0.33.2":
- version: 0.33.2
- resolution: "chrome-remote-interface@npm:0.33.2"
+"chrome-remote-interface@npm:0.33.3":
+ version: 0.33.3
+ resolution: "chrome-remote-interface@npm:0.33.3"
dependencies:
commander: "npm:2.11.x"
ws: "npm:^7.2.0"
bin:
chrome-remote-interface: bin/client.js
- checksum: 10/fa82c76c5af629f5fbccb22c383604650f8679571385b8610783fde6f006b899c48e1522be551fd9670de59c1a2d93beb152a55651f24ba9c91ca0f8df3f581c
+ checksum: 10/65d07afc8f97fad6326bd94f0c4ef004d76b16841015c72d09aefbfa4df62b47407067a01c886535a706c36b23070b40fc3edb96444665438efa1d4f65cc3db8
languageName: node
linkType: hard
@@ -13933,14 +13933,14 @@ __metadata:
languageName: node
linkType: hard
-"css-minimizer-webpack-plugin@npm:7.0.0":
- version: 7.0.0
- resolution: "css-minimizer-webpack-plugin@npm:7.0.0"
+"css-minimizer-webpack-plugin@npm:7.0.2":
+ version: 7.0.2
+ resolution: "css-minimizer-webpack-plugin@npm:7.0.2"
dependencies:
"@jridgewell/trace-mapping": "npm:^0.3.25"
- cssnano: "npm:^7.0.1"
+ cssnano: "npm:^7.0.4"
jest-worker: "npm:^29.7.0"
- postcss: "npm:^8.4.38"
+ postcss: "npm:^8.4.40"
schema-utils: "npm:^4.2.0"
serialize-javascript: "npm:^6.0.2"
peerDependencies:
@@ -13958,7 +13958,7 @@ __metadata:
optional: true
lightningcss:
optional: true
- checksum: 10/47d8f8a38c97496759f1676b5344231d48bfb205cc272e163a113d4cd40daddd17f8eb719d1f1071cf3ec4d62fd83537801cba598d7c653657aa97f1461e4a8b
+ checksum: 10/80ada5f059900a3b474e33ff0f10c0e5f5a37b7525fa7ef30812b6049bcbc28fbda1d703d8f76724a97449114306de5cd7a7af15003a16784e6c9cc374dfedc8
languageName: node
linkType: hard
@@ -14098,64 +14098,64 @@ __metadata:
languageName: node
linkType: hard
-"cssnano-preset-default@npm:^7.0.6":
- version: 7.0.6
- resolution: "cssnano-preset-default@npm:7.0.6"
+"cssnano-preset-default@npm:^7.0.7":
+ version: 7.0.7
+ resolution: "cssnano-preset-default@npm:7.0.7"
dependencies:
- browserslist: "npm:^4.23.3"
+ browserslist: "npm:^4.24.5"
css-declaration-sorter: "npm:^7.2.0"
- cssnano-utils: "npm:^5.0.0"
- postcss-calc: "npm:^10.0.2"
- postcss-colormin: "npm:^7.0.2"
- postcss-convert-values: "npm:^7.0.4"
- postcss-discard-comments: "npm:^7.0.3"
- postcss-discard-duplicates: "npm:^7.0.1"
- postcss-discard-empty: "npm:^7.0.0"
- postcss-discard-overridden: "npm:^7.0.0"
- postcss-merge-longhand: "npm:^7.0.4"
- postcss-merge-rules: "npm:^7.0.4"
- postcss-minify-font-values: "npm:^7.0.0"
- postcss-minify-gradients: "npm:^7.0.0"
- postcss-minify-params: "npm:^7.0.2"
- postcss-minify-selectors: "npm:^7.0.4"
- postcss-normalize-charset: "npm:^7.0.0"
- postcss-normalize-display-values: "npm:^7.0.0"
- postcss-normalize-positions: "npm:^7.0.0"
- postcss-normalize-repeat-style: "npm:^7.0.0"
- postcss-normalize-string: "npm:^7.0.0"
- postcss-normalize-timing-functions: "npm:^7.0.0"
- postcss-normalize-unicode: "npm:^7.0.2"
- postcss-normalize-url: "npm:^7.0.0"
- postcss-normalize-whitespace: "npm:^7.0.0"
- postcss-ordered-values: "npm:^7.0.1"
- postcss-reduce-initial: "npm:^7.0.2"
- postcss-reduce-transforms: "npm:^7.0.0"
- postcss-svgo: "npm:^7.0.1"
- postcss-unique-selectors: "npm:^7.0.3"
+ cssnano-utils: "npm:^5.0.1"
+ postcss-calc: "npm:^10.1.1"
+ postcss-colormin: "npm:^7.0.3"
+ postcss-convert-values: "npm:^7.0.5"
+ postcss-discard-comments: "npm:^7.0.4"
+ postcss-discard-duplicates: "npm:^7.0.2"
+ postcss-discard-empty: "npm:^7.0.1"
+ postcss-discard-overridden: "npm:^7.0.1"
+ postcss-merge-longhand: "npm:^7.0.5"
+ postcss-merge-rules: "npm:^7.0.5"
+ postcss-minify-font-values: "npm:^7.0.1"
+ postcss-minify-gradients: "npm:^7.0.1"
+ postcss-minify-params: "npm:^7.0.3"
+ postcss-minify-selectors: "npm:^7.0.5"
+ postcss-normalize-charset: "npm:^7.0.1"
+ postcss-normalize-display-values: "npm:^7.0.1"
+ postcss-normalize-positions: "npm:^7.0.1"
+ postcss-normalize-repeat-style: "npm:^7.0.1"
+ postcss-normalize-string: "npm:^7.0.1"
+ postcss-normalize-timing-functions: "npm:^7.0.1"
+ postcss-normalize-unicode: "npm:^7.0.3"
+ postcss-normalize-url: "npm:^7.0.1"
+ postcss-normalize-whitespace: "npm:^7.0.1"
+ postcss-ordered-values: "npm:^7.0.2"
+ postcss-reduce-initial: "npm:^7.0.3"
+ postcss-reduce-transforms: "npm:^7.0.1"
+ postcss-svgo: "npm:^7.0.2"
+ postcss-unique-selectors: "npm:^7.0.4"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/686e7652d01ad4337dbad17b22fdb9cf132cf4664fddd05194da13a1f44f1177697745bbc6da73083941356280e89fe2cceacb6f422cc4522d70ff51db83cd63
+ postcss: ^8.4.32
+ checksum: 10/1ca9b739531acc2dff66347cc1b6195da0549058b5b00b9d36c3f241535ad67476218f61201cfb15e8b460357ec42414aa53bf78a7f01ee26ac26b7852e6c244
languageName: node
linkType: hard
-"cssnano-utils@npm:^5.0.0":
- version: 5.0.0
- resolution: "cssnano-utils@npm:5.0.0"
+"cssnano-utils@npm:^5.0.1":
+ version: 5.0.1
+ resolution: "cssnano-utils@npm:5.0.1"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/89ed5b8ca554697b4ae285e0d3e134fccc9a0471adda57c8fba17a2bace2f062b9fcf7aeaf66fbd7fabddca8a15a6b1e5ccb70a2783421ae1ac164f779d9f24e
+ postcss: ^8.4.32
+ checksum: 10/cdf37315d3cf9726e10ce842b18e148e4df1d1d18d292540e724d5a96994901abc631c8894328c39ab70c864449a8a83f8fc117114fdcbade204e5e65898af90
languageName: node
linkType: hard
-"cssnano@npm:^7.0.1":
- version: 7.0.6
- resolution: "cssnano@npm:7.0.6"
+"cssnano@npm:^7.0.4":
+ version: 7.0.7
+ resolution: "cssnano@npm:7.0.7"
dependencies:
- cssnano-preset-default: "npm:^7.0.6"
- lilconfig: "npm:^3.1.2"
+ cssnano-preset-default: "npm:^7.0.7"
+ lilconfig: "npm:^3.1.3"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/12b1e1f2b52ff2ba0ecb470e51f8fb3298d976bf91a51c7d2854793ea1e2af5d3c40385a85ad82d2117c84b9528d08f4bfecbb14949c6014d953dae34260952b
+ postcss: ^8.4.32
+ checksum: 10/c5b3123757834537f818e0f3eb6b20da51a194fefed599632f7ddd600c9e25d38abe38a22582a579660a49368a146c294e2096b2837cbeeda51ddfc85b108601
languageName: node
linkType: hard
@@ -15384,10 +15384,10 @@ __metadata:
languageName: node
linkType: hard
-"electron-to-chromium@npm:^1.5.160":
- version: 1.5.167
- resolution: "electron-to-chromium@npm:1.5.167"
- checksum: 10/078093a38e7295e575f381943f62914f49b53dd73506af2ce3e59332835c42b487ad02ff1207dfdcb33a5886d74a98e352c04431c0537366d9999a79c7d15c94
+"electron-to-chromium@npm:^1.5.173":
+ version: 1.5.180
+ resolution: "electron-to-chromium@npm:1.5.180"
+ checksum: 10/8d7f68650427f6bcb107ee1dcbe18f68b5c582601653095bec653fa898bd8427be4b1836581ce74405dca7cb36ebfc265a85c186e750b4de6e6f3ac4cfeef71b
languageName: node
linkType: hard
@@ -18122,7 +18122,7 @@ __metadata:
"@grafana/flamegraph": "workspace:*"
"@grafana/google-sdk": "npm:0.3.2"
"@grafana/i18n": "workspace:*"
- "@grafana/lezer-logql": "npm:0.2.7"
+ "@grafana/lezer-logql": "npm:0.2.8"
"@grafana/llm": "npm:0.22.1"
"@grafana/monaco-logql": "npm:^0.0.8"
"@grafana/o11y-ds-frontend": "workspace:*"
@@ -18178,7 +18178,7 @@ __metadata:
"@testing-library/user-event": "npm:14.6.1"
"@types/babel__core": "npm:^7"
"@types/babel__preset-env": "npm:^7"
- "@types/chance": "npm:^1.1.3"
+ "@types/chance": "npm:^1.1.7"
"@types/common-tags": "npm:^1.8.0"
"@types/confusing-browser-globals": "npm:^1"
"@types/d3": "npm:7.4.3"
@@ -18238,15 +18238,15 @@ __metadata:
"@visx/tooltip": "npm:3.12.0"
"@welldone-software/why-did-you-render": "npm:8.0.3"
ansicolor: "npm:2.0.3"
- autoprefixer: "npm:10.4.20"
+ autoprefixer: "npm:10.4.21"
babel-loader: "npm:9.2.1"
baron: "npm:3.0.3"
blob-polyfill: "npm:9.0.20240710"
brace: "npm:0.11.1"
browserslist: "npm:^4.21.4"
centrifuge: "npm:5.3.5"
- chance: "npm:^1.0.10"
- chrome-remote-interface: "npm:0.33.2"
+ chance: "npm:^1.1.13"
+ chrome-remote-interface: "npm:0.33.3"
classnames: "npm:2.5.1"
codeowners: "npm:^5.1.1"
combokeys: "npm:^3.0.0"
@@ -18258,7 +18258,7 @@ __metadata:
crashme: "npm:0.0.15"
croner: "npm:^9.0.0"
css-loader: "npm:7.1.2"
- css-minimizer-webpack-plugin: "npm:7.0.0"
+ css-minimizer-webpack-plugin: "npm:7.0.2"
cypress: "npm:14.3.2"
cypress-file-upload: "npm:5.0.8"
cypress-recurse: "npm:^1.35.3"
@@ -21787,7 +21787,7 @@ __metadata:
languageName: node
linkType: hard
-"lilconfig@npm:^3.1.2, lilconfig@npm:^3.1.3":
+"lilconfig@npm:^3.1.3":
version: 3.1.3
resolution: "lilconfig@npm:3.1.3"
checksum: 10/b932ce1af94985f0efbe8896e57b1f814a48c8dbd7fc0ef8469785c6303ed29d0090af3ccad7e36b626bfca3a4dc56cc262697e9a8dd867623cf09a39d54e4c3
@@ -23295,12 +23295,12 @@ __metadata:
languageName: node
linkType: hard
-"nanoid@npm:^3.3.8":
- version: 3.3.8
- resolution: "nanoid@npm:3.3.8"
+"nanoid@npm:^3.3.11, nanoid@npm:^3.3.8":
+ version: 3.3.11
+ resolution: "nanoid@npm:3.3.11"
bin:
nanoid: bin/nanoid.cjs
- checksum: 10/2d1766606cf0d6f47b6f0fdab91761bb81609b2e3d367027aff45e6ee7006f660fb7e7781f4a34799fe6734f1268eeed2e37a5fdee809ade0c2d4eb11b0f9c40
+ checksum: 10/73b5afe5975a307aaa3c95dfe3334c52cdf9ae71518176895229b8d65ab0d1c0417dd081426134eb7571c055720428ea5d57c645138161e7d10df80815527c48
languageName: node
linkType: hard
@@ -25105,7 +25105,7 @@ __metadata:
languageName: node
linkType: hard
-"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.1":
+"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1":
version: 1.1.1
resolution: "picocolors@npm:1.1.1"
checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045
@@ -25303,79 +25303,79 @@ __metadata:
languageName: node
linkType: hard
-"postcss-calc@npm:^10.0.2":
- version: 10.0.2
- resolution: "postcss-calc@npm:10.0.2"
+"postcss-calc@npm:^10.1.1":
+ version: 10.1.1
+ resolution: "postcss-calc@npm:10.1.1"
dependencies:
- postcss-selector-parser: "npm:^6.1.2"
+ postcss-selector-parser: "npm:^7.0.0"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
postcss: ^8.4.38
- checksum: 10/12d497e632b4a12f7d33507ed6f74db2dd01f9b9cc1f9986271af16b118d25f959dc255777a91d742e0431f400a90b8540d00533fc0513f34c1840a491cf2bee
+ checksum: 10/16a25ec594cfbbda439fd2939820f78ed4e7b8b5ab458aed7283b05fffabe68e1d4e1f4821fac798095f10539371676cd690bd27927adefab1911ff69b33d62c
languageName: node
linkType: hard
-"postcss-colormin@npm:^7.0.2":
- version: 7.0.2
- resolution: "postcss-colormin@npm:7.0.2"
+"postcss-colormin@npm:^7.0.3":
+ version: 7.0.3
+ resolution: "postcss-colormin@npm:7.0.3"
dependencies:
- browserslist: "npm:^4.23.3"
+ browserslist: "npm:^4.24.5"
caniuse-api: "npm:^3.0.0"
colord: "npm:^2.9.3"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/cb83d95d21668c770e5268f50ec6f8cd5d991d65123bafd3aa4a697580609c62d0078e704c4b7820db57638bf386084b253885b1e86263f580e8a393a687e973
+ postcss: ^8.4.32
+ checksum: 10/b9016d205eaf61a25efb187264a2ce35cb59aa1734b946268abcd747b5796e0d855c081b460ead4042a17c6806e011b57ee543b9e1f6312620f8daf661a7e40c
languageName: node
linkType: hard
-"postcss-convert-values@npm:^7.0.4":
- version: 7.0.4
- resolution: "postcss-convert-values@npm:7.0.4"
+"postcss-convert-values@npm:^7.0.5":
+ version: 7.0.5
+ resolution: "postcss-convert-values@npm:7.0.5"
dependencies:
- browserslist: "npm:^4.23.3"
+ browserslist: "npm:^4.24.5"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/077481cc98514965acf335cdacae4f604be86f4153ed3bcfdd2c4c54058182d0b472f859931d55d9aeb01600f08fff6a88a21539adbb6169019fda8b22f064ef
+ postcss: ^8.4.32
+ checksum: 10/67920f9ba823a6f6aa3b46c3a098c2d4a7a2a32349971cfa6ce986e08e7cbae6badeb23de680d36d1439e7d3f2cdbf26f5ee080a66f2823931c1d3f8146bc2a6
languageName: node
linkType: hard
-"postcss-discard-comments@npm:^7.0.3":
- version: 7.0.3
- resolution: "postcss-discard-comments@npm:7.0.3"
+"postcss-discard-comments@npm:^7.0.4":
+ version: 7.0.4
+ resolution: "postcss-discard-comments@npm:7.0.4"
dependencies:
- postcss-selector-parser: "npm:^6.1.2"
+ postcss-selector-parser: "npm:^7.1.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/f7c994df0d2de75d876f0db7ebd5b63718ef7ee5336a35f5f753f8ea115ecf8be26d5d2ad8800e833f18b33da6e018af82de7b5f0aa69e6338d3e0aff46348d4
+ postcss: ^8.4.32
+ checksum: 10/a09ac248bfbd6f2baa72b84873a876f4113df0fb5e9dd10808f6bbb310473fcd7905cc4639dbfd3ad8a5444053d42f7bb644a6934e95305820bdedc731d3c80a
languageName: node
linkType: hard
-"postcss-discard-duplicates@npm:^7.0.1":
+"postcss-discard-duplicates@npm:^7.0.2":
+ version: 7.0.2
+ resolution: "postcss-discard-duplicates@npm:7.0.2"
+ peerDependencies:
+ postcss: ^8.4.32
+ checksum: 10/2da841b5c0117528e56e1ccda28924339c03fdb93dab61b767cebb9a9e4a2a077498d00e0c97c9ec36a534f98d6f358e6236f30913c184f90d51f6d302f4f0f6
+ languageName: node
+ linkType: hard
+
+"postcss-discard-empty@npm:^7.0.1":
version: 7.0.1
- resolution: "postcss-discard-duplicates@npm:7.0.1"
+ resolution: "postcss-discard-empty@npm:7.0.1"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/0c757bb542caf017740157a2e29186ae83085bb42cd8e5ea3649fa039cc3d505ccaca739b1aed6c89e1f0a7f18440f77c3f49e4b99f45efd767c863d6647af94
+ postcss: ^8.4.32
+ checksum: 10/39977000657e78202da891ae6300593e40e1c8a756f1d9707087390e47a410739c394c35e902130556efb5808e6701b3b34b89facf7a9e56533d617dd9597049
languageName: node
linkType: hard
-"postcss-discard-empty@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-discard-empty@npm:7.0.0"
+"postcss-discard-overridden@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-discard-overridden@npm:7.0.1"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/0c5cea198057727765855dbb43b5f16bd4d7da8c783fea8d18ad445ad3457681a7bc1696fda6bf16313e6fadaf86d519470aff68f02378b8b413e60023b70d57
- languageName: node
- linkType: hard
-
-"postcss-discard-overridden@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-discard-overridden@npm:7.0.0"
- peerDependencies:
- postcss: ^8.4.31
- checksum: 10/e41c448305f96a93ec97a4a8ce2932a123283898041ff38ed2f7a35fcb76d937f448c2c8efb7d74d53d38b4ebf9163ae12935297bb99baec2f6751776b0ea29b
+ postcss: ^8.4.32
+ checksum: 10/a0e67314b696591396e6bb371cdd57537e06f63e9fa0d742fe678decf600bed0cdcfa481487bce91b3732bdd7c46338f9102ccc8180c41032811e99962883715
languageName: node
linkType: hard
@@ -25406,78 +25406,78 @@ __metadata:
languageName: node
linkType: hard
-"postcss-merge-longhand@npm:^7.0.4":
- version: 7.0.4
- resolution: "postcss-merge-longhand@npm:7.0.4"
+"postcss-merge-longhand@npm:^7.0.5":
+ version: 7.0.5
+ resolution: "postcss-merge-longhand@npm:7.0.5"
dependencies:
postcss-value-parser: "npm:^4.2.0"
- stylehacks: "npm:^7.0.4"
+ stylehacks: "npm:^7.0.5"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/b94b98a9b21bc8671aa0fba96491e8e2deea57c9bbfe9a74305400a36035b63764d8bfbdc6bda047887b665b92b91361a8bbc1cb9c14f80b3792feef19881005
+ postcss: ^8.4.32
+ checksum: 10/3378fc3a196082dfdb9acff94efbfa0de95ed86bf87f485285e775fd3c21218e5a243e363ad80b96237edb454776f7c1deea28c37afb8b96ddfaf5cfe8bd606b
languageName: node
linkType: hard
-"postcss-merge-rules@npm:^7.0.4":
- version: 7.0.4
- resolution: "postcss-merge-rules@npm:7.0.4"
+"postcss-merge-rules@npm:^7.0.5":
+ version: 7.0.5
+ resolution: "postcss-merge-rules@npm:7.0.5"
dependencies:
- browserslist: "npm:^4.23.3"
+ browserslist: "npm:^4.24.5"
caniuse-api: "npm:^3.0.0"
- cssnano-utils: "npm:^5.0.0"
- postcss-selector-parser: "npm:^6.1.2"
+ cssnano-utils: "npm:^5.0.1"
+ postcss-selector-parser: "npm:^7.1.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/f67a4f6e814c5e7ce990a3c3d699e1c1dba7e79c5cb3a11795534d47b0fa257d27465e248546b45104d8278dfcbd07d9fbceb8046fcdfac86fe6340ca3c85f9a
+ postcss: ^8.4.32
+ checksum: 10/fa490791ea5e907e4498701593252ce33df468a821e5f3acf5f126f73c8262189c13ca7a0c1645ae3d66a46a03cf930048e10d808182a3e9bec78af30a02893a
languageName: node
linkType: hard
-"postcss-minify-font-values@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-minify-font-values@npm:7.0.0"
+"postcss-minify-font-values@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-minify-font-values@npm:7.0.1"
dependencies:
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/8578c1d1d4d65ca34db5ac0cccc7b73500040e52a3abb8abc7e5b6e47e5f72c88bfe5f3b19847556a2a68082245009d693a7c098b8bc58e7f9640abba4e80194
+ postcss: ^8.4.32
+ checksum: 10/6578a1fd293e202e738ce38d91d71c08ba970f4a998edff48022cb21ec23ef26bf7d284ddb41d6e51bf20b5b5676fe142de1bd092a76d2ef982d5ee1d6b00190
languageName: node
linkType: hard
-"postcss-minify-gradients@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-minify-gradients@npm:7.0.0"
+"postcss-minify-gradients@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-minify-gradients@npm:7.0.1"
dependencies:
colord: "npm:^2.9.3"
- cssnano-utils: "npm:^5.0.0"
+ cssnano-utils: "npm:^5.0.1"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/9649e255ad954e67e0d7c2111b0f1681a93e8cba7179a547491eacf135d64596dfee9774b589d7a46ee3ace673a026113e56e734d6ab19297367f11dd3104c0e
+ postcss: ^8.4.32
+ checksum: 10/4aa782331c5d1826e549b3940eefb54e2d51f5c5a2c5f5537384bfe6eac45bfe7ba4535c03cd1642d8a27ab088f56c3682b55f5dd2c3f7969b715692e0c1102b
languageName: node
linkType: hard
-"postcss-minify-params@npm:^7.0.2":
- version: 7.0.2
- resolution: "postcss-minify-params@npm:7.0.2"
+"postcss-minify-params@npm:^7.0.3":
+ version: 7.0.3
+ resolution: "postcss-minify-params@npm:7.0.3"
dependencies:
- browserslist: "npm:^4.23.3"
- cssnano-utils: "npm:^5.0.0"
+ browserslist: "npm:^4.24.5"
+ cssnano-utils: "npm:^5.0.1"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/26b6ce4db3cdefcceb7a00b64dfbd27dee4194b55708937dddd5c4000c1f02013dc0659e62e799dc1ce1f1a697961cec55a2a746a4f59d54ccae4b68adf41768
+ postcss: ^8.4.32
+ checksum: 10/97de22d6ba0310685d33b530dbfeefa930f7ac48effe623fc8a4a59d2b98bed221d0d2edad4f2e1f4590322240d0e1e94bdb162069c40b5d7ae00c58637c90c9
languageName: node
linkType: hard
-"postcss-minify-selectors@npm:^7.0.4":
- version: 7.0.4
- resolution: "postcss-minify-selectors@npm:7.0.4"
+"postcss-minify-selectors@npm:^7.0.5":
+ version: 7.0.5
+ resolution: "postcss-minify-selectors@npm:7.0.5"
dependencies:
cssesc: "npm:^3.0.0"
- postcss-selector-parser: "npm:^6.1.2"
+ postcss-selector-parser: "npm:^7.1.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/54c74dcb098819417e95ec2b5ecdd33a2c6fdccea2346e110037c762d37644e11f83d67e6b0c93405f2b7cc28880ca0a07ad4d6618330436f7b8b84d719b85fb
+ postcss: ^8.4.32
+ checksum: 10/12580d9a17c146c9e9bb604b4887085d897554317590cee91e0f28e2a4757c18e09299365a44eae25e848e65d53b845928dfa56a9d0199d0e159d525732fbf89
languageName: node
linkType: hard
@@ -25525,136 +25525,136 @@ __metadata:
languageName: node
linkType: hard
-"postcss-normalize-charset@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-normalize-charset@npm:7.0.0"
- peerDependencies:
- postcss: ^8.4.31
- checksum: 10/a41043fb81a1d5b3b05e8b317de7fe123854a4535f9ce2904a16196a32b3565d2fd6ac59a9842e337cf1bb298dcc108cbdbc6a5d4a500aec3520d759e951a8de
- languageName: node
- linkType: hard
-
-"postcss-normalize-display-values@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-normalize-display-values@npm:7.0.0"
- dependencies:
- postcss-value-parser: "npm:^4.2.0"
- peerDependencies:
- postcss: ^8.4.31
- checksum: 10/55bbfb4dac3bf9bcc2aed30057c0bc968927b5337b372ee2dd825d6ec626c18d1481b0e8dd928d4cab70c3e8a2e6708d6115b14bebd34fe4462eb15aacff35f4
- languageName: node
- linkType: hard
-
-"postcss-normalize-positions@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-normalize-positions@npm:7.0.0"
- dependencies:
- postcss-value-parser: "npm:^4.2.0"
- peerDependencies:
- postcss: ^8.4.31
- checksum: 10/a6b982e567ddf1ad4120aaf898056f2fdbe5f6cae1d475fef22cb1f025c9bfe37df5511a4353b9f13d01feae8b1d9638c1deb70537058312262647052d004f64
- languageName: node
- linkType: hard
-
-"postcss-normalize-repeat-style@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-normalize-repeat-style@npm:7.0.0"
- dependencies:
- postcss-value-parser: "npm:^4.2.0"
- peerDependencies:
- postcss: ^8.4.31
- checksum: 10/f8ef8cf5ac6232f1d0615a97f21ea464a6930484b58421c87e0f9e626b1bb52916592f25e4f9874f424b1529807b170d8805d45878aa8293ea0608dd753230c8
- languageName: node
- linkType: hard
-
-"postcss-normalize-string@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-normalize-string@npm:7.0.0"
- dependencies:
- postcss-value-parser: "npm:^4.2.0"
- peerDependencies:
- postcss: ^8.4.31
- checksum: 10/23ea7dd7b28880dfafd0880ab782d65186ab94a4cf789b8723f9666020c7f7c8b97546e0dc46d08da3f71a873bb6db41cd69a4cafb4fde4a85f97ef83ee38bae
- languageName: node
- linkType: hard
-
-"postcss-normalize-timing-functions@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-normalize-timing-functions@npm:7.0.0"
- dependencies:
- postcss-value-parser: "npm:^4.2.0"
- peerDependencies:
- postcss: ^8.4.31
- checksum: 10/f85870b3c8132b530fb8e5c8474f1eea1d0ef69a374d5867d0300f7501803bffa55f7fad34f662d88a747ce73d552ec0f818722d2d5157cf8e5dc45a98fa552b
- languageName: node
- linkType: hard
-
-"postcss-normalize-unicode@npm:^7.0.2":
- version: 7.0.2
- resolution: "postcss-normalize-unicode@npm:7.0.2"
- dependencies:
- browserslist: "npm:^4.23.3"
- postcss-value-parser: "npm:^4.2.0"
- peerDependencies:
- postcss: ^8.4.31
- checksum: 10/cb342f7507f28c8e9c500a2d6369c6b04a85f6c6f93aaa1ab6768d0e097453480834d3f7c5fad503f9fb9e178d9011df50ceaeebe2ac68d5daaa7c8a63ad3b3f
- languageName: node
- linkType: hard
-
-"postcss-normalize-url@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-normalize-url@npm:7.0.0"
- dependencies:
- postcss-value-parser: "npm:^4.2.0"
- peerDependencies:
- postcss: ^8.4.31
- checksum: 10/c5edca0646a13d76c5347fffaaa828184e035486d7eeb2a8b31781d30de6a90f7ad3f0cffe59e8fd4c31f1525fdb85b45777745685603ac533a151c42691f601
- languageName: node
- linkType: hard
-
-"postcss-normalize-whitespace@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-normalize-whitespace@npm:7.0.0"
- dependencies:
- postcss-value-parser: "npm:^4.2.0"
- peerDependencies:
- postcss: ^8.4.31
- checksum: 10/c409362e3256ed66629fc48c63e834c9bfb598ca20587adb620bbc04fdccef4cd0d08b1f485eb8290d6a30e8dd836fecb0def38c3a49fe8503e2579e60f5bccf
- languageName: node
- linkType: hard
-
-"postcss-ordered-values@npm:^7.0.1":
+"postcss-normalize-charset@npm:^7.0.1":
version: 7.0.1
- resolution: "postcss-ordered-values@npm:7.0.1"
- dependencies:
- cssnano-utils: "npm:^5.0.0"
- postcss-value-parser: "npm:^4.2.0"
+ resolution: "postcss-normalize-charset@npm:7.0.1"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/048082c09eee021d97def02eb8fc03fb0414402b1f6925af29a862f537b66b43d7a8e8d94c552ca67cd6172230873260f4ad44f1d5bac81c553afb054d80e6a8
+ postcss: ^8.4.32
+ checksum: 10/bcec822491e3421b009c688473433164b5c80bbef48af4e47f704bee68f0b7ba2009aaf46788e698dd233d5f4e1cf444a4f59a901623c73f8458c2227b15db57
languageName: node
linkType: hard
-"postcss-reduce-initial@npm:^7.0.2":
- version: 7.0.2
- resolution: "postcss-reduce-initial@npm:7.0.2"
+"postcss-normalize-display-values@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-normalize-display-values@npm:7.0.1"
dependencies:
- browserslist: "npm:^4.23.3"
+ postcss-value-parser: "npm:^4.2.0"
+ peerDependencies:
+ postcss: ^8.4.32
+ checksum: 10/53f341c17a5487639e6f7c917ad695e059bf4aff66b3c971e008163f774337444753310def9f38dd26066ea96b136422592fc74077c38c40b3bfdfaa338d5b58
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-positions@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-normalize-positions@npm:7.0.1"
+ dependencies:
+ postcss-value-parser: "npm:^4.2.0"
+ peerDependencies:
+ postcss: ^8.4.32
+ checksum: 10/72b23ab87c97c155d2ec475fba8a8b968f7c7b42d055a79b267449d570c328d5ea4cb0002428cf26e9daa70c58655e0b931d2a5801cc407554d3f03a21ac041b
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-repeat-style@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-normalize-repeat-style@npm:7.0.1"
+ dependencies:
+ postcss-value-parser: "npm:^4.2.0"
+ peerDependencies:
+ postcss: ^8.4.32
+ checksum: 10/db677bceec8c00a1860b64932b99af937e7674b3e5c5ac333c95efb090e9abd747eca4ad51855f0fe73fbe544c3d21e58d06b39e03fd525945309743e31ec235
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-string@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-normalize-string@npm:7.0.1"
+ dependencies:
+ postcss-value-parser: "npm:^4.2.0"
+ peerDependencies:
+ postcss: ^8.4.32
+ checksum: 10/48df2eaca6f5365af31ad46fd60a32dc7b714cc5ec8ba80980e65855ddc47c03ac82077ce7ca04c90898f73d173410d1d6a104754ff487e7e5a59e3eae8325b3
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-timing-functions@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-normalize-timing-functions@npm:7.0.1"
+ dependencies:
+ postcss-value-parser: "npm:^4.2.0"
+ peerDependencies:
+ postcss: ^8.4.32
+ checksum: 10/31fb88489244334295918fa7d6af2d76c310a83abd20be0a7f1c408c54ac0c0f81b0ae7877698bf66de1f76495766e159c8871387407dfcafa0cb1a53f5f0460
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-unicode@npm:^7.0.3":
+ version: 7.0.3
+ resolution: "postcss-normalize-unicode@npm:7.0.3"
+ dependencies:
+ browserslist: "npm:^4.24.5"
+ postcss-value-parser: "npm:^4.2.0"
+ peerDependencies:
+ postcss: ^8.4.32
+ checksum: 10/fc10205655f77d6467da811fbd26aa607c519cbf162ae2ba40821cf64227233445490881119c820c6988c0943cb2f4dc755abe94cb30637001ca35cce5d07b61
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-url@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-normalize-url@npm:7.0.1"
+ dependencies:
+ postcss-value-parser: "npm:^4.2.0"
+ peerDependencies:
+ postcss: ^8.4.32
+ checksum: 10/975dd0d1b55b637d45756ec57e554b2134f77368dd3ae09be9fa6636f2f41e72422505409d7fca75c635b9b1b8ec8ec2607d84c6c85497bbfd4e7748a2992882
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-whitespace@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-normalize-whitespace@npm:7.0.1"
+ dependencies:
+ postcss-value-parser: "npm:^4.2.0"
+ peerDependencies:
+ postcss: ^8.4.32
+ checksum: 10/05a0fa74f4c8e93243053b9cc865cbddddb309b2ccb08271ca9c38ea7ece2ff43d5faa12cce87f06e40cbcf22c94443c9fa2b74ed0c6b94d72a9e67ea0381626
+ languageName: node
+ linkType: hard
+
+"postcss-ordered-values@npm:^7.0.2":
+ version: 7.0.2
+ resolution: "postcss-ordered-values@npm:7.0.2"
+ dependencies:
+ cssnano-utils: "npm:^5.0.1"
+ postcss-value-parser: "npm:^4.2.0"
+ peerDependencies:
+ postcss: ^8.4.32
+ checksum: 10/be8fb13639fb0e1ffd7d4e9bb4824d3a283c8a63a8b0dd1a654435fff1e019007c79be877940bb101bb9ebd8ba3ac18bcffd144e939890bedeb40044dcc2b9cc
+ languageName: node
+ linkType: hard
+
+"postcss-reduce-initial@npm:^7.0.3":
+ version: 7.0.3
+ resolution: "postcss-reduce-initial@npm:7.0.3"
+ dependencies:
+ browserslist: "npm:^4.24.5"
caniuse-api: "npm:^3.0.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/5a8260cbf7fa6ea12908debe23e191bb45109b29048d15e63c60df42c4ed62c860273ce9b37172d5f31c4bdb965e984962e4e6f506939a1fc49202dd7bf520c5
+ postcss: ^8.4.32
+ checksum: 10/8fd9ff4b49a2f7e1b7c51b7da637578e32a178363e3e932c80565241454dca306658dacd390ad3d73647d55dace8be8fe29278668afa32fd9d872ee7026bdbf7
languageName: node
linkType: hard
-"postcss-reduce-transforms@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-reduce-transforms@npm:7.0.0"
+"postcss-reduce-transforms@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-reduce-transforms@npm:7.0.1"
dependencies:
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/1c369a1be820a80e8bf06376476190fe2ae5a0b5a7459257d7d9b5bc0c9aed79f46026e8558fca088f7a814e632c678f67749b246901a3839f2d50b7b9ec2d41
+ postcss: ^8.4.32
+ checksum: 10/a22d07559859b9d4313d579104a25aa254695bc37dec5134de1064d1bd52b9d1f33f050fbf330170ef1105ede9aad7741bbcf9cad2221a6a5c8d529fd3cf0259
languageName: node
linkType: hard
@@ -25705,36 +25705,36 @@ __metadata:
languageName: node
linkType: hard
-"postcss-selector-parser@npm:^7.0.0":
- version: 7.0.0
- resolution: "postcss-selector-parser@npm:7.0.0"
+"postcss-selector-parser@npm:^7.0.0, postcss-selector-parser@npm:^7.1.0":
+ version: 7.1.0
+ resolution: "postcss-selector-parser@npm:7.1.0"
dependencies:
cssesc: "npm:^3.0.0"
util-deprecate: "npm:^1.0.2"
- checksum: 10/0e92be7281e2b440a8be8cf207de40a24ca7bc765577916499614d5a47827a3e658206728cc559db96803e554270516104aad919a04f91bfa8914ccef1ba14ca
+ checksum: 10/2caf09e66e2be81d45538f8afdc5439298c89bea71e9943b364e69dce9443d9c5ab33f4dd8b237f1ed7d2f38530338dcc189c1219d888159e6afb5b0afe58b19
languageName: node
linkType: hard
-"postcss-svgo@npm:^7.0.1":
- version: 7.0.1
- resolution: "postcss-svgo@npm:7.0.1"
+"postcss-svgo@npm:^7.0.2":
+ version: 7.0.2
+ resolution: "postcss-svgo@npm:7.0.2"
dependencies:
postcss-value-parser: "npm:^4.2.0"
svgo: "npm:^3.3.2"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/4196d9b7ec37ea7c427b6d3d40fa75bdae6d1fdf5a814481202138fb9b074ecc1e442b8e0202aa8c76eaaff747e2f6bfec968cfe7bc774d8a58faf8bd945ff4e
+ postcss: ^8.4.32
+ checksum: 10/8615877dffbac2bb2b971fb0e8c882ebff479c2529a0fc20937d09623fcaf35a2d934c4046188bae2534729aba1de5a1ba227630aaf96a800b6f2acdbfbf1d32
languageName: node
linkType: hard
-"postcss-unique-selectors@npm:^7.0.3":
- version: 7.0.3
- resolution: "postcss-unique-selectors@npm:7.0.3"
+"postcss-unique-selectors@npm:^7.0.4":
+ version: 7.0.4
+ resolution: "postcss-unique-selectors@npm:7.0.4"
dependencies:
- postcss-selector-parser: "npm:^6.1.2"
+ postcss-selector-parser: "npm:^7.1.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/c38ca6b5f539cae1e0e8ef0efa338f91e4e054dbd9c619e26708d787e94ce788739bbe782103f2cf35c38819233897901038292255a1726905bd04433ac9e5f2
+ postcss: ^8.4.32
+ checksum: 10/b880f96fdb20037b16ae21b48f5240a4cf8585bf3133c7894dd869711b14f3a1a82bbdecd36adc78f8c34553a46fc2199ed3e92d5031b0267ff6f43894fc00f7
languageName: node
linkType: hard
@@ -25745,7 +25745,7 @@ __metadata:
languageName: node
linkType: hard
-"postcss@npm:8.5.1, postcss@npm:^8.4.33, postcss@npm:^8.4.38, postcss@npm:^8.5.1":
+"postcss@npm:8.5.1":
version: 8.5.1
resolution: "postcss@npm:8.5.1"
dependencies:
@@ -25756,6 +25756,17 @@ __metadata:
languageName: node
linkType: hard
+"postcss@npm:^8.4.33, postcss@npm:^8.4.40, postcss@npm:^8.5.1":
+ version: 8.5.6
+ resolution: "postcss@npm:8.5.6"
+ dependencies:
+ nanoid: "npm:^3.3.11"
+ picocolors: "npm:^1.1.1"
+ source-map-js: "npm:^1.2.1"
+ checksum: 10/9e4fbe97574091e9736d0e82a591e29aa100a0bf60276a926308f8c57249698935f35c5d2f4e80de778d0cbb8dcffab4f383d85fd50c5649aca421c3df729b86
+ languageName: node
+ linkType: hard
+
"prefix-style@npm:2.0.1":
version: 2.0.1
resolution: "prefix-style@npm:2.0.1"
@@ -30048,15 +30059,15 @@ __metadata:
languageName: node
linkType: hard
-"stylehacks@npm:^7.0.4":
- version: 7.0.4
- resolution: "stylehacks@npm:7.0.4"
+"stylehacks@npm:^7.0.5":
+ version: 7.0.5
+ resolution: "stylehacks@npm:7.0.5"
dependencies:
- browserslist: "npm:^4.23.3"
- postcss-selector-parser: "npm:^6.1.2"
+ browserslist: "npm:^4.24.5"
+ postcss-selector-parser: "npm:^7.1.0"
peerDependencies:
- postcss: ^8.4.31
- checksum: 10/fc9d6b1e0b996d139a77f391df6db49ee1ab7e8fdeb32a8fa6b4c11512e72eb072470c32080171e46ebe123c9c96d763b9e4421b09c9c428985077940b6ba085
+ postcss: ^8.4.32
+ checksum: 10/798ac0f92ff4489c251550d64b903f1aa8b5946e5b09b33ebf68290b5a345257cecf98c989526a5d462b560081194fead38c4f804ec016ceb8b1b3f17ec74fc5
languageName: node
linkType: hard