From b5c52255d5d1fa38f5e579e61546dea5f998b7b4 Mon Sep 17 00:00:00 2001 From: Dominik Broj Date: Thu, 22 Aug 2024 10:02:05 +0200 Subject: [PATCH] fix: show api url in main settings (#4896) # What this PR does - show api_url from GET /status endpoint on settings page - refactor MainSettings to be functional component ## Which issue(s) this PR closes https://raintank-corp.slack.com/archives/C0713BYQB0W/p1724249719392329 ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] Added the relevant release notes label (see labels prefixed w/ `release:`). These labels dictate how your PR will show up in the autogenerated release notes. --- .../ApiTokenSettings/ApiTokenForm.tsx | 2 +- grafana-plugin/src/models/plugin/plugin.ts | 6 +- .../src/network/oncall-api/api.types.d.ts | 7 +- .../tabs/MainSettings/MainSettings.module.css | 7 - .../tabs/MainSettings/MainSettings.tsx | 139 ++++++++---------- .../src/state/rootBaseStore/RootBaseStore.ts | 8 - grafana-plugin/src/types.ts | 4 +- 7 files changed, 69 insertions(+), 104 deletions(-) delete mode 100644 grafana-plugin/src/pages/settings/tabs/MainSettings/MainSettings.module.css diff --git a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx index c0f8246d63..e6b645be2d 100644 --- a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx +++ b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx @@ -120,7 +120,7 @@ export const ApiTokenForm = observer((props: TokenCreationModalProps) => { - {getCurlExample(token, store.onCallApiUrl)} + {getCurlExample(token, store.pluginStore.apiUrlFromStatus)} ); diff --git a/grafana-plugin/src/models/plugin/plugin.ts b/grafana-plugin/src/models/plugin/plugin.ts index b88c8b996c..c8ffe32d60 100644 --- a/grafana-plugin/src/models/plugin/plugin.ts +++ b/grafana-plugin/src/models/plugin/plugin.ts @@ -5,7 +5,7 @@ import { OnCallPluginMetaJSONData } from 'types'; import { ActionKey } from 'models/loader/action-keys'; import { GrafanaApiClient } from 'network/grafana-api/http-client'; import { makeRequest } from 'network/network'; -import { PluginConnection, PostStatusResponse } from 'network/oncall-api/api.types'; +import { PluginConnection, StatusResponse } from 'network/oncall-api/api.types'; import { RootBaseStore } from 'state/rootBaseStore/RootBaseStore'; import { waitInMs } from 'utils/async'; import { AutoLoadingState } from 'utils/decorators'; @@ -31,6 +31,7 @@ On Cloud: export class PluginStore { rootStore: RootBaseStore; connectionStatus?: PluginConnection; + apiUrlFromStatus?: string; isPluginConnected = false; appliedOnCallApiUrl = ''; @@ -53,9 +54,10 @@ export class PluginStore { @AutoLoadingState(ActionKey.PLUGIN_VERIFY_CONNECTION) async verifyPluginConnection() { - const { pluginConnection } = await makeRequest(`/plugin/status`, {}); + const { pluginConnection, api_url } = await makeRequest(`/plugin/status`, {}); runInAction(() => { this.connectionStatus = pluginConnection; + this.apiUrlFromStatus = api_url; this.isPluginConnected = Object.keys(pluginConnection).every( (key) => pluginConnection[key as keyof PluginConnection]?.ok ); diff --git a/grafana-plugin/src/network/oncall-api/api.types.d.ts b/grafana-plugin/src/network/oncall-api/api.types.d.ts index 701866a14e..d1b9364221 100644 --- a/grafana-plugin/src/network/oncall-api/api.types.d.ts +++ b/grafana-plugin/src/network/oncall-api/api.types.d.ts @@ -16,15 +16,10 @@ type PluginConnection = { grafana_url_from_engine: PluginConnectionCheck; }; -export type PostStatusResponse = { +export type StatusResponse = { pluginConnection: PluginConnection; - allow_signup: boolean; api_url: string; currently_undergoing_maintenance_message: string | null; - is_installed: boolean; - is_user_anonymous: boolean; license: string; - recaptcha_site_key: string; - token_ok: boolean; version: string; }; diff --git a/grafana-plugin/src/pages/settings/tabs/MainSettings/MainSettings.module.css b/grafana-plugin/src/pages/settings/tabs/MainSettings/MainSettings.module.css deleted file mode 100644 index 9c055775fc..0000000000 --- a/grafana-plugin/src/pages/settings/tabs/MainSettings/MainSettings.module.css +++ /dev/null @@ -1,7 +0,0 @@ -.title { - margin-bottom: 20px; -} - -.settings { - width: fit-content; -} diff --git a/grafana-plugin/src/pages/settings/tabs/MainSettings/MainSettings.tsx b/grafana-plugin/src/pages/settings/tabs/MainSettings/MainSettings.tsx index e2de1da547..fea4751d3e 100644 --- a/grafana-plugin/src/pages/settings/tabs/MainSettings/MainSettings.tsx +++ b/grafana-plugin/src/pages/settings/tabs/MainSettings/MainSettings.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { Field, Input, Switch } from '@grafana/ui'; -import cn from 'classnames/bind'; +import { css } from '@emotion/css'; +import { Field, Input, Switch, useStyles2 } from '@grafana/ui'; import { observer } from 'mobx-react'; import { LegacyNavHeading } from 'navbar/LegacyNavHeading'; @@ -10,86 +10,71 @@ import { ApiTokenSettings } from 'containers/ApiTokenSettings/ApiTokenSettings'; import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { TeamsSettings } from 'pages/settings/tabs/TeamsSettings/TeamsSettings'; import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers'; -import { WithStoreProps } from 'state/types'; -import { withMobXProviderContext } from 'state/withStore'; +import { useStore } from 'state/useStore'; import { UserActions } from 'utils/authorization/authorization'; -import styles from './MainSettings.module.css'; +export const MainSettings = observer(() => { + const styles = useStyles2(getStyles); + const { + organizationStore: { currentOrganization, saveCurrentOrganization }, + pluginStore: { apiUrlFromStatus }, + } = useStore(); -const cx = cn.bind(styles); - -interface SettingsPageProps extends WithStoreProps {} - -interface SettingsPageState { - apiUrl?: string; -} - -@observer -class Settings extends React.Component { - state: SettingsPageState = { - apiUrl: '', - }; - - async componentDidMount() { - const { store } = this.props; - const url = await store.getApiUrlForSettings(); - this.setState({ apiUrl: url }); - } - - render() { - const { organizationStore } = this.props.store; - const { currentOrganization } = organizationStore; - const { apiUrl } = this.state; - - return ( -
- - - Organization settings - - + return ( +
+ + + Organization settings + + -
- - Resolution Note - - - - { - organizationStore.saveCurrentOrganization({ - is_resolution_note_required: event.currentTarget.checked, - }); - }} - /> - - -
- {!isTopNavbar() && ( -
- - Teams and Access Settings - - -
- )} - - API URL +
+ + Resolution Note -
- - - + + + { + saveCurrentOrganization({ + is_resolution_note_required: event.currentTarget.checked, + }); + }} + /> + + +
+ {!isTopNavbar() && ( +
+ + Teams and Access Settings + +
- + )} + + API URL + +
+ + +
- ); - } -} + +
+ ); +}); -export const MainSettings = withMobXProviderContext(Settings); +const getStyles = () => ({ + settings: css` + width: fit-content; + `, + title: css` + margin-bottom: 20px; + `, +}); diff --git a/grafana-plugin/src/state/rootBaseStore/RootBaseStore.ts b/grafana-plugin/src/state/rootBaseStore/RootBaseStore.ts index 826de9af6f..2839ad30d3 100644 --- a/grafana-plugin/src/state/rootBaseStore/RootBaseStore.ts +++ b/grafana-plugin/src/state/rootBaseStore/RootBaseStore.ts @@ -69,9 +69,6 @@ export class RootBaseStore { @observable pageTitle = ''; - @observable - onCallApiUrl: string; - @observable insightsDatasource = 'grafanacloud-usage'; @@ -186,11 +183,6 @@ export class RootBaseStore { this.pageTitle = title; } - @action.bound - async getApiUrlForSettings() { - return this.onCallApiUrl; - } - @action.bound async loadRecaptcha() { const { recaptcha_site_key } = await makeRequest<{ recaptcha_site_key: string }>('/plugin/recaptcha'); diff --git a/grafana-plugin/src/types.ts b/grafana-plugin/src/types.ts index b2d7e0d211..44547883c5 100644 --- a/grafana-plugin/src/types.ts +++ b/grafana-plugin/src/types.ts @@ -1,4 +1,4 @@ -import { AppRootProps as BaseAppRootProps, AppPluginMeta, PluginConfigPageProps, BootData } from '@grafana/data'; +import { AppRootProps as BaseAppRootProps, AppPluginMeta, PluginConfigPageProps } from '@grafana/data'; import { getPluginId } from 'utils/consts'; @@ -30,8 +30,6 @@ export type OnCallPluginExtensionPoints = declare global { export interface Window { - // https://github.com/grafana/grafana/blob/78bef7a26a799209b5307d6bde8e25fcb4fbde7d/public/views/index-template.html#L251-L258 - grafanaBootData?: BootData; RECAPTCHA_SITE_KEY: string; grecaptcha: any; dataLayer: any;