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
166f93cf
Commit
166f93cf
authored
Sep 28, 2018
by
Peter Holmberg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
components, test, removed old not used files
parent
11ee65d3
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
807 additions
and
129 deletions
+807
-129
public/app/features/datasources/DataSourceList.test.tsx
+22
-0
public/app/features/datasources/DataSourcesActionBar.test.tsx
+23
-0
public/app/features/datasources/DataSourcesActionBar.tsx
+62
-0
public/app/features/datasources/DataSourcesList.tsx
+32
-0
public/app/features/datasources/DataSourcesListItem.test.tsx
+20
-0
public/app/features/datasources/DataSourcesListItem.tsx
+34
-0
public/app/features/datasources/DataSourcesListPage.test.tsx
+35
-0
public/app/features/datasources/DataSourcesListPage.tsx
+72
-0
public/app/features/datasources/__mocks__/dataSourcesMocks.ts
+45
-0
public/app/features/datasources/__snapshots__/DataSourceList.test.tsx.snap
+108
-0
public/app/features/datasources/__snapshots__/DataSourcesActionBar.test.tsx.snap
+42
-0
public/app/features/datasources/__snapshots__/DataSourcesListItem.test.tsx.snap
+45
-0
public/app/features/datasources/__snapshots__/DataSourcesListPage.test.tsx.snap
+152
-0
public/app/features/datasources/state/actions.ts
+51
-0
public/app/features/datasources/state/reducers.ts
+28
-0
public/app/features/datasources/state/selectors.ts
+10
-0
public/app/features/plugins/all.ts
+0
-1
public/app/features/plugins/ds_list_ctrl.ts
+0
-61
public/app/features/plugins/partials/ds_list.html
+0
-63
public/app/routes/routes.ts
+5
-3
public/app/store/configureStore.ts
+2
-0
public/app/types/datasources.ts
+17
-0
public/app/types/index.ts
+2
-1
No files found.
public/app/features/datasources/DataSourceList.test.tsx
0 → 100644
View file @
166f93cf
import
React
from
'react'
;
import
{
shallow
}
from
'enzyme'
;
import
DataSourcesList
from
'./DataSourcesList'
;
import
{
getMockDataSources
}
from
'./__mocks__/dataSourcesMocks'
;
import
{
LayoutModes
}
from
'../../core/components/LayoutSelector/LayoutSelector'
;
const
setup
=
()
=>
{
const
props
=
{
dataSources
:
getMockDataSources
(
3
),
layoutMode
:
LayoutModes
.
Grid
,
};
return
shallow
(<
DataSourcesList
{
...
props
}
/>);
};
describe
(
'Render'
,
()
=>
{
it
(
'should render component'
,
()
=>
{
const
wrapper
=
setup
();
expect
(
wrapper
).
toMatchSnapshot
();
});
});
public/app/features/datasources/DataSourcesActionBar.test.tsx
0 → 100644
View file @
166f93cf
import
React
from
'react'
;
import
{
shallow
}
from
'enzyme'
;
import
{
DataSourcesActionBar
,
Props
}
from
'./DataSourcesActionBar'
;
import
{
LayoutModes
}
from
'../../core/components/LayoutSelector/LayoutSelector'
;
const
setup
=
(
propOverrides
?:
object
)
=>
{
const
props
:
Props
=
{
layoutMode
:
LayoutModes
.
Grid
,
searchQuery
:
''
,
setDataSourcesLayoutMode
:
jest
.
fn
(),
setDataSourcesSearchQuery
:
jest
.
fn
(),
};
return
shallow
(<
DataSourcesActionBar
{
...
props
}
/>);
};
describe
(
'Render'
,
()
=>
{
it
(
'should render component'
,
()
=>
{
const
wrapper
=
setup
();
expect
(
wrapper
).
toMatchSnapshot
();
});
});
public/app/features/datasources/DataSourcesActionBar.tsx
0 → 100644
View file @
166f93cf
import
React
,
{
PureComponent
}
from
'react'
;
import
{
connect
}
from
'react-redux'
;
import
LayoutSelector
,
{
LayoutMode
}
from
'../../core/components/LayoutSelector/LayoutSelector'
;
import
{
setDataSourcesLayoutMode
,
setDataSourcesSearchQuery
}
from
'./state/actions'
;
import
{
getDataSourcesLayoutMode
,
getDataSourcesSearchQuery
}
from
'./state/selectors'
;
export
interface
Props
{
searchQuery
:
string
;
layoutMode
:
LayoutMode
;
setDataSourcesLayoutMode
:
typeof
setDataSourcesLayoutMode
;
setDataSourcesSearchQuery
:
typeof
setDataSourcesSearchQuery
;
}
export
class
DataSourcesActionBar
extends
PureComponent
<
Props
>
{
onSearchQueryChange
=
event
=>
{
this
.
props
.
setDataSourcesSearchQuery
(
event
.
target
.
value
);
};
render
()
{
const
{
searchQuery
,
layoutMode
,
setDataSourcesLayoutMode
}
=
this
.
props
;
return
(
<
div
className=
"page-action-bar"
>
<
div
className=
"gf-form gf-form--grow"
>
<
label
className=
"gf-form--has-input-icon"
>
<
input
type=
"text"
className=
"gf-form-input width-20"
value=
{
searchQuery
}
onChange=
{
this
.
onSearchQueryChange
}
placeholder=
"Filter by name or type"
/>
<
i
className=
"gf-form-input-icon fa fa-search"
/>
</
label
>
<
LayoutSelector
mode=
{
layoutMode
}
onLayoutModeChanged=
{
(
mode
:
LayoutMode
)
=>
setDataSourcesLayoutMode
(
mode
)
}
/>
</
div
>
<
div
className=
"page-action-bar__spacer"
/>
<
a
className=
"page-header__cta btn btn-success"
href=
"datasources/new"
>
<
i
className=
"fa fa-plus"
/>
Add data source
</
a
>
</
div
>
);
}
}
function
mapStateToProps
(
state
)
{
return
{
searchQuery
:
getDataSourcesSearchQuery
(
state
.
dataSources
),
layoutMode
:
getDataSourcesLayoutMode
(
state
.
dataSources
),
};
}
const
mapDispatchToProps
=
{
setDataSourcesLayoutMode
,
setDataSourcesSearchQuery
,
};
export
default
connect
(
mapStateToProps
,
mapDispatchToProps
)(
DataSourcesActionBar
);
public/app/features/datasources/DataSourcesList.tsx
0 → 100644
View file @
166f93cf
import
React
,
{
SFC
}
from
'react'
;
import
classNames
from
'classnames/bind'
;
import
DataSourcesListItem
from
'./DataSourcesListItem'
;
import
{
DataSource
}
from
'app/types'
;
import
{
LayoutMode
,
LayoutModes
}
from
'../../core/components/LayoutSelector/LayoutSelector'
;
export
interface
Props
{
dataSources
:
DataSource
[];
layoutMode
:
LayoutMode
;
}
const
DataSourcesList
:
SFC
<
Props
>
=
props
=>
{
const
{
dataSources
,
layoutMode
}
=
props
;
const
listStyle
=
classNames
({
'card-section'
:
true
,
'card-list-layout-grid'
:
layoutMode
===
LayoutModes
.
Grid
,
'card-list-layout-list'
:
layoutMode
===
LayoutModes
.
List
,
});
return
(
<
section
className=
{
listStyle
}
>
<
ol
className=
"card-list"
>
{
dataSources
.
map
((
dataSource
,
index
)
=>
{
return
<
DataSourcesListItem
dataSource=
{
dataSource
}
key=
{
`${dataSource.id}-${index}`
}
/>;
})
}
</
ol
>
</
section
>
);
};
export
default
DataSourcesList
;
public/app/features/datasources/DataSourcesListItem.test.tsx
0 → 100644
View file @
166f93cf
import
React
from
'react'
;
import
{
shallow
}
from
'enzyme'
;
import
DataSourcesListItem
from
'./DataSourcesListItem'
;
import
{
getMockDataSource
}
from
'./__mocks__/dataSourcesMocks'
;
const
setup
=
()
=>
{
const
props
=
{
dataSource
:
getMockDataSource
(),
};
return
shallow
(<
DataSourcesListItem
{
...
props
}
/>);
};
describe
(
'Render'
,
()
=>
{
it
(
'should render component'
,
()
=>
{
const
wrapper
=
setup
();
expect
(
wrapper
).
toMatchSnapshot
();
});
});
public/app/features/datasources/DataSourcesListItem.tsx
0 → 100644
View file @
166f93cf
import
React
,
{
SFC
}
from
'react'
;
import
{
DataSource
}
from
'app/types'
;
export
interface
Props
{
dataSource
:
DataSource
;
}
const
DataSourcesListItem
:
SFC
<
Props
>
=
props
=>
{
const
{
dataSource
}
=
props
;
return
(
<
li
className=
"card-item-wrapper"
>
<
a
className=
"card-item"
href=
{
`datasources/edit/${dataSource.id}`
}
>
<
div
className=
"card-item-header"
>
<
div
className=
"card-item-type"
>
{
dataSource
.
type
}
</
div
>
</
div
>
<
div
className=
"card-item-body"
>
<
figure
className=
"card-item-figure"
>
<
img
src=
{
dataSource
.
typeLogoUrl
}
/>
</
figure
>
<
div
className=
"card-item-details"
>
<
div
className=
"card-item-name"
>
{
dataSource
.
name
}
{
dataSource
.
isDefault
&&
<
span
className=
"btn btn-secondary btn-mini"
>
default
</
span
>
}
</
div
>
<
div
className=
"card-item-sub-name"
>
{
dataSource
.
url
}
</
div
>
</
div
>
</
div
>
</
a
>
</
li
>
);
};
export
default
DataSourcesListItem
;
public/app/features/datasources/DataSourcesListPage.test.tsx
0 → 100644
View file @
166f93cf
import
React
from
'react'
;
import
{
shallow
}
from
'enzyme'
;
import
{
DataSourcesListPage
,
Props
}
from
'./DataSourcesListPage'
;
import
{
DataSource
,
NavModel
}
from
'app/types'
;
import
{
LayoutModes
}
from
'../../core/components/LayoutSelector/LayoutSelector'
;
import
{
getMockDataSources
}
from
'./__mocks__/dataSourcesMocks'
;
const
setup
=
(
propOverrides
?:
object
)
=>
{
const
props
:
Props
=
{
dataSources
:
[]
as
DataSource
[],
layoutMode
:
LayoutModes
.
Grid
,
loadDataSources
:
jest
.
fn
(),
navModel
:
{}
as
NavModel
,
};
Object
.
assign
(
props
,
propOverrides
);
return
shallow
(<
DataSourcesListPage
{
...
props
}
/>);
};
describe
(
'Render'
,
()
=>
{
it
(
'should render component'
,
()
=>
{
const
wrapper
=
setup
();
expect
(
wrapper
).
toMatchSnapshot
();
});
it
(
'should render action bar and datasources'
,
()
=>
{
const
wrapper
=
setup
({
dataSources
:
getMockDataSources
(
5
),
});
expect
(
wrapper
).
toMatchSnapshot
();
});
});
public/app/features/datasources/DataSourcesListPage.tsx
0 → 100644
View file @
166f93cf
import
React
,
{
PureComponent
}
from
'react'
;
import
{
connect
}
from
'react-redux'
;
import
{
hot
}
from
'react-hot-loader'
;
import
PageHeader
from
'../../core/components/PageHeader/PageHeader'
;
import
DataSourcesActionBar
from
'./DataSourcesActionBar'
;
import
DataSourcesList
from
'./DataSourcesList'
;
import
{
loadDataSources
}
from
'./state/actions'
;
import
{
getDataSources
,
getDataSourcesLayoutMode
}
from
'./state/selectors'
;
import
{
getNavModel
}
from
'../../core/selectors/navModel'
;
import
{
DataSource
,
NavModel
}
from
'app/types'
;
import
{
LayoutMode
}
from
'../../core/components/LayoutSelector/LayoutSelector'
;
import
EmptyListCTA
from
'../../core/components/EmptyListCTA/EmptyListCTA'
;
export
interface
Props
{
navModel
:
NavModel
;
dataSources
:
DataSource
[];
layoutMode
:
LayoutMode
;
loadDataSources
:
typeof
loadDataSources
;
}
const
emptyListModel
=
{
title
:
'There are no data sources defined yet'
,
buttonIcon
:
'gicon gicon-add-datasources'
,
buttonLink
:
'datasources/new'
,
buttonTitle
:
'Add data source'
,
proTip
:
'You can also define data sources through configuration files.'
,
proTipLink
:
'http://docs.grafana.org/administration/provisioning/#datasources?utm_source=grafana_ds_list'
,
proTipLinkTitle
:
'Learn more'
,
proTipTarget
:
'_blank'
,
};
export
class
DataSourcesListPage
extends
PureComponent
<
Props
>
{
componentDidMount
()
{
this
.
fetchDataSources
();
}
async
fetchDataSources
()
{
return
await
this
.
props
.
loadDataSources
();
}
render
()
{
const
{
navModel
,
dataSources
,
layoutMode
}
=
this
.
props
;
if
(
dataSources
.
length
===
0
)
{
return
<
EmptyListCTA
model=
{
emptyListModel
}
/>;
}
return
(
<
div
>
<
PageHeader
model=
{
navModel
}
/>
<
div
className=
"page-container page-body"
>
<
DataSourcesActionBar
/>
<
DataSourcesList
dataSources=
{
dataSources
}
layoutMode=
{
layoutMode
}
/>
</
div
>
</
div
>
);
}
}
function
mapStateToProps
(
state
)
{
return
{
navModel
:
getNavModel
(
state
.
navIndex
,
'datasources'
),
dataSources
:
getDataSources
(
state
.
dataSources
),
layoutMode
:
getDataSourcesLayoutMode
(
state
.
dataSources
),
};
}
const
mapDispatchToProps
=
{
loadDataSources
,
};
export
default
hot
(
module
)(
connect
(
mapStateToProps
,
mapDispatchToProps
)(
DataSourcesListPage
));
public/app/features/datasources/__mocks__/dataSourcesMocks.ts
0 → 100644
View file @
166f93cf
import
{
DataSource
}
from
'app/types'
;
export
const
getMockDataSources
=
(
amount
:
number
):
DataSource
[]
=>
{
const
dataSources
=
[];
for
(
let
i
=
0
;
i
<=
amount
;
i
++
)
{
dataSources
.
push
({
access
:
''
,
basicAuth
:
false
,
database
:
`database-
${
i
}
`
,
id
:
i
,
isDefault
:
false
,
jsonData
:
{
authType
:
'credentials'
,
defaultRegion
:
'eu-west-2'
},
name
:
`dataSource-
${
i
}
`
,
orgId
:
1
,
password
:
''
,
readOnly
:
false
,
type
:
'cloudwatch'
,
typeLogoUrl
:
'public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png'
,
url
:
''
,
user
:
''
,
});
}
return
dataSources
;
};
export
const
getMockDataSource
=
():
DataSource
=>
{
return
{
access
:
''
,
basicAuth
:
false
,
database
:
''
,
id
:
13
,
isDefault
:
false
,
jsonData
:
{
authType
:
'credentials'
,
defaultRegion
:
'eu-west-2'
},
name
:
'gdev-cloudwatch'
,
orgId
:
1
,
password
:
''
,
readOnly
:
false
,
type
:
'cloudwatch'
,
typeLogoUrl
:
'public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png'
,
url
:
''
,
user
:
''
,
};
};
public/app/features/datasources/__snapshots__/DataSourceList.test.tsx.snap
0 → 100644
View file @
166f93cf
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render should render component 1`] = `
<section
className="card-section card-list-layout-grid"
>
<ol
className="card-list"
>
<DataSourcesListItem
dataSource={
Object {
"access": "",
"basicAuth": false,
"database": "database-0",
"id": 0,
"isDefault": false,
"jsonData": Object {
"authType": "credentials",
"defaultRegion": "eu-west-2",
},
"name": "dataSource-0",
"orgId": 1,
"password": "",
"readOnly": false,
"type": "cloudwatch",
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
"url": "",
"user": "",
}
}
key="0-0"
/>
<DataSourcesListItem
dataSource={
Object {
"access": "",
"basicAuth": false,
"database": "database-1",
"id": 1,
"isDefault": false,
"jsonData": Object {
"authType": "credentials",
"defaultRegion": "eu-west-2",
},
"name": "dataSource-1",
"orgId": 1,
"password": "",
"readOnly": false,
"type": "cloudwatch",
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
"url": "",
"user": "",
}
}
key="1-1"
/>
<DataSourcesListItem
dataSource={
Object {
"access": "",
"basicAuth": false,
"database": "database-2",
"id": 2,
"isDefault": false,
"jsonData": Object {
"authType": "credentials",
"defaultRegion": "eu-west-2",
},
"name": "dataSource-2",
"orgId": 1,
"password": "",
"readOnly": false,
"type": "cloudwatch",
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
"url": "",
"user": "",
}
}
key="2-2"
/>
<DataSourcesListItem
dataSource={
Object {
"access": "",
"basicAuth": false,
"database": "database-3",
"id": 3,
"isDefault": false,
"jsonData": Object {
"authType": "credentials",
"defaultRegion": "eu-west-2",
},
"name": "dataSource-3",
"orgId": 1,
"password": "",
"readOnly": false,
"type": "cloudwatch",
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
"url": "",
"user": "",
}
}
key="3-3"
/>
</ol>
</section>
`;
public/app/features/datasources/__snapshots__/DataSourcesActionBar.test.tsx.snap
0 → 100644
View file @
166f93cf
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render should render component 1`] = `
<div
className="page-action-bar"
>
<div
className="gf-form gf-form--grow"
>
<label
className="gf-form--has-input-icon"
>
<input
className="gf-form-input width-20"
onChange={[Function]}
placeholder="Filter by name or type"
type="text"
value=""
/>
<i
className="gf-form-input-icon fa fa-search"
/>
</label>
<LayoutSelector
mode="grid"
onLayoutModeChanged={[Function]}
/>
</div>
<div
className="page-action-bar__spacer"
/>
<a
className="page-header__cta btn btn-success"
href="datasources/new"
>
<i
className="fa fa-plus"
/>
Add data source
</a>
</div>
`;
public/app/features/datasources/__snapshots__/DataSourcesListItem.test.tsx.snap
0 → 100644
View file @
166f93cf
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render should render component 1`] = `
<li
className="card-item-wrapper"
>
<a
className="card-item"
href="datasources/edit/13"
>
<div
className="card-item-header"
>
<div
className="card-item-type"
>
cloudwatch
</div>
</div>
<div
className="card-item-body"
>
<figure
className="card-item-figure"
>
<img
src="public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png"
/>
</figure>
<div
className="card-item-details"
>
<div
className="card-item-name"
>
gdev-cloudwatch
</div>
<div
className="card-item-sub-name"
/>
</div>
</div>
</a>
</li>
`;
public/app/features/datasources/__snapshots__/DataSourcesListPage.test.tsx.snap
0 → 100644
View file @
166f93cf
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render should render action bar and datasources 1`] = `
<div>
<PageHeader
model={Object {}}
/>
<div
className="page-container page-body"
>
<Connect(DataSourcesActionBar) />
<DataSourcesList
dataSources={
Array [
Object {
"access": "",
"basicAuth": false,
"database": "database-0",
"id": 0,
"isDefault": false,
"jsonData": Object {
"authType": "credentials",
"defaultRegion": "eu-west-2",
},
"name": "dataSource-0",
"orgId": 1,
"password": "",
"readOnly": false,
"type": "cloudwatch",
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
"url": "",
"user": "",
},
Object {
"access": "",
"basicAuth": false,
"database": "database-1",
"id": 1,
"isDefault": false,
"jsonData": Object {
"authType": "credentials",
"defaultRegion": "eu-west-2",
},
"name": "dataSource-1",
"orgId": 1,
"password": "",
"readOnly": false,
"type": "cloudwatch",
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
"url": "",
"user": "",
},
Object {
"access": "",
"basicAuth": false,
"database": "database-2",
"id": 2,
"isDefault": false,
"jsonData": Object {
"authType": "credentials",
"defaultRegion": "eu-west-2",
},
"name": "dataSource-2",
"orgId": 1,
"password": "",
"readOnly": false,
"type": "cloudwatch",
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
"url": "",
"user": "",
},
Object {
"access": "",
"basicAuth": false,
"database": "database-3",
"id": 3,
"isDefault": false,
"jsonData": Object {
"authType": "credentials",
"defaultRegion": "eu-west-2",
},
"name": "dataSource-3",
"orgId": 1,
"password": "",
"readOnly": false,
"type": "cloudwatch",
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
"url": "",
"user": "",
},
Object {
"access": "",
"basicAuth": false,
"database": "database-4",
"id": 4,
"isDefault": false,
"jsonData": Object {
"authType": "credentials",
"defaultRegion": "eu-west-2",
},
"name": "dataSource-4",
"orgId": 1,
"password": "",
"readOnly": false,
"type": "cloudwatch",
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
"url": "",
"user": "",
},
Object {
"access": "",
"basicAuth": false,
"database": "database-5",
"id": 5,
"isDefault": false,
"jsonData": Object {
"authType": "credentials",
"defaultRegion": "eu-west-2",
},
"name": "dataSource-5",
"orgId": 1,
"password": "",
"readOnly": false,
"type": "cloudwatch",
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
"url": "",
"user": "",
},
]
}
layoutMode="grid"
/>
</div>
</div>
`;
exports[`Render should render component 1`] = `
<EmptyListCTA
model={
Object {
"buttonIcon": "gicon gicon-add-datasources",
"buttonLink": "datasources/new",
"buttonTitle": "Add data source",
"proTip": "You can also define data sources through configuration files.",
"proTipLink": "http://docs.grafana.org/administration/provisioning/#datasources?utm_source=grafana_ds_list",
"proTipLinkTitle": "Learn more",
"proTipTarget": "_blank",
"title": "There are no data sources defined yet",
}
}
/>
`;
public/app/features/datasources/state/actions.ts
0 → 100644
View file @
166f93cf
import
{
ThunkAction
}
from
'redux-thunk'
;
import
{
DataSource
,
StoreState
}
from
'app/types'
;
import
{
getBackendSrv
}
from
'../../../core/services/backend_srv'
;
import
{
LayoutMode
}
from
'../../../core/components/LayoutSelector/LayoutSelector'
;
export
enum
ActionTypes
{
LoadDataSources
=
'LOAD_DATA_SOURCES'
,
SetDataSourcesSearchQuery
=
'SET_DATA_SOURCES_SEARCH_QUERY'
,
SetDataSourcesLayoutMode
=
'SET_DATA_SOURCES_LAYOUT_MODE'
,
}
export
interface
LoadDataSourcesAction
{
type
:
ActionTypes
.
LoadDataSources
;
payload
:
DataSource
[];
}
export
interface
SetDataSourcesSearchQueryAction
{
type
:
ActionTypes
.
SetDataSourcesSearchQuery
;
payload
:
string
;
}
export
interface
SetDataSourcesLayoutModeAction
{
type
:
ActionTypes
.
SetDataSourcesLayoutMode
;
payload
:
LayoutMode
;
}
const
dataSourcesLoaded
=
(
dataSources
:
DataSource
[]):
LoadDataSourcesAction
=>
({
type
:
ActionTypes
.
LoadDataSources
,
payload
:
dataSources
,
});
export
const
setDataSourcesSearchQuery
=
(
searchQuery
:
string
):
SetDataSourcesSearchQueryAction
=>
({
type
:
ActionTypes
.
SetDataSourcesSearchQuery
,
payload
:
searchQuery
,
});
export
const
setDataSourcesLayoutMode
=
(
layoutMode
:
LayoutMode
):
SetDataSourcesLayoutModeAction
=>
({
type
:
ActionTypes
.
SetDataSourcesLayoutMode
,
payload
:
layoutMode
,
});
export
type
Action
=
LoadDataSourcesAction
|
SetDataSourcesSearchQueryAction
|
SetDataSourcesLayoutModeAction
;
type
ThunkResult
<
R
>
=
ThunkAction
<
R
,
StoreState
,
undefined
,
Action
>
;
export
function
loadDataSources
():
ThunkResult
<
void
>
{
return
async
dispatch
=>
{
const
response
=
await
getBackendSrv
().
get
(
'/api/datasources'
);
dispatch
(
dataSourcesLoaded
(
response
));
};
}
public/app/features/datasources/state/reducers.ts
0 → 100644
View file @
166f93cf
import
{
DataSource
,
DataSourcesState
}
from
'app/types'
;
import
{
Action
,
ActionTypes
}
from
'./actions'
;
import
{
LayoutModes
}
from
'../../../core/components/LayoutSelector/LayoutSelector'
;
const
initialState
:
DataSourcesState
=
{
dataSources
:
[]
as
DataSource
[],
layoutMode
:
LayoutModes
.
Grid
,
searchQuery
:
''
,
};
export
const
dataSourcesReducer
=
(
state
=
initialState
,
action
:
Action
):
DataSourcesState
=>
{
switch
(
action
.
type
)
{
case
ActionTypes
.
LoadDataSources
:
return
{
...
state
,
dataSources
:
action
.
payload
};
case
ActionTypes
.
SetDataSourcesSearchQuery
:
return
{
...
state
,
searchQuery
:
action
.
payload
};
case
ActionTypes
.
SetDataSourcesLayoutMode
:
return
{
...
state
,
layoutMode
:
action
.
payload
};
}
return
state
;
};
export
default
{
dataSources
:
dataSourcesReducer
,
};
public/app/features/datasources/state/selectors.ts
0 → 100644
View file @
166f93cf
export
const
getDataSources
=
state
=>
{
const
regex
=
new
RegExp
(
state
.
searchQuery
,
'i'
);
return
state
.
dataSources
.
filter
(
dataSource
=>
{
return
regex
.
test
(
dataSource
.
name
)
||
regex
.
test
(
dataSource
.
database
);
});
};
export
const
getDataSourcesSearchQuery
=
state
=>
state
.
searchQuery
;
export
const
getDataSourcesLayoutMode
=
state
=>
state
.
layoutMode
;
public/app/features/plugins/all.ts
View file @
166f93cf
...
...
@@ -3,6 +3,5 @@ import './plugin_page_ctrl';
import
'./import_list/import_list'
;
import
'./ds_edit_ctrl'
;
import
'./ds_dashboards_ctrl'
;
import
'./ds_list_ctrl'
;
import
'./datasource_srv'
;
import
'./plugin_component'
;
public/app/features/plugins/ds_list_ctrl.ts
deleted
100644 → 0
View file @
11ee65d3
import
coreModule
from
'../../core/core_module'
;
import
_
from
'lodash'
;
export
class
DataSourcesCtrl
{
datasources
:
any
;
unfiltered
:
any
;
navModel
:
any
;
searchQuery
:
string
;
/** @ngInject */
constructor
(
private
$scope
,
private
backendSrv
,
private
datasourceSrv
,
private
navModelSrv
)
{
this
.
navModel
=
this
.
navModelSrv
.
getNav
(
'cfg'
,
'datasources'
,
0
);
backendSrv
.
get
(
'/api/datasources'
).
then
(
result
=>
{
this
.
datasources
=
result
;
this
.
unfiltered
=
result
;
});
}
onQueryUpdated
()
{
const
regex
=
new
RegExp
(
this
.
searchQuery
,
'ig'
);
this
.
datasources
=
_
.
filter
(
this
.
unfiltered
,
item
=>
{
regex
.
lastIndex
=
0
;
return
regex
.
test
(
item
.
name
)
||
regex
.
test
(
item
.
type
);
});
}
removeDataSourceConfirmed
(
ds
)
{
this
.
backendSrv
.
delete
(
'/api/datasources/'
+
ds
.
id
)
.
then
(
()
=>
{
this
.
$scope
.
appEvent
(
'alert-success'
,
[
'Datasource deleted'
,
''
]);
},
()
=>
{
this
.
$scope
.
appEvent
(
'alert-error'
,
[
'Unable to delete datasource'
,
''
]);
}
)
.
then
(()
=>
{
this
.
backendSrv
.
get
(
'/api/datasources'
).
then
(
result
=>
{
this
.
datasources
=
result
;
});
this
.
backendSrv
.
get
(
'/api/frontend/settings'
).
then
(
settings
=>
{
this
.
datasourceSrv
.
init
(
settings
.
datasources
);
});
});
}
removeDataSource
(
ds
)
{
this
.
$scope
.
appEvent
(
'confirm-modal'
,
{
title
:
'Delete'
,
text
:
'Are you sure you want to delete datasource '
+
ds
.
name
+
'?'
,
yesText
:
'Delete'
,
icon
:
'fa-trash'
,
onConfirm
:
()
=>
{
this
.
removeDataSourceConfirmed
(
ds
);
},
});
}
}
coreModule
.
controller
(
'DataSourcesCtrl'
,
DataSourcesCtrl
);
public/app/features/plugins/partials/ds_list.html
deleted
100644 → 0
View file @
11ee65d3
<page-header
model=
"ctrl.navModel"
></page-header>
<div
class=
"page-container page-body"
>
<div
ng-if=
"ctrl.unfiltered.length"
>
<div
class=
"page-action-bar"
>
<div
class=
"gf-form gf-form--grow"
>
<label
class=
"gf-form--has-input-icon"
>
<input
type=
"text"
class=
"gf-form-input width-20"
ng-model=
"ctrl.searchQuery"
ng-change=
"ctrl.onQueryUpdated()"
placeholder=
"Filter by name or type"
/>
<i
class=
"gf-form-input-icon fa fa-search"
></i>
</label>
<layout-selector
/>
</div>
<div
class=
"page-action-bar__spacer"
></div>
<a
class=
"page-header__cta btn btn-success"
href=
"datasources/new"
>
<i
class=
"fa fa-plus"
></i>
Add data source
</a>
</div>
<section
class=
"card-section"
layout-mode
>
<ol
class=
"card-list"
>
<li
class=
"card-item-wrapper"
ng-repeat=
"ds in ctrl.datasources"
>
<a
class=
"card-item"
href=
"datasources/edit/{{ds.id}}/"
>
<div
class=
"card-item-header"
>
<div
class=
"card-item-type"
>
{{ds.type}}
</div>
</div>
<div
class=
"card-item-body"
>
<figure
class=
"card-item-figure"
>
<img
ng-src=
"{{ds.typeLogoUrl}}"
>
</figure>
<div
class=
"card-item-details"
>
<div
class=
"card-item-name"
>
{{ds.name}}
<span
ng-if=
"ds.isDefault"
>
<span
class=
"btn btn-secondary btn-mini"
>
default
</span>
</span>
</div>
<div
class=
"card-item-sub-name"
>
{{ds.url}}
</div>
</div>
</div>
</a>
</li>
</ol>
</section>
</div>
<div
ng-if=
"ctrl.unfiltered.length === 0"
>
<empty-list-cta
model=
"{
title: 'There are no data sources defined yet',
buttonIcon: 'gicon gicon-add-datasources',
buttonLink: 'datasources/new',
buttonTitle: 'Add data source',
proTip: 'You can also define data sources through configuration files.',
proTipLink: 'http://docs.grafana.org/administration/provisioning/#datasources?utm_source=grafana_ds_list',
proTipLinkTitle: 'Learn more',
proTipTarget: '_blank'
}"
/>
</div>
</div>
public/app/routes/routes.ts
View file @
166f93cf
...
...
@@ -8,6 +8,7 @@ import TeamList from 'app/features/teams/TeamList';
import
PluginListPage
from
'app/features/plugins/PluginListPage'
;
import
FolderSettingsPage
from
'app/features/folders/FolderSettingsPage'
;
import
FolderPermissions
from
'app/features/folders/FolderPermissions'
;
import
DataSourcesListPage
from
'app/features/datasources/DataSourcesListPage'
;
/** @ngInject */
export
function
setupAngularRoutes
(
$routeProvider
,
$locationProvider
)
{
...
...
@@ -62,9 +63,10 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
controllerAs
:
'ctrl'
,
})
.
when
(
'/datasources'
,
{
templateUrl
:
'public/app/features/plugins/partials/ds_list.html'
,
controller
:
'DataSourcesCtrl'
,
controllerAs
:
'ctrl'
,
template
:
'<react-container />'
,
resolve
:
{
component
:
()
=>
DataSourcesListPage
,
},
})
.
when
(
'/datasources/edit/:id'
,
{
templateUrl
:
'public/app/features/plugins/partials/ds_edit.html'
,
...
...
public/app/store/configureStore.ts
View file @
166f93cf
...
...
@@ -7,6 +7,7 @@ import teamsReducers from 'app/features/teams/state/reducers';
import
foldersReducers
from
'app/features/folders/state/reducers'
;
import
dashboardReducers
from
'app/features/dashboard/state/reducers'
;
import
pluginReducers
from
'app/features/plugins/state/reducers'
;
import
dataSourcesReducers
from
'app/features/datasources/state/reducers'
;
const
rootReducer
=
combineReducers
({
...
sharedReducers
,
...
...
@@ -15,6 +16,7 @@ const rootReducer = combineReducers({
...
foldersReducers
,
...
dashboardReducers
,
...
pluginReducers
,
...
dataSourcesReducers
,
});
export
let
store
;
...
...
public/app/types/datasources.ts
View file @
166f93cf
import
{
LayoutMode
}
from
'../core/components/LayoutSelector/LayoutSelector'
;
export
interface
DataSource
{
id
:
number
;
orgId
:
number
;
name
:
string
;
typeLogoUrl
:
string
;
type
:
string
;
access
:
string
;
url
:
string
;
password
:
string
;
user
:
string
;
database
:
string
;
basicAuth
:
false
;
isDefault
:
false
;
jsonData
:
{
authType
:
string
;
defaultRegion
:
string
};
readOnly
:
false
;
}
export
interface
DataSourcesState
{
dataSources
:
DataSource
[];
searchQuery
:
string
;
layoutMode
:
LayoutMode
;
}
public/app/types/index.ts
View file @
166f93cf
...
...
@@ -5,7 +5,7 @@ import { NavModel, NavModelItem, NavIndex } from './navModel';
import
{
FolderDTO
,
FolderState
,
FolderInfo
}
from
'./folders'
;
import
{
DashboardState
}
from
'./dashboard'
;
import
{
DashboardAcl
,
OrgRole
,
PermissionLevel
}
from
'./acl'
;
import
{
DataSource
}
from
'./datasources'
;
import
{
DataSource
,
DataSourcesState
}
from
'./datasources'
;
import
{
PluginMeta
,
Plugin
,
PluginsState
}
from
'./plugins'
;
export
{
...
...
@@ -35,6 +35,7 @@ export {
PluginMeta
,
Plugin
,
PluginsState
,
DataSourcesState
,
};
export
interface
StoreState
{
...
...
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