import { css } from '@emotion/css'; import React, { useEffect, useMemo, useState } from 'react'; import { GrafanaTheme2 } from '@grafana/data/src'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src'; import { reportInteraction } from '@grafana/runtime/src'; import { Alert, Button, ClipboardButton, Field, HorizontalGroup, Input, useStyles2, Spinner } from '@grafana/ui/src'; import { notifyApp } from 'app/core/actions'; import { createErrorNotification } from 'app/core/copy/appNotification'; import { contextSrv } from 'app/core/services/context_srv'; import { useGetConfigQuery, useSaveConfigMutation } from 'app/features/dashboard/api/publicDashboardApi'; import { AcknowledgeCheckboxes } from 'app/features/dashboard/components/ShareModal/SharePublicDashboard/AcknowledgeCheckboxes'; import { Configuration } from 'app/features/dashboard/components/ShareModal/SharePublicDashboard/Configuration'; import { Description } from 'app/features/dashboard/components/ShareModal/SharePublicDashboard/Description'; import { Acknowledgements, dashboardHasTemplateVariables, generatePublicDashboardUrl, publicDashboardPersisted, } from 'app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboardUtils'; import { ShareModalTabProps } from 'app/features/dashboard/components/ShareModal/types'; import { isOrgAdmin } from 'app/features/plugins/admin/permissions'; import { dispatch } from 'app/store/store'; import { AccessControlAction } from 'app/types'; interface Props extends ShareModalTabProps {} export const SharePublicDashboard = (props: Props) => { const dashboardVariables = props.dashboard.getVariables(); const selectors = e2eSelectors.pages.ShareDashboardModal.PublicDashboard; const styles = useStyles2(getStyles); const { isLoading: isFetchingLoading, data: publicDashboard, isError: isFetchingError, } = useGetConfigQuery(props.dashboard.uid); const [saveConfig, { isLoading: isSaveLoading }] = useSaveConfigMutation(); const [acknowledgements, setAcknowledgements] = useState({ public: false, datasources: false, usage: false, }); const [enabledSwitch, setEnabledSwitch] = useState({ isEnabled: false, wasTouched: false, }); useEffect(() => { reportInteraction('grafana_dashboards_public_share_viewed'); }, []); useEffect(() => { if (publicDashboardPersisted(publicDashboard)) { setAcknowledgements({ public: true, datasources: true, usage: true, }); } setEnabledSwitch((prevState) => ({ ...prevState, isEnabled: !!publicDashboard?.isEnabled })); }, [publicDashboard]); const isLoading = isFetchingLoading || isSaveLoading; const hasWritePermissions = contextSrv.hasAccess(AccessControlAction.DashboardsPublicWrite, isOrgAdmin()); const acknowledged = acknowledgements.public && acknowledgements.datasources && acknowledgements.usage; const isSaveEnabled = useMemo( () => !hasWritePermissions || !acknowledged || props.dashboard.hasUnsavedChanges() || isLoading || isFetchingError || (!publicDashboardPersisted(publicDashboard) && !enabledSwitch.wasTouched), [hasWritePermissions, acknowledged, props.dashboard, isLoading, isFetchingError, enabledSwitch, publicDashboard] ); const onSavePublicConfig = () => { reportInteraction('grafana_dashboards_public_create_clicked'); if (dashboardHasTemplateVariables(dashboardVariables)) { dispatch( notifyApp(createErrorNotification('This dashboard cannot be made public because it has template variables')) ); return; } saveConfig({ dashboard: props.dashboard, payload: { ...publicDashboard!, isEnabled: enabledSwitch.isEnabled }, }); }; const onAcknowledge = (field: string, checked: boolean) => { setAcknowledgements((prevState) => ({ ...prevState, [field]: checked })); }; return ( <>

Welcome to Grafana public dashboards alpha!

{isFetchingLoading && }
{dashboardHasTemplateVariables(dashboardVariables) ? ( This dashboard cannot be made public because it has template variables ) : ( <>

setEnabledSwitch((prevState) => ({ isEnabled: !prevState.isEnabled, wasTouched: true })) } hasTemplateVariables={dashboardHasTemplateVariables(dashboardVariables)} /> {publicDashboardPersisted(publicDashboard) && enabledSwitch.isEnabled && ( generatePublicDashboardUrl(publicDashboard!)} > Copy } /> )} {hasWritePermissions ? ( props.dashboard.hasUnsavedChanges() && ( ) ) : ( )} {isSaveLoading && } )}
); }; const getStyles = (theme: GrafanaTheme2) => ({ content: css` margin: ${theme.spacing(1, 0, 0, 0)}; `, checkboxes: css` margin: ${theme.spacing(2, 0)}; `, timeRange: css` padding: ${theme.spacing(1, 1)}; margin: ${theme.spacing(0, 0, 2, 0)}; `, publicUrl: css` width: 100%; margin-bottom: ${theme.spacing(0, 0, 3, 0)}; `, });