Commit 353a8361 by Johannes Schill

wip: Reactify the api keys page #13411

parent 31b8bf2d
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<Props, any> {
componentDidMount() {
this.fetchApiKeys();
}
async fetchApiKeys() {
await this.props.loadApiKeys();
}
deleteApiKey(id: number) {
return () => {
this.props.deleteApiKey(id);
};
}
render() {
const { navModel, apiKeys } = this.props;
return (
<div>
<PageHeader model={navModel} />
<div className="page-container page-body">
<h3 className="page-heading">Existing Keys</h3>
<table className="filter-table">
<thead>
<tr>
<th>Name</th>
<th>Role</th>
<th style={{ width: '34px' }} />
</tr>
</thead>
{apiKeys.length > 0 ? (
<tbody>
{apiKeys.map(key => {
// id, name, role
return (
<tr key={key.id}>
<td>{key.name}</td>
<td>{key.role}</td>
<td>
<a onClick={this.deleteApiKey(key.id)} className="btn btn-danger btn-mini">
<i className="fa fa-remove" />
</a>
</td>
</tr>
);
})}
</tbody>
) : null}
</table>
</div>
</div>
);
}
}
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));
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<R> = ThunkAction<R, StoreState, undefined, Action | UpdateNavIndexAction>;
const apiKeysLoaded = (apiKeys: ApiKey[]): LoadApiKeysAction => ({
type: ActionTypes.LoadApiKeys,
payload: apiKeys,
});
export function loadApiKeys(): ThunkResult<void> {
return async dispatch => {
const response = await getBackendSrv().get('/api/auth/keys');
dispatch(apiKeysLoaded(response));
};
}
export function deleteApiKey(id: number): ThunkResult<void> {
return async dispatch => {
getBackendSrv()
.delete('/api/auth/keys/' + id)
.then(dispatch(loadApiKeys()));
};
}
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,
};
......@@ -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: '<react-container />',
resolve: {
roles: () => ['Editor', 'Admin'],
component: () => ApiKeys,
},
})
.when('/org/teams', {
template: '<react-container />',
resolve: {
......
......@@ -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,
});
......
import { OrgRole } from './acl';
export interface ApiKey {
id: number;
name: string;
role: OrgRole;
}
export interface ApiKeysState {
keys: ApiKey[];
}
......@@ -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 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment