1
+ import type { MouseEventHandler , ReactNode } from 'react' ;
1
2
import { useCallback , useMemo } from 'react' ;
3
+ import styled from '@emotion/styled' ;
2
4
import cloneDeep from 'lodash/cloneDeep' ;
3
5
4
6
import type { SelectKey , SelectOption } from 'sentry/components/core/compactSelect' ;
7
+ import { IconHide } from 'sentry/icons/iconHide' ;
5
8
import { EQUATION_PREFIX , parseFunction } from 'sentry/utils/discover/fields' ;
6
9
import { ALLOWED_EXPLORE_VISUALIZE_AGGREGATES } from 'sentry/utils/fields' ;
7
10
import {
@@ -71,6 +74,19 @@ export function ToolbarVisualize({
71
74
[ setVisualizes , visualizes ]
72
75
) ;
73
76
77
+ const toggleVisibility = useCallback (
78
+ ( group : number ) => {
79
+ const newVisualizes = visualizes . map ( ( visualize , i ) => {
80
+ if ( i === group ) {
81
+ visualize = visualize . replace ( { visible : ! visualize . visible } ) ;
82
+ }
83
+ return visualize . serialize ( ) ;
84
+ } ) ;
85
+ setVisualizes ( newVisualizes ) ;
86
+ } ,
87
+ [ setVisualizes , visualizes ]
88
+ ) ;
89
+
74
90
const onDelete = useCallback (
75
91
( group : number ) => {
76
92
const newVisualizes = visualizes
@@ -87,13 +103,22 @@ export function ToolbarVisualize({
87
103
< ToolbarSection data-test-id = "section-visualizes" >
88
104
< ToolbarVisualizeHeader />
89
105
{ visualizes . map ( ( visualize , group ) => {
106
+ const label = (
107
+ < VisualizeLabel
108
+ index = { group }
109
+ visualize = { visualize }
110
+ onClick = { ( ) => toggleVisibility ( group ) }
111
+ />
112
+ ) ;
113
+
90
114
if ( isVisualizeEquation ( visualize ) ) {
91
115
return (
92
116
< VisualizeEquationInput
93
117
key = { group }
94
118
onDelete = { ( ) => onDelete ( group ) }
95
119
onReplace = { newVisualize => replaceOverlay ( group , newVisualize ) }
96
120
visualize = { visualize }
121
+ label = { label }
97
122
/>
98
123
) ;
99
124
}
@@ -105,6 +130,7 @@ export function ToolbarVisualize({
105
130
onDelete = { ( ) => onDelete ( group ) }
106
131
onReplace = { newVisualize => replaceOverlay ( group , newVisualize ) }
107
132
visualize = { visualize }
133
+ label = { label }
108
134
/>
109
135
) ;
110
136
} ) }
@@ -126,6 +152,7 @@ export function ToolbarVisualize({
126
152
127
153
interface VisualizeDropdownProps {
128
154
canDelete : boolean ;
155
+ label : ReactNode ;
129
156
onDelete : ( ) => void ;
130
157
onReplace : ( visualize : Visualize ) => void ;
131
158
visualize : Visualize ;
@@ -136,6 +163,7 @@ function VisualizeDropdown({
136
163
onDelete,
137
164
onReplace,
138
165
visualize,
166
+ label,
139
167
} : VisualizeDropdownProps ) {
140
168
const { tags : stringTags } = useTraceItemTags ( 'string' ) ;
141
169
const { tags : numberTags } = useTraceItemTags ( 'number' ) ;
@@ -200,6 +228,36 @@ function VisualizeDropdown({
200
228
onChangeArgument = { onChangeArgument }
201
229
onDelete = { onDelete }
202
230
parsedFunction = { parsedFunction }
231
+ label = { label }
203
232
/>
204
233
) ;
205
234
}
235
+
236
+ interface VisualizeLabelProps {
237
+ index : number ;
238
+ onClick : MouseEventHandler < HTMLDivElement > ;
239
+ visualize : Visualize ;
240
+ }
241
+
242
+ function VisualizeLabel ( { index, onClick, visualize} : VisualizeLabelProps ) {
243
+ const label = visualize . visible ? (
244
+ String . fromCharCode ( 'A' . charCodeAt ( 0 ) + index )
245
+ ) : (
246
+ < IconHide />
247
+ ) ;
248
+
249
+ return < Label onClick = { onClick } > { label } </ Label > ;
250
+ }
251
+
252
+ const Label = styled ( 'div' ) `
253
+ cursor: pointer;
254
+ border-radius: ${ p => p . theme . borderRadius } ;
255
+ background-color: ${ p => p . theme . purple100 } ;
256
+ color: ${ p => p . theme . purple300 } ;
257
+ font-weight: ${ p => p . theme . fontWeight . bold } ;
258
+ width: 24px;
259
+ height: 36px;
260
+ display: flex;
261
+ justify-content: center;
262
+ align-items: center;
263
+ ` ;
0 commit comments