Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
1aa39ee4
Unverified
Commit
1aa39ee4
authored
Dec 12, 2019
by
Ryan McKinley
Committed by
GitHub
Dec 12, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
FieldConfig: support overrides model (#20986)
parent
1f73e2aa
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
414 additions
and
125 deletions
+414
-125
packages/grafana-data/src/field/fieldDisplay.test.ts
+7
-32
packages/grafana-data/src/field/fieldDisplay.ts
+22
-90
packages/grafana-data/src/field/fieldOverrides.test.ts
+89
-0
packages/grafana-data/src/field/fieldOverrides.ts
+213
-0
packages/grafana-data/src/field/index.ts
+2
-0
packages/grafana-data/src/types/fieldOverrides.ts
+19
-0
packages/grafana-data/src/types/index.ts
+1
-0
packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.test.ts
+26
-0
packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.ts
+16
-1
packages/grafana-ui/src/components/SingleStatShared/__snapshots__/SingleStatBaseOptions.test.ts.snap
+17
-0
public/app/plugins/panel/bargauge/__snapshots__/BarGaugeMigrations.test.ts.snap
+1
-1
public/app/plugins/panel/stat/types.ts
+1
-1
No files found.
packages/grafana-data/src/field/fieldDisplay.test.ts
View file @
1aa39ee4
import
merge
from
'lodash/merge'
;
import
{
getField
Properties
,
getField
DisplayValues
,
GetFieldDisplayValuesOptions
}
from
'./fieldDisplay'
;
import
{
getFieldDisplayValues
,
GetFieldDisplayValuesOptions
}
from
'./fieldDisplay'
;
import
{
toDataFrame
}
from
'../dataframe/processDataFrame'
;
import
{
ReducerID
}
from
'../transformations/fieldReducer'
;
import
{
Threshold
}
from
'../types/threshold'
;
import
{
GrafanaTheme
}
from
'../types/theme'
;
import
{
MappingType
}
from
'../types'
;
import
{
setFieldConfigDefaults
}
from
'./fieldOverrides'
;
describe
(
'FieldDisplay'
,
()
=>
{
it
(
'Construct simple field properties'
,
()
=>
{
const
f0
=
{
min
:
0
,
max
:
100
,
};
const
f1
=
{
unit
:
'ms'
,
dateFormat
:
''
,
// should be ignored
max
:
parseFloat
(
'NOPE'
),
// should be ignored
min
:
null
,
};
let
field
=
getFieldProperties
(
f0
,
f1
);
expect
(
field
.
min
).
toEqual
(
0
);
expect
(
field
.
max
).
toEqual
(
100
);
expect
(
field
.
unit
).
toEqual
(
'ms'
);
// last one overrieds
const
f2
=
{
unit
:
'none'
,
// ignore 'none'
max
:
-
100
,
// lower than min! should flip min/max
};
field
=
getFieldProperties
(
f0
,
f1
,
f2
);
expect
(
field
.
max
).
toEqual
(
0
);
expect
(
field
.
min
).
toEqual
(
-
100
);
expect
(
field
.
unit
).
toEqual
(
'ms'
);
});
it
(
'show first numeric values'
,
()
=>
{
const
options
=
createDisplayOptions
({
fieldOptions
:
{
...
...
@@ -89,7 +63,7 @@ describe('FieldDisplay', () => {
});
it
(
'should restore -Infinity value for base threshold'
,
()
=>
{
const
field
=
getFieldProperties
(
{
const
field
=
{
thresholds
:
[
({
color
:
'#73BF69'
,
...
...
@@ -100,7 +74,8 @@ describe('FieldDisplay', () => {
value
:
50
,
},
],
});
};
setFieldConfigDefaults
(
field
);
expect
(
field
.
thresholds
!
.
length
).
toEqual
(
2
);
expect
(
field
.
thresholds
!
[
0
].
value
).
toBe
(
-
Infinity
);
});
...
...
@@ -130,7 +105,7 @@ describe('FieldDisplay', () => {
const
mapEmptyToText
=
'0'
;
const
options
=
createEmptyDisplayOptions
({
fieldOptions
:
{
override
:
{
defaults
:
{
mappings
:
[
{
id
:
1
,
...
...
@@ -203,8 +178,8 @@ function createDisplayOptions(extend = {}): GetFieldDisplayValuesOptions {
},
fieldOptions
:
{
calcs
:
[],
override
:
{},
defaults
:
{},
overrides
:
[],
},
theme
:
{}
as
GrafanaTheme
,
};
...
...
packages/grafana-data/src/field/fieldDisplay.ts
View file @
1aa39ee4
import
toNumber
from
'lodash/toNumber'
;
import
toString
from
'lodash/toString'
;
import
isEmpty
from
'lodash/isEmpty'
;
import
{
getDisplayProcessor
}
from
'./displayProcessor'
;
import
{
getFlotPairs
}
from
'../utils/flotPairs'
;
import
{
FieldConfig
,
DataFrame
,
FieldType
}
from
'../types/dataFrame'
;
import
{
InterpolateFunction
}
from
'../types/panel'
;
import
{
FieldConfig
,
DataFrame
,
FieldType
,
DisplayValue
,
DisplayValueAlignmentFactors
,
FieldConfigSource
,
InterpolateFunction
,
}
from
'../types'
;
import
{
DataFrameView
}
from
'../dataframe/DataFrameView'
;
import
{
GraphSeriesValue
}
from
'../types/graph'
;
import
{
DisplayValue
,
DisplayValueAlignmentFactors
}
from
'../types/displayValue'
;
import
{
GrafanaTheme
}
from
'../types/theme'
;
import
{
ReducerID
,
reduceField
}
from
'../transformations/fieldReducer'
;
import
{
ScopedVars
}
from
'../types/ScopedVars'
;
import
{
getTimeField
}
from
'../dataframe/processDataFrame'
;
import
{
applyFieldOverrides
}
from
'./fieldOverrides'
;
export
interface
FieldDisplayOptions
{
export
interface
FieldDisplayOptions
extends
FieldConfigSource
{
values
?:
boolean
;
// If true show each row value
limit
?:
number
;
// if showing all values limit
calcs
:
string
[];
// when !values, pick one value for the whole field
defaults
:
FieldConfig
;
// Use these values unless otherwise stated
override
:
FieldConfig
;
// Set these values regardless of the source
}
// TODO: use built in variables, same as for data links?
...
...
@@ -81,27 +84,21 @@ export interface GetFieldDisplayValuesOptions {
export
const
DEFAULT_FIELD_DISPLAY_VALUES_LIMIT
=
25
;
export
const
getFieldDisplayValues
=
(
options
:
GetFieldDisplayValuesOptions
):
FieldDisplay
[]
=>
{
const
{
data
,
replaceVariables
,
fieldOptions
}
=
options
;
const
{
defaults
,
override
}
=
fieldOptions
;
const
{
replaceVariables
,
fieldOptions
}
=
options
;
const
calcs
=
fieldOptions
.
calcs
.
length
?
fieldOptions
.
calcs
:
[
ReducerID
.
last
];
const
values
:
FieldDisplay
[]
=
[];
if
(
data
)
{
if
(
options
.
data
)
{
const
data
=
applyFieldOverrides
(
options
.
data
,
fieldOptions
,
replaceVariables
,
options
.
theme
);
let
hitLimit
=
false
;
const
limit
=
fieldOptions
.
limit
?
fieldOptions
.
limit
:
DEFAULT_FIELD_DISPLAY_VALUES_LIMIT
;
const
defaultTitle
=
getTitleTemplate
(
fieldOptions
.
defaults
.
title
,
calcs
,
data
);
const
scopedVars
:
ScopedVars
=
{};
for
(
let
s
=
0
;
s
<
data
.
length
&&
!
hitLimit
;
s
++
)
{
let
series
=
data
[
s
];
if
(
!
series
.
name
)
{
series
=
{
...
series
,
name
:
series
.
refId
?
series
.
refId
:
`Series[
${
s
}
]`
,
};
}
const
series
=
data
[
s
];
// Name is already set
scopedVars
[
'__series'
]
=
{
text
:
'Series'
,
value
:
{
name
:
series
.
name
}
};
const
{
timeField
}
=
getTimeField
(
series
);
...
...
@@ -114,7 +111,7 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
if
(
field
.
type
!==
FieldType
.
number
)
{
continue
;
}
const
config
=
getFieldProperties
(
defaults
,
field
.
config
||
{},
override
);
const
config
=
field
.
config
;
// already set by the prepare task
let
name
=
field
.
name
;
if
(
!
name
)
{
...
...
@@ -123,7 +120,9 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
scopedVars
[
'__field'
]
=
{
text
:
'Field'
,
value
:
{
name
}
};
const
display
=
getDisplayProcessor
({
const
display
=
field
.
display
??
getDisplayProcessor
({
config
,
theme
:
options
.
theme
,
type
:
field
.
type
,
...
...
@@ -206,72 +205,6 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
return
values
;
};
const
numericFieldProps
:
any
=
{
decimals
:
true
,
min
:
true
,
max
:
true
,
};
/**
* Returns a version of the field with the overries applied. Any property with
* value: null | undefined | empty string are skipped.
*
* For numeric values, only valid numbers will be applied
* for units, 'none' will be skipped
*/
export
function
applyFieldProperties
(
field
:
FieldConfig
,
props
?:
FieldConfig
):
FieldConfig
{
if
(
!
props
)
{
return
field
;
}
const
keys
=
Object
.
keys
(
props
);
if
(
!
keys
.
length
)
{
return
field
;
}
const
copy
=
{
...
field
}
as
any
;
// make a copy that we will manipulate directly
for
(
const
key
of
keys
)
{
const
val
=
(
props
as
any
)[
key
];
if
(
val
===
null
||
val
===
undefined
)
{
continue
;
}
if
(
numericFieldProps
[
key
])
{
const
num
=
toNumber
(
val
);
if
(
!
isNaN
(
num
))
{
copy
[
key
]
=
num
;
}
}
else
if
(
val
)
{
// skips empty string
if
(
key
===
'unit'
&&
val
===
'none'
)
{
continue
;
}
copy
[
key
]
=
val
;
}
}
return
copy
as
FieldConfig
;
}
export
function
getFieldProperties
(...
props
:
FieldConfig
[]):
FieldConfig
{
let
field
=
props
[
0
]
as
FieldConfig
;
for
(
let
i
=
1
;
i
<
props
.
length
;
i
++
)
{
field
=
applyFieldProperties
(
field
,
props
[
i
]);
}
// First value is always -Infinity
if
(
field
.
thresholds
&&
field
.
thresholds
.
length
)
{
field
.
thresholds
[
0
].
value
=
-
Infinity
;
}
// Verify that max > min
if
(
field
.
hasOwnProperty
(
'min'
)
&&
field
.
hasOwnProperty
(
'max'
)
&&
field
.
min
!
>
field
.
max
!
)
{
return
{
...
field
,
min
:
field
.
max
,
max
:
field
.
min
,
};
}
return
field
;
}
export
function
getDisplayValueAlignmentFactors
(
values
:
FieldDisplay
[]):
DisplayValueAlignmentFactors
{
const
info
:
DisplayValueAlignmentFactors
=
{
title
:
''
,
...
...
@@ -308,11 +241,10 @@ export function getDisplayValueAlignmentFactors(values: FieldDisplay[]): Display
function
createNoValuesFieldDisplay
(
options
:
GetFieldDisplayValuesOptions
):
FieldDisplay
{
const
displayName
=
'No data'
;
const
{
fieldOptions
}
=
options
;
const
{
defaults
,
override
}
=
fieldOptions
;
const
{
defaults
}
=
fieldOptions
;
const
config
=
getFieldProperties
(
defaults
,
{},
override
);
const
displayProcessor
=
getDisplayProcessor
({
config
,
config
:
defaults
,
theme
:
options
.
theme
,
type
:
FieldType
.
other
,
});
...
...
packages/grafana-data/src/field/fieldOverrides.test.ts
0 → 100644
View file @
1aa39ee4
import
{
setFieldConfigDefaults
,
findNumericFieldMinMax
,
applyFieldOverrides
}
from
'./fieldOverrides'
;
import
{
MutableDataFrame
}
from
'../dataframe'
;
import
{
FieldConfig
,
FieldConfigSource
,
InterpolateFunction
,
GrafanaTheme
}
from
'../types'
;
import
{
FieldMatcherID
}
from
'../transformations'
;
describe
(
'FieldOverrides'
,
()
=>
{
it
(
'will merge FieldConfig with default values'
,
()
=>
{
const
field
:
FieldConfig
=
{
min
:
0
,
max
:
100
,
};
const
f1
=
{
unit
:
'ms'
,
dateFormat
:
''
,
// should be ignored
max
:
parseFloat
(
'NOPE'
),
// should be ignored
min
:
null
,
// should alo be ignored!
};
setFieldConfigDefaults
(
field
,
f1
as
FieldConfig
);
expect
(
field
.
min
).
toEqual
(
0
);
expect
(
field
.
max
).
toEqual
(
100
);
expect
(
field
.
unit
).
toEqual
(
'ms'
);
});
it
(
'will apply field overrides'
,
()
=>
{
const
f0
=
new
MutableDataFrame
();
f0
.
add
({
title
:
'AAA'
,
value
:
100
,
value2
:
1234
},
true
);
f0
.
add
({
title
:
'BBB'
,
value
:
-
20
},
true
);
f0
.
add
({
title
:
'CCC'
,
value
:
200
,
value2
:
1000
},
true
);
expect
(
f0
.
length
).
toEqual
(
3
);
// Hardcode the max value
f0
.
fields
[
1
].
config
.
max
=
0
;
f0
.
fields
[
1
].
config
.
decimals
=
6
;
const
src
:
FieldConfigSource
=
{
defaults
:
{
unit
:
'xyz'
,
decimals
:
2
,
},
overrides
:
[
{
matcher
:
{
id
:
FieldMatcherID
.
numeric
},
properties
:
[
{
path
:
'decimals'
,
value
:
1
},
// Numeric
{
path
:
'title'
,
value
:
'Kittens'
},
// Text
],
},
],
};
const
data
=
applyFieldOverrides
(
[
f0
],
// the frame
src
,
// defaults + overrides
(
undefined
as
any
)
as
InterpolateFunction
,
(
undefined
as
any
)
as
GrafanaTheme
)[
0
];
const
valueColumn
=
data
.
fields
[
1
];
const
config
=
valueColumn
.
config
;
// Keep max from the original setting
expect
(
config
.
max
).
toEqual
(
0
);
// Automatically pick the min value
expect
(
config
.
min
).
toEqual
(
-
20
);
// The default value applied
expect
(
config
.
unit
).
toEqual
(
'xyz'
);
// The default value applied
expect
(
config
.
title
).
toEqual
(
'Kittens'
);
// The override applied
expect
(
config
.
decimals
).
toEqual
(
1
);
});
});
describe
(
'Global MinMax'
,
()
=>
{
it
(
'find global min max'
,
()
=>
{
const
f0
=
new
MutableDataFrame
();
f0
.
add
({
title
:
'AAA'
,
value
:
100
,
value2
:
1234
},
true
);
f0
.
add
({
title
:
'BBB'
,
value
:
-
20
},
true
);
f0
.
add
({
title
:
'CCC'
,
value
:
200
,
value2
:
1000
},
true
);
expect
(
f0
.
length
).
toEqual
(
3
);
const
minmax
=
findNumericFieldMinMax
([
f0
]);
expect
(
minmax
.
min
).
toEqual
(
-
20
);
expect
(
minmax
.
max
).
toEqual
(
1234
);
});
});
packages/grafana-data/src/field/fieldOverrides.ts
0 → 100644
View file @
1aa39ee4
import
set
from
'lodash/set'
;
import
{
DynamicConfigValue
,
FieldConfigSource
,
FieldConfig
,
InterpolateFunction
,
GrafanaTheme
,
DataFrame
,
Field
,
FieldType
,
}
from
'../types'
;
import
{
fieldMatchers
,
ReducerID
,
reduceField
}
from
'../transformations'
;
import
{
FieldMatcher
}
from
'../types/transformations'
;
import
isNumber
from
'lodash/isNumber'
;
import
toNumber
from
'lodash/toNumber'
;
import
{
getDisplayProcessor
}
from
'./displayProcessor'
;
interface
OverrideProps
{
match
:
FieldMatcher
;
properties
:
DynamicConfigValue
[];
}
interface
GlobalMinMax
{
min
:
number
;
max
:
number
;
}
export
function
findNumericFieldMinMax
(
data
:
DataFrame
[]):
GlobalMinMax
{
let
min
=
Number
.
MAX_VALUE
;
let
max
=
Number
.
MIN_VALUE
;
const
reducers
=
[
ReducerID
.
min
,
ReducerID
.
max
];
for
(
const
frame
of
data
)
{
for
(
const
field
of
frame
.
fields
)
{
if
(
field
.
type
===
FieldType
.
number
)
{
const
stats
=
reduceField
({
field
,
reducers
});
if
(
stats
[
ReducerID
.
min
]
<
min
)
{
min
=
stats
[
ReducerID
.
min
];
}
if
(
stats
[
ReducerID
.
max
]
>
max
)
{
max
=
stats
[
ReducerID
.
max
];
}
}
}
}
return
{
min
,
max
};
}
/**
* Return a copy of the DataFrame with all rules applied
*/
export
function
applyFieldOverrides
(
data
:
DataFrame
[],
source
:
FieldConfigSource
,
replaceVariables
:
InterpolateFunction
,
theme
:
GrafanaTheme
,
isUtc
?:
boolean
):
DataFrame
[]
{
if
(
!
source
)
{
return
data
;
}
let
range
:
GlobalMinMax
|
undefined
=
undefined
;
// Prepare the Matchers
const
override
:
OverrideProps
[]
=
[];
if
(
source
.
overrides
)
{
for
(
const
rule
of
source
.
overrides
)
{
const
info
=
fieldMatchers
.
get
(
rule
.
matcher
.
id
);
if
(
info
)
{
override
.
push
({
match
:
info
.
get
(
rule
.
matcher
),
properties
:
rule
.
properties
,
});
}
}
}
return
data
.
map
((
frame
,
index
)
=>
{
let
name
=
frame
.
name
;
if
(
!
name
)
{
name
=
`Series[
${
index
}
]`
;
}
const
fields
=
frame
.
fields
.
map
(
field
=>
{
// Config is mutable within this scope
const
config
:
FieldConfig
=
{
...
field
.
config
}
||
{};
if
(
field
.
type
===
FieldType
.
number
)
{
setFieldConfigDefaults
(
config
,
source
.
defaults
);
}
// Find any matching rules and then override
for
(
const
rule
of
override
)
{
if
(
rule
.
match
(
field
))
{
for
(
const
prop
of
rule
.
properties
)
{
setDynamicConfigValue
(
config
,
{
value
:
prop
,
config
,
field
,
data
:
frame
,
replaceVariables
,
});
}
}
}
// Set the Min/Max value automatically
if
(
field
.
type
===
FieldType
.
number
)
{
if
(
!
isNumber
(
config
.
min
)
||
!
isNumber
(
config
.
max
))
{
if
(
!
range
)
{
range
=
findNumericFieldMinMax
(
data
);
}
if
(
!
isNumber
(
config
.
min
))
{
config
.
min
=
range
.
min
;
}
if
(
!
isNumber
(
config
.
max
))
{
config
.
max
=
range
.
max
;
}
}
}
return
{
...
field
,
// Overwrite the configs
config
,
// Set the display processor
processor
:
getDisplayProcessor
({
type
:
field
.
type
,
config
:
config
,
theme
,
isUtc
,
}),
};
});
return
{
...
frame
,
fields
,
name
,
};
});
}
interface
DynamicConfigValueOptions
{
value
:
DynamicConfigValue
;
config
:
FieldConfig
;
field
:
Field
;
data
:
DataFrame
;
replaceVariables
:
InterpolateFunction
;
}
const
numericFieldProps
:
any
=
{
decimals
:
true
,
min
:
true
,
max
:
true
,
};
function
prepareConfigValue
(
key
:
string
,
input
:
any
,
options
?:
DynamicConfigValueOptions
):
any
{
if
(
options
)
{
// TODO template variables etc
}
if
(
numericFieldProps
[
key
])
{
const
num
=
toNumber
(
input
);
if
(
isNaN
(
num
))
{
return
null
;
}
return
num
;
}
else
if
(
input
)
{
// skips empty string
if
(
key
===
'unit'
&&
input
===
'none'
)
{
return
null
;
}
}
return
input
;
}
export
function
setDynamicConfigValue
(
config
:
FieldConfig
,
options
:
DynamicConfigValueOptions
)
{
const
{
value
}
=
options
;
const
v
=
prepareConfigValue
(
value
.
path
,
value
.
value
,
options
);
set
(
config
,
value
.
path
,
v
);
}
/**
* For numeric values, only valid numbers will be applied
* for units, 'none' will be skipped
*/
export
function
setFieldConfigDefaults
(
config
:
FieldConfig
,
props
?:
FieldConfig
)
{
if
(
props
)
{
const
keys
=
Object
.
keys
(
props
);
for
(
const
key
of
keys
)
{
const
val
=
prepareConfigValue
(
key
,
(
props
as
any
)[
key
]);
if
(
val
===
null
||
val
===
undefined
)
{
continue
;
}
set
(
config
,
key
,
val
);
}
}
// First value is always -Infinity
if
(
config
.
thresholds
&&
config
.
thresholds
.
length
)
{
config
.
thresholds
[
0
].
value
=
-
Infinity
;
}
// Verify that max > min (swap if necessary)
if
(
config
.
hasOwnProperty
(
'min'
)
&&
config
.
hasOwnProperty
(
'max'
)
&&
config
.
min
!
>
config
.
max
!
)
{
const
tmp
=
config
.
max
;
config
.
max
=
config
.
min
;
config
.
min
=
tmp
;
}
}
packages/grafana-data/src/field/index.ts
View file @
1aa39ee4
export
*
from
'./fieldDisplay'
;
export
*
from
'./displayProcessor'
;
export
{
applyFieldOverrides
}
from
'./fieldOverrides'
;
packages/grafana-data/src/types/fieldOverrides.ts
0 → 100644
View file @
1aa39ee4
import
{
MatcherConfig
,
FieldConfig
}
from
'../types'
;
export
interface
DynamicConfigValue
{
path
:
string
;
value
:
any
;
}
export
interface
ConfigOverrideRule
{
matcher
:
MatcherConfig
;
properties
:
DynamicConfigValue
[];
}
export
interface
FieldConfigSource
{
// Defatuls applied to all numeric fields
defaults
:
FieldConfig
;
// Rules to override individual values
overrides
:
ConfigOverrideRule
[];
}
packages/grafana-data/src/types/index.ts
View file @
1aa39ee4
...
...
@@ -12,6 +12,7 @@ export * from './displayValue';
export
*
from
'./graph'
;
export
*
from
'./ScopedVars'
;
export
*
from
'./transformations'
;
export
*
from
'./fieldOverrides'
;
export
*
from
'./vector'
;
export
*
from
'./app'
;
export
*
from
'./datasource'
;
...
...
packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.test.ts
View file @
1aa39ee4
...
...
@@ -36,4 +36,30 @@ describe('sharedSingleStatMigrationHandler', () => {
expect
(
sharedSingleStatMigrationHandler
(
panel
as
any
)).
toMatchSnapshot
();
});
it
(
'Remove unused `overrides` option'
,
()
=>
{
const
panel
=
{
options
:
{
fieldOptions
:
{
unit
:
'watt'
,
stat
:
'last'
,
decimals
:
5
,
defaults
:
{
min
:
0
,
max
:
100
,
mappings
:
[],
},
override
:
{
min
:
0
,
max
:
100
,
mappings
:
[],
},
},
},
title
:
'Usage'
,
type
:
'bargauge'
,
};
expect
(
sharedSingleStatMigrationHandler
(
panel
as
any
)).
toMatchSnapshot
();
});
});
packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.ts
View file @
1aa39ee4
...
...
@@ -12,6 +12,7 @@ import {
VizOrientation
,
PanelModel
,
FieldDisplayOptions
,
ConfigOverrideRule
,
}
from
'@grafana/data'
;
export
interface
SingleStatBaseOptions
{
...
...
@@ -33,7 +34,7 @@ export function sharedSingleStatPanelChangedHandler(
const
options
=
{
fieldOptions
:
{
defaults
:
{}
as
FieldConfig
,
override
:
{}
as
FieldConfig
,
override
s
:
[]
as
ConfigOverrideRule
[]
,
calcs
:
[
reducer
?
reducer
.
id
:
ReducerID
.
mean
],
},
orientation
:
VizOrientation
.
Horizontal
,
...
...
@@ -110,6 +111,20 @@ export function sharedSingleStatMigrationHandler(panel: PanelModel<SingleStatBas
options
=
moveThresholdsAndMappingsToField
(
options
);
}
if
(
previousVersion
<
6.6
)
{
// discard the old `override` options and enter an empty array
if
(
options
.
fieldOptions
&&
options
.
fieldOptions
.
override
)
{
const
{
override
,
...
rest
}
=
options
.
fieldOptions
;
options
=
{
...
options
,
fieldOptions
:
{
...
rest
,
overrides
:
[],
},
};
}
}
return
options
as
SingleStatBaseOptions
;
}
...
...
packages/grafana-ui/src/components/SingleStatShared/__snapshots__/SingleStatBaseOptions.test.ts.snap
View file @
1aa39ee4
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`sharedSingleStatMigrationHandler Remove unused \`overrides\` option 1`] = `
Object {
"fieldOptions": Object {
"decimals": 5,
"defaults": Object {
"mappings": undefined,
"max": 100,
"min": 0,
"thresholds": undefined,
},
"overrides": Array [],
"stat": "last",
"unit": "watt",
},
}
`;
exports[`sharedSingleStatMigrationHandler from old valueOptions model without pluginVersion 1`] = `
Object {
"fieldOptions": Object {
...
...
public/app/plugins/panel/bargauge/__snapshots__/BarGaugeMigrations.test.ts.snap
View file @
1aa39ee4
...
...
@@ -28,7 +28,7 @@ Object {
],
"unit": "watt",
},
"override
": Object {}
,
"override
s": Array []
,
"values": false,
},
"orientation": "vertical",
...
...
public/app/plugins/panel/stat/types.ts
View file @
1aa39ee4
...
...
@@ -35,7 +35,7 @@ export const standardFieldDisplayOptions: FieldDisplayOptions = {
],
mappings
:
[],
},
override
:
{}
,
override
s
:
[]
,
};
export
const
defaults
:
StatPanelOptions
=
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment