Navigation: Add descriptions to NavModelItems (#55669)

* add some descriptions!

* Update some descriptions

* Tweak playlist description

* fix unit tests + betterer
This commit is contained in:
Ashley Harrison 2022-09-23 16:08:08 +01:00 committed by GitHub
parent c65a8d3cab
commit 366731d8d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 59 additions and 54 deletions

View File

@ -58,6 +58,7 @@ func GetServerAdminNode(children []*NavLink) *NavLink {
return &NavLink{
Text: "Server admin",
SubTitle: "Manage all users and orgs",
Description: "Manage server-wide settings and access to resources such as organizations, users, and licenses",
HideFromTabs: true,
Id: "admin",
Icon: "shield",

View File

@ -40,7 +40,7 @@ func (s *ServiceImpl) setupConfigNodes(c *models.ReqContext) ([]*navtree.NavLink
configNodes = append(configNodes, &navtree.NavLink{
Text: "Users",
Id: "users",
Description: "Manage org members",
Description: "Invite and assign roles to users",
Icon: "user",
Url: s.cfg.AppSubURL + "/org/users",
})
@ -50,7 +50,7 @@ func (s *ServiceImpl) setupConfigNodes(c *models.ReqContext) ([]*navtree.NavLink
configNodes = append(configNodes, &navtree.NavLink{
Text: "Teams",
Id: "teams",
Description: "Manage org groups",
Description: "Groups of users that have common dashboard and permission needs",
Icon: "users-alt",
Url: s.cfg.AppSubURL + "/org/teams",
})
@ -61,7 +61,7 @@ func (s *ServiceImpl) setupConfigNodes(c *models.ReqContext) ([]*navtree.NavLink
configNodes = append(configNodes, &navtree.NavLink{
Text: "Plugins",
Id: "plugins",
Description: "View and configure plugins",
Description: "Extend the Grafana experience with plugins",
Icon: "plug",
Url: s.cfg.AppSubURL + "/plugins",
})
@ -71,7 +71,7 @@ func (s *ServiceImpl) setupConfigNodes(c *models.ReqContext) ([]*navtree.NavLink
configNodes = append(configNodes, &navtree.NavLink{
Text: "Preferences",
Id: "org-settings",
Description: "Organization preferences",
Description: "Manage preferences across an organization",
Icon: "sliders-v-alt",
Url: s.cfg.AppSubURL + "/org",
})
@ -88,7 +88,7 @@ func (s *ServiceImpl) setupConfigNodes(c *models.ReqContext) ([]*navtree.NavLink
configNodes = append(configNodes, &navtree.NavLink{
Text: "API keys",
Id: "apikeys",
Description: "Create & manage API keys",
Description: "Manage and create API keys that are used to interact with Grafana HTTP APIs",
Icon: "key-skeleton-alt",
Url: s.cfg.AppSubURL + "/org/apikeys",
})
@ -98,7 +98,7 @@ func (s *ServiceImpl) setupConfigNodes(c *models.ReqContext) ([]*navtree.NavLink
configNodes = append(configNodes, &navtree.NavLink{
Text: "Service accounts",
Id: "serviceaccounts",
Description: "Manage service accounts",
Description: "Use service accounts to run automated workloads in Grafana",
Icon: "gf-service-account",
Url: s.cfg.AppSubURL + "/org/serviceaccounts",
})

View File

@ -77,14 +77,15 @@ func (s *ServiceImpl) GetNavTree(c *models.ReqContext, hasEditPerm bool, prefs *
dashboardsUrl := "/dashboards"
dashboardLink := &navtree.NavLink{
Text: "Dashboards",
Id: "dashboards",
SubTitle: "Manage dashboards and folders",
Icon: "apps",
Url: s.cfg.AppSubURL + dashboardsUrl,
SortWeight: navtree.WeightDashboard,
Section: navtree.NavSectionCore,
Children: dashboardChildLinks,
Text: "Dashboards",
Id: "dashboards",
Description: "Create and manage dashboards to visualize your data",
SubTitle: "Manage dashboards and folders",
Icon: "apps",
Url: s.cfg.AppSubURL + dashboardsUrl,
SortWeight: navtree.WeightDashboard,
Section: navtree.NavSectionCore,
Children: dashboardChildLinks,
}
if s.features.IsEnabled(featuremgmt.FlagTopnav) {
@ -135,7 +136,7 @@ func (s *ServiceImpl) GetNavTree(c *models.ReqContext, hasEditPerm bool, prefs *
navTree = append(navTree, &navtree.NavLink{
Text: "Apps",
Icon: "apps",
Description: "App plugins",
Description: "App plugins that extend the Grafana experience",
Id: "apps",
Children: appLinks,
Section: navtree.NavSectionCore,
@ -357,22 +358,24 @@ func (s *ServiceImpl) buildDashboardNavLinks(c *models.ReqContext, hasEditPerm b
})
}
dashboardChildNavs = append(dashboardChildNavs, &navtree.NavLink{
Text: "Playlists", Id: "dashboards/playlists", Url: s.cfg.AppSubURL + "/playlists", Icon: "presentation-play",
Text: "Playlists", Description: "Groups of dashboards that are displayed in a sequence", Id: "dashboards/playlists", Url: s.cfg.AppSubURL + "/playlists", Icon: "presentation-play",
})
if c.IsSignedIn {
dashboardChildNavs = append(dashboardChildNavs, &navtree.NavLink{
Text: "Snapshots",
Id: "dashboards/snapshots",
Url: s.cfg.AppSubURL + "/dashboard/snapshots",
Icon: "camera",
Text: "Snapshots",
Description: "Interactive, publically available, point-in-time representations of dashboards",
Id: "dashboards/snapshots",
Url: s.cfg.AppSubURL + "/dashboard/snapshots",
Icon: "camera",
})
dashboardChildNavs = append(dashboardChildNavs, &navtree.NavLink{
Text: "Library panels",
Id: "dashboards/library-panels",
Url: s.cfg.AppSubURL + "/library-panels",
Icon: "library-panel",
Text: "Library panels",
Description: "Reusable panels that can be added to multiple dashboards",
Id: "dashboards/library-panels",
Url: s.cfg.AppSubURL + "/library-panels",
Icon: "library-panel",
})
}
@ -427,13 +430,14 @@ func (s *ServiceImpl) buildLegacyAlertNavLinks(c *models.ReqContext) []*navtree.
}
var alertNav = navtree.NavLink{
Text: "Alerting",
SubTitle: "Alert rules and notifications",
Id: "alerting-legacy",
Icon: "bell",
Children: alertChildNavs,
Section: navtree.NavSectionCore,
SortWeight: navtree.WeightAlerting,
Text: "Alerting",
Description: "Learn about problems in your systems moments after they occur",
SubTitle: "Alert rules and notifications",
Id: "alerting-legacy",
Icon: "bell",
Children: alertChildNavs,
Section: navtree.NavSectionCore,
SortWeight: navtree.WeightAlerting,
}
if s.features.IsEnabled(featuremgmt.FlagTopnav) {
@ -451,21 +455,21 @@ func (s *ServiceImpl) buildAlertNavLinks(c *models.ReqContext, hasEditPerm bool)
if hasAccess(ac.ReqViewer, ac.EvalAny(ac.EvalPermission(ac.ActionAlertingRuleRead), ac.EvalPermission(ac.ActionAlertingRuleExternalRead))) {
alertChildNavs = append(alertChildNavs, &navtree.NavLink{
Text: "Alert rules", Id: "alert-list", Url: s.cfg.AppSubURL + "/alerting/list", Icon: "list-ul",
Text: "Alert rules", Description: "Rules that determine whether an alert will fire", Id: "alert-list", Url: s.cfg.AppSubURL + "/alerting/list", Icon: "list-ul",
})
}
if hasAccess(ac.ReqOrgAdminOrEditor, ac.EvalAny(ac.EvalPermission(ac.ActionAlertingNotificationsRead), ac.EvalPermission(ac.ActionAlertingNotificationsExternalRead))) {
alertChildNavs = append(alertChildNavs, &navtree.NavLink{
Text: "Contact points", Id: "receivers", Url: s.cfg.AppSubURL + "/alerting/notifications",
Text: "Contact points", Description: "Decide how your contacts are notified when an alert fires", Id: "receivers", Url: s.cfg.AppSubURL + "/alerting/notifications",
Icon: "comment-alt-share", SubTitle: "Manage the settings of your contact points",
})
alertChildNavs = append(alertChildNavs, &navtree.NavLink{Text: "Notification policies", Id: "am-routes", Url: s.cfg.AppSubURL + "/alerting/routes", Icon: "sitemap"})
alertChildNavs = append(alertChildNavs, &navtree.NavLink{Text: "Notification policies", Description: "Determine how alerts are routed to contact points", Id: "am-routes", Url: s.cfg.AppSubURL + "/alerting/routes", Icon: "sitemap"})
}
if hasAccess(ac.ReqViewer, ac.EvalAny(ac.EvalPermission(ac.ActionAlertingInstanceRead), ac.EvalPermission(ac.ActionAlertingInstancesExternalRead))) {
alertChildNavs = append(alertChildNavs, &navtree.NavLink{Text: "Silences", Id: "silences", Url: s.cfg.AppSubURL + "/alerting/silences", Icon: "bell-slash"})
alertChildNavs = append(alertChildNavs, &navtree.NavLink{Text: "Alert groups", Id: "groups", Url: s.cfg.AppSubURL + "/alerting/groups", Icon: "layer-group"})
alertChildNavs = append(alertChildNavs, &navtree.NavLink{Text: "Silences", Description: "Stop notifications from one or more alerting rules", Id: "silences", Url: s.cfg.AppSubURL + "/alerting/silences", Icon: "bell-slash"})
alertChildNavs = append(alertChildNavs, &navtree.NavLink{Text: "Alert groups", Description: "See grouped alerts from an Alertmanager instance", Id: "groups", Url: s.cfg.AppSubURL + "/alerting/groups", Icon: "layer-group"})
}
if c.OrgRole == org.RoleAdmin {
@ -490,13 +494,14 @@ func (s *ServiceImpl) buildAlertNavLinks(c *models.ReqContext, hasEditPerm bool)
if len(alertChildNavs) > 0 {
var alertNav = navtree.NavLink{
Text: "Alerting",
SubTitle: "Alert rules and notifications",
Id: "alerting",
Icon: "bell",
Children: alertChildNavs,
Section: navtree.NavSectionCore,
SortWeight: navtree.WeightAlerting,
Text: "Alerting",
Description: "Learn about problems in your systems moments after they occur",
SubTitle: "Alert rules and notifications",
Id: "alerting",
Icon: "bell",
Children: alertChildNavs,
Section: navtree.NavSectionCore,
SortWeight: navtree.WeightAlerting,
}
if s.features.IsEnabled(featuremgmt.FlagTopnav) {
@ -562,19 +567,19 @@ func (s *ServiceImpl) buildAdminNavLinks(c *models.ReqContext) []*navtree.NavLin
if hasAccess(ac.ReqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead, ac.ScopeGlobalUsersAll)) {
adminNavLinks = append(adminNavLinks, &navtree.NavLink{
Text: "Users", Id: "global-users", Url: s.cfg.AppSubURL + "/admin/users", Icon: "user",
Text: "Users", Description: "Manage and create users across the whole Grafana server", Id: "global-users", Url: s.cfg.AppSubURL + "/admin/users", Icon: "user",
})
}
if hasGlobalAccess(ac.ReqGrafanaAdmin, orgsAccessEvaluator) {
adminNavLinks = append(adminNavLinks, &navtree.NavLink{
Text: "Orgs", Id: "global-orgs", Url: s.cfg.AppSubURL + "/admin/orgs", Icon: "building",
Text: "Organizations", Description: "Isolated instances of Grafana running on the same server", Id: "global-orgs", Url: s.cfg.AppSubURL + "/admin/orgs", Icon: "building",
})
}
if hasAccess(ac.ReqGrafanaAdmin, ac.EvalPermission(ac.ActionSettingsRead)) {
adminNavLinks = append(adminNavLinks, &navtree.NavLink{
Text: "Settings", Id: "server-settings", Url: s.cfg.AppSubURL + "/admin/settings", Icon: "sliders-v-alt",
Text: "Settings", Description: "View the settings defined in your Grafana config", Id: "server-settings", Url: s.cfg.AppSubURL + "/admin/settings", Icon: "sliders-v-alt",
})
}

View File

@ -27,7 +27,7 @@ describe('NavLandingPage', () => {
const mockChild3 = {
text: 'Child 3',
id: 'child3',
subTitle: 'Child 3 subtitle',
description: 'Child 3 subtitle',
url: 'mock-section-url/child3',
hideFromTabs: true,
children: [
@ -86,9 +86,9 @@ describe('NavLandingPage', () => {
expect(screen.getByRole('heading', { name: mockChild3.text })).toBeInTheDocument();
});
it('renders the subTitle for a nested section', () => {
it('renders the description for a nested section', () => {
setup();
expect(screen.getByText(mockChild3.subTitle)).toBeInTheDocument();
expect(screen.getByText(mockChild3.description)).toBeInTheDocument();
});
it('renders a link for a nested child', () => {

View File

@ -40,7 +40,7 @@ export function NavLandingPage({ navId }: Props) {
<div style={{ display: 'flex', alignItems: 'center' }}>
<h2 className={styles.nestedTitle}>{child.text}</h2>
</div>
<div className={styles.nestedDescription}>{child.subTitle}</div>
<div className={styles.nestedDescription}>{child.description}</div>
<div className={styles.grid}>
{child.children?.map((child) => (
<NavLandingPageCard

View File

@ -11,7 +11,7 @@ export interface Props {
export function PageHeader({ navItem, subTitle }: Props) {
const styles = useStyles2(getStyles);
const sub = subTitle ?? navItem.subTitle;
const sub = subTitle ?? navItem.description;
return (
<>

View File

@ -30,7 +30,7 @@ export default function AdminListOrgsPages() {
}, [fetchOrgs]);
return (
<Page navId="global-orgs" subTitle="Manage and create orgs across the whole Grafana server.">
<Page navId="global-orgs">
<Page.Contents>
<>
<div className="page-action-bar">

View File

@ -77,7 +77,7 @@ const UserListAdminPageUnConnected = ({
const showLicensedRole = useMemo(() => users.some((user) => user.licensedRole), [users]);
return (
<Page navId="global-users" subTitle="Manage and create users across the whole Grafana server.">
<Page navId="global-users">
<Page.Contents>
<div className="page-action-bar">
<div className="gf-form gf-form--grow">

View File

@ -52,7 +52,6 @@ function mapStateToProps(state: StoreState) {
const defaultPageProps = {
navId: 'apikeys',
subTitle: 'Manage and create API keys that are used to interact with Grafana HTTP APIs.',
};
const mapDispatchToProps = {