Skip to content

Commit 0a870e6

Browse files
Canvas: Element data links refactor (#90636)
Co-authored-by: Leon Sorokin <[email protected]>
1 parent d3061ab commit 0a870e6

File tree

28 files changed

+113
-83
lines changed

28 files changed

+113
-83
lines changed

docs/sources/panels-visualizations/visualizations/canvas/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,12 @@ You can configure a canvas data link to open with a single click on the element.
190190
1. Click the element to which you want to add the data link.
191191
1. In either the inline editor or panel editor, expand the **Selected element** editor.
192192
1. Scroll down to the **Data links** section and expand it.
193-
1. Toggle the **One-click** switch in the element's data links section.
193+
1. In the **One-click** section, choose **Link**.
194194
1. Disable inline editing.
195195

196196
The first data link in the list will be configured as your one-click data link. If you want to change the one-click data link, simply drag the desired data link to the top of the list.
197197

198-
{{< video-embed src="/media/docs/grafana/panels-visualizations/canvas-one-click-data-link.mp4" >}}
198+
{{< video-embed src="/media/docs/grafana/panels-visualizations/canvas-one-click-datalink-.mp4" >}}
199199

200200
## Panel options
201201

packages/grafana-data/src/field/fieldOverrides.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,6 @@ export const getLinksSupplier =
479479
href,
480480
title: replaceVariables(link.title || '', dataLinkScopedVars),
481481
target: link.targetBlank ? '_blank' : undefined,
482-
sortIndex: link.sortIndex,
483482
onClick: (evt: MouseEvent, origin: Field) => {
484483
link.onClick!({
485484
origin: origin ?? field,
@@ -495,7 +494,6 @@ export const getLinksSupplier =
495494
title: replaceVariables(link.title || '', dataLinkScopedVars),
496495
target: link.targetBlank ? '_blank' : undefined,
497496
origin: field,
498-
sortIndex: link.sortIndex,
499497
};
500498
}
501499

packages/grafana-data/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,7 @@ export {
793793
VariableOrigin,
794794
type VariableSuggestion,
795795
VariableSuggestionsScope,
796+
OneClickMode,
796797
} from './types/dataLink';
797798
export { DataFrameType } from './types/dataFrameTypes';
798799
export {

packages/grafana-data/src/types/dataLink.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ export interface LinkModel<T = any> {
9999

100100
// When a click callback exists, this is passed the raw mouse|react event
101101
onClick?: (e: any, origin?: any) => void;
102-
sortIndex?: number;
103102
}
104103

105104
/**
@@ -130,3 +129,8 @@ export interface VariableSuggestion {
130129
export enum VariableSuggestionsScope {
131130
Values = 'values',
132131
}
132+
133+
export enum OneClickMode {
134+
Link = 'link',
135+
Off = 'off',
136+
}

packages/grafana-schema/src/raw/composable/canvas/panelcfg/x/CanvasPanelCfg_types.gen.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ export interface CanvasElementOptions {
104104
connections?: Array<CanvasConnection>;
105105
constraint?: Constraint;
106106
name: string;
107-
oneClickLinks?: boolean;
108107
placement?: Placement;
109108
type: string;
110109
}

packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,20 @@ interface DataLinksInlineEditorProps {
1717
onChange: (links: DataLink[]) => void;
1818
getSuggestions: () => VariableSuggestion[];
1919
data: DataFrame[];
20-
oneClickEnabled?: boolean;
20+
showOneClick?: boolean;
2121
}
2222

2323
export const DataLinksInlineEditor = ({
2424
links,
2525
onChange,
2626
getSuggestions,
2727
data,
28-
oneClickEnabled = false,
28+
showOneClick = false,
2929
}: DataLinksInlineEditorProps) => {
3030
const [editIndex, setEditIndex] = useState<number | null>(null);
3131
const [isNew, setIsNew] = useState(false);
3232

3333
const [linksSafe, setLinksSafe] = useState<DataLink[]>([]);
34-
links?.sort((a, b) => (a.sortIndex ?? 0) - (b.sortIndex ?? 0));
3534

3635
useEffect(() => {
3736
setLinksSafe(links ?? []);
@@ -81,24 +80,20 @@ export const DataLinksInlineEditor = ({
8180
return;
8281
}
8382

84-
const copy = [...linksSafe];
85-
const link = copy[result.source.index];
86-
link.sortIndex = result.destination.index;
87-
88-
const swapLink = copy[result.destination.index];
89-
swapLink.sortIndex = result.source.index;
83+
const update = cloneDeep(linksSafe);
84+
const link = update[result.source.index];
9085

91-
copy.splice(result.source.index, 1);
92-
copy.splice(result.destination.index, 0, link);
86+
update.splice(result.source.index, 1);
87+
update.splice(result.destination.index, 0, link);
9388

94-
setLinksSafe(copy);
95-
onChange(linksSafe);
89+
setLinksSafe(update);
90+
onChange(update);
9691
};
9792

98-
const renderFirstLink = (linkJSX: ReactNode) => {
99-
if (oneClickEnabled) {
93+
const renderFirstLink = (linkJSX: ReactNode, key: string) => {
94+
if (showOneClick) {
10095
return (
101-
<div className={styles.oneClickOverlay}>
96+
<div className={styles.oneClickOverlay} key={key}>
10297
<span className={styles.oneClickSpan}>One-click</span>
10398
{linkJSX}
10499
</div>
@@ -130,7 +125,7 @@ export const DataLinksInlineEditor = ({
130125
);
131126

132127
if (idx === 0) {
133-
return renderFirstLink(linkJSX);
128+
return renderFirstLink(linkJSX, key);
134129
}
135130

136131
return linkJSX;

public/app/features/canvas/element.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ComponentType } from 'react';
22

3-
import { DataLink, RegistryItem } from '@grafana/data';
3+
import { DataLink, RegistryItem, OneClickMode } from '@grafana/data';
44
import { PanelOptionsSupplier } from '@grafana/data/src/panel/PanelPlugin';
55
import { ColorDimensionConfig, ScaleDimensionConfig } from '@grafana/schema';
66
import { config } from 'app/core/config';
@@ -33,7 +33,7 @@ export interface CanvasElementOptions<TConfig = any> {
3333
border?: LineConfig;
3434
connections?: CanvasConnection[];
3535
links?: DataLink[];
36-
oneClickLinks?: boolean;
36+
oneClickMode?: OneClickMode;
3737
}
3838

3939
// Unit is percentage from the middle of the element

public/app/features/canvas/elements/cloud.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { css } from '@emotion/css';
22
import { v4 as uuidv4 } from 'uuid';
33

4-
import { GrafanaTheme2 } from '@grafana/data';
4+
import { GrafanaTheme2, OneClickMode } from '@grafana/data';
55
import { config } from 'app/core/config';
66
import { DimensionContext } from 'app/features/dimensions';
77
import { ColorDimensionEditor } from 'app/features/dimensions/editors/ColorDimensionEditor';
@@ -99,6 +99,7 @@ export const cloudItem: CanvasElementItem = {
9999
left: options?.placement?.left,
100100
rotation: options?.placement?.rotation ?? 0,
101101
},
102+
oneClickMode: options?.oneClickMode ?? OneClickMode.Off,
102103
links: options?.links ?? [],
103104
}),
104105

public/app/features/canvas/elements/droneFront.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { css } from '@emotion/css';
22

3-
import { GrafanaTheme2 } from '@grafana/data';
3+
import { GrafanaTheme2, OneClickMode } from '@grafana/data';
44
import { ScalarDimensionConfig } from '@grafana/schema';
55
import { useStyles2 } from '@grafana/ui';
66
import { DimensionContext } from 'app/features/dimensions';
@@ -94,6 +94,8 @@ export const droneFrontItem: CanvasElementItem = {
9494
left: options?.placement?.left,
9595
rotation: options?.placement?.rotation ?? 0,
9696
},
97+
oneClickMode: options?.oneClickMode ?? OneClickMode.Off,
98+
links: options?.links ?? [],
9799
}),
98100

99101
// Called when data changes

public/app/features/canvas/elements/droneSide.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { css } from '@emotion/css';
22

3-
import { GrafanaTheme2 } from '@grafana/data';
3+
import { GrafanaTheme2, OneClickMode } from '@grafana/data';
44
import { ScalarDimensionConfig } from '@grafana/schema';
55
import { useStyles2 } from '@grafana/ui';
66
import { DimensionContext } from 'app/features/dimensions';
@@ -93,6 +93,8 @@ export const droneSideItem: CanvasElementItem = {
9393
left: options?.placement?.left,
9494
rotation: options?.placement?.rotation ?? 0,
9595
},
96+
oneClickMode: options?.oneClickMode ?? OneClickMode.Off,
97+
links: options?.links ?? [],
9698
}),
9799

98100
// Called when data changes

0 commit comments

Comments
 (0)