diff --git a/grafana-plugin/src/GrafanaPluginRootPage.tsx b/grafana-plugin/src/GrafanaPluginRootPage.tsx index aacc6f44..81c3c573 100644 --- a/grafana-plugin/src/GrafanaPluginRootPage.tsx +++ b/grafana-plugin/src/GrafanaPluginRootPage.tsx @@ -118,6 +118,7 @@ export const Root = observer((props: AppRootProps) => { meta, grafanaUser: window.grafanaBootData.user, enableLiveSettings: store.hasFeature(AppFeature.LiveSettings), + enableCloudPage: store.hasFeature(AppFeature.CloudConnection), }), [meta, pathWithoutLeadingSlash, page, store.features] ) diff --git a/grafana-plugin/src/containers/UserSettings/parts/index.tsx b/grafana-plugin/src/containers/UserSettings/parts/index.tsx index 62f14daf..7cbb0f4b 100644 --- a/grafana-plugin/src/containers/UserSettings/parts/index.tsx +++ b/grafana-plugin/src/containers/UserSettings/parts/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useEffect } from 'react'; import { Tab, TabContent, TabsBar } from '@grafana/ui'; import cn from 'classnames/bind'; @@ -105,6 +105,9 @@ interface TabsContentProps { export const TabsContent = observer((props: TabsContentProps) => { const { id, activeTab, onTabChange, isDesktopOrLaptop } = props; + useEffect(() => { + store.updateFeatures(); + }, []); const store = useStore(); const { userStore } = store; diff --git a/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx b/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx index 07544bea..4a9d6f20 100644 --- a/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx +++ b/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx @@ -22,8 +22,10 @@ import PluginLink from 'components/PluginLink/PluginLink'; import Text from 'components/Text/Text'; import WithConfirm from 'components/WithConfirm/WithConfirm'; import { User as UserType } from 'models/user/user.types'; +import { AppFeature } from 'state/features'; import { WithStoreProps } from 'state/types'; import { useStore } from 'state/useStore'; +import { UserAction } from 'state/userAction'; import { withMobXProviderContext } from 'state/withStore'; import styles from './CloudPhoneSettings.module.css'; @@ -34,8 +36,7 @@ interface CloudPhoneSettingsProps extends WithStoreProps {} const CloudPhoneSettings = observer((props: CloudPhoneSettingsProps) => { const store = useStore(); - const [isAccountMatched, setIsAccountMatched] = useState(true); - const [isPhoneVerified, setIsPhoneVerified] = useState(true); + const [syncing, setSyncing] = useState(false); const [userStatus, setUserStatus] = useState(0); const [userLink, setUserLink] = useState(null); @@ -47,8 +48,10 @@ const CloudPhoneSettings = observer((props: CloudPhoneSettingsProps) => { getLocationSrv().update({ partial: false, path: link }); }; - const syncUser = () => { - store.cloudStore.syncCloudUser(store.userStore.currentUserPk); + const syncUser = async () => { + setSyncing(true); + await store.cloudStore.syncCloudUser(store.userStore.currentUserPk); + setSyncing(false); }; const getCloudUserInfo = async () => { @@ -60,6 +63,18 @@ const CloudPhoneSettings = observer((props: CloudPhoneSettingsProps) => { const UserCloudStatus = () => { switch (userStatus) { case 0: + if (store.hasFeature(AppFeature.CloudNotifications)) { + return ( + + Your account successfully matched, but Cloud is not connected. + + + + + ); + } return ( Grafana Cloud is not synced @@ -117,15 +132,30 @@ const CloudPhoneSettings = observer((props: CloudPhoneSettingsProps) => { }; return ( - - - OnCall use Grafana Cloud for SMS and phone call notifications - - - {userStatus ? : } - + <> + {store.isUserActionAllowed(UserAction.UpdateOtherUsersSettings) ? ( + + + OnCall use Grafana Cloud for SMS and phone call notifications + {syncing ? ( + + ) : ( + + )} + + {!syncing ? : } + + ) : ( + + OnCall use Grafana Cloud for SMS and phone call notifications + You do not have permission to perform this action. Ask an admin to upgrade your permissions. + + )} + ); }); diff --git a/grafana-plugin/src/pages/cloud/CloudPage.tsx b/grafana-plugin/src/pages/cloud/CloudPage.tsx index 804c7863..c02cf162 100644 --- a/grafana-plugin/src/pages/cloud/CloudPage.tsx +++ b/grafana-plugin/src/pages/cloud/CloudPage.tsx @@ -52,8 +52,9 @@ const CloudPage = observer((props: CloudPageProps) => { setCloudIsConnected(cloudStatus.cloud_connection_status); setHeartbitStatus(cloudStatus.cloud_heartbeat_enabled); setHeartbitLink(cloudStatus.cloud_heartbeat_link); + getApiKeyFromGlobalSettings(); }); - }, []); + }, [cloudIsConnected]); const { count, results } = store.cloudStore.getSearchResult(); @@ -76,6 +77,12 @@ const CloudPage = observer((props: CloudPageProps) => { store.cloudStore.disconnectToCloud(); }; + const getApiKeyFromGlobalSettings = async () => { + const globalSettingItem = await store.globalSettingStore.getGlobalSettingItemByName('GRAFANA_CLOUD_ONCALL_TOKEN'); + if (cloudIsConnected === false) { + setCloudApiKey(globalSettingItem?.value); + } + }; const connectToCloud = async () => { setShowConfirmationModal(false); const globalSettingItem = await store.globalSettingStore.getGlobalSettingItemByName('GRAFANA_CLOUD_ONCALL_TOKEN'); @@ -260,7 +267,7 @@ const CloudPage = observer((props: CloudPageProps) => {
{ - 'Ask your users to sign up in Grafana Cloud, verify phone number and feel free to set up SMS & phone call notificaitons in personal settings!' + 'Ask your users to sign up in Grafana Cloud, verify phone number and feel free to set up SMS & phone call notificaitons in personal settings! Only users with Admin or Editor role will be synced.' } @@ -317,7 +324,7 @@ const CloudPage = observer((props: CloudPageProps) => { style={{ width: '100%' }} invalid={apiKeyError} > - +