Merge pull request #3155 from influxdata/table/fieldnames-from-query-config
Table/Get FieldNames from query configpull/10616/head
commit
5b87bea961
|
@ -49,7 +49,6 @@ class CellEditorOverlay extends Component {
|
||||||
activeQueryIndex: 0,
|
activeQueryIndex: 0,
|
||||||
isDisplayOptionsTabActive: false,
|
isDisplayOptionsTabActive: false,
|
||||||
staticLegend: IS_STATIC_LEGEND(legend),
|
staticLegend: IS_STATIC_LEGEND(legend),
|
||||||
dataLabels: [],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,10 +252,6 @@ class CellEditorOverlay extends Component {
|
||||||
this.overlayRef.focus()
|
this.overlayRef.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
setDataLabels = dataLabels => {
|
|
||||||
this.setState({dataLabels})
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
onCancel,
|
onCancel,
|
||||||
|
@ -271,7 +266,6 @@ class CellEditorOverlay extends Component {
|
||||||
isDisplayOptionsTabActive,
|
isDisplayOptionsTabActive,
|
||||||
queriesWorkingDraft,
|
queriesWorkingDraft,
|
||||||
staticLegend,
|
staticLegend,
|
||||||
dataLabels,
|
|
||||||
} = this.state
|
} = this.state
|
||||||
|
|
||||||
const queryActions = {
|
const queryActions = {
|
||||||
|
@ -304,7 +298,6 @@ class CellEditorOverlay extends Component {
|
||||||
queryConfigs={queriesWorkingDraft}
|
queryConfigs={queriesWorkingDraft}
|
||||||
editQueryStatus={editQueryStatus}
|
editQueryStatus={editQueryStatus}
|
||||||
staticLegend={staticLegend}
|
staticLegend={staticLegend}
|
||||||
setDataLabels={this.setDataLabels}
|
|
||||||
/>
|
/>
|
||||||
<CEOBottom>
|
<CEOBottom>
|
||||||
<OverlayControls
|
<OverlayControls
|
||||||
|
@ -324,7 +317,6 @@ class CellEditorOverlay extends Component {
|
||||||
onToggleStaticLegend={this.handleToggleStaticLegend}
|
onToggleStaticLegend={this.handleToggleStaticLegend}
|
||||||
staticLegend={staticLegend}
|
staticLegend={staticLegend}
|
||||||
onResetFocus={this.handleResetFocus}
|
onResetFocus={this.handleResetFocus}
|
||||||
dataLabels={dataLabels}
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<QueryMaker
|
<QueryMaker
|
||||||
|
|
|
@ -42,7 +42,7 @@ class DisplayOptions extends Component {
|
||||||
staticLegend,
|
staticLegend,
|
||||||
onToggleStaticLegend,
|
onToggleStaticLegend,
|
||||||
onResetFocus,
|
onResetFocus,
|
||||||
dataLabels,
|
queryConfigs,
|
||||||
} = this.props
|
} = this.props
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'gauge':
|
case 'gauge':
|
||||||
|
@ -51,7 +51,10 @@ class DisplayOptions extends Component {
|
||||||
return <SingleStatOptions onResetFocus={onResetFocus} />
|
return <SingleStatOptions onResetFocus={onResetFocus} />
|
||||||
case 'table':
|
case 'table':
|
||||||
return (
|
return (
|
||||||
<TableOptions onResetFocus={onResetFocus} dataLabels={dataLabels} />
|
<TableOptions
|
||||||
|
onResetFocus={onResetFocus}
|
||||||
|
queryConfigs={queryConfigs}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
|
@ -90,7 +93,6 @@ DisplayOptions.propTypes = {
|
||||||
onToggleStaticLegend: func.isRequired,
|
onToggleStaticLegend: func.isRequired,
|
||||||
staticLegend: bool,
|
staticLegend: bool,
|
||||||
onResetFocus: func.isRequired,
|
onResetFocus: func.isRequired,
|
||||||
dataLabels: arrayOf(string),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = ({cellEditorOverlay: {cell, cell: {axes}}}) => ({
|
const mapStateToProps = ({cellEditorOverlay: {cell, cell: {axes}}}) => ({
|
||||||
|
|
|
@ -23,16 +23,6 @@ class GraphOptionsCustomizableField extends PureComponent<Props, {}> {
|
||||||
this.handleToggleVisible = this.handleToggleVisible.bind(this)
|
this.handleToggleVisible = this.handleToggleVisible.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
public handleFieldRename(rename: string) {
|
|
||||||
const {onFieldUpdate, internalName, visible} = this.props
|
|
||||||
onFieldUpdate({internalName, displayName: rename, visible})
|
|
||||||
}
|
|
||||||
|
|
||||||
public handleToggleVisible() {
|
|
||||||
const {onFieldUpdate, internalName, displayName, visible} = this.props
|
|
||||||
onFieldUpdate({internalName, displayName, visible: !visible})
|
|
||||||
}
|
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {internalName, displayName, visible} = this.props
|
const {internalName, displayName, visible} = this.props
|
||||||
|
|
||||||
|
@ -65,6 +55,16 @@ class GraphOptionsCustomizableField extends PureComponent<Props, {}> {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleFieldRename(rename: string) {
|
||||||
|
const {onFieldUpdate, internalName, visible} = this.props
|
||||||
|
onFieldUpdate({internalName, displayName: rename, visible})
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleToggleVisible() {
|
||||||
|
const {onFieldUpdate, internalName, displayName, visible} = this.props
|
||||||
|
onFieldUpdate({internalName, displayName, visible: !visible})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GraphOptionsCustomizableField
|
export default GraphOptionsCustomizableField
|
||||||
|
|
|
@ -16,6 +16,7 @@ import ThresholdsListTypeToggle from 'src/shared/components/ThresholdsListTypeTo
|
||||||
|
|
||||||
import {updateTableOptions} from 'src/dashboards/actions/cellEditorOverlay'
|
import {updateTableOptions} from 'src/dashboards/actions/cellEditorOverlay'
|
||||||
import {TIME_FIELD_DEFAULT} from 'src/shared/constants/tableGraph'
|
import {TIME_FIELD_DEFAULT} from 'src/shared/constants/tableGraph'
|
||||||
|
import {QueryConfig} from 'src/types/query'
|
||||||
|
|
||||||
interface Option {
|
interface Option {
|
||||||
text: string
|
text: string
|
||||||
|
@ -37,10 +38,10 @@ interface Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
queryConfigs: QueryConfig[]
|
||||||
handleUpdateTableOptions: (options: Options) => void
|
handleUpdateTableOptions: (options: Options) => void
|
||||||
tableOptions: Options
|
tableOptions: Options
|
||||||
onResetFocus: () => void
|
onResetFocus: () => void
|
||||||
dataLabels: string[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TableOptions extends PureComponent<Props, {}> {
|
export class TableOptions extends PureComponent<Props, {}> {
|
||||||
|
@ -48,79 +49,6 @@ export class TableOptions extends PureComponent<Props, {}> {
|
||||||
super(props)
|
super(props)
|
||||||
}
|
}
|
||||||
|
|
||||||
get fieldNames() {
|
|
||||||
const {tableOptions: {fieldNames}} = this.props
|
|
||||||
return fieldNames || []
|
|
||||||
}
|
|
||||||
|
|
||||||
get timeField() {
|
|
||||||
return (
|
|
||||||
this.fieldNames.find(f => f.internalName === 'time') || TIME_FIELD_DEFAULT
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
get computedFieldNames() {
|
|
||||||
const {dataLabels} = this.props
|
|
||||||
|
|
||||||
return _.isEmpty(dataLabels)
|
|
||||||
? [this.timeField]
|
|
||||||
: dataLabels.map(label => {
|
|
||||||
const existing = this.fieldNames.find(f => f.internalName === label)
|
|
||||||
return (
|
|
||||||
existing || {internalName: label, displayName: '', visible: true}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public handleChooseSortBy = (option: Option) => {
|
|
||||||
const {tableOptions, handleUpdateTableOptions} = this.props
|
|
||||||
const sortBy = {
|
|
||||||
displayName: option.text === option.key ? '' : option.text,
|
|
||||||
internalName: option.key,
|
|
||||||
visible: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
handleUpdateTableOptions({...tableOptions, sortBy})
|
|
||||||
}
|
|
||||||
|
|
||||||
public handleTimeFormatChange = timeFormat => {
|
|
||||||
const {tableOptions, handleUpdateTableOptions} = this.props
|
|
||||||
handleUpdateTableOptions({...tableOptions, timeFormat})
|
|
||||||
}
|
|
||||||
|
|
||||||
public handleToggleVerticalTimeAxis = verticalTimeAxis => () => {
|
|
||||||
const {tableOptions, handleUpdateTableOptions} = this.props
|
|
||||||
handleUpdateTableOptions({...tableOptions, verticalTimeAxis})
|
|
||||||
}
|
|
||||||
|
|
||||||
public handleToggleFixFirstColumn = () => {
|
|
||||||
const {handleUpdateTableOptions, tableOptions} = this.props
|
|
||||||
const fixFirstColumn = !tableOptions.fixFirstColumn
|
|
||||||
handleUpdateTableOptions({...tableOptions, fixFirstColumn})
|
|
||||||
}
|
|
||||||
|
|
||||||
public handleFieldUpdate = field => {
|
|
||||||
const {handleUpdateTableOptions, tableOptions, dataLabels} = this.props
|
|
||||||
const {sortBy, fieldNames} = tableOptions
|
|
||||||
const fields =
|
|
||||||
fieldNames.length >= dataLabels.length
|
|
||||||
? fieldNames
|
|
||||||
: this.computedFieldNames
|
|
||||||
const updatedFields = fields.map(
|
|
||||||
f => (f.internalName === field.internalName ? field : f)
|
|
||||||
)
|
|
||||||
const updatedSortBy =
|
|
||||||
sortBy.internalName === field.internalName
|
|
||||||
? {...sortBy, displayName: field.displayName}
|
|
||||||
: sortBy
|
|
||||||
|
|
||||||
handleUpdateTableOptions({
|
|
||||||
...tableOptions,
|
|
||||||
fieldNames: updatedFields,
|
|
||||||
sortBy: updatedSortBy,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public componentWillMount() {
|
public componentWillMount() {
|
||||||
const {handleUpdateTableOptions, tableOptions} = this.props
|
const {handleUpdateTableOptions, tableOptions} = this.props
|
||||||
handleUpdateTableOptions({
|
handleUpdateTableOptions({
|
||||||
|
@ -130,14 +58,13 @@ export class TableOptions extends PureComponent<Props, {}> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public shouldComponentUpdate(nextProps) {
|
public shouldComponentUpdate(nextProps) {
|
||||||
const {tableOptions, dataLabels} = this.props
|
const {tableOptions} = this.props
|
||||||
const tableOptionsDifferent = !_.isEqual(
|
const tableOptionsDifferent = !_.isEqual(
|
||||||
tableOptions,
|
tableOptions,
|
||||||
nextProps.tableOptions
|
nextProps.tableOptions
|
||||||
)
|
)
|
||||||
const dataLabelsDifferent = !_.isEqual(dataLabels, nextProps.dataLabels)
|
|
||||||
|
|
||||||
return tableOptionsDifferent || dataLabelsDifferent
|
return tableOptionsDifferent
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
|
@ -147,13 +74,11 @@ export class TableOptions extends PureComponent<Props, {}> {
|
||||||
tableOptions,
|
tableOptions,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const tableSortByOptions = this.computedFieldNames.map(field => ({
|
const tableSortByOptions = this.fieldNames.map(field => ({
|
||||||
key: field.internalName,
|
key: field.internalName,
|
||||||
text: field.displayName || field.internalName,
|
text: field.displayName || field.internalName,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const fields = fieldNames.length > 1 ? fieldNames : this.computedFieldNames
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FancyScrollbar
|
<FancyScrollbar
|
||||||
className="display-options--cell y-axis-controls"
|
className="display-options--cell y-axis-controls"
|
||||||
|
@ -181,7 +106,7 @@ export class TableOptions extends PureComponent<Props, {}> {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<GraphOptionsCustomizeFields
|
<GraphOptionsCustomizeFields
|
||||||
fields={fields}
|
fields={fieldNames}
|
||||||
onFieldUpdate={this.handleFieldUpdate}
|
onFieldUpdate={this.handleFieldUpdate}
|
||||||
/>
|
/>
|
||||||
<ThresholdsList showListHeading={true} onResetFocus={onResetFocus} />
|
<ThresholdsList showListHeading={true} onResetFocus={onResetFocus} />
|
||||||
|
@ -192,6 +117,79 @@ export class TableOptions extends PureComponent<Props, {}> {
|
||||||
</FancyScrollbar>
|
</FancyScrollbar>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get fieldNames() {
|
||||||
|
const {tableOptions: {fieldNames}} = this.props
|
||||||
|
return fieldNames || []
|
||||||
|
}
|
||||||
|
|
||||||
|
private get timeField() {
|
||||||
|
return (
|
||||||
|
this.fieldNames.find(f => f.internalName === 'time') || TIME_FIELD_DEFAULT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private get computedFieldNames() {
|
||||||
|
const {queryConfigs} = this.props
|
||||||
|
const queryFields = _.flatten(
|
||||||
|
queryConfigs.map(({measurement, fields}) => {
|
||||||
|
return fields.map(({alias}) => {
|
||||||
|
const internalName = `${measurement}.${alias}`
|
||||||
|
const existing = this.fieldNames.find(
|
||||||
|
c => c.internalName === internalName
|
||||||
|
)
|
||||||
|
return existing || {internalName, displayName: '', visible: true}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
return [this.timeField, ...queryFields]
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleChooseSortBy = (option: Option) => {
|
||||||
|
const {tableOptions, handleUpdateTableOptions} = this.props
|
||||||
|
const sortBy = {
|
||||||
|
displayName: option.text === option.key ? '' : option.text,
|
||||||
|
internalName: option.key,
|
||||||
|
visible: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUpdateTableOptions({...tableOptions, sortBy})
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleTimeFormatChange = timeFormat => {
|
||||||
|
const {tableOptions, handleUpdateTableOptions} = this.props
|
||||||
|
handleUpdateTableOptions({...tableOptions, timeFormat})
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleToggleVerticalTimeAxis = verticalTimeAxis => () => {
|
||||||
|
const {tableOptions, handleUpdateTableOptions} = this.props
|
||||||
|
handleUpdateTableOptions({...tableOptions, verticalTimeAxis})
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleToggleFixFirstColumn = () => {
|
||||||
|
const {handleUpdateTableOptions, tableOptions} = this.props
|
||||||
|
const fixFirstColumn = !tableOptions.fixFirstColumn
|
||||||
|
handleUpdateTableOptions({...tableOptions, fixFirstColumn})
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleFieldUpdate = field => {
|
||||||
|
const {handleUpdateTableOptions, tableOptions} = this.props
|
||||||
|
const {sortBy, fieldNames} = tableOptions
|
||||||
|
const updatedFields = fieldNames.map(
|
||||||
|
f => (f.internalName === field.internalName ? field : f)
|
||||||
|
)
|
||||||
|
const updatedSortBy =
|
||||||
|
sortBy.internalName === field.internalName
|
||||||
|
? {...sortBy, displayName: field.displayName}
|
||||||
|
: sortBy
|
||||||
|
|
||||||
|
handleUpdateTableOptions({
|
||||||
|
...tableOptions,
|
||||||
|
fieldNames: updatedFields,
|
||||||
|
sortBy: updatedSortBy,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = ({cellEditorOverlay: {cell: {tableOptions}}}) => ({
|
const mapStateToProps = ({cellEditorOverlay: {cell: {tableOptions}}}) => ({
|
||||||
|
|
|
@ -24,7 +24,6 @@ const DashVisualization = (
|
||||||
staticLegend,
|
staticLegend,
|
||||||
thresholdsListColors,
|
thresholdsListColors,
|
||||||
tableOptions,
|
tableOptions,
|
||||||
setDataLabels,
|
|
||||||
},
|
},
|
||||||
{source: {links: {proxy}}}
|
{source: {links: {proxy}}}
|
||||||
) => {
|
) => {
|
||||||
|
@ -50,7 +49,6 @@ const DashVisualization = (
|
||||||
editQueryStatus={editQueryStatus}
|
editQueryStatus={editQueryStatus}
|
||||||
resizerTopHeight={resizerTopHeight}
|
resizerTopHeight={resizerTopHeight}
|
||||||
staticLegend={staticLegend}
|
staticLegend={staticLegend}
|
||||||
setDataLabels={setDataLabels}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -80,7 +78,6 @@ DashVisualization.propTypes = {
|
||||||
gaugeColors: colorsNumberSchema,
|
gaugeColors: colorsNumberSchema,
|
||||||
lineColors: colorsStringSchema,
|
lineColors: colorsStringSchema,
|
||||||
staticLegend: bool,
|
staticLegend: bool,
|
||||||
setDataLabels: func,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DashVisualization.contextTypes = {
|
DashVisualization.contextTypes = {
|
||||||
|
|
|
@ -25,7 +25,6 @@ const RefreshingGraph = ({
|
||||||
cellID,
|
cellID,
|
||||||
queries,
|
queries,
|
||||||
tableOptions,
|
tableOptions,
|
||||||
setDataLabels,
|
|
||||||
templates,
|
templates,
|
||||||
timeRange,
|
timeRange,
|
||||||
cellHeight,
|
cellHeight,
|
||||||
|
@ -101,7 +100,6 @@ const RefreshingGraph = ({
|
||||||
hoverTime={hoverTime}
|
hoverTime={hoverTime}
|
||||||
onSetHoverTime={onSetHoverTime}
|
onSetHoverTime={onSetHoverTime}
|
||||||
inView={inView}
|
inView={inView}
|
||||||
setDataLabels={setDataLabels}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -160,7 +158,6 @@ RefreshingGraph.propTypes = {
|
||||||
cellID: string,
|
cellID: string,
|
||||||
inView: bool,
|
inView: bool,
|
||||||
tableOptions: shape({}),
|
tableOptions: shape({}),
|
||||||
setDataLabels: func,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefreshingGraph.defaultProps = {
|
RefreshingGraph.defaultProps = {
|
||||||
|
|
|
@ -40,7 +40,6 @@ class TableGraph extends Component {
|
||||||
data: [[]],
|
data: [[]],
|
||||||
processedData: [[]],
|
processedData: [[]],
|
||||||
sortedTimeVals: [],
|
sortedTimeVals: [],
|
||||||
labels: [],
|
|
||||||
hoveredColumnIndex: NULL_ARRAY_INDEX,
|
hoveredColumnIndex: NULL_ARRAY_INDEX,
|
||||||
hoveredRowIndex: NULL_ARRAY_INDEX,
|
hoveredRowIndex: NULL_ARRAY_INDEX,
|
||||||
sortField,
|
sortField,
|
||||||
|
@ -51,7 +50,7 @@ class TableGraph extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
const {labels, data} = timeSeriesToTableGraph(nextProps.data)
|
const {data} = timeSeriesToTableGraph(nextProps.data)
|
||||||
if (_.isEmpty(data[0])) {
|
if (_.isEmpty(data[0])) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -64,13 +63,8 @@ class TableGraph extends Component {
|
||||||
verticalTimeAxis,
|
verticalTimeAxis,
|
||||||
timeFormat,
|
timeFormat,
|
||||||
},
|
},
|
||||||
setDataLabels,
|
|
||||||
} = nextProps
|
} = nextProps
|
||||||
|
|
||||||
if (setDataLabels) {
|
|
||||||
setDataLabels(labels)
|
|
||||||
}
|
|
||||||
|
|
||||||
let direction, sortFieldName
|
let direction, sortFieldName
|
||||||
if (
|
if (
|
||||||
_.get(this.props, ['tableOptions', 'sortBy', 'internalName'], '') ===
|
_.get(this.props, ['tableOptions', 'sortBy', 'internalName'], '') ===
|
||||||
|
@ -99,7 +93,6 @@ class TableGraph extends Component {
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
data,
|
data,
|
||||||
labels,
|
|
||||||
processedData,
|
processedData,
|
||||||
sortedTimeVals,
|
sortedTimeVals,
|
||||||
sortField: sortFieldName,
|
sortField: sortFieldName,
|
||||||
|
@ -194,7 +187,7 @@ class TableGraph extends Component {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateColumnWidth = __ => column => {
|
calculateColumnWidth = columnSizerWidth => column => {
|
||||||
const {index} = column
|
const {index} = column
|
||||||
const {tableOptions: {fixFirstColumn}} = this.props
|
const {tableOptions: {fixFirstColumn}} = this.props
|
||||||
const {processedData, columnWidths, totalColumnWidths} = this.state
|
const {processedData, columnWidths, totalColumnWidths} = this.state
|
||||||
|
@ -205,8 +198,12 @@ class TableGraph extends Component {
|
||||||
|
|
||||||
const tableWidth = _.get(this, ['gridContainer', 'clientWidth'], 0)
|
const tableWidth = _.get(this, ['gridContainer', 'clientWidth'], 0)
|
||||||
if (tableWidth > totalColumnWidths) {
|
if (tableWidth > totalColumnWidths) {
|
||||||
|
if (columnCount === 1) {
|
||||||
|
return columnSizerWidth
|
||||||
|
}
|
||||||
const difference = tableWidth - totalColumnWidths
|
const difference = tableWidth - totalColumnWidths
|
||||||
const distributeOver = fixFirstColumn ? columnCount - 1 : columnCount
|
const distributeOver =
|
||||||
|
fixFirstColumn && columnCount > 1 ? columnCount - 1 : columnCount
|
||||||
const increment = difference / distributeOver
|
const increment = difference / distributeOver
|
||||||
adjustedColumnSizerWidth =
|
adjustedColumnSizerWidth =
|
||||||
fixFirstColumn && index === 0
|
fixFirstColumn && index === 0
|
||||||
|
@ -412,7 +409,6 @@ TableGraph.propTypes = {
|
||||||
hoverTime: string,
|
hoverTime: string,
|
||||||
onSetHoverTime: func,
|
onSetHoverTime: func,
|
||||||
colors: colorsStringSchema,
|
colors: colorsStringSchema,
|
||||||
setDataLabels: func,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TableGraph
|
export default TableGraph
|
||||||
|
|
|
@ -180,7 +180,6 @@ export const timeSeriesToTableGraph = raw => {
|
||||||
const tableData = map(sortedTimeSeries, ({time, values}) => [time, ...values])
|
const tableData = map(sortedTimeSeries, ({time, values}) => [time, ...values])
|
||||||
const data = tableData.length ? [labels, ...tableData] : [[]]
|
const data = tableData.length ? [labels, ...tableData] : [[]]
|
||||||
return {
|
return {
|
||||||
labels,
|
|
||||||
data,
|
data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,47 +72,4 @@ describe('Dashboards.Components.GraphOptionsCustomizableField', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('instance methods', () => {
|
|
||||||
describe('#handleFieldUpdate', () => {
|
|
||||||
it('calls onFieldUpdate once with internalName, new name, and visible', () => {
|
|
||||||
const onFieldUpdate = jest.fn()
|
|
||||||
const internalName = 'test'
|
|
||||||
const {instance, props: {visible}} = setup({
|
|
||||||
internalName,
|
|
||||||
onFieldUpdate,
|
|
||||||
})
|
|
||||||
const rename = 'TEST'
|
|
||||||
|
|
||||||
instance.handleFieldRename(rename)
|
|
||||||
|
|
||||||
expect(onFieldUpdate).toHaveBeenCalledTimes(1)
|
|
||||||
expect(onFieldUpdate).toHaveBeenCalledWith({
|
|
||||||
displayName: rename,
|
|
||||||
internalName,
|
|
||||||
visible,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('#handleToggleVisible', () => {
|
|
||||||
it('calls onFieldUpdate once with !visible, internalName, and displayName', () => {
|
|
||||||
const onFieldUpdate = jest.fn()
|
|
||||||
const visible = true
|
|
||||||
const {instance, props: {internalName, displayName}} = setup({
|
|
||||||
onFieldUpdate,
|
|
||||||
visible,
|
|
||||||
})
|
|
||||||
|
|
||||||
instance.handleToggleVisible()
|
|
||||||
|
|
||||||
expect(onFieldUpdate).toHaveBeenCalledTimes(1)
|
|
||||||
expect(onFieldUpdate).toHaveBeenCalledWith({
|
|
||||||
displayName,
|
|
||||||
internalName,
|
|
||||||
visible: !visible,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -9,12 +9,11 @@ import {TableOptions} from 'src/dashboards/components/TableOptions'
|
||||||
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
||||||
import ThresholdsList from 'src/shared/components/ThresholdsList'
|
import ThresholdsList from 'src/shared/components/ThresholdsList'
|
||||||
import ThresholdsListTypeToggle from 'src/shared/components/ThresholdsListTypeToggle'
|
import ThresholdsListTypeToggle from 'src/shared/components/ThresholdsListTypeToggle'
|
||||||
import {TIME_FIELD_DEFAULT} from 'src/shared/constants/tableGraph'
|
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
dataLabels: [],
|
|
||||||
handleUpdateTableOptions: () => {},
|
handleUpdateTableOptions: () => {},
|
||||||
onResetFocus: () => {},
|
onResetFocus: () => {},
|
||||||
|
queryConfigs: [],
|
||||||
tableOptions: {
|
tableOptions: {
|
||||||
columnNames: [],
|
columnNames: [],
|
||||||
fieldNames: [],
|
fieldNames: [],
|
||||||
|
@ -39,100 +38,6 @@ const setup = (override = {}) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Dashboards.Components.TableOptions', () => {
|
describe('Dashboards.Components.TableOptions', () => {
|
||||||
describe('getters', () => {
|
|
||||||
describe('fieldNames', () => {
|
|
||||||
describe('if fieldNames are passed in tableOptions as props', () => {
|
|
||||||
it('returns fieldNames', () => {
|
|
||||||
const fieldNames = [
|
|
||||||
{internalName: 'time', displayName: 'TIME', visible: true},
|
|
||||||
{internalName: 'foo', displayName: 'BAR', visible: false},
|
|
||||||
]
|
|
||||||
const {instance} = setup({tableOptions: {fieldNames}})
|
|
||||||
|
|
||||||
expect(instance.fieldNames).toBe(fieldNames)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('if fieldNames are not passed in tableOptions as props', () => {
|
|
||||||
it('returns empty array', () => {
|
|
||||||
const {instance} = setup()
|
|
||||||
|
|
||||||
expect(instance.fieldNames).toEqual([])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('timeField', () => {
|
|
||||||
describe('if time field in fieldNames', () => {
|
|
||||||
it('returns time field', () => {
|
|
||||||
const timeField = {
|
|
||||||
internalName: 'time',
|
|
||||||
displayName: 'TIME',
|
|
||||||
visible: true,
|
|
||||||
}
|
|
||||||
const fieldNames = [
|
|
||||||
timeField,
|
|
||||||
{internalName: 'foo', displayName: 'BAR', visible: false},
|
|
||||||
]
|
|
||||||
const {instance} = setup({tableOptions: {fieldNames}})
|
|
||||||
|
|
||||||
expect(instance.timeField).toBe(timeField)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('if time field not in fieldNames', () => {
|
|
||||||
it('returns default time field', () => {
|
|
||||||
const fieldNames = [
|
|
||||||
{internalName: 'foo', displayName: 'BAR', visible: false},
|
|
||||||
]
|
|
||||||
const {instance} = setup({tableOptions: {fieldNames}})
|
|
||||||
|
|
||||||
expect(instance.timeField).toBe(TIME_FIELD_DEFAULT)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('computedFieldNames', () => {
|
|
||||||
describe('if dataLabels are not passed in', () => {
|
|
||||||
it('returns an array of the time column', () => {
|
|
||||||
const {instance} = setup()
|
|
||||||
|
|
||||||
expect(instance.computedFieldNames).toEqual([TIME_FIELD_DEFAULT])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('if dataLabels are passed in', () => {
|
|
||||||
describe('if dataLabel has a matching fieldName', () => {
|
|
||||||
it('returns array with the matching fieldName', () => {
|
|
||||||
const fieldNames = [
|
|
||||||
{internalName: 'foo', displayName: 'bar', visible: true},
|
|
||||||
]
|
|
||||||
const dataLabels = ['foo']
|
|
||||||
const {instance} = setup({tableOptions: {fieldNames}, dataLabels})
|
|
||||||
|
|
||||||
expect(instance.computedFieldNames).toEqual(fieldNames)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('if dataLabel does not have a matching fieldName', () => {
|
|
||||||
it('returns array with a new fieldName created for it', () => {
|
|
||||||
const fieldNames = [
|
|
||||||
{internalName: 'time', displayName: 'bar', visible: true},
|
|
||||||
]
|
|
||||||
const unmatchedLabel = 'foo'
|
|
||||||
const dataLabels = ['time', unmatchedLabel]
|
|
||||||
const {instance} = setup({tableOptions: {fieldNames}, dataLabels})
|
|
||||||
|
|
||||||
expect(instance.computedFieldNames).toEqual([
|
|
||||||
...fieldNames,
|
|
||||||
{internalName: unmatchedLabel, displayName: '', visible: true},
|
|
||||||
])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('rendering', () => {
|
describe('rendering', () => {
|
||||||
it('should render all components', () => {
|
it('should render all components', () => {
|
||||||
const {wrapper} = setup()
|
const {wrapper} = setup()
|
||||||
|
|
|
@ -351,58 +351,6 @@ describe('timeSeriesToTableGraph', () => {
|
||||||
expect(actual.data).toEqual(expected)
|
expect(actual.data).toEqual(expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns labels starting with time and then alphabetized', () => {
|
|
||||||
const influxResponse = [
|
|
||||||
{
|
|
||||||
response: {
|
|
||||||
results: [
|
|
||||||
{
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: 'mb',
|
|
||||||
columns: ['time', 'f1'],
|
|
||||||
values: [[1000, 1], [2000, 2]],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: 'ma',
|
|
||||||
columns: ['time', 'f1'],
|
|
||||||
values: [[1000, 1], [2000, 2]],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: 'mc',
|
|
||||||
columns: ['time', 'f2'],
|
|
||||||
values: [[2000, 3], [4000, 4]],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: 'mc',
|
|
||||||
columns: ['time', 'f1'],
|
|
||||||
values: [[2000, 3], [4000, 4]],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
const actual = timeSeriesToTableGraph(influxResponse)
|
|
||||||
const expected = ['time', 'ma.f1', 'mb.f1', 'mc.f1', 'mc.f2']
|
|
||||||
|
|
||||||
expect(actual.labels).toEqual(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('parses raw data into a table-readable format with the first row being labels', () => {
|
it('parses raw data into a table-readable format with the first row being labels', () => {
|
||||||
const influxResponse = [
|
const influxResponse = [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue