diff --git a/grafana-plugin/src/components/SourceCode/SourceCode.module.css b/grafana-plugin/src/components/SourceCode/SourceCode.module.scss similarity index 56% rename from grafana-plugin/src/components/SourceCode/SourceCode.module.css rename to grafana-plugin/src/components/SourceCode/SourceCode.module.scss index beabde1e..0b281c05 100644 --- a/grafana-plugin/src/components/SourceCode/SourceCode.module.css +++ b/grafana-plugin/src/components/SourceCode/SourceCode.module.scss @@ -1,29 +1,29 @@ .root { position: relative; width: 100%; + + &:hover .copyButton { + opacity: 1; + } } .scroller { overflow-y: auto; + border-radius: 2px; + padding: 12px 60px 12px 20px; + + &--maxHeight { + max-height: 400px; + } } -.scroller_max-height { - max-height: 400px; -} - -.root .button { +.copyIcon, +.copyButton { position: absolute; top: 15px; right: 15px; - opacity: 0; transition: opacity 0.2s ease; } - -.root:hover .button { - opacity: 1; -} - -.root pre { - border-radius: 2px; - padding: 12px 20px; -} +.copyButton { + opacity: 0; +} \ No newline at end of file diff --git a/grafana-plugin/src/components/SourceCode/SourceCode.tsx b/grafana-plugin/src/components/SourceCode/SourceCode.tsx index 91c3513c..de97190c 100644 --- a/grafana-plugin/src/components/SourceCode/SourceCode.tsx +++ b/grafana-plugin/src/components/SourceCode/SourceCode.tsx @@ -1,41 +1,47 @@ import React, { FC } from 'react'; -import { Button } from '@grafana/ui'; +import { Button, Icon, IconButton } from '@grafana/ui'; import cn from 'classnames/bind'; import CopyToClipboard from 'react-copy-to-clipboard'; import { openNotification } from 'utils'; -import styles from './SourceCode.module.css'; +import styles from './SourceCode.module.scss'; const cx = cn.bind(styles); interface SourceCodeProps { noMaxHeight?: boolean; + showClipboardIconOnly?: boolean; showCopyToClipboard?: boolean; - children?: any + children?: any; } const SourceCode: FC = (props) => { - const { children, noMaxHeight = false, showCopyToClipboard = true } = props; + const { children, noMaxHeight = false, showClipboardIconOnly = false, showCopyToClipboard = true } = props; + const showClipboardCopy = showClipboardIconOnly || showCopyToClipboard; return (
- {showCopyToClipboard && ( + {showClipboardCopy && ( { openNotification('Copied!'); }} > - + {showClipboardIconOnly ? ( + + ) : ( + + )} )}
         {children}
diff --git a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.module.css b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.module.css
new file mode 100644
index 00000000..d8058bec
--- /dev/null
+++ b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.module.css
@@ -0,0 +1,16 @@
+.token__inputContainer {
+  width: 100%;
+  display: flex;
+  margin-bottom: 24px;
+}
+
+.token__input {
+  flex-grow: 1;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+.token__copyButton {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
diff --git a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx
index 8de6d269..5457d4f6 100644
--- a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx
+++ b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx
@@ -1,13 +1,20 @@
 import React, { useCallback, HTMLAttributes, useState } from 'react';
 
-import { Button, Field, HorizontalGroup, Input, Modal, VerticalGroup } from '@grafana/ui';
+import { Button, HorizontalGroup, Input, Label, Modal, VerticalGroup } from '@grafana/ui';
+import cn from 'classnames/bind';
 import { get } from 'lodash-es';
 import { observer } from 'mobx-react';
 import CopyToClipboard from 'react-copy-to-clipboard';
 
+import SourceCode from 'components/SourceCode/SourceCode';
 import { ApiToken } from 'models/api_token/api_token.types';
 import { useStore } from 'state/useStore';
 import { openErrorNotification, openNotification } from 'utils';
+import { getItem } from 'utils/localStorage';
+
+import styles from './ApiTokenForm.module.css';
+
+const cx = cn.bind(styles);
 
 interface TokenCreationModalProps extends HTMLAttributes {
   visible: boolean;
@@ -16,7 +23,7 @@ interface TokenCreationModalProps extends HTMLAttributes {
 }
 
 const ApiTokenForm = observer((props: TokenCreationModalProps) => {
-  const { visible, onHide = () => {}, onUpdate = () => {} } = props;
+  const { onHide = () => {}, onUpdate = () => {} } = props;
   const [name, setName] = useState('');
   const [token, setToken] = useState('');
 
@@ -39,30 +46,68 @@ const ApiTokenForm = observer((props: TokenCreationModalProps) => {
   return (
     
       
-        
-        {token && (
-          <>
-            
-          
-        )}
-        
-          {token && (
-             {
-                openNotification('Token copied');
-              }}
-            >
-              
-            
-          )}
-          
+          {!token && (
+            
+          )}
         
       
     
   );
+
+  function renderTokenInput() {
+    return token ? (
+      
+    ) : (
+      
+    );
+  }
+
+  function renderCopyToClipboard() {
+    if (!token) {
+      return null;
+    }
+    return (
+       openNotification('Token copied')}>
+        
+      
+    );
+  }
+
+  function renderCurlExample() {
+    if (!token) {
+      return null;
+    }
+    return (
+      
+        
+        {getCurlExample(token)}
+      
+    );
+  }
 });
 
+function getCurlExample(token) {
+  return `curl -H "Authorization: ${token}" ${getItem('onCallApiUrl')}/api/internal/v1/alert_receive_channels`;
+}
+
 export default ApiTokenForm;
diff --git a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx
index 71e85426..f9a9f0bb 100644
--- a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx
+++ b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx
@@ -48,8 +48,6 @@ class ApiTokens extends React.Component {
 
     const apiTokens = apiTokenStore.getSearchResult();
 
-    const loading = !apiTokens;
-
     const { showCreateTokenModal } = this.state;
 
     const columns = [