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
e8cc0f3f
Commit
e8cc0f3f
authored
Sep 25, 2018
by
Peter Holmberg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
render list
parent
8009bc39
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
214 additions
and
4 deletions
+214
-4
public/app/features/plugins/PluginActionBar.tsx
+24
-0
public/app/features/plugins/PluginList.tsx
+21
-0
public/app/features/plugins/PluginListItem.tsx
+30
-0
public/app/features/plugins/PluginListPage.tsx
+53
-0
public/app/features/plugins/state/actions.ts
+28
-0
public/app/features/plugins/state/reducers.ts
+16
-0
public/app/features/plugins/state/selectors.ts
+1
-0
public/app/routes/routes.ts
+5
-3
public/app/store/configureStore.ts
+2
-0
public/app/types/index.ts
+4
-1
public/app/types/plugins.ts
+30
-0
No files found.
public/app/features/plugins/PluginActionBar.tsx
0 → 100644
View file @
e8cc0f3f
import
React
from
'react'
;
export
default
function
({
searchQuery
,
onQueryChange
})
{
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=
{
onQueryChange
}
placeholder=
"Filter by name or type"
/>
<
i
className=
"gf-form-input-icon fa fa-search"
/>
</
label
>
</
div
>
<
div
className=
"page-action-bar__spacer"
/>
<
a
className=
"btn btn-success"
href=
"https://grafana.com/plugins?utm_source=grafana_plugin_list"
target=
"_blank"
>
Find more plugins on Grafana.com
</
a
>
</
div
>
);
}
public/app/features/plugins/PluginList.tsx
0 → 100644
View file @
e8cc0f3f
import
React
from
'react'
;
import
classNames
from
'classnames/bind'
;
import
PluginListItem
from
'./PluginListItem'
;
export
default
function
PluginList
({
plugins
,
layout
})
{
const
listStyle
=
classNames
({
'card-section'
:
true
,
'card-list-layout-grid'
:
layout
===
'grid'
,
'card-list-layout-list'
:
layout
===
'list'
,
});
return
(
<
section
className=
{
listStyle
}
>
<
ol
className=
"card-list"
>
{
plugins
.
map
((
plugin
,
index
)
=>
{
return
<
PluginListItem
plugin=
{
plugin
}
key=
{
`${plugin.name}-${index}`
}
/>;
})
}
</
ol
>
</
section
>
);
}
public/app/features/plugins/PluginListItem.tsx
0 → 100644
View file @
e8cc0f3f
import
React
from
'react'
;
export
default
function
PluginListItem
({
plugin
})
{
return
(
<
li
className=
"card-item-wrapper"
>
<
a
className=
"card-item"
href=
{
`plugins/${plugin.id}/edit`
}
>
<
div
className=
"card-item-header"
>
<
div
className=
"card-item-type"
>
<
i
className=
{
`icon-gf icon-gf-${plugin.type}`
}
/>
{
plugin
.
type
}
</
div
>
{
plugin
.
hasUpdate
&&
(
<
div
className=
"card-item-notice"
>
<
span
bs
-
tooltip=
"plugin.latestVersion"
>
Update available!
</
span
>
</
div
>
)
}
</
div
>
<
div
className=
"card-item-body"
>
<
figure
className=
"card-item-figure"
>
<
img
src=
{
plugin
.
info
.
logos
.
small
}
/>
</
figure
>
<
div
className=
"card-item-details"
>
<
div
className=
"card-item-name"
>
{
plugin
.
name
}
</
div
>
<
div
className=
"card-item-sub-name"
>
{
`By ${plugin.info.author.name}`
}
</
div
>
</
div
>
</
div
>
</
a
>
</
li
>
);
}
public/app/features/plugins/PluginListPage.tsx
0 → 100644
View file @
e8cc0f3f
import
React
,
{
PureComponent
}
from
'react'
;
import
{
hot
}
from
'react-hot-loader'
;
import
{
connect
}
from
'react-redux'
;
import
PageHeader
from
'../../core/components/PageHeader/PageHeader'
;
import
PluginActionBar
from
'./PluginActionBar'
;
import
PluginList
from
'./PluginList'
;
import
{
NavModel
,
Plugin
}
from
'../../types'
;
import
{
loadPlugins
}
from
'./state/actions'
;
import
{
getNavModel
}
from
'../../core/selectors/navModel'
;
import
{
getPlugins
}
from
'./state/selectors'
;
interface
Props
{
navModel
:
NavModel
;
plugins
:
Plugin
[];
loadPlugins
:
typeof
loadPlugins
;
}
export
class
PluginListPage
extends
PureComponent
<
Props
>
{
componentDidMount
()
{
this
.
fetchPlugins
();
}
async
fetchPlugins
()
{
await
this
.
props
.
loadPlugins
();
}
render
()
{
const
{
navModel
,
plugins
}
=
this
.
props
;
return
(
<
div
>
<
PageHeader
model=
{
navModel
}
/>
<
div
className=
"page-container page-body"
>
<
PluginActionBar
searchQuery=
""
onQueryChange=
{
()
=>
{}
}
/>
{
plugins
&&
<
PluginList
plugins=
{
plugins
}
layout=
"grid"
/>
}
</
div
>
</
div
>
);
}
}
function
mapStateToProps
(
state
)
{
return
{
navModel
:
getNavModel
(
state
.
navIndex
,
'plugins'
),
plugins
:
getPlugins
(
state
.
plugins
),
};
}
const
mapDispatchToProps
=
{
loadPlugins
,
};
export
default
hot
(
module
)(
connect
(
mapStateToProps
,
mapDispatchToProps
)(
PluginListPage
));
public/app/features/plugins/state/actions.ts
0 → 100644
View file @
e8cc0f3f
import
{
Plugin
,
StoreState
}
from
'app/types'
;
import
{
ThunkAction
}
from
'redux-thunk'
;
import
{
getBackendSrv
}
from
'../../../core/services/backend_srv'
;
export
enum
ActionTypes
{
LoadPlugins
=
'LOAD_PLUGINS'
,
}
export
interface
LoadPluginsAction
{
type
:
ActionTypes
.
LoadPlugins
;
payload
:
Plugin
[];
}
export
const
pluginsLoaded
=
(
plugins
:
Plugin
[]):
LoadPluginsAction
=>
({
type
:
ActionTypes
.
LoadPlugins
,
payload
:
plugins
,
});
export
type
Action
=
LoadPluginsAction
;
type
ThunkResult
<
R
>
=
ThunkAction
<
R
,
StoreState
,
undefined
,
Action
>
;
export
function
loadPlugins
():
ThunkResult
<
void
>
{
return
async
dispatch
=>
{
const
result
=
await
getBackendSrv
().
get
(
'api/plugins'
,
{
embedded
:
0
});
dispatch
(
pluginsLoaded
(
result
));
};
}
public/app/features/plugins/state/reducers.ts
0 → 100644
View file @
e8cc0f3f
import
{
Action
,
ActionTypes
}
from
'./actions'
;
import
{
Plugin
,
PluginsState
}
from
'app/types'
;
export
const
initialState
:
PluginsState
=
{
plugins
:
[]
as
Plugin
[]
};
export
const
pluginsReducer
=
(
state
=
initialState
,
action
:
Action
):
PluginsState
=>
{
switch
(
action
.
type
)
{
case
ActionTypes
.
LoadPlugins
:
return
{
...
state
,
plugins
:
action
.
payload
};
}
return
state
;
};
export
default
{
plugins
:
pluginsReducer
,
};
public/app/features/plugins/state/selectors.ts
0 → 100644
View file @
e8cc0f3f
export
const
getPlugins
=
state
=>
state
.
plugins
;
public/app/routes/routes.ts
View file @
e8cc0f3f
...
...
@@ -5,6 +5,7 @@ import ServerStats from 'app/features/admin/ServerStats';
import
AlertRuleList
from
'app/features/alerting/AlertRuleList'
;
import
TeamPages
from
'app/features/teams/TeamPages'
;
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'
;
...
...
@@ -245,9 +246,10 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
controllerAs
:
'ctrl'
,
})
.
when
(
'/plugins'
,
{
templateUrl
:
'public/app/features/plugins/partials/plugin_list.html'
,
controller
:
'PluginListCtrl'
,
controllerAs
:
'ctrl'
,
template
:
'<react-container />'
,
resolve
:
{
component
:
()
=>
PluginListPage
,
},
})
.
when
(
'/plugins/:pluginId/edit'
,
{
templateUrl
:
'public/app/features/plugins/partials/plugin_edit.html'
,
...
...
public/app/store/configureStore.ts
View file @
e8cc0f3f
...
...
@@ -6,6 +6,7 @@ import alertingReducers from 'app/features/alerting/state/reducers';
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'
;
const
rootReducer
=
combineReducers
({
...
sharedReducers
,
...
...
@@ -13,6 +14,7 @@ const rootReducer = combineReducers({
...
teamsReducers
,
...
foldersReducers
,
...
dashboardReducers
,
...
pluginReducers
,
});
export
let
store
;
...
...
public/app/types/index.ts
View file @
e8cc0f3f
...
...
@@ -6,7 +6,7 @@ import { FolderDTO, FolderState, FolderInfo } from './folders';
import
{
DashboardState
}
from
'./dashboard'
;
import
{
DashboardAcl
,
OrgRole
,
PermissionLevel
}
from
'./acl'
;
import
{
DataSource
}
from
'./datasources'
;
import
{
PluginMeta
}
from
'./plugins'
;
import
{
PluginMeta
,
Plugin
,
PluginInfo
,
PluginsState
}
from
'./plugins'
;
export
{
Team
,
...
...
@@ -33,6 +33,9 @@ export {
PermissionLevel
,
DataSource
,
PluginMeta
,
PluginInfo
,
Plugin
,
PluginsState
,
};
export
interface
StoreState
{
...
...
public/app/types/plugins.ts
View file @
e8cc0f3f
...
...
@@ -17,3 +17,33 @@ export interface PluginMetaInfo {
small
:
string
;
};
}
export
interface
PluginInfo
{
author
:
{
name
:
string
;
url
:
string
;
};
description
:
string
;
links
:
string
[];
logos
:
{
small
:
string
;
large
:
string
};
screenshots
:
string
;
updated
:
string
;
version
:
string
;
}
export
interface
Plugin
{
defaultNavUrl
:
string
;
enabled
:
boolean
;
hasUpdate
:
boolean
;
id
:
string
;
info
:
PluginInfo
;
latestVersion
:
string
;
name
:
string
;
pinned
:
boolean
;
state
:
string
;
type
:
string
;
}
export
interface
PluginsState
{
plugins
:
Plugin
[];
}
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