瀏覽代碼

Show CTA if there are no ApiKeys, otherwise show table.

Carlos Mondragon 7 年之前
父節點
當前提交
d2573a6bc8
共有 1 個文件被更改,包括 127 次插入104 次删除
  1. 127 104
      public/app/features/api-keys/ApiKeysPage.tsx

+ 127 - 104
public/app/features/api-keys/ApiKeysPage.tsx

@@ -1,10 +1,10 @@
-import React, { PureComponent } from 'react';
+import React, { PureComponent } from 'react';
 import ReactDOMServer from 'react-dom/server';
 import { connect } from 'react-redux';
 import { hot } from 'react-hot-loader';
 import { NavModel, ApiKey, NewApiKey, OrgRole } from 'app/types';
 import { getNavModel } from 'app/core/selectors/navModel';
-import { getApiKeys } from './state/selectors';
+import { getApiKeys, getApiKeysCount } from './state/selectors';
 import { loadApiKeys, deleteApiKey, setSearchQuery, addApiKey } from './state/actions';
 import PageHeader from 'app/core/components/PageHeader/PageHeader';
 import SlideDown from 'app/core/components/Animations/SlideDown';
@@ -12,6 +12,7 @@ import PageLoader from 'app/core/components/PageLoader/PageLoader';
 import ApiKeysAddedModal from './ApiKeysAddedModal';
 import config from 'app/core/config';
 import appEvents from 'app/core/app_events';
+import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
 
 export interface Props {
   navModel: NavModel;
@@ -22,6 +23,7 @@ export interface Props {
   deleteApiKey: typeof deleteApiKey;
   setSearchQuery: typeof setSearchQuery;
   addApiKey: typeof addApiKey;
+  apiKeysCount: number;
 }
 
 export interface State {
@@ -101,115 +103,135 @@ export class ApiKeysPage extends PureComponent<Props, any> {
     });
   };
 
-  renderTable() {
-    const { apiKeys } = this.props;
-
-    return [
-      <h3 key="header" className="page-heading">
-        Existing Keys
-      </h3>,
-      <table key="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 => {
-              return (
-                <tr key={key.id}>
-                  <td>{key.name}</td>
-                  <td>{key.role}</td>
-                  <td>
-                    <a onClick={() => this.onDeleteApiKey(key)} className="btn btn-danger btn-mini">
-                      <i className="fa fa-remove" />
-                    </a>
-                  </td>
-                </tr>
-              );
-            })}
-          </tbody>
-        )}
-      </table>,
-    ];
+  renderEmptyList() {
+    return (
+      <div className="page-container page-body">
+        <EmptyListCTA
+          model={{
+            title: "You haven't added any API Keys yet.",
+            buttonIcon: 'fa fa-plus',
+            buttonLink: 'org/apikeys/new',
+            buttonTitle: ' New API Key',
+            proTip: 'Assign folder and dashboard permissions to teams instead of users to ease administration.',
+            proTipLink: '',
+            proTipLinkTitle: '',
+            proTipTarget: '_blank',
+          }}
+        />
+      </div>
+    );
   }
 
-  render() {
+  renderApiKeyList() {
     const { newApiKey, isAdding } = this.state;
-    const { hasFetched, navModel, searchQuery } = this.props;
+    const { apiKeys, searchQuery } = this.props;
 
     return (
-      <div>
-        <PageHeader model={navModel} />
-        <div className="page-container page-body">
-          <div className="page-action-bar">
-            <div className="gf-form gf-form--grow">
-              <label className="gf-form--has-input-icon gf-form--grow">
-                <input
-                  type="text"
-                  className="gf-form-input"
-                  placeholder="Search keys"
-                  value={searchQuery}
-                  onChange={this.onSearchQueryChange}
-                />
-                <i className="gf-form-input-icon fa fa-search" />
-              </label>
-            </div>
-
-            <div className="page-action-bar__spacer" />
-            <button className="btn btn-success pull-right" onClick={this.onToggleAdding} disabled={isAdding}>
-              <i className="fa fa-plus" /> Add API Key
-            </button>
+      <div className="page-container page-body">
+        <div className="page-action-bar">
+          <div className="gf-form gf-form--grow">
+            <label className="gf-form--has-input-icon gf-form--grow">
+              <input
+                type="text"
+                className="gf-form-input"
+                placeholder="Search keys"
+                value={searchQuery}
+                onChange={this.onSearchQueryChange}
+              />
+              <i className="gf-form-input-icon fa fa-search" />
+            </label>
           </div>
 
-          <SlideDown in={isAdding}>
-            <div className="cta-form">
-              <button className="cta-form__close btn btn-transparent" onClick={this.onToggleAdding}>
-                <i className="fa fa-close" />
-              </button>
-              <h5>Add API Key</h5>
-              <form className="gf-form-group" onSubmit={this.onAddApiKey}>
-                <div className="gf-form-inline">
-                  <div className="gf-form max-width-21">
-                    <span className="gf-form-label">Key name</span>
-                    <input
-                      type="text"
-                      className="gf-form-input"
-                      value={newApiKey.name}
-                      placeholder="Name"
-                      onChange={evt => this.onApiKeyStateUpdate(evt, ApiKeyStateProps.Name)}
-                    />
-                  </div>
-                  <div className="gf-form">
-                    <span className="gf-form-label">Role</span>
-                    <span className="gf-form-select-wrapper">
-                      <select
-                        className="gf-form-input gf-size-auto"
-                        value={newApiKey.role}
-                        onChange={evt => this.onApiKeyStateUpdate(evt, ApiKeyStateProps.Role)}
-                      >
-                        {Object.keys(OrgRole).map(role => {
-                          return (
-                            <option key={role} label={role} value={role}>
-                              {role}
-                            </option>
-                          );
-                        })}
-                      </select>
-                    </span>
-                  </div>
-                  <div className="gf-form">
-                    <button className="btn gf-form-btn btn-success">Add</button>
-                  </div>
-                </div>
-              </form>
-            </div>
-          </SlideDown>
-          {hasFetched ? this.renderTable() : <PageLoader pageName="Api keys" />}
+          <div className="page-action-bar__spacer" />
+          <button className="btn btn-success pull-right" onClick={this.onToggleAdding} disabled={isAdding}>
+            <i className="fa fa-plus" /> Add API Key
+          </button>
         </div>
+
+        <SlideDown in={isAdding}>
+          <div className="cta-form">
+            <button className="cta-form__close btn btn-transparent" onClick={this.onToggleAdding}>
+              <i className="fa fa-close" />
+            </button>
+            <h5>Add API Key</h5>
+            <form className="gf-form-group" onSubmit={this.onAddApiKey}>
+              <div className="gf-form-inline">
+                <div className="gf-form max-width-21">
+                  <span className="gf-form-label">Key name</span>
+                  <input
+                    type="text"
+                    className="gf-form-input"
+                    value={newApiKey.name}
+                    placeholder="Name"
+                    onChange={evt => this.onApiKeyStateUpdate(evt, ApiKeyStateProps.Name)}
+                  />
+                </div>
+                <div className="gf-form">
+                  <span className="gf-form-label">Role</span>
+                  <span className="gf-form-select-wrapper">
+                    <select
+                      className="gf-form-input gf-size-auto"
+                      value={newApiKey.role}
+                      onChange={evt => this.onApiKeyStateUpdate(evt, ApiKeyStateProps.Role)}
+                    >
+                      {Object.keys(OrgRole).map(role => {
+                        return (
+                          <option key={role} label={role} value={role}>
+                            {role}
+                          </option>
+                        );
+                      })}
+                    </select>
+                  </span>
+                </div>
+                <div className="gf-form">
+                  <button className="btn gf-form-btn btn-success">Add</button>
+                </div>
+              </div>
+            </form>
+          </div>
+        </SlideDown>
+
+        <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 => {
+                return (
+                  <tr key={key.id}>
+                    <td>{key.name}</td>
+                    <td>{key.role}</td>
+                    <td>
+                      <a onClick={() => this.onDeleteApiKey(key)} className="btn btn-danger btn-mini">
+                        <i className="fa fa-remove" />
+                      </a>
+                    </td>
+                  </tr>
+                );
+              })}
+            </tbody>
+          ) : null}
+        </table>
+      </div>
+    );
+  }
+
+  render() {
+    const { hasFetched, navModel, apiKeysCount } = this.props;
+
+    return (
+      <div>
+        <PageHeader model={navModel} />
+        {hasFetched ?
+          (apiKeysCount > 0 ? this.renderApiKeyList() : this.renderEmptyList())
+        : <PageLoader pageName="Api keys" />}
       </div>
     );
   }
@@ -220,7 +242,8 @@ function mapStateToProps(state) {
     navModel: getNavModel(state.navIndex, 'apikeys'),
     apiKeys: getApiKeys(state.apiKeys),
     searchQuery: state.apiKeys.searchQuery,
-    hasFetched: state.apiKeys.hasFetched,
+    apiKeysCount: getApiKeysCount(state.apiKeys),
+    hasFetched: state.apiKeys.hasFetched
   };
 }