mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
FieldOverride: Support data links via field overrides (#23590)
* Move xss and sanitize packages to grafana-data
* Move text, url and location utils to grafana-data
* Move grafana config types to grafana-data
* Move field display value proxy to grafana-data
* Fix
* Move data links built in vars to grafana-data
* Attach links supplier to when applying field overrides
* Prep tests
* Use links suppliers attached via field overrides
* locationUtil dependencies type
* Move sanitize-url declaration to grafana-data
* Revert "Move sanitize-url declaration to grafana-data"
This reverts commit 11db9f5e55.
* Fix typo
* fix ts vol1
* Remove import from runtime in data.... Make TS happy at the same time ;)
* Lovely TS, please shut up
* Lovely TS, please shut up vol2
* fix tests
* Fixes
* minor refactor
* Attach get links to FieldDisplayValue for seamless usage
* Update packages/grafana-data/src/field/fieldOverrides.ts
* Make storybook build
This commit is contained in:
@@ -6,5 +6,5 @@
|
||||
},
|
||||
"exclude": ["../dist", "../node_modules"],
|
||||
"extends": "../tsconfig.json",
|
||||
"include": ["../src/**/*.ts", "../src/**/*.tsx"]
|
||||
"include": ["../src/**/*.ts", "../src/**/*.tsx", "../../../public/app/types/sanitize-url.d.ts"]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState, useMemo, useContext, useRef, RefObject, memo, useEffect } from 'react';
|
||||
import usePrevious from 'react-use/lib/usePrevious';
|
||||
import { DataLinkSuggestions } from './DataLinkSuggestions';
|
||||
import { ThemeContext, DataLinkBuiltInVars, makeValue } from '../../index';
|
||||
import { ThemeContext, makeValue } from '../../index';
|
||||
import { SelectionReference } from './SelectionReference';
|
||||
import { Portal } from '../index';
|
||||
|
||||
@@ -14,7 +14,7 @@ import { css } from 'emotion';
|
||||
import { SlatePrism } from '../../slate-plugins';
|
||||
import { SCHEMA } from '../../utils/slate';
|
||||
import { stylesFactory } from '../../themes';
|
||||
import { GrafanaTheme, VariableSuggestion, VariableOrigin } from '@grafana/data';
|
||||
import { GrafanaTheme, VariableSuggestion, VariableOrigin, DataLinkBuiltInVars } from '@grafana/data';
|
||||
|
||||
const modulo = (a: number, n: number) => a - n * Math.floor(a / n);
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React from 'react';
|
||||
import { WithContextMenu } from '../ContextMenu/WithContextMenu';
|
||||
import { LinkModelSupplier } from '@grafana/data';
|
||||
import { LinkModel } from '@grafana/data';
|
||||
import { linkModelToContextMenuItems } from '../../utils/dataLinks';
|
||||
import { css } from 'emotion';
|
||||
|
||||
interface DataLinksContextMenuProps {
|
||||
children: (props: { openMenu?: React.MouseEventHandler<HTMLElement>; targetClassName?: string }) => JSX.Element;
|
||||
links?: LinkModelSupplier<any>;
|
||||
links?: () => LinkModel[];
|
||||
}
|
||||
|
||||
export const DataLinksContextMenu: React.FC<DataLinksContextMenuProps> = ({ children, links }) => {
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import React from 'react';
|
||||
import { FieldConfigEditorProps, DataLink, DataLinksFieldConfigSettings } from '@grafana/data';
|
||||
import {
|
||||
DataLink,
|
||||
DataLinksFieldConfigSettings,
|
||||
FieldConfigEditorProps,
|
||||
VariableSuggestionsScope,
|
||||
} from '@grafana/data';
|
||||
import { DataLinksInlineEditor } from '../DataLinks/DataLinksInlineEditor/DataLinksInlineEditor';
|
||||
|
||||
export const DataLinksValueEditor: React.FC<FieldConfigEditorProps<DataLink[], DataLinksFieldConfigSettings>> = ({
|
||||
@@ -12,7 +17,7 @@ export const DataLinksValueEditor: React.FC<FieldConfigEditorProps<DataLink[], D
|
||||
links={value}
|
||||
onChange={onChange}
|
||||
data={context.data}
|
||||
suggestions={context.getSuggestions ? context.getSuggestions() : []}
|
||||
suggestions={context.getSuggestions ? context.getSuggestions(VariableSuggestionsScope.Values) : []}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,14 +1,33 @@
|
||||
import React, { FC } from 'react';
|
||||
import { TableCellProps } from './types';
|
||||
import { formattedValueToString } from '@grafana/data';
|
||||
import { formattedValueToString, LinkModel } from '@grafana/data';
|
||||
|
||||
export const DefaultCell: FC<TableCellProps> = props => {
|
||||
const { field, cell, tableStyles } = props;
|
||||
const { field, cell, tableStyles, row } = props;
|
||||
let link: LinkModel<any> | undefined;
|
||||
|
||||
if (!field.display) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const displayValue = field.display(cell.value);
|
||||
return <div className={tableStyles.tableCell}>{formattedValueToString(displayValue)}</div>;
|
||||
|
||||
if (field.getLinks) {
|
||||
link = field.getLinks({
|
||||
valueRowIndex: row.index,
|
||||
})[0];
|
||||
}
|
||||
const value = formattedValueToString(displayValue);
|
||||
|
||||
return (
|
||||
<div className={tableStyles.tableCell}>
|
||||
{link ? (
|
||||
<a href={link.href} target={link.target} title={link.title}>
|
||||
{value}
|
||||
</a>
|
||||
) : (
|
||||
value
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,26 +1,11 @@
|
||||
import { ContextMenuItem } from '../components/ContextMenu/ContextMenu';
|
||||
import { LinkModelSupplier } from '@grafana/data';
|
||||
|
||||
export const DataLinkBuiltInVars = {
|
||||
keepTime: '__url_time_range',
|
||||
timeRangeFrom: '__from',
|
||||
timeRangeTo: '__to',
|
||||
includeVars: '__all_variables',
|
||||
seriesName: '__series.name',
|
||||
fieldName: '__field.name',
|
||||
valueTime: '__value.time',
|
||||
valueNumeric: '__value.numeric',
|
||||
valueText: '__value.text',
|
||||
valueRaw: '__value.raw',
|
||||
// name of the calculation represented by the value
|
||||
valueCalc: '__value.calc',
|
||||
};
|
||||
import { LinkModel } from '@grafana/data';
|
||||
|
||||
/**
|
||||
* Delays creating links until we need to open the ContextMenu
|
||||
*/
|
||||
export const linkModelToContextMenuItems: (links: LinkModelSupplier<any>) => ContextMenuItem[] = links => {
|
||||
return links.getLinks().map(link => {
|
||||
export const linkModelToContextMenuItems: (links: () => LinkModel[]) => ContextMenuItem[] = links => {
|
||||
return links().map(link => {
|
||||
return {
|
||||
label: link.title,
|
||||
// TODO: rename to href
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
},
|
||||
"exclude": ["dist", "node_modules"],
|
||||
"extends": "@grafana/tsconfig",
|
||||
"include": ["src/**/*.ts*"]
|
||||
"include": ["src/**/*.ts*", "../../public/app/types/sanitize-url.d.ts"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user