Chnages regarding env variables and Viewer role

This commit is contained in:
Yulia Shanyrova 2022-06-08 16:09:34 +02:00
parent e277534f32
commit fc53cd014e
8 changed files with 65 additions and 27 deletions

View file

@ -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]
)

View file

@ -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;

View file

@ -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<boolean>(true);
const [isPhoneVerified, setIsPhoneVerified] = useState<boolean>(true);
const [syncing, setSyncing] = useState<boolean>(false);
const [userStatus, setUserStatus] = useState<number>(0);
const [userLink, setUserLink] = useState<string>(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 (
<VerticalGroup spacing="lg">
<Text>Your account successfully matched, but Cloud is not connected. </Text>
<PluginLink query={{ page: 'cloud' }}>
<Button variant="secondary" icon="external-link-alt">
Open Grafana Cloud page
</Button>
</PluginLink>
</VerticalGroup>
);
}
return (
<VerticalGroup spacing="lg">
<Text>Grafana Cloud is not synced</Text>
@ -117,15 +132,30 @@ const CloudPhoneSettings = observer((props: CloudPhoneSettingsProps) => {
};
return (
<VerticalGroup spacing="lg">
<HorizontalGroup justify="space-between">
<Text.Title level={3}>OnCall use Grafana Cloud for SMS and phone call notifications</Text.Title>
<Button variant="secondary" icon="sync" onClick={syncUser}>
Update
</Button>
</HorizontalGroup>
{userStatus ? <UserCloudStatus /> : <LoadingPlaceholder text="Loading..." />}
</VerticalGroup>
<>
{store.isUserActionAllowed(UserAction.UpdateOtherUsersSettings) ? (
<VerticalGroup spacing="lg">
<HorizontalGroup justify="space-between">
<Text.Title level={3}>OnCall use Grafana Cloud for SMS and phone call notifications</Text.Title>
{syncing ? (
<Button variant="secondary" icon="sync" disabled>
Updating...
</Button>
) : (
<Button variant="secondary" icon="sync" onClick={syncUser}>
Update
</Button>
)}
</HorizontalGroup>
{!syncing ? <UserCloudStatus /> : <LoadingPlaceholder text="Loading..." />}
</VerticalGroup>
) : (
<VerticalGroup spacing="lg">
<Text.Title level={3}>OnCall use Grafana Cloud for SMS and phone call notifications</Text.Title>
<Text>You do not have permission to perform this action. Ask an admin to upgrade your permissions.</Text>
</VerticalGroup>
)}
</>
);
});

View file

@ -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) => {
<div style={{ width: '100%' }}>
<Text type="secondary">
{
'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.'
}
</Text>
@ -317,7 +324,7 @@ const CloudPage = observer((props: CloudPageProps) => {
style={{ width: '100%' }}
invalid={apiKeyError}
>
<Input id="cloudApiKey" onChange={handleChangeCloudApiKey} />
<Input id="cloudApiKey" onChange={handleChangeCloudApiKey} defaultValue={cloudApiKey} />
</Field>
<Button variant="primary" onClick={saveKeyAndConnect} disabled={!cloudApiKey} size="md">
Save key and connect

View file

@ -122,6 +122,7 @@ export const pages: PageDefinition[] = [
icon: 'cloud',
id: 'cloud',
text: 'Cloud',
role: 'Admin',
},
{
component: Test,

View file

@ -98,13 +98,6 @@
"path": "/a/grafana-oncall-app/?page=outgoing_webhooks",
"role": "Viewer",
"addToNav": true
},
{
"type": "page",
"name": "Cloud",
"path": "/a/grafana-oncall-app/?page=cloud",
"role": "Editor",
"addToNav": true
}
],
"routes": [

View file

@ -4,4 +4,5 @@ export enum AppFeature {
LiveSettings = 'live_settings',
MobileApp = 'mobile_app',
CloudNotifications = 'grafana_cloud_notifications',
CloudConnection = 'grafana_cloud_connection',
}

View file

@ -16,6 +16,7 @@ type Args = {
orgRole: 'Viewer' | 'Editor' | 'Admin';
};
enableLiveSettings: boolean;
enableCloudPage: boolean;
};
export function useForceUpdate() {
@ -23,7 +24,7 @@ export function useForceUpdate() {
return () => setValue((value) => value + 1);
}
export function useNavModel({ meta, pages, path, page, grafanaUser, enableLiveSettings }: Args) {
export function useNavModel({ meta, pages, path, page, grafanaUser, enableLiveSettings, enableCloudPage }: Args) {
return useMemo(() => {
const tabs: NavModelItem[] = [];
@ -36,7 +37,8 @@ export function useNavModel({ meta, pages, path, page, grafanaUser, enableLiveSe
hideFromTabs:
hideFromTabs ||
(role === 'Admin' && grafanaUser.orgRole !== role) ||
(id === 'live-settings' && !enableLiveSettings),
(id === 'live-settings' && !enableLiveSettings) ||
(id === 'cloud' && !enableCloudPage),
});
if (page === id) {
@ -61,7 +63,7 @@ export function useNavModel({ meta, pages, path, page, grafanaUser, enableLiveSe
node,
main: node,
};
}, [meta.info.logos.large, pages, path, page, enableLiveSettings]);
}, [meta.info.logos.large, pages, path, page, enableLiveSettings, enableCloudPage]);
}
export function usePrevious(value: any) {