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
c4f55fec
Commit
c4f55fec
authored
Feb 01, 2019
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into solo-panel-rewrite
parents
6a4777ea
e54689a9
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
214 additions
and
59 deletions
+214
-59
.circleci/config.yml
+1
-0
CHANGELOG.md
+3
-0
packages/grafana-ui/src/components/Gauge/Gauge.test.tsx
+1
-1
packages/grafana-ui/src/types/data.ts
+17
-0
packages/grafana-ui/src/types/datasource.ts
+2
-2
packages/grafana-ui/src/types/index.ts
+1
-1
packages/grafana-ui/src/types/panel.ts
+6
-1
pkg/services/alerting/notifiers/pushover.go
+120
-24
pkg/services/auth/auth_token.go
+1
-1
pkg/services/provisioning/notifiers/alert_notifications.go
+2
-2
public/app/features/dashboard/components/RowOptions/RowOptionsCtrl.ts
+1
-1
public/app/features/dashboard/dashgrid/DataPanel.tsx
+30
-5
public/app/features/dashboard/dashgrid/PanelChrome.tsx
+3
-5
public/app/features/dashboard/panel_editor/PanelEditor.tsx
+0
-11
public/app/features/dashboard/state/PanelModel.ts
+2
-1
public/app/plugins/datasource/elasticsearch/pipeline_variables.ts
+1
-0
public/app/plugins/panel/graph/specs/time_region_manager.test.ts
+19
-0
public/app/plugins/panel/graph/time_region_manager.ts
+4
-4
No files found.
.circleci/config.yml
View file @
c4f55fec
...
...
@@ -333,6 +333,7 @@ jobs:
docker
:
-
image
:
grafana/grafana-ci-deploy:1.2.0
steps
:
-
checkout
-
attach_workspace
:
at
:
.
-
run
:
...
...
CHANGELOG.md
View file @
c4f55fec
# 6.0.0-beta2 (unreleased)
### Minor
*
**Pushover**
: Adds support for images in pushover notifier
[
#10780
](
https://github.com/grafana/grafana/issues/10780
)
, thx
[
@jpenalbae
](
https://github.com/jpenalbae
)
# 6.0.0-beta1 (2019-01-30)
### New Features
...
...
packages/grafana-ui/src/components/Gauge/Gauge.test.tsx
View file @
c4f55fec
...
...
@@ -2,7 +2,7 @@ import React from 'react';
import
{
shallow
}
from
'enzyme'
;
import
{
Gauge
,
Props
}
from
'./Gauge'
;
import
{
TimeSeriesVMs
}
from
'../../types/
series
'
;
import
{
TimeSeriesVMs
}
from
'../../types/
data
'
;
import
{
ValueMapping
,
MappingType
}
from
'../../types'
;
jest
.
mock
(
'jquery'
,
()
=>
({
...
...
packages/grafana-ui/src/types/
series
.ts
→
packages/grafana-ui/src/types/
data
.ts
View file @
c4f55fec
...
...
@@ -52,3 +52,20 @@ export interface TimeSeriesVMs {
[
index
:
number
]:
TimeSeriesVM
;
length
:
number
;
}
interface
Column
{
text
:
string
;
title
?:
string
;
type
?:
string
;
sort
?:
boolean
;
desc
?:
boolean
;
filterable
?:
boolean
;
unit
?:
string
;
}
export
interface
TableData
{
columns
:
Column
[];
rows
:
any
[];
type
:
string
;
columnMap
:
any
;
}
packages/grafana-ui/src/types/datasource.ts
View file @
c4f55fec
import
{
TimeRange
,
RawTimeRange
}
from
'./time'
;
import
{
TimeSeries
}
from
'./series'
;
import
{
PluginMeta
}
from
'./plugin'
;
import
{
TableData
,
TimeSeries
}
from
'./data'
;
export
interface
DataQueryResponse
{
data
:
TimeSeries
[];
data
:
TimeSeries
[]
|
[
TableData
]
;
}
export
interface
DataQuery
{
...
...
packages/grafana-ui/src/types/index.ts
View file @
c4f55fec
export
*
from
'./
series
'
;
export
*
from
'./
data
'
;
export
*
from
'./time'
;
export
*
from
'./panel'
;
export
*
from
'./plugin'
;
...
...
packages/grafana-ui/src/types/panel.ts
View file @
c4f55fec
import
{
TimeSeries
,
LoadingState
}
from
'./series
'
;
import
{
TimeSeries
,
LoadingState
,
TableData
}
from
'./data
'
;
import
{
TimeRange
}
from
'./time'
;
export
type
InterpolateFunction
=
(
value
:
string
,
format
?:
string
|
Function
)
=>
string
;
...
...
@@ -14,6 +14,11 @@ export interface PanelProps<T = any> {
onInterpolate
:
InterpolateFunction
;
}
export
interface
PanelData
{
timeSeries
?:
TimeSeries
[];
tableData
?:
TableData
;
}
export
interface
PanelOptionsProps
<
T
=
any
>
{
options
:
T
;
onChange
:
(
options
:
T
)
=>
void
;
...
...
pkg/services/alerting/notifiers/pushover.go
View file @
c4f55fec
package
notifiers
import
(
"bytes"
"fmt"
"net/url"
"io"
"mime/multipart"
"os"
"strconv"
"github.com/grafana/grafana/pkg/bus"
...
...
@@ -91,6 +94,7 @@ func NewPushoverNotifier(model *m.AlertNotification) (alerting.Notifier, error)
retry
,
_
:=
strconv
.
Atoi
(
model
.
Settings
.
Get
(
"retry"
)
.
MustString
())
expire
,
_
:=
strconv
.
Atoi
(
model
.
Settings
.
Get
(
"expire"
)
.
MustString
())
sound
:=
model
.
Settings
.
Get
(
"sound"
)
.
MustString
()
uploadImage
:=
model
.
Settings
.
Get
(
"uploadImage"
)
.
MustBool
(
true
)
if
userKey
==
""
{
return
nil
,
alerting
.
ValidationError
{
Reason
:
"User key not given"
}
...
...
@@ -107,6 +111,7 @@ func NewPushoverNotifier(model *m.AlertNotification) (alerting.Notifier, error)
Expire
:
expire
,
Device
:
device
,
Sound
:
sound
,
Upload
:
uploadImage
,
log
:
log
.
New
(
"alerting.notifier.pushover"
),
},
nil
}
...
...
@@ -120,6 +125,7 @@ type PushoverNotifier struct {
Expire
int
Device
string
Sound
string
Upload
bool
log
log
.
Logger
}
...
...
@@ -140,38 +146,22 @@ func (this *PushoverNotifier) Notify(evalContext *alerting.EvalContext) error {
if
evalContext
.
Error
!=
nil
{
message
+=
fmt
.
Sprintf
(
"
\n
<b>Error message:</b> %s"
,
evalContext
.
Error
.
Error
())
}
if
evalContext
.
ImagePublicUrl
!=
""
{
message
+=
fmt
.
Sprintf
(
"
\n
<a href=
\"
%s
\"
>Show graph image</a>"
,
evalContext
.
ImagePublicUrl
)
}
if
message
==
""
{
message
=
"Notification message missing (Set a notification message to replace this text.)"
}
q
:=
url
.
Values
{}
q
.
Add
(
"user"
,
this
.
UserKey
)
q
.
Add
(
"token"
,
this
.
ApiToken
)
q
.
Add
(
"priority"
,
strconv
.
Itoa
(
this
.
Priority
))
if
this
.
Priority
==
2
{
q
.
Add
(
"retry"
,
strconv
.
Itoa
(
this
.
Retry
))
q
.
Add
(
"expire"
,
strconv
.
Itoa
(
this
.
Expire
))
}
if
this
.
Device
!=
""
{
q
.
Add
(
"device"
,
this
.
Device
)
}
if
this
.
Sound
!=
"default"
{
q
.
Add
(
"sound"
,
this
.
Sound
)
headers
,
uploadBody
,
err
:=
this
.
genPushoverBody
(
evalContext
,
message
,
ruleUrl
)
if
err
!=
nil
{
this
.
log
.
Error
(
"Failed to generate body for pushover"
,
"error"
,
err
)
return
err
}
q
.
Add
(
"title"
,
evalContext
.
GetNotificationTitle
())
q
.
Add
(
"url"
,
ruleUrl
)
q
.
Add
(
"url_title"
,
"Show dashboard with alert"
)
q
.
Add
(
"message"
,
message
)
q
.
Add
(
"html"
,
"1"
)
cmd
:=
&
m
.
SendWebhookSync
{
Url
:
PUSHOVER_ENDPOINT
,
HttpMethod
:
"POST"
,
HttpHeader
:
map
[
string
]
string
{
"Content-Type"
:
"application/x-www-form-urlencoded"
}
,
Body
:
q
.
Encode
(),
HttpHeader
:
headers
,
Body
:
uploadBody
.
String
(),
}
if
err
:=
bus
.
DispatchCtx
(
evalContext
.
Ctx
,
cmd
);
err
!=
nil
{
...
...
@@ -181,3 +171,109 @@ func (this *PushoverNotifier) Notify(evalContext *alerting.EvalContext) error {
return
nil
}
func
(
this
*
PushoverNotifier
)
genPushoverBody
(
evalContext
*
alerting
.
EvalContext
,
message
string
,
ruleUrl
string
)
(
map
[
string
]
string
,
bytes
.
Buffer
,
error
)
{
var
b
bytes
.
Buffer
var
err
error
w
:=
multipart
.
NewWriter
(
&
b
)
// Add image only if requested and available
if
this
.
Upload
&&
evalContext
.
ImageOnDiskPath
!=
""
{
f
,
err
:=
os
.
Open
(
evalContext
.
ImageOnDiskPath
)
if
err
!=
nil
{
return
nil
,
b
,
err
}
defer
f
.
Close
()
fw
,
err
:=
w
.
CreateFormFile
(
"attachment"
,
evalContext
.
ImageOnDiskPath
)
if
err
!=
nil
{
return
nil
,
b
,
err
}
_
,
err
=
io
.
Copy
(
fw
,
f
)
if
err
!=
nil
{
return
nil
,
b
,
err
}
}
// Add the user token
err
=
w
.
WriteField
(
"user"
,
this
.
UserKey
)
if
err
!=
nil
{
return
nil
,
b
,
err
}
// Add the api token
err
=
w
.
WriteField
(
"token"
,
this
.
ApiToken
)
if
err
!=
nil
{
return
nil
,
b
,
err
}
// Add priority
err
=
w
.
WriteField
(
"priority"
,
strconv
.
Itoa
(
this
.
Priority
))
if
err
!=
nil
{
return
nil
,
b
,
err
}
if
this
.
Priority
==
2
{
err
=
w
.
WriteField
(
"retry"
,
strconv
.
Itoa
(
this
.
Retry
))
if
err
!=
nil
{
return
nil
,
b
,
err
}
err
=
w
.
WriteField
(
"expire"
,
strconv
.
Itoa
(
this
.
Expire
))
if
err
!=
nil
{
return
nil
,
b
,
err
}
}
// Add device
if
this
.
Device
!=
""
{
err
=
w
.
WriteField
(
"device"
,
this
.
Device
)
if
err
!=
nil
{
return
nil
,
b
,
err
}
}
// Add sound
if
this
.
Sound
!=
"default"
{
err
=
w
.
WriteField
(
"sound"
,
this
.
Sound
)
if
err
!=
nil
{
return
nil
,
b
,
err
}
}
// Add title
err
=
w
.
WriteField
(
"title"
,
evalContext
.
GetNotificationTitle
())
if
err
!=
nil
{
return
nil
,
b
,
err
}
// Add URL
err
=
w
.
WriteField
(
"url"
,
ruleUrl
)
if
err
!=
nil
{
return
nil
,
b
,
err
}
// Add URL title
err
=
w
.
WriteField
(
"url_title"
,
"Show dashboard with alert"
)
if
err
!=
nil
{
return
nil
,
b
,
err
}
// Add message
err
=
w
.
WriteField
(
"message"
,
message
)
if
err
!=
nil
{
return
nil
,
b
,
err
}
// Mark as html message
err
=
w
.
WriteField
(
"html"
,
"1"
)
if
err
!=
nil
{
return
nil
,
b
,
err
}
w
.
Close
()
headers
:=
map
[
string
]
string
{
"Content-Type"
:
w
.
FormDataContentType
(),
}
return
headers
,
b
,
nil
}
pkg/services/auth/auth_token.go
View file @
c4f55fec
...
...
@@ -151,7 +151,7 @@ func (s *UserAuthTokenServiceImpl) CreateToken(userId int64, clientIP, userAgent
func
(
s
*
UserAuthTokenServiceImpl
)
LookupToken
(
unhashedToken
string
)
(
*
userAuthToken
,
error
)
{
hashedToken
:=
hashToken
(
unhashedToken
)
if
setting
.
Env
==
setting
.
DEV
{
s
.
log
.
Info
(
"looking up token"
,
"unhashed"
,
unhashedToken
,
"hashed"
,
hashedToken
)
s
.
log
.
Debug
(
"looking up token"
,
"unhashed"
,
unhashedToken
,
"hashed"
,
hashedToken
)
}
expireBefore
:=
getTime
()
.
Add
(
time
.
Duration
(
-
86400
*
s
.
Cfg
.
LoginCookieMaxDays
)
*
time
.
Second
)
.
Unix
()
...
...
pkg/services/provisioning/notifiers/alert_notifications.go
View file @
c4f55fec
...
...
@@ -92,7 +92,7 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not
}
if
cmd
.
Result
==
nil
{
dc
.
log
.
Info
(
"Inserting alert notification from configuration
"
,
"name"
,
notification
.
Name
,
"uid"
,
notification
.
Uid
)
dc
.
log
.
Debug
(
"inserting alert notification from configuration
"
,
"name"
,
notification
.
Name
,
"uid"
,
notification
.
Uid
)
insertCmd
:=
&
models
.
CreateAlertNotificationCommand
{
Uid
:
notification
.
Uid
,
Name
:
notification
.
Name
,
...
...
@@ -109,7 +109,7 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not
return
err
}
}
else
{
dc
.
log
.
Info
(
"U
pdating alert notification from configuration"
,
"name"
,
notification
.
Name
)
dc
.
log
.
Debug
(
"u
pdating alert notification from configuration"
,
"name"
,
notification
.
Name
)
updateCmd
:=
&
models
.
UpdateAlertNotificationWithUidCommand
{
Uid
:
notification
.
Uid
,
Name
:
notification
.
Name
,
...
...
public/app/features/dashboard/components/RowOptions/RowOptionsCtrl.ts
View file @
c4f55fec
...
...
@@ -24,7 +24,7 @@ export class RowOptionsCtrl {
export
function
rowOptionsDirective
()
{
return
{
restrict
:
'E'
,
templateUrl
:
'public/app/features/dashboard/
partials/row_options
.html'
,
templateUrl
:
'public/app/features/dashboard/
components/RowOptions/template
.html'
,
controller
:
RowOptionsCtrl
,
bindToController
:
true
,
controllerAs
:
'ctrl'
,
...
...
public/app/features/dashboard/dashgrid/DataPanel.tsx
View file @
c4f55fec
...
...
@@ -8,13 +8,21 @@ import { DatasourceSrv, getDatasourceSrv } from 'app/features/plugins/datasource
// Utils
import
kbn
from
'app/core/utils/kbn'
;
// Types
import
{
DataQueryOptions
,
DataQueryResponse
,
LoadingState
,
TimeRange
,
TimeSeries
}
from
'@grafana/ui/src/types'
;
import
{
DataQueryOptions
,
DataQueryResponse
,
LoadingState
,
PanelData
,
TableData
,
TimeRange
,
TimeSeries
,
}
from
'@grafana/ui'
;
const
DEFAULT_PLUGIN_ERROR
=
'Error in plugin'
;
interface
RenderProps
{
loading
:
LoadingState
;
timeSeries
:
TimeSeries
[]
;
panelData
:
PanelData
;
}
export
interface
Props
{
...
...
@@ -129,6 +137,7 @@ export class DataPanel extends Component<Props, State> {
console
.
log
(
'Issuing DataPanel query'
,
queryOptions
);
const
resp
=
await
ds
.
query
(
queryOptions
);
console
.
log
(
'Issuing DataPanel query Resp'
,
resp
);
if
(
this
.
isUnmounted
)
{
...
...
@@ -160,11 +169,27 @@ export class DataPanel extends Component<Props, State> {
}
};
getPanelData
=
()
=>
{
const
{
response
}
=
this
.
state
;
if
(
response
.
data
.
length
>
0
&&
(
response
.
data
[
0
]
as
TableData
).
type
===
'table'
)
{
return
{
tableData
:
response
.
data
[
0
]
as
TableData
,
timeSeries
:
null
,
};
}
return
{
timeSeries
:
response
.
data
as
TimeSeries
[],
tableData
:
null
,
};
};
render
()
{
const
{
queries
}
=
this
.
props
;
const
{
response
,
loading
,
isFirstLoad
}
=
this
.
state
;
const
{
loading
,
isFirstLoad
}
=
this
.
state
;
const
timeSeries
=
response
.
data
;
const
panelData
=
this
.
getPanelData
()
;
if
(
isFirstLoad
&&
loading
===
LoadingState
.
Loading
)
{
return
this
.
renderLoadingStates
();
...
...
@@ -190,8 +215,8 @@ export class DataPanel extends Component<Props, State> {
return
(
<>
{
this
.
props
.
children
({
timeSeries
,
loading
,
panelData
,
})
}
</>
);
...
...
public/app/features/dashboard/dashgrid/PanelChrome.tsx
View file @
c4f55fec
...
...
@@ -14,8 +14,7 @@ import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel';
import
{
PANEL_HEADER_HEIGHT
}
from
'app/core/constants'
;
// Types
import
{
PanelModel
}
from
'../state/PanelModel'
;
import
{
DashboardModel
}
from
'../state/DashboardModel'
;
import
{
DashboardModel
,
PanelModel
}
from
'../state'
;
import
{
PanelPlugin
}
from
'app/types'
;
import
{
TimeRange
}
from
'@grafana/ui'
;
...
...
@@ -139,7 +138,6 @@ export class PanelChrome extends PureComponent<Props, State> {
scopedVars=
{
panel
.
scopedVars
}
links=
{
panel
.
links
}
/>
{
panel
.
snapshotData
?
(
this
.
renderPanel
(
false
,
panel
.
snapshotData
,
width
,
height
)
)
:
(
...
...
@@ -152,8 +150,8 @@ export class PanelChrome extends PureComponent<Props, State> {
refreshCounter=
{
refreshCounter
}
onDataResponse=
{
this
.
onDataResponse
}
>
{
({
loading
,
timeSeries
})
=>
{
return
this
.
renderPanel
(
loading
,
timeSeries
,
width
,
height
);
{
({
loading
,
panelData
})
=>
{
return
this
.
renderPanel
(
loading
,
panelData
.
timeSeries
,
width
,
height
);
}
}
</
DataPanel
>
)
}
...
...
public/app/features/dashboard/panel_editor/PanelEditor.tsx
View file @
c4f55fec
...
...
@@ -101,17 +101,6 @@ export class PanelEditor extends PureComponent<PanelEditorProps> {
return
(
<
div
className=
"panel-editor-container__editor"
>
{
// <div className="panel-editor__close">
// <i className="fa fa-arrow-left" />
// </div>
// <div className="panel-editor-resizer">
// <div className="panel-editor-resizer__handle">
// <div className="panel-editor-resizer__handle-dots" />
// </div>
// </div>
}
<
div
className=
"panel-editor-tabs"
>
{
tabs
.
map
(
tab
=>
{
return
<
TabItem
tab=
{
tab
}
activeTab=
{
activeTab
}
onClick=
{
this
.
onChangeTab
}
key=
{
tab
.
id
}
/>;
...
...
public/app/features/dashboard/state/PanelModel.ts
View file @
c4f55fec
...
...
@@ -5,6 +5,7 @@ import _ from 'lodash';
import
{
Emitter
}
from
'app/core/utils/emitter'
;
import
{
PANEL_OPTIONS_KEY_PREFIX
}
from
'app/core/constants'
;
import
{
DataQuery
,
TimeSeries
}
from
'@grafana/ui'
;
import
{
TableData
}
from
'@grafana/ui/src'
;
export
interface
GridPos
{
x
:
number
;
...
...
@@ -87,7 +88,7 @@ export class PanelModel {
datasource
:
string
;
thresholds
?:
any
;
snapshotData
?:
TimeSeries
[];
snapshotData
?:
TimeSeries
[]
|
[
TableData
]
;
timeFrom
?:
any
;
timeShift
?:
any
;
hideTimeOverride
?:
any
;
...
...
public/app/plugins/datasource/elasticsearch/pipeline_variables.ts
View file @
c4f55fec
...
...
@@ -22,6 +22,7 @@ const newVariable = index => {
};
export
class
ElasticPipelineVariablesCtrl
{
/** @ngInject */
constructor
(
$scope
)
{
$scope
.
variables
=
$scope
.
variables
||
[
newVariable
(
1
)];
...
...
public/app/plugins/panel/graph/specs/time_region_manager.test.ts
View file @
c4f55fec
...
...
@@ -43,6 +43,25 @@ describe('TimeRegionManager', () => {
});
}
describe
(
'When colors missing in config'
,
()
=>
{
plotOptionsScenario
(
'should not throw an error when fillColor is undefined'
,
ctx
=>
{
const
regions
=
[
{
fromDayOfWeek
:
1
,
toDayOfWeek
:
1
,
fill
:
true
,
line
:
true
,
lineColor
:
'#ffffff'
,
colorMode
:
'custom'
},
];
const
from
=
moment
(
'2018-01-01T00:00:00+01:00'
);
const
to
=
moment
(
'2018-01-01T23:59:00+01:00'
);
expect
(()
=>
ctx
.
setup
(
regions
,
from
,
to
)).
not
.
toThrow
();
});
plotOptionsScenario
(
'should not throw an error when lineColor is undefined'
,
ctx
=>
{
const
regions
=
[
{
fromDayOfWeek
:
1
,
toDayOfWeek
:
1
,
fill
:
true
,
fillColor
:
'#ffffff'
,
line
:
true
,
colorMode
:
'custom'
},
];
const
from
=
moment
(
'2018-01-01T00:00:00+01:00'
);
const
to
=
moment
(
'2018-01-01T23:59:00+01:00'
);
expect
(()
=>
ctx
.
setup
(
regions
,
from
,
to
)).
not
.
toThrow
();
});
});
describe
(
'When creating plot markings using local time'
,
()
=>
{
plotOptionsScenario
(
'for day of week region'
,
ctx
=>
{
const
regions
=
[{
fromDayOfWeek
:
1
,
toDayOfWeek
:
1
,
fill
:
true
,
line
:
true
,
colorMode
:
'red'
}];
...
...
public/app/plugins/panel/graph/time_region_manager.ts
View file @
c4f55fec
...
...
@@ -50,8 +50,8 @@ function getColor(timeRegion, theme: GrafanaTheme): TimeRegionColorDefinition {
if
(
timeRegion
.
colorMode
===
'custom'
)
{
return
{
fill
:
getColorFromHexRgbOrName
(
timeRegion
.
fillColor
,
theme
)
,
line
:
getColorFromHexRgbOrName
(
timeRegion
.
lineColor
,
theme
)
,
fill
:
timeRegion
.
fill
&&
timeRegion
.
fillColor
?
getColorFromHexRgbOrName
(
timeRegion
.
fillColor
,
theme
)
:
null
,
line
:
timeRegion
.
line
&&
timeRegion
.
lineColor
?
getColorFromHexRgbOrName
(
timeRegion
.
lineColor
,
theme
)
:
null
,
};
}
...
...
@@ -62,8 +62,8 @@ function getColor(timeRegion, theme: GrafanaTheme): TimeRegionColorDefinition {
}
return
{
fill
:
getColorFromHexRgbOrName
(
colorMode
.
color
.
fill
,
theme
)
,
line
:
getColorFromHexRgbOrName
(
colorMode
.
color
.
line
,
theme
)
,
fill
:
timeRegion
.
fill
?
getColorFromHexRgbOrName
(
colorMode
.
color
.
fill
,
theme
)
:
null
,
line
:
timeRegion
.
fill
?
getColorFromHexRgbOrName
(
colorMode
.
color
.
line
,
theme
)
:
null
,
};
}
...
...
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