diff --git a/pkg/api/dtos/index.go b/pkg/api/dtos/index.go index 5661ae1df91..8c7f505277d 100644 --- a/pkg/api/dtos/index.go +++ b/pkg/api/dtos/index.go @@ -24,11 +24,13 @@ type NavLink struct { Id string `json:"id,omitempty"` Text string `json:"text,omitempty"` Description string `json:"description,omitempty"` + SubTitle string `json:"subTitle,omitempty"` Icon string `json:"icon,omitempty"` Img string `json:"img,omitempty"` Url string `json:"url,omitempty"` Target string `json:"target,omitempty"` Divider bool `json:"divider,omitempty"` HideFromMenu bool `json:"hideFromMenu,omitempty"` + HideFromTabs bool `json:"hideFromTabs,omitempty"` Children []*NavLink `json:"children,omitempty"` } diff --git a/pkg/api/index.go b/pkg/api/index.go index bf5a128a03f..a0f21cc9571 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -101,38 +101,41 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) { } dashboardChildNavs := []*dtos.NavLink{ - {Text: "Home", Url: setting.AppSubUrl + "/", Icon: "fa fa-fw fa-home"}, + {Text: "Home", Url: setting.AppSubUrl + "/", Icon: "fa fa-fw fa-home", HideFromTabs: true}, + {Divider: true}, + {Text: "Manage", Id: "dashboards", Url: setting.AppSubUrl + "/dashboards", Icon: "fa fa-fw fa-sitemap"}, {Text: "Playlists", Id: "playlists", Url: setting.AppSubUrl + "/playlists", Icon: "fa fa-fw fa-film"}, {Text: "Snapshots", Id: "snapshots", Url: setting.AppSubUrl + "/dashboard/snapshots", Icon: "icon-gf icon-gf-fw icon-gf-snapshot"}, - {Text: "Dashboard List", Description: "Manage Dashboards And Folders", Id: "dashboards", Url: setting.AppSubUrl + "/dashboards", Icon: "fa fa-fw fa-bars"}, } data.NavTree = append(data.NavTree, &dtos.NavLink{ Text: "Dashboards", Id: "dashboards", + SubTitle: "Manage dashboards & folders", Icon: "gicon gicon-dashboard", - Url: setting.AppSubUrl + "/", + Url: setting.AppSubUrl + "/dashboards", Children: dashboardChildNavs, }) if c.IsSignedIn { profileNode := &dtos.NavLink{ - Text: c.SignedInUser.Login, + Text: c.SignedInUser.Name, + SubTitle: c.SignedInUser.Login, Id: "profile", Img: data.User.GravatarUrl, Url: setting.AppSubUrl + "/profile", HideFromMenu: true, Children: []*dtos.NavLink{ - {Text: "Your profile", Url: setting.AppSubUrl + "/profile", Icon: "fa fa-fw fa-sliders"}, + {Text: "Preferences", Id: "profile-settings", Url: setting.AppSubUrl + "/profile", Icon: "fa fa-fw fa-sliders"}, {Text: "Change Password", Id: "change-password", Url: setting.AppSubUrl + "/profile/password", Icon: "fa fa-fw fa-lock", HideFromMenu: true}, }, } if !setting.DisableSignoutMenu { // add sign out first - profileNode.Children = append([]*dtos.NavLink{ - {Text: "Sign out", Url: setting.AppSubUrl + "/logout", Icon: "fa fa-fw fa-sign-out", Target: "_self"}, - }, profileNode.Children...) + profileNode.Children = append(profileNode.Children, &dtos.NavLink{ + Text: "Sign out", Id: "sign-out", Url: setting.AppSubUrl + "/logout", Icon: "fa fa-fw fa-sign-out", Target: "_self", + }) } data.NavTree = append(data.NavTree, profileNode) @@ -140,12 +143,13 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) { if setting.AlertingEnabled && (c.OrgRole == m.ROLE_ADMIN || c.OrgRole == m.ROLE_EDITOR) { alertChildNavs := []*dtos.NavLink{ - {Text: "Alert List", Id: "alert-list", Url: setting.AppSubUrl + "/alerting/list", Icon: "fa fa-fw fa-list-ul"}, - {Text: "Notification channels", Id: "channels", Url: setting.AppSubUrl + "/alerting/notifications", Icon: "fa fa-fw fa-bell-o"}, + {Text: "Alert Rules", Id: "alert-list", Url: setting.AppSubUrl + "/alerting/list", Icon: "fa fa-fw fa-list-ul"}, + {Text: "Notification channels", Id: "channels", Url: setting.AppSubUrl + "/alerting/notifications", Icon: "gicon gicon-alert-notification-channel"}, } data.NavTree = append(data.NavTree, &dtos.NavLink{ Text: "Alerting", + SubTitle: "Alert rules & notifications", Id: "alerting", Icon: "gicon gicon-alert", Url: setting.AppSubUrl + "/alerting/list", @@ -202,10 +206,11 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) { if c.OrgRole == m.ROLE_ADMIN { cfgNode := &dtos.NavLink{ - Id: "cfg", - Text: "Configuration", - Icon: "fa fa-fw fa-cogs", - Url: setting.AppSubUrl + "/configuration", + Id: "cfg", + Text: "Configuration", + SubTitle: "Organization: " + c.OrgName, + Icon: "fa fa-fw fa-cog", + Url: setting.AppSubUrl + "/datasources", Children: []*dtos.NavLink{ { Text: "Data Sources", @@ -213,29 +218,6 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) { Description: "Add and configure data sources", Id: "datasources", Url: setting.AppSubUrl + "/datasources", - Children: []*dtos.NavLink{ - {Text: "List", Url: setting.AppSubUrl + "/datasources", Icon: "gicon gicon-datasources"}, - {Text: "New", Url: setting.AppSubUrl + "/datasources", Icon: "fa fa-fw fa-plus"}, - }, - }, - { - Text: "Preferences", - Id: "org", - Description: "Organization preferences", - Icon: "fa fa-fw fa-sliders", - Url: setting.AppSubUrl + "/org", - }, - { - Text: "Plugins", - Id: "plugins", - Description: "View and configure plugins", - Icon: "icon-gf icon-gf-fw icon-gf-apps", - Url: setting.AppSubUrl + "/plugins", - Children: []*dtos.NavLink{ - {Text: "Panels", Url: setting.AppSubUrl + "/plugins?type=panel", Icon: "fa fa-fw fa-stop"}, - {Text: "Data sources", Url: setting.AppSubUrl + "/plugins?type=datasource", Icon: "icon-gf icon-gf-datasources"}, - {Text: "Apps", Url: setting.AppSubUrl + "/plugins?type=app", Icon: "icon-gf icon-gf-apps"}, - }, }, { Text: "Members", @@ -245,12 +227,32 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) { Url: setting.AppSubUrl + "/org/users", }, { - Text: "Groups", - Id: "users", + Text: "Teams", + Id: "teams", Description: "Manage org groups", - Icon: "fa fa-fw fa-users", + Icon: "gicon gicon-user-group", Url: setting.AppSubUrl + "/org/user-groups", }, + { + Text: "Plugins", + Id: "plugins", + Description: "View and configure plugins", + Icon: "icon-gf icon-gf-fw icon-gf-apps", + Url: setting.AppSubUrl + "/plugins", + // Children: []*dtos.NavLink{ + // {Text: "Panels", Url: setting.AppSubUrl + "/plugins?type=panel", Icon: "fa fa-fw fa-stop"}, + // {Text: "Data sources", Url: setting.AppSubUrl + "/plugins?type=datasource", Icon: "icon-gf icon-gf-datasources"}, + // {Text: "Apps", Url: setting.AppSubUrl + "/plugins?type=app", Icon: "icon-gf icon-gf-apps"}, + // }, + }, + { + Text: "Preferences", + Id: "org-settings", + Description: "Organization preferences", + Icon: "fa fa-fw fa-sliders", + Url: setting.AppSubUrl + "/org", + }, + { Text: "API Keys", Id: "apikeys", @@ -261,21 +263,21 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) { }, } - if c.IsGrafanaAdmin { - cfgNode.Children = append(cfgNode.Children, &dtos.NavLink{ - Text: "Server Admin", - Id: "admin", - Icon: "fa fa-fw fa-shield", - Url: setting.AppSubUrl + "/admin", - Children: []*dtos.NavLink{ - {Text: "Users", Id: "global-users", Url: setting.AppSubUrl + "/admin/users"}, - {Text: "Orgs", Id: "global-orgs", Url: setting.AppSubUrl + "/admin/orgs"}, - {Text: "Server Settings", Id: "server-settings", Url: setting.AppSubUrl + "/admin/settings"}, - {Text: "Server Stats", Id: "server-stats", Url: setting.AppSubUrl + "/admin/stats"}, - {Text: "Style Guide", Id: "styleguide", Url: setting.AppSubUrl + "/styleguide"}, - }, - }) - } + // if c.IsGrafanaAdmin { + // cfgNode.Children = append(cfgNode.Children, &dtos.NavLink{ + // Text: "Server Admin", + // Id: "admin", + // Icon: "fa fa-fw fa-shield", + // Url: setting.AppSubUrl + "/admin", + // Children: []*dtos.NavLink{ + // {Text: "Users", Id: "global-users", Url: setting.AppSubUrl + "/admin/users"}, + // {Text: "Orgs", Id: "global-orgs", Url: setting.AppSubUrl + "/admin/orgs"}, + // {Text: "Server Settings", Id: "server-settings", Url: setting.AppSubUrl + "/admin/settings"}, + // {Text: "Server Stats", Id: "server-stats", Url: setting.AppSubUrl + "/admin/stats"}, + // {Text: "Style Guide", Id: "styleguide", Url: setting.AppSubUrl + "/styleguide"}, + // }, + // }) + // } data.NavTree = append(data.NavTree, cfgNode) } diff --git a/public/app/core/angular_wrappers.ts b/public/app/core/angular_wrappers.ts index 7acdc79d55a..00181736119 100644 --- a/public/app/core/angular_wrappers.ts +++ b/public/app/core/angular_wrappers.ts @@ -1,8 +1,10 @@ import { react2AngularDirective } from 'app/core/utils/react2angular'; import { PasswordStrength } from './components/PasswordStrength'; +import PageHeader from './components/PageHeader'; export function registerAngularDirectives() { react2AngularDirective('passwordStrength', PasswordStrength, ['password']); + react2AngularDirective('pageHeader', PageHeader, ['model', "noTabs"]); } diff --git a/public/app/core/components/PageHeader.tsx b/public/app/core/components/PageHeader.tsx new file mode 100644 index 00000000000..57bcdc3b896 --- /dev/null +++ b/public/app/core/components/PageHeader.tsx @@ -0,0 +1,94 @@ +import React from 'react'; +import { NavModel, NavModelItem } from '../nav_model_srv'; +import classNames from 'classnames'; + +export interface IProps { + model: NavModel; +} + +// function BreadcrumbItem(item: NavModelItem) { +// return ( +// +// {item.text} +// +// ); +// } +// +// function Breadcrumb(model: NavModel) { +// return ( +//
+//
+// +// +// +// {model.breadcrumbs.map(BreadcrumbItem)} +//
+//
+// ); +// } + +function TabItem(tab: NavModelItem) { + if (tab.hideFromTabs || tab.divider) { + return (null); + } + + let tabClasses = classNames({ + 'gf-tabs-link': true, + active: tab.active, + }); + + return ( +
  • + + + {tab.text} + +
  • + ); +} + +function Tabs({main}: {main: NavModelItem}) { + return ; +} + +export default class PageHeader extends React.Component { + constructor(props) { + super(props); + } + + renderHeaderTitle(main) { + return ( +
    + + {main.icon && } + {main.img && } + + +
    +

    {main.text}

    + {main.subTitle &&
    {main.subTitle}
    } + {main.subType && ( +
    + + {main.subType.text} +
    + )} +
    +
    + ); + } + + render() { + return ( +
    +
    +
    + {this.renderHeaderTitle(this.props.model.main)} + + {this.props.model.main.children && } +
    +
    +
    + ); + } +} diff --git a/public/app/core/components/navbar/navbar.html b/public/app/core/components/navbar/navbar.html index aafd806e47d..6d611692efc 100644 --- a/public/app/core/components/navbar/navbar.html +++ b/public/app/core/components/navbar/navbar.html @@ -1,13 +1,11 @@