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
e642fce4
Commit
e642fce4
authored
Oct 12, 2018
by
Peter Holmberg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
created component for http settings
parent
c5946ebd
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
385 additions
and
17 deletions
+385
-17
public/app/core/components/InfoPopover/InfoPopover.tsx
+7
-0
public/app/features/datasources/DataSourceHttpSettings.tsx
+223
-0
public/app/features/datasources/DataSourceSettings.tsx
+47
-9
public/app/features/datasources/EditDataSourcePage.test.tsx
+74
-0
public/app/features/datasources/EditDataSourcePage.tsx
+7
-3
public/app/features/datasources/__snapshots__/EditDataSourcePage.test.tsx.snap
+27
-0
public/app/routes/routes.ts
+0
-5
No files found.
public/app/core/components/InfoPopover/InfoPopover.tsx
0 → 100644
View file @
e642fce4
import
React
,
{
SFC
}
from
'react'
;
interface
Props
{}
const
InfoPopover
:
SFC
<
Props
>
=
props
=>
{
return
<
div
/>;
};
export
default
InfoPopover
;
public/app/features/datasources/DataSourceHttpSettings.tsx
0 → 100644
View file @
e642fce4
import
React
,
{
PureComponent
}
from
'react'
;
interface
Props
{
access
:
any
;
basicAuth
:
any
;
showAccessOption
:
any
;
tlsAuth
:
any
;
tlsAuthWithCACert
:
any
;
tlsCACert
:
any
;
tlsClientCert
:
any
;
tlsClientKey
:
any
;
url
:
any
;
}
interface
State
{
basicAuthUser
:
string
;
basicAuthPassword
:
string
;
showAccessHelp
:
boolean
;
}
export
default
class
DataSourceHttpSettings
extends
PureComponent
<
Props
,
State
>
{
state
=
{
basicAuthUser
:
''
,
basicAuthPassword
:
''
,
showAccessHelp
:
false
,
};
onToggleAccessHelp
=
()
=>
{};
render
()
{
const
{
access
,
basicAuth
,
showAccessOption
,
tlsAuth
,
tlsAuthWithCACert
,
tlsCACert
,
tlsClientCert
,
tlsClientKey
,
url
,
}
=
this
.
props
;
const
{
showAccessHelp
,
basicAuthUser
,
basicAuthPassword
}
=
this
.
state
;
// const accessOptions = [{key: 'proxy', value: 'Server (Default)'}, { key: 'direct', value: 'Browser'}];
return
(
<
div
className=
"gf-form-group"
>
<
h3
className=
"page-heading"
>
HTTP
</
h3
>
<
div
className=
"gf-form-group"
>
<
div
className=
"gf-form-inline"
>
<
div
className=
"gf-form max-width-30"
>
<
span
className=
"gf-form-label width-10"
>
URL
</
span
>
<
input
className=
"gf-form-input"
type=
"text"
value=
{
url
}
placeholder=
"https://localhost:9090"
/>
</
div
>
</
div
>
{
showAccessOption
&&
(
<
div
className=
"gf-form-inline"
>
<
div
className=
"gf-form max-width-30"
>
<
span
className=
"gf-form-label width-10"
>
Access
</
span
>
<
div
className=
"gf-form-select-wrapper max-width-24"
/>
</
div
>
<
div
className=
"gf-form"
>
<
label
className=
"gf-form-label query-keyword pointer"
onClick=
{
this
.
onToggleAccessHelp
}
>
Help
{
showAccessHelp
&&
<
i
className=
"fa fa-caret-down"
/>
}
{
!
showAccessHelp
&&
<
i
className=
"fa fa-caret-right"
>
</
i
>
}
</
label
>
</
div
>
</
div
>
)
}
{
showAccessHelp
&&
(
<
div
className=
"grafana-info-box m-t-2"
>
<
p
>
Access mode controls how requests to the data source will be handled.
<
strong
>
<
i
>
Server
</
i
>
</
strong
>
{
' '
}
should be the preferred way if nothing else stated.
</
p
>
<
div
className=
"alert-title"
>
Server access mode (Default):
</
div
>
<
p
>
All requests will be made from the browser to Grafana backend/server which in turn will forward the
requests to the data source and by that circumvent possible Cross-Origin Resource Sharing (CORS)
requirements. The URL needs to be accessible from the grafana backend/server if you select this access
mode.
</
p
>
<
div
className=
"alert-title"
>
Browser access mode:
</
div
>
<
p
>
All requests will be made from the browser directly to the data source and may be subject to
Cross-Origin Resource Sharing (CORS) requirements. The URL needs to be accessible from the browser if
you select this access mode.
</
p
>
</
div
>
)
}
{
access
===
'proxy'
&&
(
<
div
className=
"gf-form-inline"
>
<
div
className=
"gf-form"
>
<
span
className=
"gf-form-label width-10"
>
Whitelisted Cookies
</
span
>
</
div
>
</
div
>
)
}
<
h3
className=
"page-heading"
>
Auth
</
h3
>
<
div
className=
"gf-form-group"
>
<
div
className=
"gf-form-inline"
/>
<
div
className=
"gf-form-inline"
/>
<
div
className=
"gf-form-inline"
/>
</
div
>
{
basicAuth
&&
(
<
div
className=
"gf-form-group"
>
<
h6
>
Basic Auth Details
</
h6
>
<
div
className=
"gf-form"
>
<
span
className=
"gf-form-label width-10"
>
User
</
span
>
<
input
className=
"gf-form-input max-width-21"
type=
"text"
value=
{
basicAuthUser
}
placeholder=
"User"
/>
</
div
>
<
div
className=
"gf-form"
>
<
span
className=
"gf-form-label width-10"
>
Password
</
span
>
<
input
className=
"gf-form-input max-width-21"
type=
"password"
value=
{
basicAuthPassword
}
placeholder=
"Password"
/>
</
div
>
</
div
>
)
}
{
(
tlsAuth
||
tlsAuthWithCACert
)
&&
access
===
'proxy'
&&
(
<
div
className=
"gf-form-group"
>
<
div
className=
"gf-form"
>
<
h6
>
TLS Auth Details
</
h6
>
</
div
>
{
tlsAuthWithCACert
&&
(
<
div
>
<
div
className=
"gf-form-inline"
>
<
div
className=
"gf-form gf-form--v-stretch"
>
<
label
className=
"gf-form-label width-7"
>
CA Cert
</
label
>
</
div
>
{
!
tlsCACert
&&
(
<
div
className=
"gf-form gf-form--grow"
>
<
textarea
rows=
{
7
}
className=
"gf-form-input gf-form-textarea"
value=
{
tlsCACert
}
placeholder=
"Begins with -----BEGIN CERTIFICATE-----"
/>
</
div
>
)
}
{
tlsCACert
&&
(
<
div
className=
"gf-form"
>
<
input
type=
"text"
className=
"gf-form-input max-width-12"
value=
"configured"
/>
<
a
className=
"btn btn-secondary gf-form-btn"
href=
"#"
onClick=
{
()
=>
{}
}
>
reset
</
a
>
</
div
>
)
}
</
div
>
</
div
>
)
}
{
tlsAuth
&&
(
<
div
>
<
div
className=
"gf-form-inline"
>
<
div
className=
"gf-form gf-form--v-stretch"
>
<
label
className=
"gf-form-label width-7"
>
Client Cert
</
label
>
</
div
>
{
!
tlsClientCert
&&
(
<
div
className=
"gf-form gf-form--grow"
>
<
textarea
rows=
{
7
}
className=
"gf-form-input gf-form-textarea"
value=
{
tlsClientCert
}
placeholder=
"Begins with -----BEGIN CERTIFICATE-----"
required
/>
</
div
>
)
}
{
tlsClientCert
&&
(
<
div
className=
"gf-form"
>
<
input
type=
"text"
className=
"gf-form-input max-width-12"
value=
"configured"
/>
<
a
className=
"btn btn-secondary gf-form-btn"
href=
"#"
onClick=
{
()
=>
{}
}
>
reset
</
a
>
</
div
>
)
}
</
div
>
<
div
className=
"gf-form-inline"
>
<
div
className=
"gf-form gf-form--v-stretch"
>
<
label
className=
"gf-form-label width-7"
>
Client Key
</
label
>
</
div
>
{
tlsClientKey
&&
(
<
div
className=
"gf-form gf-form--grow"
>
<
textarea
rows=
{
7
}
className=
"gf-form-input gf-form-textarea"
value=
{
tlsClientKey
}
placeholder=
"Begins with -----BEGIN RSA PRIVATE KEY-----"
/>
</
div
>
)
}
{
tlsClientKey
&&
(
<
div
className=
"gf-form"
>
<
input
type=
"text"
className=
"gf-form-input max-width-12"
value=
"configured"
/>
<
a
className=
"btn btn-secondary gf-form-btn"
href=
"#"
onClick=
{
()
=>
{}
}
>
reset
</
a
>
</
div
>
)
}
</
div
>
</
div
>
)
}
</
div
>
)
}
</
div
>
</
div
>
);
}
}
public/app/features/datasources/DataSourceSettings.tsx
View file @
e642fce4
import
React
,
{
PureComponent
}
from
'react'
;
import
React
,
{
PureComponent
}
from
'react'
;
import
{
connect
}
from
'react-redux'
;
import
{
connect
}
from
'react-redux'
;
import
{
DataSource
,
Plugin
}
from
'app/types'
;
import
{
DataSource
,
Plugin
}
from
'app/types'
;
import
DataSourceHttpSettings
from
'./DataSourceHttpSettings'
;
export
interface
Props
{
export
interface
Props
{
dataSource
:
DataSource
;
dataSource
:
DataSource
;
...
@@ -8,6 +9,7 @@ export interface Props {
...
@@ -8,6 +9,7 @@ export interface Props {
}
}
interface
State
{
interface
State
{
name
:
string
;
name
:
string
;
showNamePopover
:
boolean
;
}
}
enum
DataSourceStates
{
enum
DataSourceStates
{
...
@@ -16,13 +18,10 @@ enum DataSourceStates {
...
@@ -16,13 +18,10 @@ enum DataSourceStates {
}
}
export
class
DataSourceSettings
extends
PureComponent
<
Props
,
State
>
{
export
class
DataSourceSettings
extends
PureComponent
<
Props
,
State
>
{
constructor
(
props
)
{
state
=
{
super
(
props
);
name
:
this
.
props
.
dataSource
.
name
,
showNamePopover
:
false
,
this
.
state
=
{
name
:
props
.
dataSource
.
name
,
};
};
}
onNameChange
=
event
=>
{
onNameChange
=
event
=>
{
this
.
setState
({
this
.
setState
({
...
@@ -39,6 +38,12 @@ export class DataSourceSettings extends PureComponent<Props, State> {
...
@@ -39,6 +38,12 @@ export class DataSourceSettings extends PureComponent<Props, State> {
console
.
log
(
event
);
console
.
log
(
event
);
};
};
onTogglePopover
=
()
=>
{
this
.
setState
(
prevState
=>
({
showNamePopover
:
!
prevState
.
showNamePopover
,
}));
};
isReadyOnly
()
{
isReadyOnly
()
{
return
this
.
props
.
dataSource
.
readOnly
===
true
;
return
this
.
props
.
dataSource
.
readOnly
===
true
;
}
}
...
@@ -70,11 +75,22 @@ export class DataSourceSettings extends PureComponent<Props, State> {
...
@@ -70,11 +75,22 @@ export class DataSourceSettings extends PureComponent<Props, State> {
}
}
render
()
{
render
()
{
const
{
name
}
=
this
.
state
;
const
{
name
,
showNamePopover
}
=
this
.
state
;
const
props
=
{
access
:
{},
basicAuth
:
{},
showAccessOption
:
{},
tlsAuth
:
{},
tlsAuthWithCACert
:
{},
tlsCACert
:
{},
tlsClientCert
:
{},
tlsClientKey
:
{},
url
:
{},
};
return
(
return
(
<
div
>
<
div
>
<
h3
className=
"page-sub-heading"
>
Settings
</
h3
>
<
form
onSubmit=
{
this
.
onSubmit
}
>
<
form
onSubmit=
{
this
.
onSubmit
}
>
<
div
className=
"gf-form-group"
>
<
div
className=
"gf-form-group"
>
<
div
className=
"gf-form-inline"
>
<
div
className=
"gf-form-inline"
>
...
@@ -84,10 +100,31 @@ export class DataSourceSettings extends PureComponent<Props, State> {
...
@@ -84,10 +100,31 @@ export class DataSourceSettings extends PureComponent<Props, State> {
className=
"gf-form-input max-width-23"
className=
"gf-form-input max-width-23"
type=
"text"
type=
"text"
value=
{
name
}
value=
{
name
}
placeholder=
"
n
ame"
placeholder=
"
N
ame"
onChange=
{
this
.
onNameChange
}
onChange=
{
this
.
onNameChange
}
required
required
/>
/>
<
div
onClick=
{
this
.
onTogglePopover
}
>
<
i
className=
"fa fa-info-circle"
/>
</
div
>
{
showNamePopover
&&
(
<
div
style=
{
{
position
:
'absolute'
,
left
:
'450px'
,
top
:
'-20px'
,
padding
:
'10px'
,
backgroundColor
:
'black'
,
zIndex
:
2
,
width
:
'300px'
,
border
:
'1px solid gray'
,
borderRadius
:
'3px'
,
}
}
>
The name is used when you select the data source in panels. The
<
em
>
Default
</
em
>
data source is
preselected in new panels.
</
div
>
)
}
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
...
@@ -110,6 +147,7 @@ export class DataSourceSettings extends PureComponent<Props, State> {
...
@@ -110,6 +147,7 @@ export class DataSourceSettings extends PureComponent<Props, State> {
</
a
>
</
a
>
</
div
>
</
div
>
</
form
>
</
form
>
<
DataSourceHttpSettings
{
...
props
}
/>
</
div
>
</
div
>
);
);
}
}
...
...
public/app/features/datasources/EditDataSourcePage.test.tsx
0 → 100644
View file @
e642fce4
import
React
from
'react'
;
import
{
shallow
}
from
'enzyme'
;
import
{
EditDataSourcePage
,
Props
}
from
'./EditDataSourcePage'
;
import
{
DataSource
,
NavModel
}
from
'../../types'
;
const
setup
=
(
propOverrides
?:
object
)
=>
{
const
props
:
Props
=
{
navModel
:
{}
as
NavModel
,
dataSource
:
{}
as
DataSource
,
dataSourceId
:
1
,
pageName
:
''
,
loadDataSource
:
jest
.
fn
(),
};
Object
.
assign
(
props
,
propOverrides
);
const
wrapper
=
shallow
(<
EditDataSourcePage
{
...
props
}
/>);
const
instance
=
wrapper
.
instance
()
as
EditDataSourcePage
;
return
{
wrapper
,
instance
,
};
};
describe
(
'Render'
,
()
=>
{
it
(
'should render component'
,
()
=>
{
const
{
wrapper
}
=
setup
();
expect
(
wrapper
).
toMatchSnapshot
();
});
it
(
'should render permissions page'
,
()
=>
{
const
{
wrapper
}
=
setup
({
pageName
:
'permissions'
,
});
expect
(
wrapper
).
toMatchSnapshot
();
});
});
describe
(
'Functions'
,
()
=>
{
describe
(
'is page valid'
,
()
=>
{
it
(
'should be a valid page'
,
()
=>
{
const
{
instance
}
=
setup
();
expect
(
instance
.
isValidPage
(
'permissions'
)).
toBeTruthy
();
});
it
(
'should not be a valid page'
,
()
=>
{
const
{
instance
}
=
setup
();
expect
(
instance
.
isValidPage
(
'asdf'
)).
toBeFalsy
();
});
});
describe
(
'get current page'
,
()
=>
{
it
(
'should return permissions'
,
()
=>
{
const
{
instance
}
=
setup
({
pageName
:
'permissions'
,
});
expect
(
instance
.
getCurrentPage
()).
toEqual
(
'permissions'
);
});
it
(
'should return settings if bogus route'
,
()
=>
{
const
{
instance
}
=
setup
({
pageName
:
'asdf'
,
});
expect
(
instance
.
getCurrentPage
()).
toEqual
(
'settings'
);
});
});
});
public/app/features/datasources/EditDataSourcePage.tsx
View file @
e642fce4
...
@@ -3,6 +3,7 @@ import { hot } from 'react-hot-loader';
...
@@ -3,6 +3,7 @@ import { hot } from 'react-hot-loader';
import
{
connect
}
from
'react-redux'
;
import
{
connect
}
from
'react-redux'
;
import
PageHeader
from
'../../core/components/PageHeader/PageHeader'
;
import
PageHeader
from
'../../core/components/PageHeader/PageHeader'
;
import
DataSourcePermissions
from
'./DataSourcePermissions'
;
import
DataSourcePermissions
from
'./DataSourcePermissions'
;
import
DataSourceSettings
from
'./DataSourceSettings'
;
import
{
DataSource
,
NavModel
}
from
'app/types'
;
import
{
DataSource
,
NavModel
}
from
'app/types'
;
import
{
loadDataSource
}
from
'./state/actions'
;
import
{
loadDataSource
}
from
'./state/actions'
;
import
{
getNavModel
}
from
'../../core/selectors/navModel'
;
import
{
getNavModel
}
from
'../../core/selectors/navModel'
;
...
@@ -24,6 +25,8 @@ enum PageTypes {
...
@@ -24,6 +25,8 @@ enum PageTypes {
Dashboards
=
'dashboards'
,
Dashboards
=
'dashboards'
,
}
}
const
fallBackPage
=
PageTypes
.
Settings
;
export
class
EditDataSourcePage
extends
PureComponent
<
Props
>
{
export
class
EditDataSourcePage
extends
PureComponent
<
Props
>
{
componentDidMount
()
{
componentDidMount
()
{
this
.
fetchDataSource
();
this
.
fetchDataSource
();
...
@@ -39,12 +42,13 @@ export class EditDataSourcePage extends PureComponent<Props> {
...
@@ -39,12 +42,13 @@ export class EditDataSourcePage extends PureComponent<Props> {
getCurrentPage
()
{
getCurrentPage
()
{
const
currentPage
=
this
.
props
.
pageName
;
const
currentPage
=
this
.
props
.
pageName
;
return
this
.
isValidPage
(
currentPage
)
?
currentPage
:
fallBackPage
;
return
this
.
isValidPage
(
currentPage
)
?
currentPage
:
PageTypes
.
Permissions
;
}
}
renderPage
()
{
renderPage
()
{
switch
(
this
.
getCurrentPage
())
{
switch
(
this
.
getCurrentPage
())
{
case
PageTypes
.
Settings
:
return
<
DataSourceSettings
/>;
case
PageTypes
.
Permissions
:
case
PageTypes
.
Permissions
:
return
<
DataSourcePermissions
/>;
return
<
DataSourcePermissions
/>;
}
}
...
@@ -65,7 +69,7 @@ export class EditDataSourcePage extends PureComponent<Props> {
...
@@ -65,7 +69,7 @@ export class EditDataSourcePage extends PureComponent<Props> {
}
}
function
mapStateToProps
(
state
)
{
function
mapStateToProps
(
state
)
{
const
pageName
=
getRouteParamsPage
(
state
.
location
)
||
PageTypes
.
Permissions
;
const
pageName
=
getRouteParamsPage
(
state
.
location
)
||
fallBackPage
;
const
dataSourceId
=
getRouteParamsId
(
state
.
location
);
const
dataSourceId
=
getRouteParamsId
(
state
.
location
);
const
dataSourceLoadingNav
=
getDataSourceLoadingNav
(
pageName
);
const
dataSourceLoadingNav
=
getDataSourceLoadingNav
(
pageName
);
...
...
public/app/features/datasources/__snapshots__/EditDataSourcePage.test.tsx.snap
0 → 100644
View file @
e642fce4
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render should render component 1`] = `
<div>
<PageHeader
model={Object {}}
/>
<div
className="page-container page-body"
>
<Connect(DataSourceSettings) />
</div>
</div>
`;
exports[`Render should render permissions page 1`] = `
<div>
<PageHeader
model={Object {}}
/>
<div
className="page-container page-body"
>
<Connect(DataSourcePermissions) />
</div>
</div>
`;
public/app/routes/routes.ts
View file @
e642fce4
...
@@ -73,11 +73,6 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
...
@@ -73,11 +73,6 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
component
:
()
=>
DataSourcesListPage
,
component
:
()
=>
DataSourcesListPage
,
},
},
})
})
.
when
(
'/datasources/edit/:id'
,
{
templateUrl
:
'public/app/features/plugins/partials/ds_edit.html'
,
controller
:
'DataSourceEditCtrl'
,
controllerAs
:
'ctrl'
,
})
.
when
(
'/datasources/edit/:id/dashboards'
,
{
.
when
(
'/datasources/edit/:id/dashboards'
,
{
templateUrl
:
'public/app/features/plugins/partials/ds_dashboards.html'
,
templateUrl
:
'public/app/features/plugins/partials/ds_dashboards.html'
,
controller
:
'DataSourceDashboardsCtrl'
,
controller
:
'DataSourceDashboardsCtrl'
,
...
...
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