From c7fb6916b9292420a1589c595be1e184e0a0699b Mon Sep 17 00:00:00 2001 From: Johannes Schill Date: Thu, 27 Sep 2018 11:26:47 +0200 Subject: [PATCH] Open modal with API key information after key is added #13411 --- .../api-keys/ApiKeysAddedModal.test.tsx | 25 ++++++ .../features/api-keys/ApiKeysAddedModal.tsx | 46 +++++++++++ public/app/features/api-keys/ApiKeysPage.tsx | 17 +++- .../ApiKeysAddedModal.test.tsx.snap | 78 +++++++++++++++++++ public/app/features/api-keys/state/actions.ts | 6 +- 5 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 public/app/features/api-keys/ApiKeysAddedModal.test.tsx create mode 100644 public/app/features/api-keys/ApiKeysAddedModal.tsx create mode 100644 public/app/features/api-keys/__snapshots__/ApiKeysAddedModal.test.tsx.snap diff --git a/public/app/features/api-keys/ApiKeysAddedModal.test.tsx b/public/app/features/api-keys/ApiKeysAddedModal.test.tsx new file mode 100644 index 00000000000..160418a7ab8 --- /dev/null +++ b/public/app/features/api-keys/ApiKeysAddedModal.test.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { ApiKeysAddedModal, Props } from './ApiKeysAddedModal'; + +const setup = (propOverrides?: object) => { + const props: Props = { + apiKey: 'api key test', + rootPath: 'test/path', + }; + + Object.assign(props, propOverrides); + + const wrapper = shallow(); + + return { + wrapper, + }; +}; + +describe('Render', () => { + it('should render component', () => { + const { wrapper } = setup(); + expect(wrapper).toMatchSnapshot(); + }); +}); diff --git a/public/app/features/api-keys/ApiKeysAddedModal.tsx b/public/app/features/api-keys/ApiKeysAddedModal.tsx new file mode 100644 index 00000000000..995aa46c773 --- /dev/null +++ b/public/app/features/api-keys/ApiKeysAddedModal.tsx @@ -0,0 +1,46 @@ +import React from 'react'; + +export interface Props { + apiKey: string; + rootPath: string; +} + +export const ApiKeysAddedModal = (props: Props) => { + return ( +
+
+

+ + API Key Created +

+ + + + +
+ +
+
+
+ Key + {props.apiKey} +
+
+ +
+ You will only be able to view this key here once! It is not stored in this form. So be sure to copy it now. +
+
+ You can authenticate request using the Authorization HTTP header, example: +
+
+
+            curl -H "Authorization: Bearer {props.apiKey}" {props.rootPath}/api/dashboards/home
+          
+
+
+
+ ); +}; + +export default ApiKeysAddedModal; diff --git a/public/app/features/api-keys/ApiKeysPage.tsx b/public/app/features/api-keys/ApiKeysPage.tsx index 3225fd7d2b5..2f19250e835 100644 --- a/public/app/features/api-keys/ApiKeysPage.tsx +++ b/public/app/features/api-keys/ApiKeysPage.tsx @@ -1,13 +1,16 @@ 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 { loadApiKeys, deleteApiKey, setSearchQuery, addApiKey } from './state/actions'; -// import { getSearchQuery, getTeams, getTeamsCount } from './state/selectors'; import PageHeader from 'app/core/components/PageHeader/PageHeader'; import SlideDown from 'app/core/components/Animations/SlideDown'; +import ApiKeysAddedModal from './ApiKeysAddedModal'; +import config from 'app/core/config'; +import appEvents from 'app/core/app_events'; export interface Props { navModel: NavModel; @@ -62,7 +65,17 @@ export class ApiKeysPage extends PureComponent { onAddApiKey = async evt => { evt.preventDefault(); - this.props.addApiKey(this.state.newApiKey); + + const openModal = (apiKey: string) => { + const rootPath = window.location.origin + config.appSubUrl; + const modalTemplate = ReactDOMServer.renderToString(); + + appEvents.emit('show-modal', { + templateHtml: modalTemplate, + }); + }; + + this.props.addApiKey(this.state.newApiKey, openModal); this.setState((prevState: State) => { return { ...prevState, diff --git a/public/app/features/api-keys/__snapshots__/ApiKeysAddedModal.test.tsx.snap b/public/app/features/api-keys/__snapshots__/ApiKeysAddedModal.test.tsx.snap new file mode 100644 index 00000000000..0fcb13308eb --- /dev/null +++ b/public/app/features/api-keys/__snapshots__/ApiKeysAddedModal.test.tsx.snap @@ -0,0 +1,78 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Render should render component 1`] = ` +
+
+

+ + + API Key Created + +

+ + + +
+
+
+
+ + Key + + + api key test + +
+
+
+ You will only be able to view this key here once! It is not stored in this form. So be sure to copy it now. +
+
+ You can authenticate request using the Authorization HTTP header, example: +
+
+
+        curl -H "Authorization: Bearer 
+        api key test
+        " 
+        test/path
+        /api/dashboards/home
+      
+
+
+
+`; diff --git a/public/app/features/api-keys/state/actions.ts b/public/app/features/api-keys/state/actions.ts index 934852e1b19..63e91088476 100644 --- a/public/app/features/api-keys/state/actions.ts +++ b/public/app/features/api-keys/state/actions.ts @@ -26,10 +26,12 @@ const apiKeysLoaded = (apiKeys: ApiKey[]): LoadApiKeysAction => ({ payload: apiKeys, }); -export function addApiKey(apiKey: ApiKey): ThunkResult { +export function addApiKey(apiKey: ApiKey, openModal: (key: string) => void): ThunkResult { return async dispatch => { - await getBackendSrv().post('/api/auth/keys', apiKey); + const result = await getBackendSrv().post('/api/auth/keys', apiKey); + dispatch(setSearchQuery('')); dispatch(loadApiKeys()); + openModal(result.key); }; }