Explorar el Código

wip: Reactify the api keys page #13411

Johannes Schill hace 7 años
padre
commit
353a836128

+ 94 - 0
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<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));

+ 37 - 0
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<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()));
+  };
+}

+ 16 - 0
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,
+};

+ 8 - 0
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: '<react-container />',
+      resolve: {
+        roles: () => ['Editor', 'Admin'],
+        component: () => ApiKeys,
+      },
+    })
     .when('/org/teams', {
       template: '<react-container />',
       resolve: {

+ 2 - 0
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,
 });

+ 11 - 0
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[];
+}

+ 3 - 0
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 {