mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			88 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
| import { css } from '@emotion/css';
 | |
| import { useEffect, useState } from 'react';
 | |
| 
 | |
| import { AnnotationQuery, EventBus, GrafanaTheme2 } from '@grafana/data';
 | |
| import { selectors } from '@grafana/e2e-selectors';
 | |
| import { InlineField, InlineFieldRow, InlineSwitch, useStyles2 } from '@grafana/ui';
 | |
| import { LoadingIndicator } from '@grafana/ui/internal';
 | |
| 
 | |
| import { AnnotationQueryFinished, AnnotationQueryStarted } from '../../../../types/events';
 | |
| import { getDashboardQueryRunner } from '../../../query/state/DashboardQueryRunner/DashboardQueryRunner';
 | |
| 
 | |
| export interface AnnotationPickerProps {
 | |
|   events: EventBus;
 | |
|   annotation: AnnotationQuery;
 | |
|   onEnabledChanged: (annotation: AnnotationQuery) => void;
 | |
| }
 | |
| 
 | |
| export const AnnotationPicker = ({ annotation, events, onEnabledChanged }: AnnotationPickerProps): JSX.Element => {
 | |
|   const [loading, setLoading] = useState(false);
 | |
|   const styles = useStyles2(getStyles);
 | |
|   const onCancel = () => getDashboardQueryRunner().cancel(annotation);
 | |
| 
 | |
|   useEffect(() => {
 | |
|     const started = events.getStream(AnnotationQueryStarted).subscribe({
 | |
|       next: (event) => {
 | |
|         if (event.payload === annotation) {
 | |
|           setLoading(true);
 | |
|         }
 | |
|       },
 | |
|     });
 | |
|     const stopped = events.getStream(AnnotationQueryFinished).subscribe({
 | |
|       next: (event) => {
 | |
|         if (event.payload === annotation) {
 | |
|           setLoading(false);
 | |
|         }
 | |
|       },
 | |
|     });
 | |
| 
 | |
|     return () => {
 | |
|       started.unsubscribe();
 | |
|       stopped.unsubscribe();
 | |
|     };
 | |
|   });
 | |
| 
 | |
|   return (
 | |
|     <div key={annotation.name} className={styles.annotation}>
 | |
|       <InlineFieldRow>
 | |
|         <InlineField
 | |
|           label={annotation.name}
 | |
|           disabled={loading}
 | |
|           data-testid={selectors.pages.Dashboard.SubMenu.Annotations.annotationLabel(annotation.name)}
 | |
|         >
 | |
|           <InlineSwitch
 | |
|             label={annotation.name}
 | |
|             value={annotation.enable}
 | |
|             onChange={() => onEnabledChanged(annotation)}
 | |
|             disabled={loading}
 | |
|             data-testid={selectors.pages.Dashboard.SubMenu.Annotations.annotationToggle(annotation.name)}
 | |
|           />
 | |
|         </InlineField>
 | |
|         <div className={styles.indicator}>
 | |
|           <LoadingIndicator loading={loading} onCancel={onCancel} />
 | |
|         </div>
 | |
|       </InlineFieldRow>
 | |
|     </div>
 | |
|   );
 | |
| };
 | |
| 
 | |
| function getStyles(theme: GrafanaTheme2) {
 | |
|   return {
 | |
|     annotation: css({
 | |
|       display: 'inline-block',
 | |
|       marginRight: theme.spacing(1),
 | |
|       '.fa-caret-down': {
 | |
|         fontSize: '75%',
 | |
|         paddingLeft: theme.spacing(1),
 | |
|       },
 | |
|       '.gf-form-inline .gf-form': {
 | |
|         marginBottom: 0,
 | |
|       },
 | |
|     }),
 | |
|     indicator: css({
 | |
|       alignSelf: 'center',
 | |
|       padding: `0 ${theme.spacing(0.5)}`,
 | |
|     }),
 | |
|   };
 | |
| }
 |