diff --git a/ui/src/shared/components/TimeMachine.tsx b/ui/src/shared/components/TimeMachine.tsx index 58d05a98e6..fafb4e8b98 100644 --- a/ui/src/shared/components/TimeMachine.tsx +++ b/ui/src/shared/components/TimeMachine.tsx @@ -40,7 +40,7 @@ const TimeMachine: SFC = props => { size: 0.33, }, { - handlePixels: 8, + handlePixels: 12, render: () => , headerOrientation: HANDLE_HORIZONTAL, size: 0.67, diff --git a/ui/src/shared/components/TimeMachineQueryEditor.scss b/ui/src/shared/components/TimeMachineQueryEditor.scss index 09cc0b77f9..5daef15bf3 100644 --- a/ui/src/shared/components/TimeMachineQueryEditor.scss +++ b/ui/src/shared/components/TimeMachineQueryEditor.scss @@ -1,20 +1,16 @@ +@import "src/style/modules"; + .time-machine-query-editor { height: 100%; width: 100%; - padding: 10px; display: flex; flex-direction: column; - > .time-machine-editor { - height: 100%; - border-radius: 4px; - overflow: hidden; + .time-machine-editor { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; } } - -.time-machine-query-editor--controls { - flex: 0 0 30px; - margin-bottom: 10px; - display: flex; - justify-content: flex-end; -} diff --git a/ui/src/shared/components/TimeMachineQueryEditor.tsx b/ui/src/shared/components/TimeMachineQueryEditor.tsx index aef3c973b3..9f556fc6b9 100644 --- a/ui/src/shared/components/TimeMachineQueryEditor.tsx +++ b/ui/src/shared/components/TimeMachineQueryEditor.tsx @@ -4,7 +4,9 @@ import {connect} from 'react-redux' // Components import FluxEditor from 'src/shared/components/FluxEditor' -import {Button, ComponentColor} from 'src/clockface' +import {Button, ComponentColor, ComponentSize} from 'src/clockface' +import Threesizer from 'src/shared/components/threesizer/Threesizer' +import FluxFunctionsToolbar from 'src/shared/components/flux_functions_toolbar/FluxFunctionsToolbar' // Actions import {setDraftScript, submitScript} from 'src/shared/actions/v2/timeMachines' @@ -12,6 +14,9 @@ import {setDraftScript, submitScript} from 'src/shared/actions/v2/timeMachines' // Utils import {getActiveTimeMachine} from 'src/shared/selectors/timeMachines' +// Constants +import {HANDLE_VERTICAL} from 'src/shared/constants' + // Types import {AppState} from 'src/types/v2' @@ -34,21 +39,38 @@ class TimeMachineQueryEditor extends PureComponent { public render() { const {draftScript, onSetDraftScript, onSubmitScript} = this.props - return ( -
-
+ const divisions = [ + { + name: 'Script', + size: 0.75, + headerButtons: [
- + ), + }, + { + name: 'Flux Functions', + render: () => , + size: 0.25, + }, + ] + + return ( +
+
) } diff --git a/ui/src/shared/components/flux_functions_toolbar/FluxFunctionsToolbar.scss b/ui/src/shared/components/flux_functions_toolbar/FluxFunctionsToolbar.scss new file mode 100644 index 0000000000..56c9edeb75 --- /dev/null +++ b/ui/src/shared/components/flux_functions_toolbar/FluxFunctionsToolbar.scss @@ -0,0 +1,200 @@ +.flux-functions-toolbar { + height: 100%; + display: flex; + flex-direction: column; + background-color: $g3-castle; + font-size: 13px; +} + +.flux-functions-toolbar--search { + padding: $ix-marg-a; + flex-shrink: 0; + padding-bottom: $ix-marg-a + 1px; + border-bottom: $ix-border solid $g4-onyx; + background-color: $g3-castle; +} + +.flux-functions-toolbar--list { + padding-bottom: $ix-marg-a; +} + +.flux-functions-toolbar--category { + dt, dd { + height: 30px; + display: flex; + align-items: center; + padding-left: 10px; + } + + dt { + background-color: $g6-smoke; + font-weight: 600; + color: $g18-cloud; + } + + dd { + font-family: "RobotoMono", monospace; + cursor: pointer; + } + + dd:hover, dd:active { + background-color: $g4-onyx; + color: $c-laser; + } +} + +.flux-functions-toolbar--function { + position: relative; +} + +.flux-functions-toolbar--helper { + color: $g10-wolf; + padding: 15px; +} + +.flux-functions-toolbar--tooltip { + padding-right: 8px; + max-width: 600px; + position: fixed; + transform: translateY(50%); + z-index: 10; +} + +.flux-functions-toolbar--tooltip-caret { + content: ""; + width: 0; + height: 0; + position: fixed; + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + border-left: 6px solid $c-pool; + margin-top: 9px; + margin-left: -8px; + z-index: 9999; +} + +.flux-functions-toolbar--tooltip-contents { + border: $ix-border solid $c-pool; + border-radius: $radius; + width: 100%; + max-width: 600px; + display: inline-flex; + align-items: center; + background-color: $g1-raven; + padding: 10px; + + article { + margin-bottom: $ix-marg-c; + } +} + +.flux-functions-toolbar--heading { + font-weight: 600; + margin-bottom: $ix-marg-a; +} + +.flux-functions-toolbar--snippet { + background-color: $g3-castle; + border-radius: $radius; + margin: $ix-marg-a 0; + padding: $ix-marg-b; + font-family: "RobotoMono", monospace; +} + +.flux-functions-toolbar--arguments { + span:first-child { + font-weight: 600; + color: $c-pool; + margin-right: $ix-marg-a; + } + + span:nth-child(2) { + color: $c-rainforest; + font-style: italic; + margin-right: 2px; + } + + div { + margin: $ix-marg-a 0 $ix-marg-c 0; + } +} + +.flux-functions-toolbar--tooltip-dismiss { + position: absolute; + z-index: 5000; + top: 0; + right: 0; + transform: translate(0,-50%); + width: 24px; + height: 24px; + outline: none; + border-radius: 50%; + background-color: $c-pool; + transition: background-color 0.25s ease; + border: 0; + + &:before, + &:after { + content: ''; + position: absolute; + width: 13px; + height: 3px; + top: 50%; + left: 50%; + border-radius: 1px; + background-color: $g20-white; + } + + &:before { + transform: translate(-50%, -50%) rotate(45deg); + } + + &:after { + transform: translate(-50%, -50%) rotate(-45deg); + } + + &:hover { + background-color: $c-laser; + cursor: pointer; + } +} + +.flux-functions-toolbar--tooltip-dismiss { + position: absolute; + z-index: 5000; + top: 0; + right: 0; + transform: translate(0,-50%); + width: 24px; + height: 24px; + outline: none; + border-radius: 50%; + background-color: $c-pool; + transition: background-color 0.25s ease; + border: 0; + + &:before, + &:after { + content: ''; + position: absolute; + width: 13px; + height: 3px; + top: 50%; + left: 50%; + border-radius: 1px; + background-color: $g20-white; + } + + &:before { + transform: translate(-50%, -50%) rotate(45deg); + } + + &:after { + transform: translate(-50%, -50%) rotate(-45deg); + } + + &:hover { + background-color: $c-laser; + cursor: pointer; + } +} diff --git a/ui/src/shared/components/flux_functions_toolbar/FluxFunctionsToolbar.tsx b/ui/src/shared/components/flux_functions_toolbar/FluxFunctionsToolbar.tsx new file mode 100644 index 0000000000..326576fbd4 --- /dev/null +++ b/ui/src/shared/components/flux_functions_toolbar/FluxFunctionsToolbar.tsx @@ -0,0 +1,92 @@ +// Libraries +import React, {PureComponent} from 'react' +import {connect} from 'react-redux' + +// Components +import TransformToolbarFunctions from 'src/shared/components/flux_functions_toolbar/TransformToolbarFunctions' +import FunctionCategory from 'src/shared/components/flux_functions_toolbar/FunctionCategory' +import SearchBar from 'src/shared/components/flux_functions_toolbar/SearchBar' +import FancyScrollbar from 'src/shared/components/fancy_scrollbar/FancyScrollbar' +import {ErrorHandling} from 'src/shared/decorators/errors' + +// Actions +import {setDraftScript} from 'src/shared/actions/v2/timeMachines' + +// Utils +import {getActiveTimeMachine} from 'src/shared/selectors/timeMachines' + +// Constants +import {FLUX_FUNCTIONS} from 'src/shared/constants/fluxFunctions' + +// Types +import {AppState} from 'src/types/v2' + +interface StateProps { + draftScript: string +} + +interface DispatchProps { + onSetDraftScript: (script: string) => void +} + +type Props = StateProps & DispatchProps + +interface State { + searchTerm: string +} + +class FluxFunctionsToolbar extends PureComponent { + public state: State = {searchTerm: ''} + + public render() { + const {searchTerm} = this.state + + return ( +
+ + +
+ + {sortedFunctions => + Object.entries(sortedFunctions).map(([category, funcs]) => ( + + )) + } + +
+
+
+ ) + } + + private handleSearch = (searchTerm: string): void => { + this.setState({searchTerm}) + } + + private handleUpdateScript = (funcExample: string) => { + const {draftScript, onSetDraftScript} = this.props + + onSetDraftScript(`${draftScript}\n |> ${funcExample}`) + } +} + +const mstp = (state: AppState) => ({ + draftScript: getActiveTimeMachine(state).draftScript, +}) + +const mdtp = { + onSetDraftScript: setDraftScript, +} + +export default connect( + mstp, + mdtp +)(ErrorHandling(FluxFunctionsToolbar)) diff --git a/ui/src/shared/components/flux_functions_toolbar/FunctionCategory.tsx b/ui/src/shared/components/flux_functions_toolbar/FunctionCategory.tsx new file mode 100644 index 0000000000..8e491d1642 --- /dev/null +++ b/ui/src/shared/components/flux_functions_toolbar/FunctionCategory.tsx @@ -0,0 +1,33 @@ +// Libraries +import React, {SFC} from 'react' + +// Components +import ToolbarFunction from 'src/shared/components/flux_functions_toolbar/ToolbarFunction' + +// Types +import {FluxToolbarFunction} from 'src/types/shared' + +interface Props { + category: string + funcs: FluxToolbarFunction[] + onClickFunction: (s: string) => void +} + +const FunctionCategory: SFC = props => { + const {category, funcs, onClickFunction} = props + + return ( +
+
{category}
+ {funcs.map(func => ( + + ))} +
+ ) +} + +export default FunctionCategory diff --git a/ui/src/shared/components/flux_functions_toolbar/FunctionTooltip.tsx b/ui/src/shared/components/flux_functions_toolbar/FunctionTooltip.tsx new file mode 100644 index 0000000000..063431cb30 --- /dev/null +++ b/ui/src/shared/components/flux_functions_toolbar/FunctionTooltip.tsx @@ -0,0 +1,103 @@ +// Libraries +import React, {PureComponent, MouseEvent, CSSProperties, createRef} from 'react' + +// Components +import FancyScrollbar from 'src/shared/components/fancy_scrollbar/FancyScrollbar' +import TooltipDescription from 'src/shared/components/flux_functions_toolbar/TooltipDescription' +import TooltipArguments from 'src/shared/components/flux_functions_toolbar/TooltipArguments' +import TooltipExample from 'src/shared/components/flux_functions_toolbar/TooltipExample' +import TooltipLink from 'src/shared/components/flux_functions_toolbar/TooltipLink' +import {ErrorHandling} from 'src/shared/decorators/errors' + +// Types +import {FluxToolbarFunction} from 'src/types/shared' + +interface Props { + func: FluxToolbarFunction + onDismiss: () => void + tipPosition?: {top: number; right: number} +} + +interface State { + bottomPosition: number | null +} + +const MAX_HEIGHT = 400 + +class FunctionTooltip extends PureComponent { + public state: State = {bottomPosition: null} + + private tooltipRef = createRef() + + public componentDidMount() { + const {bottom, height} = this.tooltipRef.current.getBoundingClientRect() + + if (bottom > window.innerHeight) { + this.setState({bottomPosition: height / 2}) + } + } + + public render() { + const {desc, args, example, link} = this.props.func + + return ( + <> +
+
+ + + ) + } + + private get styleCaretPosition(): CSSProperties { + const {top, right} = this.props.tipPosition + + return { + top: `${Math.min(top, window.innerHeight)}px`, + right: `${right + 4}px`, + } + } + + private get stylePosition(): CSSProperties { + const {top, right} = this.props.tipPosition + const {bottomPosition} = this.state + + return { + bottom: `${bottomPosition || window.innerHeight - top - 15}px`, + right: `${right + 2}px`, + } + } + + private handleDismiss = (e: MouseEvent) => { + const {onDismiss} = this.props + + e.preventDefault() + e.stopPropagation() + onDismiss() + } +} + +export default ErrorHandling(FunctionTooltip) diff --git a/ui/src/shared/components/flux_functions_toolbar/SearchBar.tsx b/ui/src/shared/components/flux_functions_toolbar/SearchBar.tsx new file mode 100644 index 0000000000..9989a78e04 --- /dev/null +++ b/ui/src/shared/components/flux_functions_toolbar/SearchBar.tsx @@ -0,0 +1,55 @@ +// Libraries +import React, {PureComponent, ChangeEvent} from 'react' +import {debounce} from 'lodash' + +// Components +import {Input, IconFont} from 'src/clockface' + +// Types +import {InputType} from 'src/clockface/components/inputs/Input' + +interface Props { + onSearch: (s: string) => void +} + +interface State { + searchTerm: string +} + +const DEBOUNCE_MS = 100 + +class SearchBar extends PureComponent { + constructor(props: Props) { + super(props) + + this.state = { + searchTerm: '', + } + + this.handleSearch = debounce(this.handleSearch, DEBOUNCE_MS) + } + + public render() { + return ( +
+ +
+ ) + } + + private handleSearch = (): void => { + this.props.onSearch(this.state.searchTerm) + } + + private handleChange = (e: ChangeEvent): void => { + this.setState({searchTerm: e.target.value}, this.handleSearch) + } +} + +export default SearchBar diff --git a/ui/src/shared/components/flux_functions_toolbar/ToolbarFunction.tsx b/ui/src/shared/components/flux_functions_toolbar/ToolbarFunction.tsx new file mode 100644 index 0000000000..e194386a86 --- /dev/null +++ b/ui/src/shared/components/flux_functions_toolbar/ToolbarFunction.tsx @@ -0,0 +1,84 @@ +// Libraries +import React, {PureComponent, createRef} from 'react' + +// Component +import FunctionTooltip from 'src/shared/components/flux_functions_toolbar/FunctionTooltip' + +// Types +import {FluxToolbarFunction} from 'src/types/shared' + +interface Props { + func: FluxToolbarFunction + onClickFunction: (s: string) => void +} + +interface State { + isActive: boolean + hoverPosition: {top: number; right: number} +} + +class ToolbarFunction extends PureComponent { + public state: State = {isActive: false, hoverPosition: undefined} + private functionRef = createRef() + + public render() { + const {func} = this.props + + return ( +
+ {this.tooltip} +
+ {func.name} {this.helperText} +
+
+ ) + } + + private get tooltip(): JSX.Element | null { + if (this.state.isActive) { + return ( + + ) + } + + return null + } + + private get helperText(): JSX.Element | null { + if (this.state.isActive) { + return ( + Click to Add + ) + } + + return null + } + + private handleHover = () => { + const {top, left} = this.functionRef.current.getBoundingClientRect() + const right = window.innerWidth - left + + this.setState({isActive: true, hoverPosition: {top, right}}) + } + + private handleStopHover = () => { + this.setState({isActive: false}) + } + + private handleClickFunction = () => { + const {func, onClickFunction} = this.props + + onClickFunction(func.example) + } +} + +export default ToolbarFunction diff --git a/ui/src/shared/components/flux_functions_toolbar/TooltipArguments.tsx b/ui/src/shared/components/flux_functions_toolbar/TooltipArguments.tsx new file mode 100644 index 0000000000..3afca32811 --- /dev/null +++ b/ui/src/shared/components/flux_functions_toolbar/TooltipArguments.tsx @@ -0,0 +1,42 @@ +import React, {PureComponent} from 'react' + +interface Args { + name: string + type: string + desc: string +} + +interface Props { + argsList?: Args[] +} + +class TooltipArguments extends PureComponent { + public render() { + return ( +
+
Arguments
+
{this.arguments}
+
+ ) + } + + private get arguments(): JSX.Element | JSX.Element[] { + const {argsList} = this.props + + if (argsList.length > 0) { + return argsList.map(a => { + return ( +
+ {a.name}: + {a.type} +
{a.desc}
+
+ ) + }) + } + + return
None
+ } +} + +export default TooltipArguments diff --git a/ui/src/shared/components/flux_functions_toolbar/TooltipDescription.tsx b/ui/src/shared/components/flux_functions_toolbar/TooltipDescription.tsx new file mode 100644 index 0000000000..27d498cb4c --- /dev/null +++ b/ui/src/shared/components/flux_functions_toolbar/TooltipDescription.tsx @@ -0,0 +1,14 @@ +import React, {SFC} from 'react' + +interface Props { + description: string +} + +const TooltipDescription: SFC = ({description}) => ( +
+
Description
+ {description} +
+) + +export default TooltipDescription diff --git a/ui/src/shared/components/flux_functions_toolbar/TooltipExample.tsx b/ui/src/shared/components/flux_functions_toolbar/TooltipExample.tsx new file mode 100644 index 0000000000..951201fe8d --- /dev/null +++ b/ui/src/shared/components/flux_functions_toolbar/TooltipExample.tsx @@ -0,0 +1,14 @@ +import React, {SFC} from 'react' + +interface Props { + example: string +} + +const TooltipExample: SFC = ({example}) => ( +
+
Example
+
{example}
+
+) + +export default TooltipExample diff --git a/ui/src/shared/components/flux_functions_toolbar/TooltipLink.tsx b/ui/src/shared/components/flux_functions_toolbar/TooltipLink.tsx new file mode 100644 index 0000000000..2039de0b5d --- /dev/null +++ b/ui/src/shared/components/flux_functions_toolbar/TooltipLink.tsx @@ -0,0 +1,23 @@ +import React, {PureComponent} from 'react' + +interface Props { + link: string +} + +class TooltipLink extends PureComponent { + public render() { + const {link} = this.props + + return ( +

+ Still have questions? Check out the{' '} + + Flux Docs + + . +

+ ) + } +} + +export default TooltipLink diff --git a/ui/src/shared/components/flux_functions_toolbar/TransformToolbarFunctions.tsx b/ui/src/shared/components/flux_functions_toolbar/TransformToolbarFunctions.tsx new file mode 100644 index 0000000000..8103ff2c5a --- /dev/null +++ b/ui/src/shared/components/flux_functions_toolbar/TransformToolbarFunctions.tsx @@ -0,0 +1,28 @@ +// Libraries +import {SFC, ReactElement} from 'react' +import {groupBy} from 'lodash' + +// Types +import {FluxToolbarFunction} from 'src/types/shared' + +interface Props { + funcs: FluxToolbarFunction[] + searchTerm?: string + children: ( + funcs: {[category: string]: FluxToolbarFunction[]} + ) => JSX.Element | JSX.Element[] +} + +const TransformToolbarFunctions: SFC = props => { + const {searchTerm, funcs, children} = props + + const filteredFunctions = funcs.filter(func => + func.name.toLowerCase().includes(searchTerm.toLowerCase()) + ) + + const groupedFunctions = groupBy(filteredFunctions, 'category') + + return children(groupedFunctions) as ReactElement +} + +export default TransformToolbarFunctions diff --git a/ui/src/shared/components/threesizer/Division.tsx b/ui/src/shared/components/threesizer/Division.tsx index ef6ae6fbb0..fe96591034 100644 --- a/ui/src/shared/components/threesizer/Division.tsx +++ b/ui/src/shared/components/threesizer/Division.tsx @@ -43,6 +43,8 @@ class Division extends PureComponent { name: '', handleDisplay: 'visible', style: {}, + headerButtons: [], + menuOptions: [], } private collapseThreshold: number = 0 @@ -282,7 +284,7 @@ class Division extends PureComponent { return true } - if (!this.divisionRef || this.props.size >= 0.33) { + if (!this.divisionRef.current || this.props.size >= 0.33) { return false } diff --git a/ui/src/shared/components/threesizer/Threesizer.scss b/ui/src/shared/components/threesizer/Threesizer.scss index 86aee8f408..a59ed8bfa5 100644 --- a/ui/src/shared/components/threesizer/Threesizer.scss +++ b/ui/src/shared/components/threesizer/Threesizer.scss @@ -171,6 +171,8 @@ $threesizer-shadow-stop: fade-out($g0-obsidian, 1); } .threesizer--body { + position: relative; + .horizontal>&:only-child { width: 100%; } diff --git a/ui/src/shared/components/threesizer/Threesizer.tsx b/ui/src/shared/components/threesizer/Threesizer.tsx index d202a194fe..2ca14ee6e6 100644 --- a/ui/src/shared/components/threesizer/Threesizer.tsx +++ b/ui/src/shared/components/threesizer/Threesizer.tsx @@ -136,6 +136,7 @@ class Threesizer extends Component { > {divisions.map((d, i) => { const headerOrientation = _.get(d, 'headerOrientation', orientation) + return ( r._measurement == "cpu")', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/filter', + }, + { + name: 'first', + args: [], + desc: 'Selects the first non-null record from an input table.', + example: 'first()', + category: 'Selectors', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/selectors/first', + }, + { + name: 'from', + args: [ + { + name: 'bucket', + desc: 'The name of the bucket to query.', + type: 'String', + }, + { + name: 'bucketID', + desc: 'The string-encoded ID of the bucket to query.', + type: 'String', + }, + ], + desc: + 'Used to retrieve data from an InfluxDB data source. It returns a stream of tables from the specified bucket. Each unique series is contained within its own table. Each record in the table represents a single point in the series.', + example: 'from(bucket: "telegraf/autogen")', + category: 'Inputs', + link: 'https://docs.influxdata.com/flux/latest/functions/inputs/from', + }, + { + name: 'fromRows', + args: [ + { + name: 'bucket', + desc: 'The name of the bucket to query.', + type: 'String', + }, + { + name: 'bucketID', + desc: 'The string-encoded ID of the bucket to query.', + type: 'String', + }, + ], + desc: + 'This is a special application of the `pivot()` function that will automatically align fields within each measurement that have the same timestamp.', + example: 'fromRows(bucket: "bucket-name")', + category: 'Inputs', + link: 'https://docs.influxdata.com/flux/latest/functions/inputs/fromrows', + }, + { + name: 'group', + args: [ + { + name: 'by', + desc: + 'List of columns by which to group. Cannot be used with `except`.', + type: 'Array of Strings', + }, + { + name: 'except', + desc: + 'List of columns by which to NOT group. All other columns are used to group records. Cannot be used with `by`.', + type: 'Array of Strings', + }, + { + name: 'none', + desc: 'Remove existing groups.', + type: 'Boolean', + }, + ], + desc: + 'Groups records based on their values for specific columns. It produces tables with new group keys based on provided properties.', + example: 'group(by: ["host", "_measurement"])', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/group', + }, + { + name: 'histogram', + args: [ + { + name: 'column', + desc: + 'The name of a column containing input data values. The column type must be float. Defaults to `"_value"`.', + type: 'Strings', + }, + { + name: 'upperBoundColumn', + desc: + 'The name of the column in which to store the histogram\'s upper bounds. Defaults to `"le"`.', + type: 'String', + }, + { + name: 'countColumn', + desc: + 'The name of the column in which to store the histogram counts. Defaults to `"_value"`.', + type: 'String', + }, + { + name: 'buckets', + desc: + 'A list of upper bounds to use when computing the histogram frequencies. Buckets should contain a bucket whose bound is the maximum value of the data set. This value can be set to positive infinity if no maximum is known.', + type: 'Array of Floats', + }, + { + name: 'normalize', + desc: + 'When `true`, will convert the counts into frequency values between 0 and 1. Defaults to `false`.', + type: 'Boolean', + }, + ], + desc: + 'Approximates the cumulative distribution function of a dataset by counting data frequencies for a list of buckets.', + example: + 'histogram(column: "_value", upperBoundColumn: "le", countColumn: "_value", buckets: [50.0, 75.0, 90.0], normalize: false)', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/histogram', + }, + { + name: 'histogramQuantile', + args: [ + { + name: 'quantile', + desc: + 'A value between 0 and 1 indicating the desired quantile to compute.', + type: 'Float', + }, + { + name: 'upperBoundColumn', + desc: + 'The name of the column in which to store the histogram\'s upper bounds. The count column type must be float. Defaults to `"le"`.', + type: 'String', + }, + { + name: 'countColumn', + desc: + 'The name of the column in which to store the histogram counts. The count column type must be float. Defaults to `"_value"`.', + type: 'String', + }, + { + name: 'valueColumn', + desc: + 'The name of the output column which will contain the computed quantile. Defaults to `"_value"`.', + type: 'String', + }, + { + name: 'minValue', + desc: + 'The assumed minimum value of the dataset. When the quantile falls below the lowest upper bound, interpolation is performed between `minValue` and the lowest upper bound. When `minValue` is equal to negative infinity, the lowest upper bound is used. Defaults to `0`.', + type: 'Float', + }, + ], + desc: + 'Approximates a quantile given a histogram that approximates the cumulative distribution of the dataset.', + example: + 'histogramQuantile(quantile: 0.5, countColumn: "_value", upperBoundColumn: "le", valueColumn: "_value", minValue: 0)', + category: 'Aggregates', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/aggregates/histogramquantile', + }, + { + name: 'increase', + args: [ + { + name: 'columns', + desc: + 'A list of columns for which the increase is calculated. Defaults to `["_value"]`.', + type: 'Array of Strings', + }, + ], + desc: + 'Computes the total non-negative difference between values in a table.', + example: 'increase(columns: ["_values"])', + category: 'Aggregates', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/aggregates/increase', + }, + { + name: 'integral', + args: [ + { + name: 'unit', + desc: 'The time duration used when computing the integral.', + type: 'Duration', + }, + { + name: 'columns', + desc: + 'A list of columns on which to operate. Defaults to `["_value"]`.', + type: 'Array of Strings', + }, + ], + desc: + 'Computes the area under the curve per unit of time of subsequent non-null records. The curve is defined using `_time` as the domain and record values as the range.', + example: 'integral(unit: 10s, columns: ["_value"])', + category: 'Aggregates', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/aggregates/integral', + }, + { + name: 'intervals', + args: [ + { + name: 'every', + desc: + 'The duration between starts of each of the intervals. Defaults to the value of the `period` duration.', + type: 'Duration', + }, + { + name: 'period', + desc: + 'The length of each interval. Defaults to the value of the `every` duration.', + type: 'Duration', + }, + { + name: 'offset', + desc: + 'The offset duration relative to the location offset. Defaults to `0h`.', + type: 'Duration', + }, + { + name: 'columns', + desc: + 'A list of columns on which to operate. Defaults to `["_value"]`.', + type: 'Array of Strings', + }, + { + name: 'fn', + desc: + 'A function that accepts an interval object and returns a boolean value. Each potential interval is passed to the filter function. When the function returns false, that interval is excluded from the set of intervals. Defaults to include all intervals.', + type: 'Function', + }, + ], + desc: 'Generates a set of time intervals over a range of time.', + example: 'intervals()', + category: 'Miscellaneous', + link: 'https://docs.influxdata.com/flux/latest/functions/misc/intervals', + }, + { + name: 'join', + args: [ + { + name: 'tables', + desc: 'The map of streams to be joined.', + type: 'Object', + }, + { + name: 'on', + desc: 'The list of columns on which to join.', + type: 'Array of Strings', + }, + { + name: 'method', + desc: + 'The method used to join. Possible values are: `inner`, `cross`, `left`, `right`, or `full`. Defaults to `"inner"`.', + type: 'String', + }, + ], + desc: + 'Merges two or more input streams, whose values are equal on a set of common columns, into a single output stream. The resulting schema is the union of the input schemas. The resulting group key is the union of the input group keys.', + example: + 'join(tables: {key1: table1, key2: table2}, on: ["_time", "_field"], method: "inner")', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/join', + }, + { + name: 'keep', + args: [ + { + name: 'columns', + desc: + 'Columns that should be included in the resulting table. Cannot be used with `fn`.', + type: 'Array of Strings', + }, + { + name: 'fn', + desc: + 'A function which takes a column name as a parameter and returns a boolean indicating whether or not the column should be removed from the table. Cannot be used with `columns`.', + type: 'Function', + }, + ], + desc: + 'Returns a table containing only the specified columns, ignoring all others. Only columns in the group key that are also specified in the `keep()` function will be kept in the resulting group key. It is the inverse of `drop`.', + example: 'keep(columns: ["col1", "col2"])', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/keep', + }, + { + name: 'keys', + args: [ + { + name: 'except', + desc: + 'Exclude the specified column names in the output. Defaults to `["_time", "_value"]`.', + type: 'Array of Strings', + }, + ], + desc: + "Returns a table with the input table's group key columns, plus a `_value` column containing the names of the input table's columns.", + example: 'keys(except: ["_time", "_value"])', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/keys', + }, + { + name: 'keyValues', + args: [ + { + name: 'keyCols', + desc: + 'A list of columns from which values are extracted. All columns indicated must be of the same type.', + type: 'Array of Strings', + }, + { + name: 'fn', + desc: + 'Function used to identify a set of columns. All columns indicated must be of the same type.', + type: 'Function', + }, + ], + desc: + "Returns a table with the input table's group key plus two columns, `_key` and `_value`, that correspond to unique column + value pairs from the input table.", + example: 'keyValues(keyCols: ["usage_idle", "usage_user"])', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/keyvalues', + }, + { + name: 'last', + args: [], + desc: 'Selects the last non-null record from an input table.', + example: 'last()', + category: 'Selectors', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/selectors/last', + }, + { + name: 'limit', + args: [ + { + name: 'n', + desc: 'The maximum number of records to output.', + type: 'Integer', + }, + ], + desc: + 'Limits the number of records in output tables to a fixed number `n`. If the input table has less than `n` records, all records are be output.', + example: 'limit(n:10)', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/limit', + }, + { + name: 'linearBuckets', + args: [ + { + name: 'start', + desc: 'The first value in the returned list.', + type: 'Float', + }, + { + name: 'width', + desc: 'The distance between subsequent bucket values.', + type: 'Float', + }, + { + name: 'count', + desc: 'The number of buckets to create.', + type: 'Integer', + }, + { + name: 'infinity', + desc: + 'When `true`, adds an additional bucket with a value of positive infinity. Defaults to `true`.', + type: 'Boolean', + }, + ], + desc: 'Generates a list of linearly separated floats.', + example: 'linearBuckets(start: 0.0, width: 5.0, count: 20, infinity: true)', + category: 'Miscellaneous', + link: + 'https://docs.influxdata.com/flux/latest/functions/misc/linearbuckets', + }, + { + name: 'logarithmicBuckets', + args: [ + { + name: 'start', + desc: 'The first value in the returned list.', + type: 'Float', + }, + { + name: 'factor', + desc: 'The multiplier applied to each subsequent bucket.', + type: 'Float', + }, + { + name: 'count', + desc: 'The number of buckets to create.', + type: 'Integer', + }, + { + name: 'infinity', + desc: + 'When `true`, adds an additional bucket with a value of positive infinity. Defaults to `true`.', + type: 'Boolean', + }, + ], + desc: 'Generates a list of exponentially separated floats.', + example: + 'logarithmicBuckets(start: 1.0, factor: 2.0, count: 10, infinty: true)', + category: 'Miscellaneous', + link: + 'https://docs.influxdata.com/flux/latest/functions/misc/logarithmicbuckets', + }, + { + name: 'map', + args: [ + { + name: 'fn', + desc: + 'A single argument function that to apply to each record. The return value must be an object.', + type: 'Function', + }, + { + name: 'mergeKey', + desc: + 'Indicates if the record returned from `fn` should be merged with the group key. Defaults to `true`.', + type: 'Boolean', + }, + ], + desc: 'Applies a function to each record in the input tables.', + example: 'map(fn: (r) => r._value * r._value), mergeKey: true)', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/map', + }, + { + name: 'max', + args: [], + desc: 'Selects record with the highest `_value` from the input table.', + example: 'max()', + category: 'Selectors', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/selectors/max', + }, + { + name: 'mean', + args: [ + { + name: 'columns', + desc: + 'A list of columns on which to compute the mean. Defaults to `["_value"]`', + type: 'Array of Strings', + }, + ], + desc: + 'Computes the mean or average of non-null records in the input table.', + example: 'mean(columns: ["_value"])', + category: 'Aggregates', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/aggregates/mean', + }, + { + name: 'median', + args: [ + { + name: 'columns', + desc: + 'A list of columns on which to compute the mean. Defaults to `["_value"]`', + type: 'Array of Strings', + }, + ], + desc: + 'Returns the median `_value` of an input table. The `median()` function can only be used with float value types.', + example: 'median()', + category: 'Aggregates', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/aggregates/median', + }, + { + name: 'min', + args: [], + desc: 'Selects record with the lowest `_value` from the input table.', + example: 'min()', + category: 'Selectors', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/selectors/min', + }, + { + name: 'pearsonr', + args: [ + { + name: 'x', + desc: 'First input stream used in the operation.', + type: 'Object', + }, + { + name: 'y', + desc: 'Second input stream used in the operation.', + type: 'Object', + }, + { + name: 'on', + desc: 'List of columns on which to join.', + type: 'Array of Strings', + }, + ], + desc: + 'Computes the Pearson R correlation coefficient between two streams by first joining the streams, then performing the covariance operation normalized to compute R.', + example: 'pearsonr(x: table1, y: table2, on: ["_time", "_field"])', + category: 'Aggregates', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/aggregates/pearsonr', + }, + { + name: 'percentile', + args: [ + { + name: 'columns', + desc: + 'A list of columns on which to compute the percentile. Defaults to `["_value"]`.', + type: 'Array of Strings', + }, + { + name: 'percentile', + desc: 'A value between 0 and 1 indicating the desired percentile.', + type: 'Float', + }, + { + name: 'method', + desc: + 'Defines the method of computation. The available options are: `estimate_tdigest`, `exact_mean`, or `exact_selector`.', + type: 'String', + }, + { + name: 'compression', + desc: + 'Indicates how many centroids to use when compressing the dataset. A larger number produces a more accurate result at the cost of increased memory requirements. Defaults to 1000.', + type: 'Float', + }, + ], + desc: + 'This is both an aggregate and selector function depending on the `method` used. When using the `estimate_tdigest` or `exact_mean` methods, it outputs non-null records with values that fall within the specified percentile. When using the `exact_selector` method, it outputs the non-null record with the value that represents the specified percentile.', + example: + 'percentile(columns: ["_value"], percentile: 0.99, method: "estimate_tdigest", compression: 1000)', + category: 'Aggregates', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/aggregates/percentile', + }, + { + name: 'pivot', + args: [ + { + name: 'rowKey', + desc: 'List of columns used to uniquely identify a row for the output.', + type: 'Array of Strings', + }, + { + name: 'columnKey', + desc: + 'List of columns used to pivot values onto each row identified by the rowKey.', + type: 'Array of Strings', + }, + { + name: 'valueColumn', + desc: + 'The single column that contains the value to be moved around the pivot.', + type: 'String', + }, + ], + desc: + 'Collects values stored vertically (column-wise) in a table and aligns them horizontally (row-wise) into logical sets.', + example: + 'pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/pivot', + }, + { + name: 'range', + args: [ + { + name: 'start', + desc: 'Specifies the oldest time to be included in the results.', + type: 'Duration', + }, + { + name: 'stop', + desc: + 'Specifies the exclusive newest time to be included in the results. Defaults to `now`.', + type: 'Duration', + }, + ], + desc: + "Filters records based on time bounds. Each input table's records are filtered to contain only records that exist within the time bounds. Each input table's group key value is modified to fit within the time bounds. Tables where all records exists outside the time bounds are filtered entirely.", + example: 'range(start: -15m, stop: now)', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/range', + }, + { + name: 'rename', + args: [ + { + name: 'columns', + desc: + 'A map of columns to rename and their corresponding new names. Cannot be used with `fn`.', + type: 'Map', + }, + { + name: 'fn', + desc: + 'A function which takes a single string parameter (the old column name) and returns a string representing the new column name. Cannot be used with `columns`.', + type: 'Function', + }, + ], + desc: + 'Renames specified columns in a table. If a column is renamed and is part of the group key, the column name in the group key will be updated.', + example: 'rename(columns: {host: "server", facility: "datacenter"})', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/rename', + }, + { + name: 'sample', + args: [ + { + name: 'n', + desc: 'Sample every Nth element.', + type: 'Integer', + }, + { + name: 'pos', + desc: + 'The position offset from the start of results where sampling begins. `pos` must be less than `n`. If `pos` is less than 0, a random offset is used. Defaults to -1 (random offset).', + type: 'Integer', + }, + ], + desc: 'Selects a subset of the records from the input table.', + example: 'sample(n:5, pos: -1)', + category: 'Selectors', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/selectors/sample', + }, + { + name: 'set', + args: [ + { + name: 'key', + desc: 'The label of the column to modify or set.', + type: 'String', + }, + { + name: 'value', + desc: 'The string value to set.', + type: 'String', + }, + ], + desc: + 'Assigns a static value to each record in the input table. The key may modify an existing column or add a new column to the tables. If the modified column is part of the group key, the output tables are regrouped as needed.', + example: 'set(key: "myKey", value: "myValue")', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/set', + }, + { + name: 'shift', + args: [ + { + name: 'shift', + desc: + 'The amount of time to add to each time value. The shift may be a negative duration.', + type: 'String', + }, + { + name: 'columns', + desc: + 'The list of all columns to be shifted. Defaults to `["_start", "_stop", "_time"]`.', + type: 'Array of Strings', + }, + ], + desc: + 'Adds a fixed duration to time columns. The output table schema is the same as the input table.', + example: 'shift(shift: 10h, columns: ["_start", "_stop", "_time"])', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/shift', + }, + { + name: 'skew', + args: [ + { + name: 'columns', + desc: + 'Specifies a list of columns on which to operate. Defaults to `["_value"]`.', + type: 'Array of Strings', + }, + ], + desc: 'Outputs the skew of non-null records as a float.', + example: 'skew(columns: ["_value"])', + category: 'Aggregates', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/aggregates/skew', + }, + { + name: 'sort', + args: [ + { + name: 'columns', + desc: + 'List of columns by which to sort. Sort precedence is determined by list order (left to right). Default is `["_value"]`.', + type: 'Array of Strings', + }, + { + name: 'desc', + desc: 'Sort results in descending order. Default is `false`.', + type: 'Boolean', + }, + ], + desc: + 'Orders the records within each table. One output table is produced for each input table. The output tables will have the same schema as their corresponding input tables.', + example: 'sort(columns: ["_value"], desc: false)', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/sort', + }, + { + name: 'spread', + args: [ + { + name: 'columns', + desc: + 'Specifies a list of columns on which to operate. Defaults to `["_value"]`.', + type: 'Array of Strings', + }, + ], + desc: + 'Outputs the difference between the minimum and maximum values in each specified column. Only `uint`, `int`, and `float` column types can be used.', + example: 'spread(columns: ["_value"])', + category: 'Aggregates', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/aggregates/spread', + }, + { + name: 'stateCount', + args: [ + { + name: 'fn', + desc: + 'A single argument function that evaluates true or false to identify the state of the record.', + type: 'Function', + }, + { + name: 'label', + desc: + 'The name of the column added to each record that contains the incremented state count.', + type: 'String', + }, + ], + desc: + 'Computes the number of consecutive records in a given state and stores the increment in a new column.', + example: 'stateCount(fn: (r) => r._field == "state", label: "stateCount")', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/statecount', + }, + { + name: 'stateDuration', + args: [ + { + name: 'fn', + desc: + 'A single argument function that evaluates true or false to identify the state of the record.', + type: 'Function', + }, + { + name: 'label', + desc: + 'Name of the column added to each record that contains the incremented state duration.', + type: 'String', + }, + { + name: 'unit', + desc: 'Unit of time in which the state duration is incremented.', + type: 'Duration', + }, + ], + desc: + 'Computes the duration of a given state and stores the increment in a new column.', + example: + 'stateDuration(fn: (r) => r._measurement == "state", lable: "stateDuration", unit: 1s)', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/stateduration', + }, + { + name: 'stddev', + args: [ + { + name: 'columns', + desc: + 'Specifies a list of columns on which to operate. Defaults to `["_value"]`.', + type: 'Array of Strings', + }, + ], + desc: + 'Computes the standard deviation of non-null records in specified columns.', + example: 'stddev(columns: ["_value"])', + category: 'Aggregates', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/aggregates/stddev', + }, + { + name: 'sum', + args: [ + { + name: 'columns', + desc: + 'Specifies a list of columns on which to operate. Defaults to `["_value"]`.', + type: 'Array of Strings', + }, + ], + desc: 'Computes the sum of non-null records in specified columns.', + example: 'sum(columns: ["_value"])', + category: 'Aggregates', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/aggregates/sum', + }, + { + name: 'systemTime', + args: [], + desc: 'Returns the current system time.', + example: 'systemTime()', + category: 'Miscellaneous', + link: 'https://docs.influxdata.com/flux/latest/functions/misc/systemtime', + }, + { + name: 'to', + args: [ + { + name: 'bucket', + desc: + 'The bucket to which data is written. Mutually exclusive with `bucketID`.', + type: 'String', + }, + { + name: 'bucketID', + desc: + 'The ID of the bucket to which data is written. Mutually exclusive with `bucket`.', + type: 'String', + }, + { + name: 'org', + desc: + 'The organization name of the specified `bucket`. Only required when writing to a remote host. Mutually exclusive with `orgID`.', + type: 'String', + }, + { + name: 'orgID', + desc: + 'The organization ID of the specified `bucket`. Only required when writing to a remote host. Mutually exclusive with `org`.', + type: 'String', + }, + { + name: 'host', + desc: + 'The remote InfluxDB host to which to write. If specified, a `token` is required.', + type: 'String', + }, + { + name: 'token', + desc: + 'The authorization token to use when writing to a remote host. Required when a `host` is specified.', + type: 'String', + }, + { + name: 'timeColumn', + desc: 'The time column of the output. Default is `"_time"`.', + type: 'String', + }, + { + name: 'tagColumns', + desc: + 'The tag columns of the output. Defaults to all columns with type `string`, excluding all value columns and the `_field` column if present.', + type: 'Array of Strings', + }, + { + name: 'fieldFn', + desc: + 'Function that takes a record from the input table and returns an object. For each record from the input table, `fieldFn` returns an object that maps output the field key to the output value. Default is `(r) => ({ [r._field]: r._value })`', + type: 'Function', + }, + ], + desc: 'The `to()` function writes data to an InfluxDB v2.0 bucket.', + example: + 'to(bucket: "my-bucket", org: "my-org", host: "http://example.com:8086", token: "xxxxxx", timeColumn: "_time", tagColumns: ["tag1", "tag2", "tag3"], fieldFn: (r) => ({ [r._field]: r._value }))', + category: 'Outputs', + link: 'https://docs.influxdata.com/flux/latest/functions/outputs/to', + }, + { + name: 'toBool', + args: [], + desc: 'Converts a value to a boolean.', + example: 'toBool()', + category: 'Type Conversions', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/type-conversions/tobool', + }, + { + name: 'toDuration', + args: [], + desc: 'Converts a value to a duration.', + example: 'toDuration()', + category: 'Type Conversions', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/type-conversions/toduration', + }, + { + name: 'toFloat', + args: [], + desc: 'Converts a value to a float.', + example: 'toFloat()', + category: 'Type Conversions', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/type-conversions/tofloat', + }, + { + name: 'toInt', + args: [], + desc: 'Converts a value to a integer.', + example: 'toInt()', + category: 'Type Conversions', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/type-conversions/toint', + }, + { + name: 'top', + args: [ + { + name: 'n', + desc: 'Number of rows to return.', + type: 'Integer', + }, + { + name: 'columns', + desc: + 'List of columns by which to sort. Sort precedence is determined by list order (left to right). Default is `["_value"]`.', + type: 'Array of Strings', + }, + ], + desc: 'Sorts a table by columns and keeps only the top n rows.', + example: 'top(n:10, cols: ["_value"])', + category: 'Selectors', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/selectors/top', + }, + { + name: 'toString', + args: [], + desc: 'Converts a value to a string.', + example: 'toString()', + category: 'Type Conversions', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/type-conversions/tostring', + }, + { + name: 'toTime', + args: [], + desc: 'Converts a value to a time.', + example: 'toTime()', + category: 'Type Conversions', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/type-conversions/totime', + }, + { + name: 'toUInt', + args: [], + desc: 'Converts a value to an unsigned integer.', + example: 'toUInt()', + category: 'Type Conversions', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/type-conversions/touint', + }, + { + name: 'union', + args: [ + { + name: 'tables', + desc: + 'Specifies the streams to union together. There must be at least two streams.', + type: 'Array of Strings', + }, + ], + desc: + 'Concatenates two or more input streams into a single output stream. The output schemas of the `union()` function is the union of all input schemas. A sort operation may be added if a specific sort order is needed.', + example: 'union(tables: ["table1", "table2"])', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/union', + }, + { + name: 'unique', + args: [ + { + name: 'column', + desc: 'The column searched for unique values. Defaults to `"_value"`.', + type: 'String', + }, + ], + desc: 'Returns all rows containing unique values in a specified column.', + example: 'unique(column: "_value")', + category: 'Selectors', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/selectors/unique', + }, + { + name: 'window', + args: [ + { + name: 'every', + desc: 'Duration of time between windows. Defaults to `period` value.', + type: 'Duration', + }, + { + name: 'period', + desc: + 'Duration of the window. Period is the length of each interval. It can be negative, indicating the start and stop boundaries are reversed. Defaults to `every` value.', + type: 'Duration', + }, + { + name: 'offset', + desc: + 'The offset duration relative to the `location` offset. It can be negative, indicating that the offset goes backwards in time. The default aligns the window boundaries with `now`.', + type: 'Duration', + }, + { + name: 'intervals', + desc: + 'A function that returns an interval generator, a set of intervals used as windows. See docs for an example.', + type: 'Function', + }, + { + name: 'timeCol', + desc: 'The column containing time. Defaults to `"_time"`.', + type: 'String', + }, + { + name: 'startCol', + desc: + 'The column containing the window start time. Defaults to `"_start"`.', + type: 'String', + }, + { + name: 'stopCol', + desc: + 'The column containing the window stop time. Defaults to `"_stop"`.', + type: 'String', + }, + ], + desc: + 'Groups records based on a time value. New columns are added to uniquely identify each window. Those columns are added to the group key of the output tables. A single input record will be placed into zero or more output tables, depending on the specific windowing function.', + example: + 'window(every: 5m, period: 5m, offset: 12h, timeCol: "_time", startCol: "_start", stopCol: "_stop")', + category: 'Transformations', + link: + 'https://docs.influxdata.com/flux/latest/functions/transformations/window', + }, + { + name: 'yield', + args: [ + { + name: 'name', + desc: 'A unique name for the yielded results.', + type: 'String', + }, + ], + desc: + 'Indicates the input tables received should be delivered as a result of the query. Yield outputs the input stream unmodified. A query may have multiple results, each identified by the name provided to the `yield()` function.', + example: 'yield(name: "custom-name")', + category: 'Outputs', + link: 'https://docs.influxdata.com/flux/latest/functions/outputs/yield', + }, +] diff --git a/ui/src/style/chronograf.scss b/ui/src/style/chronograf.scss index e260630858..6742e792d2 100644 --- a/ui/src/style/chronograf.scss +++ b/ui/src/style/chronograf.scss @@ -44,6 +44,7 @@ @import "src/shared/components/custom_singular_time/CustomSingularTime"; @import "src/onboarding/OnboardingWizard.scss"; @import "src/shared/components/RawFluxDataTable.scss"; +@import "src/shared/components/flux_functions_toolbar/FluxFunctionsToolbar.scss"; @import "src/logs/containers/logs_page/LogsPage"; @import "src/logs/components/loading_status/LoadingStatus"; diff --git a/ui/src/types/shared.ts b/ui/src/types/shared.ts index 600cc59a7c..c13a096af9 100644 --- a/ui/src/types/shared.ts +++ b/ui/src/types/shared.ts @@ -16,3 +16,18 @@ export interface PageSection { component: ReactNode enabled: boolean } + +export interface FluxToolbarArg { + name: string + desc: string + type: string +} + +export interface FluxToolbarFunction { + name: string + args: FluxToolbarArg[] + desc: string + example: string + category: string + link: string +}