diff --git a/public/app/features/api-keys/ApiKeysPage.tsx b/public/app/features/api-keys/ApiKeysPage.tsx new file mode 100644 index 00000000000..e0b4da28c40 --- /dev/null +++ b/public/app/features/api-keys/ApiKeysPage.tsx @@ -0,0 +1,94 @@ +import React, { PureComponent } from 'react'; +import { connect } from 'react-redux'; +import { hot } from 'react-hot-loader'; +import { NavModel, ApiKey } from '../../types'; +import { getNavModel } from 'app/core/selectors/navModel'; +// import { getSearchQuery, getTeams, getTeamsCount } from './state/selectors'; +import PageHeader from 'app/core/components/PageHeader/PageHeader'; +import { loadApiKeys, deleteApiKey } from './state/actions'; +import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; + +export interface Props { + navModel: NavModel; + apiKeys: ApiKey[]; + searchQuery: string; + loadApiKeys: typeof loadApiKeys; + deleteApiKey: typeof deleteApiKey; + // loadTeams: typeof loadTeams; + // deleteTeam: typeof deleteTeam; + // setSearchQuery: typeof setSearchQuery; +} + +export class ApiKeysPage extends PureComponent { + componentDidMount() { + this.fetchApiKeys(); + } + + async fetchApiKeys() { + await this.props.loadApiKeys(); + } + + deleteApiKey(id: number) { + return () => { + this.props.deleteApiKey(id); + }; + } + + render() { + const { navModel, apiKeys } = this.props; + + return ( +
+ +
+

Existing Keys

+ + + + + + + + {apiKeys.length > 0 ? ( + + {apiKeys.map(key => { + // id, name, role + return ( + + + + + + ); + })} + + ) : null} +
NameRole +
{key.name}{key.role} + + + +
+
+
+ ); + } +} + +function mapStateToProps(state) { + return { + navModel: getNavModel(state.navIndex, 'apikeys'), + apiKeys: state.apiKeys.keys, + // searchQuery: getSearchQuery(state.teams), + }; +} + +const mapDispatchToProps = { + loadApiKeys, + deleteApiKey, + // loadTeams, + // deleteTeam, + // setSearchQuery, +}; + +export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(ApiKeysPage)); diff --git a/public/app/features/api-keys/state/actions.ts b/public/app/features/api-keys/state/actions.ts new file mode 100644 index 00000000000..494b562b3c9 --- /dev/null +++ b/public/app/features/api-keys/state/actions.ts @@ -0,0 +1,37 @@ +import { ThunkAction } from 'redux-thunk'; +import { getBackendSrv } from 'app/core/services/backend_srv'; +import { StoreState, ApiKey } from 'app/types'; +import { updateNavIndex, UpdateNavIndexAction } from 'app/core/actions'; + +export enum ActionTypes { + LoadApiKeys = 'LOAD_API_KEYS', +} + +export interface LoadApiKeysAction { + type: ActionTypes.LoadApiKeys; + payload: ApiKey[]; +} + +export type Action = LoadApiKeysAction; + +type ThunkResult = ThunkAction; + +const apiKeysLoaded = (apiKeys: ApiKey[]): LoadApiKeysAction => ({ + type: ActionTypes.LoadApiKeys, + payload: apiKeys, +}); + +export function loadApiKeys(): ThunkResult { + return async dispatch => { + const response = await getBackendSrv().get('/api/auth/keys'); + dispatch(apiKeysLoaded(response)); + }; +} + +export function deleteApiKey(id: number): ThunkResult { + return async dispatch => { + getBackendSrv() + .delete('/api/auth/keys/' + id) + .then(dispatch(loadApiKeys())); + }; +} diff --git a/public/app/features/api-keys/state/reducers.ts b/public/app/features/api-keys/state/reducers.ts new file mode 100644 index 00000000000..6d45ccbfa03 --- /dev/null +++ b/public/app/features/api-keys/state/reducers.ts @@ -0,0 +1,16 @@ +import { ApiKeysState } from 'app/types'; +import { Action, ActionTypes } from './actions'; + +export const initialApiKeysState: ApiKeysState = { keys: [] }; + +export const apiKeysReducer = (state = initialApiKeysState, action: Action): ApiKeysState => { + switch (action.type) { + case ActionTypes.LoadApiKeys: + return { ...state, keys: action.payload }; + } + return state; +}; + +export default { + apiKeys: apiKeysReducer, +}; diff --git a/public/app/routes/routes.ts b/public/app/routes/routes.ts index 015b4ae0b51..9b90e374769 100644 --- a/public/app/routes/routes.ts +++ b/public/app/routes/routes.ts @@ -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 ApiKeys from 'app/features/api-keys/ApiKeysPage'; import FolderSettingsPage from 'app/features/folders/FolderSettingsPage'; import FolderPermissions from 'app/features/folders/FolderPermissions'; @@ -141,6 +142,13 @@ export function setupAngularRoutes($routeProvider, $locationProvider) { templateUrl: 'public/app/features/org/partials/orgApiKeys.html', controller: 'OrgApiKeysCtrl', }) + .when('/org/apikeys2', { + template: '', + resolve: { + roles: () => ['Editor', 'Admin'], + component: () => ApiKeys, + }, + }) .when('/org/teams', { template: '', resolve: { diff --git a/public/app/store/configureStore.ts b/public/app/store/configureStore.ts index 8f6cf25043d..3988dad0cd8 100644 --- a/public/app/store/configureStore.ts +++ b/public/app/store/configureStore.ts @@ -4,6 +4,7 @@ import { createLogger } from 'redux-logger'; import sharedReducers from 'app/core/reducers'; import alertingReducers from 'app/features/alerting/state/reducers'; import teamsReducers from 'app/features/teams/state/reducers'; +import apiKeysReducers from 'app/features/api-keys/state/reducers'; import foldersReducers from 'app/features/folders/state/reducers'; import dashboardReducers from 'app/features/dashboard/state/reducers'; @@ -11,6 +12,7 @@ const rootReducer = combineReducers({ ...sharedReducers, ...alertingReducers, ...teamsReducers, + ...apiKeysReducers, ...foldersReducers, ...dashboardReducers, }); diff --git a/public/app/types/apiKeys.ts b/public/app/types/apiKeys.ts new file mode 100644 index 00000000000..56d3e930504 --- /dev/null +++ b/public/app/types/apiKeys.ts @@ -0,0 +1,11 @@ +import { OrgRole } from './acl'; + +export interface ApiKey { + id: number; + name: string; + role: OrgRole; +} + +export interface ApiKeysState { + keys: ApiKey[]; +} diff --git a/public/app/types/index.ts b/public/app/types/index.ts index 778a1b21b55..8c50ea88782 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -7,6 +7,7 @@ import { DashboardState } from './dashboard'; import { DashboardAcl, OrgRole, PermissionLevel } from './acl'; import { DataSource } from './datasources'; import { PluginMeta } from './plugins'; +import { ApiKey, ApiKeysState } from './apiKeys'; export { Team, @@ -33,6 +34,8 @@ export { PermissionLevel, DataSource, PluginMeta, + ApiKey, + ApiKeysState, }; export interface StoreState {