From a99485ba331b716af953f02bec4b3325761734f6 Mon Sep 17 00:00:00 2001 From: Jev Forsberg <46619047+baldm0mma@users.noreply.github.com> Date: Tue, 7 Nov 2023 09:29:45 -0700 Subject: [PATCH] Transformations: Build help content for all standard transformers (#74052) * baldm0mma/transformation_info_modal * baldm0mma/transformation_info_modal/ add getDisplayContent * baldm0mma/transformation_info_modal/ reamove OperationRowHelp * baldm0mma/transformation_info_modal/ update prepMarkdown * baldm0mma/transformation_help_modal/ add example mkdwn * baldm0mma/transformation_help_modal/ add examples anno * baldm0mma/transformation_info_modal/ add calFieldHelper * baldm0mma/transformation_info_modal/ remove file * baldm0mma/transformation_info_modal/ add CalculateFieldHelper * baldm0mma/transformation_info_modal/ add TransformationEditorHelperModal * baldm0mma/transformation_info_modal/ add getHelperContent * baldm0mma/transformation_info_modal/ move TransformationEditorHelperModal * baldm0mma/transformation_info_modal/ add ReactElement * baldm0mma/transformations_info_modal * baldm0mma/transformation_info_modal/ update props for TransformationEditorHelperModal * baldm0mma/transformation_info_modal/ test * test * baldm0mma/transformation_info_modal/ reset vscode auth * baldm0mma/transformation_info_modal/ update getHelperContent * baldm0mma/transformations_info_modal/ add items for rebuilding markdown to react component * test * test * baldm0mma/transformations_info_modal/ remove comment in TransformationOperationRow * test * baldm0mma/transformation_info_modal/ add element to typing * baldm0mma/transformation_info_modal/ update getHelperContent with help component * baldm0mma/transformation_info_modal/ update modal title * baldm0mma/transformation_info_modal/ move logic to tranforms * baldm0mma/transformation_info_modal/ remove unused comments * baldm0mma/transformation_info_modal/ update standard reg * baldm0mma/trfansformation_info_modal/ remove context styling * baldm0mma/transformation_info_modal/ add content for CalculateFieldHelper * baldm0mma/transformation_info_modal/ add ConcatenateHelper * baldm0mma/transformations_info_modal/ add ConcatenateHelper * baldm0mma/transformation_info_modal/ add ConfigFromQueryHelper * baldm0mma/transformations/info_modal/ add ConvertFieldTypeHelper * baldm0mma/transformation_info_modal/ add CreateHeatmapHelp * baldm0mma/transformation_info_modal/ add ExtractFieldsHelper * baldm0mma/transformation_info_modal/ add FilterFieldsByNameHelper * baldm0mma/transformation_info_modal/ add FilterFieldsByNameHelper * baldm0mma/transformation_info_modal/ add OperationRowHelp to parse markdown * baldm0mma/transformation_info_modal/ remove commented out markdown * baldm0mma/transformations_info_modal/ remove comment * baldm0mma/transformation_info_modal/ update configFromQueryTransformRegistryItem * baldm0mma/transformation_info_modal/ update ConcatenateHelper * baldm0mma/transformation_info_modal/ update ConvertFieldTypeHelper * baldm0mma/transformation_info_modal/ update ExtractFieldsHelper * baldm0mma/transformation_info_modal/ update FieldLookupHelper * baldm0mma/transformation_info_modal/ update TransformationEditorHelperModal with determineContentDisplay() * baldm0mma/transformation_info_modal/ add FilterByRefIdHelper * baldm0mma/transformation_info_modal/ add FilterByValueHelper * baldm0mma/transformation_info_modal/ update file ext * baldm0mma/transformation_info_modal/ add GroupByHelper * baldm0mma/transformation_info_modal/ add HistogramHelper * baldm0mma/transformation_info_modal/ add JoinByFieldHelper * baldm0mma/transformation_info_modal/ add JoinByLabelsHelper * baldm0mma/transformations_info_modal/ add LabelsToFieldsHelper * baldm0mma/transformation_info_modal/ add LimitHelper * baldm0mma/transformation_info_modal/ add MergeHelper * baldm0mma/transformation_info_modal/ add PartitionByValuesHelper * baldm0mma/transformation_info_modal/ add ReduceHelper * baldm0mma/transformation_info_modal/ add RenameByRegexHelper * baldm0mma/transformation_info_modal/ add SeriesToRowsHelper * baldm0mma/transformation_info_modal/ add SortByHelper * baldm0mma/transformations_info_modal/ add spatial * baldm0mma/transformation_info_modal/ update to markdown * baldm0mma/transformation_info_modal/ remove comments * baldm0mma/transformation_info_modal/ update boarder with theme * baldm0mma/transformation_info_modal/ add test suite * baldm0mma/transformation_info_modal/ update tests * baldm0mma/transformation_info_modal/ update test to run on all transformations * baldm0mma/transformation_info_modaol/ add TimeSeriesTableHelper * baldm0mma/transformation_info_modal/ update concatenateHelper * baldm0mma/transformation_info_modal/ update calculateFieldHelper * baldmomma/transformation_info_modal/ update naming * baldm0mma/transformation_info_modal/ update getLinkToDocs location * baldm0mma/transformation_info_modal/ update docs * baldm0mma/transformation_info_modal/ update language * baldm0mma/transformation_info_modal/ rename test * baldm0mma/transformation_info_modal/ update naming 2 * baldm0mma/transformation_info_modal/ update to helper * baldm0mma/transformation_info_modal/ update docs * Apply suggestions from @imatwawana Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com> * baldm0mma/transformation_info_modal/ update convertFieldTypeHelper capitalization * Hack around with generating Markdown from transformations helpers (#75677) ```console $ cd docs $ make sources/panels-visualizations/query-transform-data/transform-data/index.md $ make docs ``` Browse to http://localhost:3003/docs/grafana/latest/panels-visualizations/query-transform-data/transform-data/ Signed-off-by: Jack Baldry * baldm0mma/transformation_info_modal/ add calculateFieldHelper * baldm0mma/transformation_info_modal/ update concatenate * baldm0mma/transformation_info_modal/ add fieldLookup * baldm0mma/transformation_info_modal/ add filterFieldsByName * baldm0mma/transformation_info_modal/ add joinByField * baldm0mma/transformation_info_modal/ update renameByRegex * baldm0mma/transformation_info_modal/ update getHelperContent * baldm0mma/transformation_info_modal/ update calculateFieldTransformRegistryItem * baldm0mma/transformation_info_modal/ update concatenateTransformRegistryItem * baldm0mma/transformation_info_modal/ update configFromDataTransformer * baldm0mma/transformation_info_modal/ update extractFieldsTransformRegistryItem * baldm0mma/transformation_info_modal/ update formatTimeTransformerRegistryItem * baldm0mma/transformation_info_modal/ update heatmapTransformRegistryItem * baldm0mma/transformation_info_modal/ update mergeTransformerRegistryItem * baldm0mma/transformation_info_modal/ update timeSeriesTableTransformRegistryItem * baldm0mma/transformation_info_modal/ update doc builder * baldm0mma/transformation_info_modal/ update docs * baldm0mma/transformation_info_modal/ remove console log * baldm0mma/transformation_info_modal/ update console log * baldm0mma/transformation_info_modal/ update gitignore * baldm0mma/transformation_info_modal/ update calculateField * baldm0mma/transformation_info_modal/ add links * baldm0mma/transformation_info_modal/ update template * baldm0mma/transformation_info_modal/ update template with images * baldm0mma/transformation_info_modal/ build markdown * baldm0mma/transformations_info_modal/update with links * baldm0mma/transformation_info_modal/ update links * baldm0mma/transformation_info_modal/ apdate FormatTimeTransfomerEditor * baldm0mma/transformation_indo_modal/ update HeatmapTransformerEditor * baldm0mma/transformation_indo_modal/ update ConfigFromQueryTransformerEditor * baldm0mma/transformation_indo_modal/ update CalculateFieldTransformerEditor * baldm0mma/transformation_indo_modal/ update ConcatenateTransformerEditor * baldm0mma/transformation_indo_modal/ update FilterByNameTransformerEditor * baldm0mma/transformation_indo_modal/ update FilterByRefIdTransformerEditor * baldm0mma/transformation_indo_modal/ update GroupByTransformerEditor * baldm0mma/transformation_indo_modal/ update GroupingToMatrixTransformerEditor get helper * baldm0mma/transformation_indo_modal/ update SeriesToFieldsTransformerEditor get helper * baldm0mma/transformation_indo_modal/ update LabelsAsFieldsTransformerEditor * baldm0mma/transformation_info_modal/ update MergeTransformerEditor * baldm0mma/transformation_info_modal/ update OrganizeFieldsTransformerEditor * baldm0mma/transformation_info_modal/ update ReduceTransformerEditor * baldm0mma/transformation_info_modal/ update RenameByRegexTransformerEditor * baldm0mma/transformation_info_modal/ update SeriesToRowsTransformerEditor * baldm0mma/transformation_info_modal/ update SortByTransformerEditor * baldm0mma/transformation_info_modal/ update extractFieldsTransformerEditor * baldm0mma/transformation_info_modal/ update FilterByValueTransformerEditor * baldm0mma/transformation_info_modal/ update JoinByLabelsTransformerEditor * baldm0mma/transformation_info_modal/ update FieldLookupTransformerEditor * baldm0mma/transformation_info_modal/ update PartitionByValuesEditor * baldm0mma/transformation_info_modal/ update PrepareTimeSeriesEditor * baldm0mma/transformation_info_modal/ update RowsToFieldsTransformerEditor * baldm0mma/transformation_info_modal/ update spatialTransformRegistryItem * baldm0mma/transformation_info_modal/ update timeSeriesTableTransformRegistryItem * baldm0mma/transformation_info_modal/ update to helperDocs * baldm0mma/transformation_info_modal/ update built markdown * baldm0mma/transformation_info_modal/ run prettier * baldm0mma/transformation_info_modal/ update comments in getTransformationContent * baldm0mma/transformation_info_modal/ add removeMarkdownAnchorLinks * baldm0mma/transformation_info_modal/ update annos in getTransformationContent * baldm0mma/transformation_info_modal/ add requisite url prefix to markdown images * baldm0mma/transformation_info_modal/ add cleanMarkdownOfUnwantedSyntax * baldm0mma/transformation_info_modal/ update annos in content.ts * baldm0mma/transformation_info_modal/ update e2e tests with always-visiable trabnsformation * baldm0mma/transformation_info_modal/ remove note * baldm0mma/transformation_info_modal/ add annotation in getTransformationContent * baldm0mma/transformation_info_modal/ update e2e test naming --------- Signed-off-by: Jack Baldry Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com> Co-authored-by: Jack Baldry --- .../transform-data/index.md | 2 +- e2e/panels-suite/panelEdit_base.spec.ts | 2 +- .../QueryOperationRow/OperationRowHelp.tsx | 29 +++--- .../TransformationEditorHelperModal.test.tsx | 93 +++++++++++++++++++ .../TransformationEditorHelperModal.tsx | 39 ++++++++ .../TransformationOperationRow.tsx | 83 ++++++----------- .../TransformationOperationRows.tsx | 1 + .../FilterByValueTransformerEditor.tsx | 3 + .../HeatmapTransformerEditor.tsx | 2 + .../ConfigFromQueryTransformerEditor.tsx | 69 +------------- .../app/features/transformers/docs/content.ts | 35 ++++--- .../docs/getTransformationContent.ts | 57 ++++++++++++ .../CalculateFieldTransformerEditor.tsx | 5 +- .../editors/ConcatenateTransformerEditor.tsx | 5 +- .../ConvertFieldTypeTransformerEditor.tsx | 2 + .../editors/FilterByNameTransformerEditor.tsx | 5 +- .../FilterByRefIdTransformerEditor.tsx | 5 +- .../editors/FormatTimeTransformerEditor.tsx | 2 + .../editors/GroupByTransformerEditor.tsx | 2 + .../GroupingToMatrixTransformerEditor.tsx | 4 +- .../editors/HistogramTransformerEditor.tsx | 2 + .../editors/JoinByFieldTransformerEditor.tsx | 2 + .../LabelsToFieldsTransformerEditor.tsx | 5 +- .../editors/LimitTransformerEditor.tsx | 4 +- .../editors/MergeTransformerEditor.tsx | 5 +- .../OrganizeFieldsTransformerEditor.tsx | 4 +- .../editors/ReduceTransformerEditor.tsx | 3 + .../editors/RenameByRegexTransformer.tsx | 5 +- .../editors/SeriesToRowsTransformerEditor.tsx | 5 +- .../editors/SortByTransformerEditor.tsx | 2 + .../ExtractFieldsTransformerEditor.tsx | 5 +- .../JoinByLabelsTransformerEditor.tsx | 7 +- .../FieldLookupTransformerEditor.tsx | 5 +- .../PartitionByValuesEditor.tsx | 3 + .../PrepareTimeSeriesEditor.tsx | 10 +- .../RowsToFieldsTransformerEditor.tsx | 37 +------- .../spatial/SpatialTransformerEditor.tsx | 3 + .../TimeSeriesTableTransformEditor.tsx | 4 +- 38 files changed, 350 insertions(+), 206 deletions(-) create mode 100644 public/app/features/dashboard/components/TransformationsEditor/TransformationEditorHelperModal.test.tsx create mode 100644 public/app/features/dashboard/components/TransformationsEditor/TransformationEditorHelperModal.tsx create mode 100644 public/app/features/transformers/docs/getTransformationContent.ts diff --git a/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md b/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md index 3d81888d5d2..7397893ef02 100644 --- a/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md +++ b/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md @@ -479,7 +479,7 @@ The result from using the regular expression 'prod.\*' would be: | 2023-03-04 23:56:23 | 22.2 | 20.2 | | 2023-03-04 23:56:23 | 22.1 | 20.1 | -The regular expression can include an interpolated dashboard variable by using the ${$variableName} syntax. +The regular expression can include an interpolated dashboard variable by using the ${variableName} syntax. #### Manually select included fields diff --git a/e2e/panels-suite/panelEdit_base.spec.ts b/e2e/panels-suite/panelEdit_base.spec.ts index f3792dae532..248e8e72ae9 100644 --- a/e2e/panels-suite/panelEdit_base.spec.ts +++ b/e2e/panels-suite/panelEdit_base.spec.ts @@ -39,7 +39,7 @@ describe('Panel edit tests', () => { e2e.components.Tab.active().within((li: JQuery) => { expect(li.text()).equals('Transform data0'); // there's no transform so therefore Transform + 0 }); - e2e.components.Transforms.card('Merge').scrollIntoView().should('be.visible'); + e2e.components.Transforms.card('Merge series/tables').scrollIntoView().should('be.visible'); e2e.components.QueryTab.content().should('not.exist'); e2e.components.AlertTab.content().should('not.exist'); e2e.components.PanelAlertTabContent.content().should('not.exist'); diff --git a/public/app/core/components/QueryOperationRow/OperationRowHelp.tsx b/public/app/core/components/QueryOperationRow/OperationRowHelp.tsx index 600b2f5eb15..ea17c9ff423 100644 --- a/public/app/core/components/QueryOperationRow/OperationRowHelp.tsx +++ b/public/app/core/components/QueryOperationRow/OperationRowHelp.tsx @@ -8,19 +8,22 @@ export interface Props extends React.HTMLAttributes { children?: React.ReactNode; markdown?: string; onRemove?: () => void; + styleOverrides?: { [key: string]: string }; } export const OperationRowHelp = React.memo( - React.forwardRef(({ className, children, markdown, onRemove, ...otherProps }, ref) => { - const styles = useStyles2(getStyles); + React.forwardRef( + ({ className, children, markdown, styleOverrides, onRemove, ...otherProps }, ref) => { + const styles = useStyles2((theme) => getStyles(theme, styleOverrides?.borderTop)); - return ( -
- {markdown && markdownHelper(markdown)} - {children} -
- ); - }) + return ( +
+ {markdown && markdownHelper(markdown)} + {children} +
+ ); + } + ) ); function markdownHelper(markdown: string) { @@ -30,14 +33,16 @@ function markdownHelper(markdown: string) { OperationRowHelp.displayName = 'OperationRowHelp'; -const getStyles = (theme: GrafanaTheme2) => { +const getStyles = (theme: GrafanaTheme2, borderTop?: string) => { const borderRadius = theme.shape.radius.default; + const themeBackgroundColor = theme.colors.background.secondary; + return { wrapper: css` padding: ${theme.spacing(2)}; - border: 2px solid ${theme.colors.background.secondary}; - border-top: none; + border: 2px solid ${themeBackgroundColor}; + border-top: ${borderTop ? borderTop + themeBackgroundColor : 'none'}; border-radius: 0 0 ${borderRadius} ${borderRadius}; position: relative; top: -4px; diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationEditorHelperModal.test.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationEditorHelperModal.test.tsx new file mode 100644 index 00000000000..0d6cd74f322 --- /dev/null +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationEditorHelperModal.test.tsx @@ -0,0 +1,93 @@ +import { render, screen, fireEvent } from '@testing-library/react'; +import React from 'react'; + +import { TransformerRegistryItem } from '@grafana/data'; +import { getStandardTransformers } from 'app/features/transformers/standardTransformers'; + +import { TransformationEditorHelperModal } from './TransformationEditorHelperModal'; + +// Mock the onCloseClick function +const mockOnCloseClick = jest.fn(); + +const standardTransformers: Array> = getStandardTransformers(); + +const singleTestTransformer: TransformerRegistryItem = standardTransformers[0]; + +describe('TransformationEditorHelperModal', () => { + it('renders the modal with the correct title and content', () => { + // Test each transformer + standardTransformers.forEach((transformer) => { + const { unmount } = render( + + ); + + // Check if the modal title is rendered with the correct text + expect(screen.getByText(`Transformation help - ${transformer.transformation.name}`)).toBeInTheDocument(); + + // Unmount the component to clean up + unmount(); + }); + }); + + it('calls onCloseClick when the modal is dismissed', () => { + render( + + ); + + // Find and click the modal's close button + const closeButton = screen.getByRole('button', { name: 'Close' }); + fireEvent.click(closeButton); + + // Ensure that the onCloseClick function was called with the correct argument + expect(mockOnCloseClick).toHaveBeenCalledWith(false); + }); + + it('does not render when isOpen is false', () => { + render( + + ); + + // Ensure that the modal is not rendered + expect(screen.queryByText(`Transformation help - ${singleTestTransformer.name}`)).toBeNull(); + }); + + it('renders a default message when help content is not provided', () => { + const transformerWithoutHelp = { ...singleTestTransformer, help: undefined }; + + render( + + ); + + // Check if the default message is rendered when help content is not provided + expect(screen.getByText('transformation documentation')).toBeInTheDocument(); + }); + + it('renders with custom help content when provided', () => { + const customHelpContent = 'Custom help content for testing'; + + const transformerWithCustomHelp = { ...singleTestTransformer, help: customHelpContent }; + + render( + + ); + + // Check if the custom help content is rendered + expect(screen.getByText(customHelpContent)).toBeInTheDocument(); + }); +}); diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationEditorHelperModal.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationEditorHelperModal.tsx new file mode 100644 index 00000000000..3d39e19853a --- /dev/null +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationEditorHelperModal.tsx @@ -0,0 +1,39 @@ +import React from 'react'; + +import { TransformerRegistryItem } from '@grafana/data'; +import { Modal } from '@grafana/ui'; +import { OperationRowHelp } from 'app/core/components/QueryOperationRow/OperationRowHelp'; + +import { getLinkToDocs } from '../../../transformers/docs/content'; + +interface TransformationEditorHelperModalProps { + isOpen: boolean; + onCloseClick: (value: boolean) => void; + transformer: TransformerRegistryItem; +} + +export const TransformationEditorHelperModal = ({ + isOpen, + onCloseClick, + transformer, +}: TransformationEditorHelperModalProps) => { + const { + transformation: { name }, + help, + } = transformer; + + const helpContent = help ? help : getLinkToDocs(); + + const helpTitle = `Transformation help - ${name}`; + + return ( + onCloseClick(false)} + onDismiss={() => onCloseClick(false)} + > + + + ); +}; diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx index 15d0410a9f9..4c4c85e31a3 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx @@ -4,7 +4,6 @@ import { useToggle } from 'react-use'; import { DataFrame, DataTransformerConfig, TransformerRegistryItem, FrameMatcherID } from '@grafana/data'; import { reportInteraction } from '@grafana/runtime'; import { ConfirmModal } from '@grafana/ui'; -import { OperationRowHelp } from 'app/core/components/QueryOperationRow/OperationRowHelp'; import { QueryOperationAction, QueryOperationToggleAction, @@ -14,6 +13,7 @@ import config from 'app/core/config'; import { PluginStateInfo } from 'app/features/plugins/components/PluginStateInfo'; import { TransformationEditor } from './TransformationEditor'; +import { TransformationEditorHelperModal } from './TransformationEditorHelperModal'; import { TransformationFilter } from './TransformationFilter'; import { TransformationsEditorTransformation } from './types'; @@ -54,16 +54,6 @@ export const TransformationOperationRow = ({ [onChange, configs] ); - const toggleExpand = useCallback(() => { - if (showHelp) { - return true; - } - - // We return `undefined` here since the QueryOperationRow component ignores an `undefined` value for the `isOpen` prop. - // If we returned `false` here, the row would be collapsed when the user toggles off `showHelp`, which is not what we want. - return undefined; - }, [showHelp]); - // Adds or removes the frame filter const toggleFilter = useCallback(() => { let current = { ...configs[index].transformation }; @@ -106,8 +96,8 @@ export const TransformationOperationRow = ({ title="Show transform help" icon="info-circle" // `instrumentToggleCallback` expects a function that takes a MouseEvent, is unused in the state setter. Instead, we simply toggle the state. - onClick={instrumentToggleCallback((_e) => toggleShowHelp(!showHelp), 'help', showHelp)} - active={!!showHelp} + onClick={instrumentToggleCallback(toggleShowHelp, 'help', showHelp)} + active={showHelp} /> {showFilter && ( toggleShowHelp(false)} - expanderMessages={{ - close: 'Collapse transformation row', - open: 'Expand transformation row', - }} - > - {showHelp && } - {filter && ( - - )} - + - + title={`${index + 1} - ${uiConfig.name}`} + draggable + actions={renderActions} + disabled={disabled} + expanderMessages={{ + close: 'Collapse transformation row', + open: 'Expand transformation row', + }} + > + {filter && ( + + )} + + + + ); }; - -function prepMarkdown(uiConfig: TransformerRegistryItem) { - let helpMarkdown = uiConfig.help ?? uiConfig.description; - - return ` -${helpMarkdown} - -Go the -transformation documentation - for more. -`; -} diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRows.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRows.tsx index 69c17692445..6b845a1a682 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRows.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRows.tsx @@ -22,6 +22,7 @@ export const TransformationOperationRows = ({ <> {configs.map((t, i) => { const uiConfig = standardTransformersRegistry.getIfExists(t.transformation.id); + if (!uiConfig) { return null; } diff --git a/public/app/features/transformers/FilterByValueTransformer/FilterByValueTransformerEditor.tsx b/public/app/features/transformers/FilterByValueTransformer/FilterByValueTransformerEditor.tsx index 4fccd5651bd..bb5ecf34abf 100644 --- a/public/app/features/transformers/FilterByValueTransformer/FilterByValueTransformerEditor.tsx +++ b/public/app/features/transformers/FilterByValueTransformer/FilterByValueTransformerEditor.tsx @@ -22,6 +22,8 @@ import { } from '@grafana/data/src/transformations/transformers/filterByValue'; import { Button, RadioButtonGroup, InlineField, Box } from '@grafana/ui'; +import { getTransformationContent } from '../docs/getTransformationContent'; + import { DataFrameFieldsInfo, FilterByValueFilterEditor } from './FilterByValueFilterEditor'; const filterTypes: Array> = [ @@ -135,6 +137,7 @@ export const filterByValueTransformRegistryItem: TransformerRegistryItem { diff --git a/public/app/features/transformers/calculateHeatmap/HeatmapTransformerEditor.tsx b/public/app/features/transformers/calculateHeatmap/HeatmapTransformerEditor.tsx index 1870cbd2d5b..2fb94c1dc80 100644 --- a/public/app/features/transformers/calculateHeatmap/HeatmapTransformerEditor.tsx +++ b/public/app/features/transformers/calculateHeatmap/HeatmapTransformerEditor.tsx @@ -9,6 +9,7 @@ import { TransformerCategory, } from '@grafana/data'; +import { getTransformationContent } from '../docs/getTransformationContent'; import { getDefaultOptions, getTransformerOptionPane } from '../spatial/optionsHelper'; import { addHeatmapCalculationOptions } from './editor/helper'; @@ -49,4 +50,5 @@ export const heatmapTransformRegistryItem: TransformerRegistryItem ({ diff --git a/public/app/features/transformers/docs/content.ts b/public/app/features/transformers/docs/content.ts index 2ce18627e02..3857e281f91 100644 --- a/public/app/features/transformers/docs/content.ts +++ b/public/app/features/transformers/docs/content.ts @@ -83,7 +83,7 @@ export const transformationDocsContent: TransformationDocsContentType = { ${buildImageContent( '/static/img/docs/transformations/add-field-from-calc-stat-example-7-0.png', imageRenderType, - this.name + 'Add field from calculation' )} `; }, @@ -336,7 +336,7 @@ export const transformationDocsContent: TransformationDocsContentType = { ${buildImageContent( '/static/img/docs/transformations/filter-by-query-stat-example-7-0.png', imageRenderType, - this.name + 'Filter data by query refId' )} `; }, @@ -440,7 +440,7 @@ export const transformationDocsContent: TransformationDocsContentType = { | 2023-03-04 23:56:23 | 22.2 | 20.2 | | 2023-03-04 23:56:23 | 22.1 | 20.1 | - The regular expression can include an interpolated dashboard variable by using the \${$${'variableName'}} syntax. + The regular expression can include an interpolated dashboard variable by using the \${${'variableName'}} syntax. #### Manually select included fields @@ -453,7 +453,8 @@ export const transformationDocsContent: TransformationDocsContentType = { ${buildImageContent( '/static/img/docs/transformations/filter-name-table-before-7-0.png', imageRenderType, - this.name + 1 + // Distinguish alt text for multiple images by appending a number. + 'Filter fields by name' + 1 )} Here's the table after we applied the transformation to remove the Min field. @@ -461,7 +462,7 @@ export const transformationDocsContent: TransformationDocsContentType = { ${buildImageContent( '/static/img/docs/transformations/filter-name-table-after-7-0.png', imageRenderType, - this.name + 2 + 'Filter fields by name' + 2 )} Here is the same query using a Stat visualization. @@ -469,7 +470,7 @@ export const transformationDocsContent: TransformationDocsContentType = { ${buildImageContent( '/static/img/docs/transformations/filter-name-stat-after-7-0.png', imageRenderType, - this.name + 3 + 'Filter fields by name' + 3 )} `; }, @@ -742,11 +743,19 @@ export const transformationDocsContent: TransformationDocsContentType = { In the following example, a template query displays time series data from multiple servers in a table visualization. The results of only one query can be viewed at a time. - ${buildImageContent('/static/img/docs/transformations/join-fields-before-7-0.png', imageRenderType, this.name + 1)} + ${buildImageContent( + '/static/img/docs/transformations/join-fields-before-7-0.png', + imageRenderType, + 'Join by field' + 1 + )} I applied a transformation to join the query results using the time field. Now I can run calculations, combine, and organize the results in this new table. - ${buildImageContent('/static/img/docs/transformations/join-fields-after-7-0.png', imageRenderType, this.name + 2)} + ${buildImageContent( + '/static/img/docs/transformations/join-fields-after-7-0.png', + imageRenderType, + 'Join by field' + 2 + )} `; }, }, @@ -1071,12 +1080,16 @@ export const transformationDocsContent: TransformationDocsContentType = { ${buildImageContent( '/static/img/docs/transformations/rename-by-regex-before-7-3.png', imageRenderType, - this.name + 1 + 'Rename by regex' + 1 )} With the transformation applied, you can see we are left with just the remainder of the string. - ${buildImageContent('/static/img/docs/transformations/rename-by-regex-after-7-3.png', imageRenderType, this.name + 1)} + ${buildImageContent( + '/static/img/docs/transformations/rename-by-regex-after-7-3.png', + imageRenderType, + 'Rename by regex' + 2 + )} `; }, }, @@ -1240,5 +1253,5 @@ function buildImageContent(source: string, imageRenderType: ImageRenderType, ima ? // This will build a Hugo Shortcode "figure" image template, which shares the same default class and max-width. `{{< figure src="${source}" class="docs-image--no-shadow" max-width= "1100px" >}}` : // This will build generic Markdown image syntax for UI rendering. - `![${imageName} helper image](${source})`; + `![${imageName} helper image](https://grafana.com${source})`; } diff --git a/public/app/features/transformers/docs/getTransformationContent.ts b/public/app/features/transformers/docs/getTransformationContent.ts new file mode 100644 index 00000000000..800c37af4d8 --- /dev/null +++ b/public/app/features/transformers/docs/getTransformationContent.ts @@ -0,0 +1,57 @@ +import { transformationDocsContent, getLinkToDocs, ImageRenderType } from './content'; + +export function getTransformationContent(id: string): { name: string; helperDocs: string } { + if (id in transformationDocsContent) { + const { name, getHelperDocs, links } = transformationDocsContent[id]; + + const helperDocs = getHelperDocs(ImageRenderType.UIImage); + + const cleansedMarkdown = cleanMarkdownOfUnwantedSyntax(helperDocs); + + // NOTE: string interpolation whitespace/indentation formatting is intentional. + if (links?.length) { + const renderedLinks = links + .map((link) => { + return ` + Or visit ${link.title}\n + `; + }) + .join(''); + + // If external links exist, build and add them to the returned documentation. + return { + name, + helperDocs: ` + ${cleansedMarkdown} + ${getLinkToDocs()} + ${renderedLinks} + `, + }; + } + + // If NO external links exist, simply return the basic documentation. + return { + name, + helperDocs: ` + ${cleansedMarkdown} + ${getLinkToDocs()} + `, + }; + } + + // If the transformation has no documentation, return an external link to the online documentation. + return { + name: 'No documentation found', + helperDocs: getLinkToDocs(), + }; +} + +const cleanMarkdownOfUnwantedSyntax = (markdown: string) => { + // Remove anchor links: [text](#link) + const markdownWithoutAnchorLinks = markdown.replace(/\[(.*?)\]\(#.*?\)/g, '$1'); + + // Remove shortcode syntax: [text][] + const markdownWithoutShortcodeSyntax = markdownWithoutAnchorLinks.replace(/\[[^\]]*\]\[\]/g, ''); + + return markdownWithoutShortcodeSyntax; +}; diff --git a/public/app/features/transformers/editors/CalculateFieldTransformerEditor.tsx b/public/app/features/transformers/editors/CalculateFieldTransformerEditor.tsx index 00cb8dbeb7d..17122018def 100644 --- a/public/app/features/transformers/editors/CalculateFieldTransformerEditor.tsx +++ b/public/app/features/transformers/editors/CalculateFieldTransformerEditor.tsx @@ -49,6 +49,8 @@ import { } from '@grafana/ui'; import { NumberInput } from 'app/core/components/OptionsUI/NumberInput'; +import { getTransformationContent } from '../docs/getTransformationContent'; + interface CalculateFieldTransformerEditorProps extends TransformerUIProps {} interface CalculateFieldTransformerEditorState { @@ -668,7 +670,8 @@ export const calculateFieldTransformRegistryItem: TransformerRegistryItem {} const nameModes: Array> = [ @@ -88,8 +90,9 @@ export const concatenateTransformRegistryItem: TransformerRegistryItem {} interface FilterByNameTransformerEditorState { @@ -251,7 +253,8 @@ export const filterFieldsByNameTransformRegistryItem: TransformerRegistryItem {} interface FilterByRefIdTransformerEditorState { @@ -143,8 +145,9 @@ export const filterFramesByRefIdTransformRegistryItem: TransformerRegistryItem> = [ { value: LabelsToFieldsMode.Columns, label: 'Columns' }, { value: LabelsToFieldsMode.Rows, label: 'Rows' }, @@ -124,8 +126,9 @@ export const labelsToFieldsTransformerRegistryItem: TransformerRegistryItem) => { if (input.length <= 1) { // Show warning that merge is useless only apply on a single frame @@ -22,8 +24,9 @@ export const mergeTransformerRegistryItem: TransformerRegistryItem {} @@ -206,8 +207,9 @@ export const organizeFieldsTransformRegistryItem: TransformerRegistryItem) => { const modes: Array> = [ @@ -102,4 +104,5 @@ export const reduceTransformRegistryItem: TransformerRegistryItem {} interface RenameByRegexTransformerEditorState { @@ -128,7 +130,8 @@ export const renameByRegexTransformRegistryItem: TransformerRegistryItem) => { @@ -65,4 +66,5 @@ export const sortByTransformRegistryItem: TransformerRegistryItem = { @@ -82,8 +84,9 @@ export const fieldLookupTransformRegistryItem: TransformerRegistryItem