diff --git a/pkg/services/navtree/navtreeimpl/admin.go b/pkg/services/navtree/navtreeimpl/admin.go
index dfeacca9d5f..700fc8323f9 100644
--- a/pkg/services/navtree/navtreeimpl/admin.go
+++ b/pkg/services/navtree/navtreeimpl/admin.go
@@ -62,9 +62,9 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
}
if hasAccess(ac.EvalPermission(ac.ActionSettingsRead, ac.ScopeSettingsAll)) {
generalNodeLinks = append(generalNodeLinks, &navtree.NavLink{
- Text: "Remote provisioning",
+ Text: "Provisioning",
Id: "provisioning",
- SubTitle: "Manage resources from remote repositories",
+ SubTitle: "View and manage your provisioning connections",
Url: s.cfg.AppSubURL + "/admin/provisioning",
})
}
diff --git a/public/app/features/provisioning/GettingStarted/EnhancedFeatures.tsx b/public/app/features/provisioning/GettingStarted/EnhancedFeatures.tsx
index 33cbcb232ef..d6d40fcf8b6 100644
--- a/public/app/features/provisioning/GettingStarted/EnhancedFeatures.tsx
+++ b/public/app/features/provisioning/GettingStarted/EnhancedFeatures.tsx
@@ -1,29 +1,10 @@
import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
-import { Box, Stack, Text, LinkButton, Icon, IconName, useStyles2 } from '@grafana/ui';
-import { Trans, t } from 'app/core/internationalization';
+import { Box, Stack, Text, LinkButton, useStyles2 } from '@grafana/ui';
+import { Trans } from 'app/core/internationalization';
-import { FeatureCard } from './FeatureCard';
-
-interface IconCircleProps {
- icon: IconName;
- color: string;
- background: string;
-}
-
-const IconCircle = ({ icon, color, background }: IconCircleProps) => (
-
-
-
-);
+import { IconCircle } from './IconCircle';
interface EnhancedFeaturesProps {
hasPublicAccess: boolean;
@@ -35,65 +16,68 @@ export const EnhancedFeatures = ({ hasPublicAccess, hasImageRenderer, onSetupPub
const style = useStyles2(getStyles);
return (
-
-
-
- Unlock enhanced functionality for GitHub
-
-
-
-
- }
- action={
- !hasPublicAccess && (
-
- Set up public access
-
- )
- }
- />
+
+
+
+ Enhance your GitHub experience
+
+
+
+ Get the most out of your GitHub integration with these optional add-ons
+
+
+
+
+
+
+
+
+
+
+ Instant updates and pull requests with webhooks.
+
+
+
+
+ Get instant updates in Grafana as soon as changes are committed. Review and approve changes using pull
+ requests before they go live.
+
+
+
+ {!hasPublicAccess && (
+
+ Set up public webhooks
+
+ )}
+
-
+
-
-
-
-
- }
- action={
- !hasImageRenderer && (
-
- Set up image rendering
-
- )
- }
- />
-
-
-
+
+
+
+ Visual previews in pull requests with image rendering
+
+
+
+
+ See visual previews of dashboard updates directly in pull requests
+
+
+
+ {hasImageRenderer && (
+
+ Set up image rendering
+
+ )}
+
+
+
);
};
diff --git a/public/app/features/provisioning/GettingStarted/FeatureCard.tsx b/public/app/features/provisioning/GettingStarted/FeatureCard.tsx
deleted file mode 100644
index b70ad55d880..00000000000
--- a/public/app/features/provisioning/GettingStarted/FeatureCard.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Box, Stack, Text } from '@grafana/ui';
-
-interface FeatureCardProps {
- title: string;
- description: string;
- icon?: React.ReactNode;
- action?: React.ReactNode;
-}
-
-export const FeatureCard = ({ title, description, icon, action }: FeatureCardProps) => (
-
-
-
- {icon}
- {title}
- {description}
- {action && {action}}
-
-
-
-);
diff --git a/public/app/features/provisioning/GettingStarted/FeaturesList.tsx b/public/app/features/provisioning/GettingStarted/FeaturesList.tsx
index 1ba201ff814..17eeedf1270 100644
--- a/public/app/features/provisioning/GettingStarted/FeaturesList.tsx
+++ b/public/app/features/provisioning/GettingStarted/FeaturesList.tsx
@@ -1,43 +1,46 @@
-import { ReactNode } from 'react';
+import { css } from '@emotion/css';
-import { Stack, Text, Box, LinkButton, Icon } from '@grafana/ui';
+import { GrafanaTheme2 } from '@grafana/data';
+import { Stack, Text, Box, LinkButton, useStyles2 } from '@grafana/ui';
import { Repository } from 'app/api/clients/provisioning';
import { Trans } from 'app/core/internationalization';
import { ConnectRepositoryButton } from '../Shared/ConnectRepositoryButton';
-interface FeatureItemProps {
- children: NonNullable;
-}
-
-const FeatureItem = ({ children }: FeatureItemProps) => {
- // We use a stack here to ensure the icon and text are aligned correctly.
- return (
-
-
- {children}
-
- );
-};
-
interface FeaturesListProps {
repos?: Repository[];
- hasPublicAccess: boolean;
- hasImageRenderer: boolean;
hasRequiredFeatures: boolean;
onSetupFeatures: () => void;
}
-export const FeaturesList = ({
- repos,
- hasPublicAccess,
- hasImageRenderer,
- hasRequiredFeatures,
- onSetupFeatures,
-}: FeaturesListProps) => {
- const actions = () => {
- if (!hasRequiredFeatures) {
- return (
+export const FeaturesList = ({ repos, hasRequiredFeatures, onSetupFeatures }: FeaturesListProps) => {
+ const styles = useStyles2(getStyles);
+
+ return (
+
+
+
+ Get started with GitSync
+
+
+
+ -
+
+ Manage dashboards as code in GitHub and provision updates automatically
+
+
+ -
+
+ Store dashboards in version-controlled storage for better organization and history tracking
+
+
+ -
+
+ Migrate existing dashboards to GitHub for provisioning
+
+
+
+ {!hasRequiredFeatures ? (
@@ -45,61 +48,34 @@ export const FeaturesList = ({
- );
- }
-
- return (
-
-
-
- );
- };
-
- return (
-
-
-
- Manage your dashboards with remote provisioning
-
-
-
-
- Manage dashboards as code and provision updates automatically
-
-
-
-
- Store dashboards in version-controlled storage for better organization and history tracking
-
-
-
-
- Migrate existing dashboards to storage for provisioning
-
-
- {hasPublicAccess && (
-
-
- Automatically provision and update your dashboards as soon as changes are pushed to your GitHub repository
-
-
+ ) : (
+
+
+
)}
- {hasImageRenderer && hasPublicAccess && (
-
-
- Visual previews in pull requests to review your changes before going live
-
-
- )}
-
- {false && (
- // We haven't gotten the design for this quite yet.
-
- Learn more
-
- )}
-
- {actions()}
);
};
+
+const getStyles = (theme: GrafanaTheme2) => {
+ return {
+ featuresList: css({
+ listStyleType: 'none',
+ paddingLeft: 0,
+ marginLeft: theme.spacing(-1),
+ '& li': {
+ position: 'relative',
+ paddingLeft: theme.spacing(4),
+ marginBottom: theme.spacing(1),
+ '&:before': {
+ content: '"✓"',
+ position: 'absolute',
+ left: theme.spacing(1),
+ top: '0',
+ color: theme.colors.text.secondary,
+ fontWeight: theme.typography.fontWeightBold,
+ },
+ },
+ }),
+ };
+};
diff --git a/public/app/features/provisioning/GettingStarted/GettingStarted.tsx b/public/app/features/provisioning/GettingStarted/GettingStarted.tsx
index a39fd510fb2..881f7e02590 100644
--- a/public/app/features/provisioning/GettingStarted/GettingStarted.tsx
+++ b/public/app/features/provisioning/GettingStarted/GettingStarted.tsx
@@ -1,7 +1,7 @@
import { css } from '@emotion/css';
import { useState } from 'react';
-import { Alert, Stack, Text, Box } from '@grafana/ui';
+import { Alert, Stack, Text } from '@grafana/ui';
import { useGetFrontendSettingsQuery, Repository } from 'app/api/clients/provisioning';
import { t, Trans } from 'app/core/internationalization';
@@ -47,6 +47,76 @@ HTTP Requests
const rootUrlExample = `[server]
root_url = https://d60d-83-33-235-27.ngrok-free.app`;
+const getModalContent = (setupType: SetupType) => {
+ switch (setupType) {
+ case 'public-access':
+ return {
+ title: t('provisioning.getting-started.modal-title-set-up-public-access', 'Set up public access'),
+ description: t(
+ 'provisioning.getting-started.modal-description-public-access',
+ 'Set up public access to your Grafana instance to enable GitHub integration'
+ ),
+ steps: [
+ {
+ title: t('provisioning.getting-started.step-title-start-ngrok', 'Start ngrok for temporary public access'),
+ description: t(
+ 'provisioning.getting-started.step-description-start-ngrok',
+ 'Run this command to create a secure tunnel to your local Grafana:'
+ ),
+ code: 'ngrok http 3000',
+ },
+ {
+ title: t('provisioning.getting-started.step-title-copy-url', 'Copy your public URL'),
+ description: t(
+ 'provisioning.getting-started.step-description-copy-url',
+ 'From the ngrok output, copy the https:// forwarding URL that looks like this:'
+ ),
+ code: ngrokExample,
+ copyCode: false,
+ },
+ {
+ title: t(
+ 'provisioning.getting-started.step-title-update-grafana-config',
+ 'Update your Grafana configuration'
+ ),
+ description: t(
+ 'provisioning.getting-started.step-description-update-grafana-config',
+ 'Add this to your custom.ini file, replacing the URL with your actual ngrok URL:'
+ ),
+ code: rootUrlExample,
+ },
+ ],
+ };
+ case 'required-features':
+ return {
+ title: t('provisioning.getting-started.modal-title-set-up-required-features', 'Set up required features'),
+ description: t(
+ 'provisioning.getting-started.modal-description-required-features',
+ 'Enable required Grafana features for provisioning'
+ ),
+ steps: [
+ {
+ title: t(
+ 'provisioning.getting-started.step-title-enable-feature-toggles',
+ 'Enable Required Feature Toggles'
+ ),
+ description: t(
+ 'provisioning.getting-started.step-description-enable-feature-toggles',
+ 'Add these settings to your custom.ini file to enable necessary features:'
+ ),
+ code: featureIni,
+ },
+ ],
+ };
+ default:
+ return {
+ title: '',
+ description: '',
+ steps: [],
+ };
+ }
+};
+
interface Props {
items: Repository[];
}
@@ -59,79 +129,6 @@ export default function GettingStarted({ items }: Props) {
const [showInstructionsModal, setShowModal] = useState(false);
const [setupType, setSetupType] = useState(null);
- const getModalContent = () => {
- switch (setupType) {
- case 'public-access':
- return {
- title: t('provisioning.getting-started.modal-title-set-up-public-access', 'Set up public access'),
- description: t(
- 'provisioning.getting-started.modal-description-public-access',
- 'Set up public access to your Grafana instance to enable GitHub integration'
- ),
- steps: [
- {
- title: t(
- 'provisioning.getting-started.step-title-start-ngrok',
- 'Start ngrok for temporary public access'
- ),
- description: t(
- 'provisioning.getting-started.step-description-start-ngrok',
- 'Run this command to create a secure tunnel to your local Grafana:'
- ),
- code: 'ngrok http 3000',
- },
- {
- title: t('provisioning.getting-started.step-title-copy-url', 'Copy your public URL'),
- description: t(
- 'provisioning.getting-started.step-description-copy-url',
- 'From the ngrok output, copy the https:// forwarding URL that looks like this:'
- ),
- code: ngrokExample,
- copyCode: false,
- },
- {
- title: t(
- 'provisioning.getting-started.step-title-update-grafana-config',
- 'Update your Grafana configuration'
- ),
- description: t(
- 'provisioning.getting-started.step-description-update-grafana-config',
- 'Add this to your custom.ini file, replacing the URL with your actual ngrok URL:'
- ),
- code: rootUrlExample,
- },
- ],
- };
- case 'required-features':
- return {
- title: t('provisioning.getting-started.modal-title-set-up-required-features', 'Set up required features'),
- description: t(
- 'provisioning.getting-started.modal-description-required-features',
- 'Enable required Grafana features for provisioning'
- ),
- steps: [
- {
- title: t(
- 'provisioning.getting-started.step-title-enable-feature-toggles',
- 'Enable Required Feature Toggles'
- ),
- description: t(
- 'provisioning.getting-started.step-description-enable-feature-toggles',
- 'Add these settings to your custom.ini file to enable necessary features:'
- ),
- code: featureIni,
- },
- ],
- };
- default:
- return {
- title: '',
- description: '',
- steps: [],
- };
- }
- };
-
return (
<>
{legacyStorage && (
@@ -148,23 +145,20 @@ export default function GettingStarted({ items }: Props) {
)}
-
-
+
+
{
setSetupType('required-features');
setShowModal(true);
}}
/>
-
-
Engaging graphic
-
+
+ {(!hasPublicAccess || !hasImageRenderer) && (
+ {
+ setSetupType('public-access');
+ setShowModal(true);
+ }}
+ />
+ )}
- {(!hasPublicAccess || !hasImageRenderer) && (
- {
- setSetupType('public-access');
- setShowModal(true);
- }}
- />
- )}
{showInstructionsModal && setupType && (
- setShowModal(false)} />
+ setShowModal(false)}
+ />
)}
>
);
diff --git a/public/app/features/provisioning/GettingStarted/GettingStartedPage.tsx b/public/app/features/provisioning/GettingStarted/GettingStartedPage.tsx
index 552e2589ffc..ed8a1e3e06f 100644
--- a/public/app/features/provisioning/GettingStarted/GettingStartedPage.tsx
+++ b/public/app/features/provisioning/GettingStarted/GettingStartedPage.tsx
@@ -12,10 +12,10 @@ export default function GettingStartedPage({ items }: Props) {
diff --git a/public/app/features/provisioning/GettingStarted/IconCircle.tsx b/public/app/features/provisioning/GettingStarted/IconCircle.tsx
new file mode 100644
index 00000000000..adfa0cdb115
--- /dev/null
+++ b/public/app/features/provisioning/GettingStarted/IconCircle.tsx
@@ -0,0 +1,32 @@
+import { css } from '@emotion/css';
+
+import { GrafanaTheme2, colorManipulator } from '@grafana/data';
+import { Icon, IconName, useStyles2 } from '@grafana/ui';
+
+export interface IconCircleProps {
+ icon: IconName;
+ color: 'blue' | 'orange' | 'purple';
+}
+
+export const IconCircle = ({ icon, color }: IconCircleProps) => {
+ const styles = useStyles2(getStyles, color);
+
+ return (
+
+
+
+ );
+};
+
+function getStyles(theme: GrafanaTheme2, color: IconCircleProps['color']) {
+ const resolvedColor = theme.visualization.getColorByName(color);
+
+ return {
+ iconCircle: css({
+ borderRadius: theme.shape.radius.circle,
+ padding: theme.spacing(1),
+ color: resolvedColor,
+ backgroundColor: colorManipulator.alpha(resolvedColor, 0.2),
+ }),
+ };
+}
diff --git a/public/app/features/provisioning/Shared/ConnectRepositoryButton.tsx b/public/app/features/provisioning/Shared/ConnectRepositoryButton.tsx
index 5bbe5596496..e1df0c2e83c 100644
--- a/public/app/features/provisioning/Shared/ConnectRepositoryButton.tsx
+++ b/public/app/features/provisioning/Shared/ConnectRepositoryButton.tsx
@@ -1,6 +1,6 @@
-import { LinkButton } from '@grafana/ui';
+import { Alert, LinkButton, Stack } from '@grafana/ui';
import { Repository } from 'app/api/clients/provisioning';
-import { Trans, t } from 'app/core/internationalization';
+import { Trans } from 'app/core/internationalization';
import { CONNECT_URL } from '../constants';
import { checkSyncSettings } from '../utils/checkSyncSettings';
@@ -18,29 +18,24 @@ export function ConnectRepositoryButton({ items }: Props) {
if (state.maxReposReached) {
return (
-
+
-
+
);
}
return (
-
- Connect to repository
-
+
+
+ Configure GitSync
+
+
+ Configure file provisioning
+
+
);
}
diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json
index 10b1c45a9e0..d10c187f2b8 100644
--- a/public/locales/en-US/grafana.json
+++ b/public/locales/en-US/grafana.json
@@ -5158,10 +5158,9 @@
"title-webhook-will-be-created": "Webhook will be created"
},
"connect-repository-button": {
- "connect-to-repository": "Connect to repository",
- "max-repositories-exist": "Maximum repositories exist ({{count}})",
- "tooltip-max-repos_one": "Max repositories already created ({{count}})",
- "tooltip-max-repos_other": "Max repositories already created ({{count}})"
+ "configure-file": "Configure file provisioning",
+ "configure-git-sync": "Configure GitSync",
+ "repository-limit-info-alert": "Repository limit reached ({{count}})"
},
"connect-step": {
"description-choose-storage-resources": "Choose the type of storage for your resources",
@@ -5200,13 +5199,14 @@
"no-jobs": "No jobs..."
},
"enhanced-features": {
+ "description": "Get the most out of your GitHub integration with these optional add-ons",
"description-instant-updates": "Get instant updates in Grafana as soon as changes are committed. Review and approve changes using pull requests before they go live.",
"description-visual-previews-dashboard-updates-directly-requests": "See visual previews of dashboard updates directly in pull requests",
+ "header": "Enhance your GitHub experience",
"set-up-image-rendering": "Set up image rendering",
- "set-up-public-access": "Set up public access",
- "title-instant-updates-requests-webhooks": "Instant updates and pull requests with webhooks",
- "title-visual-previews-in-pull-requests": "Visual previews in pull requests",
- "unlock-enhanced-functionality-for-git-hub": "Unlock enhanced functionality for GitHub"
+ "set-up-public-webhooks": "Set up public webhooks",
+ "title-instant-updates-requests-webhooks": "Instant updates and pull requests with webhooks.",
+ "title-visual-previews-in-pull-requests": "Visual previews in pull requests with image rendering"
},
"expanded-row": {
"job-specification": "Job Specification",
@@ -5217,13 +5217,10 @@
"actions": {
"set-up-required-feature-toggles": "Set up required feature toggles"
},
- "automatically-provision-and-update-dashboards": "Automatically provision and update your dashboards as soon as changes are pushed to your GitHub repository",
- "learn-more": "Learn more",
- "manage-dashboards-provision-updates-automatically": "Manage dashboards as code and provision updates automatically",
- "manage-your-dashboards-with-remote-provisioning": "Manage your dashboards with remote provisioning",
- "migrate-existing-dashboards-storage-provisioning": "Migrate existing dashboards to storage for provisioning",
- "store-dashboards-in-version-controlled-storage": "Store dashboards in version-controlled storage for better organization and history tracking",
- "visual-previews-in-pull-requests": "Visual previews in pull requests to review your changes before going live"
+ "manage-dashboards-provision-updates-automatically": "Manage dashboards as code in GitHub and provision updates automatically",
+ "manage-your-dashboards-with-remote-provisioning": "Get started with GitSync",
+ "migrate-existing-dashboards-storage-provisioning": "Migrate existing dashboards to GitHub for provisioning",
+ "store-dashboards-in-version-controlled-storage": "Store dashboards in version-controlled storage for better organization and history tracking"
},
"file-history-page": {
"back-to-repositories": "Back to repositories",
@@ -5276,8 +5273,8 @@
"title-setting-connection-could-cause-temporary-outage": "Setting up this connection could cause a temporary outage"
},
"getting-started-page": {
- "subtitle-provisioning-feature": "Provisioning is a feature that allows you to manage your dashboards using GitHub and other storage systems",
- "text-remote-provisioning": "Remote provisioning"
+ "header": "Provisioning",
+ "subtitle-provisioning-feature": "View and manage your provisioning connections"
},
"history-view": {
"not-found": "Not found"