diff --git a/frontend/src/metabase/admin/settings/components/SettingsSetting.jsx b/frontend/src/metabase/admin/settings/components/SettingsSetting.jsx index 87dfc6e37cf7d3c4f89ed055860ff2afcc3762bb..62edd0c91be6fd4d3c9197b26588546fcfd3e51b 100644 --- a/frontend/src/metabase/admin/settings/components/SettingsSetting.jsx +++ b/frontend/src/metabase/admin/settings/components/SettingsSetting.jsx @@ -60,6 +60,13 @@ export default class SettingsSetting extends Component { ); Widget = SettingInput; } + + const widgetProps = { + ...setting.getProps?.(setting), + ...setting.props, + ...updatePlaceholderForEnvironmentVars(this.props), + }; + return ( // TODO - this formatting needs to be moved outside this component <li className="m2 mb4"> @@ -67,11 +74,7 @@ export default class SettingsSetting extends Component { <SettingHeader id={settingId} setting={setting} /> )} <div className="flex"> - <Widget - id={settingId} - {...(setting.props || {})} - {...updatePlaceholderForEnvironmentVars(this.props)} - /> + <Widget id={settingId} {...widgetProps} /> </div> {errorMessage && ( <div className="text-error text-bold pt1">{errorMessage}</div> diff --git a/frontend/src/metabase/admin/settings/components/widgets/EmbeddingLegalese.jsx b/frontend/src/metabase/admin/settings/components/widgets/EmbeddingLegalese.jsx index 18dec33af363fdbd700dbe0064e18c7c6bb5a3ed..54cdd170e01da0faa2041cc9e5d2cc38274a0579 100644 --- a/frontend/src/metabase/admin/settings/components/widgets/EmbeddingLegalese.jsx +++ b/frontend/src/metabase/admin/settings/components/widgets/EmbeddingLegalese.jsx @@ -3,8 +3,10 @@ import React from "react"; import * as MetabaseAnalytics from "metabase/lib/analytics"; import { t } from "ttag"; import ExternalLink from "metabase/core/components/ExternalLink"; +import Tooltip from "metabase/components/Tooltip"; +import Button from "metabase/core/components/Button"; -const EmbeddingLegalese = ({ onChange }) => ( +const EmbeddingLegalese = ({ setting, onChange }) => ( <div className="bordered rounded text-measure p4"> <h3 className="text-brand">{t`Using embedding`}</h3> <p className="text-medium" style={{ lineHeight: 1.48 }}> @@ -21,18 +23,23 @@ const EmbeddingLegalese = ({ onChange }) => ( {t`In plain English, when you embed charts or dashboards from Metabase in your own application, that application isn't subject to the Affero General Public License that covers the rest of Metabase, provided you keep the Metabase logo and the "Powered by Metabase" visible on those embeds. You should, however, read the license text linked above as that is the actual license that you will be agreeing to by enabling this feature.`} </p> <div className="flex layout-centered mt4"> - <button - className="Button Button--primary" - onClick={() => { - MetabaseAnalytics.trackStructEvent( - "Admin Embed Settings", - "Embedding Enable Click", - ); - onChange(true); - }} + <Tooltip + tooltip={setting.placeholder} + isEnabled={setting.is_env_setting} + maxWidth={300} > - {t`Enable`} - </button> + <Button + primary + disabled={setting.is_env_setting} + onClick={() => { + MetabaseAnalytics.trackStructEvent( + "Admin Embed Settings", + "Embedding Enable Click", + ); + onChange(true); + }} + >{t`Enable`}</Button> + </Tooltip> </div> </div> ); diff --git a/frontend/src/metabase/admin/settings/components/widgets/SettingToggle.jsx b/frontend/src/metabase/admin/settings/components/widgets/SettingToggle.jsx index e730c2d9c82ebbaa6d66b5f0e4d7689ec86d604a..0874ec93e7dfdc0197bdc0b98febbf4fcc7cb102 100644 --- a/frontend/src/metabase/admin/settings/components/widgets/SettingToggle.jsx +++ b/frontend/src/metabase/admin/settings/components/widgets/SettingToggle.jsx @@ -2,13 +2,16 @@ import React from "react"; import { t } from "ttag"; import Toggle from "metabase/core/components/Toggle"; +import Tooltip from "metabase/components/Tooltip"; -const SettingToggle = ({ setting, onChange, disabled }) => { +const SettingToggle = ({ setting, onChange, disabled, tooltip }) => { const value = setting.value == null ? setting.default : setting.value; const on = value === true || value === "true"; return ( <div className="flex align-center pt1"> - <Toggle value={on} onChange={!disabled ? () => onChange(!on) : null} /> + <Tooltip tooltip={tooltip} isEnabled={!!tooltip}> + <Toggle value={on} onChange={!disabled ? () => onChange(!on) : null} /> + </Tooltip> <span className="text-bold mx1">{on ? t`Enabled` : t`Disabled`}</span> </div> ); diff --git a/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx b/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx index 2d746ecff9e7ebf1f98255b2f3a3e488ffba3d45..5c5b60083a7fcbb3a76adaa418a7204a77334769 100644 --- a/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx +++ b/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx @@ -21,6 +21,7 @@ import cx from "classnames"; import { getSettings, getSettingValues, + getDerivedSettingValues, getSections, getActiveSection, getActiveSectionName, @@ -32,6 +33,7 @@ const mapStateToProps = (state, props) => { return { settings: getSettings(state, props), settingValues: getSettingValues(state, props), + derivedSettingValues: getDerivedSettingValues(state, props), sections: getSections(state, props), activeSection: getActiveSection(state, props), activeSectionName: getActiveSectionName(state, props), @@ -136,7 +138,12 @@ export default class SettingsEditorApp extends Component { }; renderSettingsPane() { - const { activeSection, settings, settingValues } = this.props; + const { + activeSection, + settings, + settingValues, + derivedSettingValues, + } = this.props; const isLoading = settings.length === 0; if (isLoading) { @@ -160,7 +167,9 @@ export default class SettingsEditorApp extends Component { <ul> {activeSection.settings .filter(setting => - setting.getHidden ? !setting.getHidden(settingValues) : true, + setting.getHidden + ? !setting.getHidden(settingValues, derivedSettingValues) + : true, ) .map((setting, index) => ( <SettingsSetting diff --git a/frontend/src/metabase/admin/settings/selectors.js b/frontend/src/metabase/admin/settings/selectors.js index 0a6d6ceebcde9f6cc3521178dae91beb2d186bcc..741ae4ab36d79a0e2e755f735d8c86e023b8ac02 100644 --- a/frontend/src/metabase/admin/settings/selectors.js +++ b/frontend/src/metabase/admin/settings/selectors.js @@ -309,7 +309,7 @@ const SECTIONS = updateSectionsWithPlugins({ key: "enable-embedding", description: null, widget: EmbeddingLegalese, - getHidden: settings => settings["enable-embedding"], + getHidden: (_, derivedSettings) => derivedSettings["enable-embedding"], onChanged: async ( oldValue, newValue, @@ -331,35 +331,47 @@ const SECTIONS = updateSectionsWithPlugins({ key: "enable-embedding", display_name: t`Enable Embedding Metabase in other Applications`, type: "boolean", - getHidden: settings => !settings["enable-embedding"], + showActualValue: true, + getProps: setting => { + if (setting.is_env_setting) { + return { + tooltip: setting.placeholder, + disabled: true, + }; + } + return null; + }, + getHidden: (_, derivedSettings) => !derivedSettings["enable-embedding"], }, { widget: EmbeddingCustomizationInfo, - getHidden: settings => - !settings["enable-embedding"] || MetabaseSettings.isEnterprise(), + getHidden: (_, derivedSettings) => + !derivedSettings["enable-embedding"] || + MetabaseSettings.isEnterprise(), }, { key: "embedding-secret-key", display_name: t`Embedding secret key`, widget: SecretKeyWidget, - getHidden: settings => !settings["enable-embedding"], + getHidden: (_, derivedSettings) => !derivedSettings["enable-embedding"], }, { key: "-embedded-dashboards", display_name: t`Embedded Dashboards`, widget: EmbeddedDashboardListing, - getHidden: settings => !settings["enable-embedding"], + getHidden: (_, derivedSettings) => !derivedSettings["enable-embedding"], }, { key: "-embedded-questions", display_name: t`Embedded Questions`, widget: EmbeddedQuestionListing, - getHidden: settings => !settings["enable-embedding"], + getHidden: (_, derivedSettings) => !derivedSettings["enable-embedding"], }, { widget: PremiumEmbeddingLinkWidget, - getHidden: settings => - !settings["enable-embedding"] || MetabaseSettings.isEnterprise(), + getHidden: (_, derivedSettings) => + !derivedSettings["enable-embedding"] || + MetabaseSettings.isEnterprise(), }, ], }, @@ -455,6 +467,11 @@ export const getSettings = createSelector( ), ); +// getSettings selector returns settings for admin setting page and values specified by +// environment variables set to "null". Actual applied setting values are coming from +// /api/session/properties API handler and getDerivedSettingValues returns them. +export const getDerivedSettingValues = state => state.settings?.values ?? {}; + export const getSettingValues = createSelector(getSettings, settings => { const settingValues = {}; for (const setting of settings) { @@ -469,8 +486,9 @@ export const getNewVersionAvailable = createSelector(getSettings, settings => { export const getSections = createSelector( getSettings, + getDerivedSettingValues, getUserIsAdmin, - (settings, isAdmin) => { + (settings, derivedSettingValues, isAdmin) => { if (!settings || _.isEmpty(settings)) { return {}; } @@ -485,11 +503,16 @@ export const getSections = createSelector( const settings = section.settings.map(function(setting) { const apiSetting = settingsByKey[setting.key] && settingsByKey[setting.key][0]; + if (apiSetting) { + const value = setting.showActualValue + ? derivedSettingValues[setting.key] + : apiSetting.value; return { placeholder: apiSetting.default, ...apiSetting, ...setting, + value, }; } else { return setting;