2015-01-29 05:10:34 -06:00
package api
import (
2016-09-23 05:29:53 -05:00
"fmt"
2016-07-05 10:59:43 -05:00
"strings"
2015-02-05 03:37:13 -06:00
"github.com/grafana/grafana/pkg/api/dtos"
2016-04-02 15:54:06 -05:00
"github.com/grafana/grafana/pkg/bus"
2015-11-20 02:43:10 -06:00
m "github.com/grafana/grafana/pkg/models"
2015-10-06 04:20:50 -05:00
"github.com/grafana/grafana/pkg/plugins"
2015-02-05 03:37:13 -06:00
"github.com/grafana/grafana/pkg/setting"
2015-01-29 05:10:34 -06:00
)
2018-03-07 10:54:50 -06:00
func setIndexViewData ( c * m . ReqContext ) ( * dtos . IndexViewData , error ) {
2015-02-18 07:06:44 -06:00
settings , err := getFrontendSettingsMap ( c )
2015-01-29 05:10:34 -06:00
if err != nil {
2015-11-20 02:43:10 -06:00
return nil , err
2015-01-29 05:10:34 -06:00
}
2016-04-02 15:54:06 -05:00
prefsQuery := m . GetPreferencesWithDefaultsQuery { OrgId : c . OrgId , UserId : c . UserId }
if err := bus . Dispatch ( & prefsQuery ) ; err != nil {
return nil , err
}
prefs := prefsQuery . Result
2016-07-05 10:59:43 -05:00
// Read locale from acccept-language
acceptLang := c . Req . Header . Get ( "Accept-Language" )
locale := "en-US"
if len ( acceptLang ) > 0 {
parts := strings . Split ( acceptLang , "," )
locale = parts [ 0 ]
}
2018-03-22 06:37:35 -05:00
appURL := setting . AppUrl
appSubURL := setting . AppSubUrl
2016-09-23 05:29:53 -05:00
// special case when doing localhost call from phantomjs
if c . IsRenderCall {
2018-03-22 06:37:35 -05:00
appURL = fmt . Sprintf ( "%s://localhost:%s" , setting . Protocol , setting . HttpPort )
appSubURL = ""
2016-09-23 05:29:53 -05:00
settings [ "appSubUrl" ] = ""
}
2015-11-20 02:43:10 -06:00
var data = dtos . IndexViewData {
User : & dtos . CurrentUser {
Id : c . UserId ,
IsSignedIn : c . IsSignedIn ,
Login : c . Login ,
Email : c . Email ,
Name : c . Name ,
2017-08-16 08:03:49 -05:00
OrgCount : c . OrgCount ,
2015-11-20 02:43:10 -06:00
OrgId : c . OrgId ,
OrgName : c . OrgName ,
OrgRole : c . OrgRole ,
GravatarUrl : dtos . GetGravatarUrl ( c . Email ) ,
IsGrafanaAdmin : c . IsGrafanaAdmin ,
2016-04-02 15:54:06 -05:00
LightTheme : prefs . Theme == "light" ,
Timezone : prefs . Timezone ,
2016-07-05 10:59:43 -05:00
Locale : locale ,
2016-11-09 03:41:39 -06:00
HelpFlags1 : c . HelpFlags1 ,
2015-11-20 02:43:10 -06:00
} ,
2016-05-03 02:00:58 -05:00
Settings : settings ,
2017-10-11 14:36:03 -05:00
Theme : prefs . Theme ,
2018-03-22 06:37:35 -05:00
AppUrl : appURL ,
AppSubUrl : appSubURL ,
2016-05-03 02:00:58 -05:00
GoogleAnalyticsId : setting . GoogleAnalyticsId ,
GoogleTagManagerId : setting . GoogleTagManagerId ,
BuildVersion : setting . BuildVersion ,
BuildCommit : setting . BuildCommit ,
NewGrafanaVersion : plugins . GrafanaLatestVersion ,
NewGrafanaVersionExists : plugins . GrafanaHasUpdate ,
2015-01-29 05:10:34 -06:00
}
2015-05-01 01:40:13 -05:00
if setting . DisableGravatar {
2018-03-06 04:46:01 -06:00
data . User . GravatarUrl = setting . AppSubUrl + "/public/img/user_profile.png"
2015-05-01 01:40:13 -05:00
}
2015-11-20 02:43:10 -06:00
if len ( data . User . Name ) == 0 {
data . User . Name = data . User . Login
2015-02-03 03:46:52 -06:00
}
2018-03-22 06:37:35 -05:00
themeURLParam := c . Query ( "theme" )
if themeURLParam == "light" {
2015-11-20 02:43:10 -06:00
data . User . LightTheme = true
2017-10-18 02:48:37 -05:00
data . Theme = "light"
2015-04-02 02:21:38 -05:00
}
2017-06-22 17:41:39 -05:00
if c . OrgRole == m . ROLE_ADMIN || c . OrgRole == m . ROLE_EDITOR {
2017-08-15 10:52:52 -05:00
data . NavTree = append ( data . NavTree , & dtos . NavLink {
2017-08-16 08:03:49 -05:00
Text : "Create" ,
2017-12-04 09:00:22 -06:00
Id : "create" ,
2017-06-22 17:41:39 -05:00
Icon : "fa fa-fw fa-plus" ,
2017-12-15 08:17:05 -06:00
Url : setting . AppSubUrl + "/dashboard/new" ,
2017-06-22 17:41:39 -05:00
Children : [ ] * dtos . NavLink {
2017-10-14 14:17:16 -05:00
{ Text : "Dashboard" , Icon : "gicon gicon-dashboard-new" , Url : setting . AppSubUrl + "/dashboard/new" } ,
2017-12-07 12:32:38 -06:00
{ Text : "Folder" , SubTitle : "Create a new folder to organize your dashboards" , Id : "folder" , Icon : "gicon gicon-folder-new" , Url : setting . AppSubUrl + "/dashboards/folder/new" } ,
2017-12-05 05:19:01 -06:00
{ Text : "Import" , SubTitle : "Import dashboard from file or Grafana.com" , Id : "import" , Icon : "gicon gicon-dashboard-import" , Url : setting . AppSubUrl + "/dashboard/import" } ,
2017-06-22 17:41:39 -05:00
} ,
} )
2016-03-10 09:38:16 -06:00
}
2017-06-22 17:41:39 -05:00
dashboardChildNavs := [ ] * dtos . NavLink {
2018-01-11 08:42:45 -06:00
{ Text : "Home" , Id : "home" , Url : setting . AppSubUrl + "/" , Icon : "gicon gicon-home" , HideFromTabs : true } ,
{ Text : "Divider" , Divider : true , Id : "divider" , HideFromTabs : true } ,
2017-12-13 16:48:44 -06:00
{ Text : "Manage" , Id : "manage-dashboards" , Url : setting . AppSubUrl + "/dashboards" , Icon : "gicon gicon-manage" } ,
{ Text : "Playlists" , Id : "playlists" , Url : setting . AppSubUrl + "/playlists" , Icon : "gicon gicon-playlists" } ,
{ Text : "Snapshots" , Id : "snapshots" , Url : setting . AppSubUrl + "/dashboard/snapshots" , Icon : "gicon gicon-snapshots" } ,
2016-03-10 09:38:16 -06:00
}
2017-08-15 10:52:52 -05:00
data . NavTree = append ( data . NavTree , & dtos . NavLink {
2016-03-10 09:38:16 -06:00
Text : "Dashboards" ,
2017-08-15 13:24:16 -05:00
Id : "dashboards" ,
2017-12-01 04:32:00 -06:00
SubTitle : "Manage dashboards & folders" ,
2017-10-14 14:17:16 -05:00
Icon : "gicon gicon-dashboard" ,
2017-12-01 05:51:46 -06:00
Url : setting . AppSubUrl + "/" ,
2016-03-10 09:38:16 -06:00
Children : dashboardChildNavs ,
2015-11-20 02:43:10 -06:00
} )
2018-04-26 04:58:42 -05:00
// data.NavTree = append(data.NavTree, &dtos.NavLink{
// Text: "Explore",
// Id: "explore",
// SubTitle: "Explore your data",
// Icon: "fa fa-rocket",
// Url: setting.AppSubUrl + "/explore",
// Children: []*dtos.NavLink{
// {Text: "New tab", Icon: "gicon gicon-dashboard-new", Url: setting.AppSubUrl + "/explore/new"},
// },
// })
2017-08-15 13:24:16 -05:00
if c . IsSignedIn {
2018-04-16 06:37:05 -05:00
// Only set login if it's different from the name
var login string
if c . SignedInUser . Login != c . SignedInUser . NameOrFallback ( ) {
login = c . SignedInUser . Login
}
2017-08-16 08:03:49 -05:00
profileNode := & dtos . NavLink {
2017-12-15 06:06:11 -06:00
Text : c . SignedInUser . NameOrFallback ( ) ,
2018-04-16 06:37:05 -05:00
SubTitle : login ,
2017-08-15 16:17:34 -05:00
Id : "profile" ,
Img : data . User . GravatarUrl ,
Url : setting . AppSubUrl + "/profile" ,
HideFromMenu : true ,
2017-08-15 13:24:16 -05:00
Children : [ ] * dtos . NavLink {
2017-12-13 16:48:44 -06:00
{ Text : "Preferences" , Id : "profile-settings" , Url : setting . AppSubUrl + "/profile" , Icon : "gicon gicon-preferences" } ,
2017-08-15 13:24:16 -05:00
{ Text : "Change Password" , Id : "change-password" , Url : setting . AppSubUrl + "/profile/password" , Icon : "fa fa-fw fa-lock" , HideFromMenu : true } ,
} ,
2017-08-16 08:03:49 -05:00
}
if ! setting . DisableSignoutMenu {
// add sign out first
2017-11-30 10:28:24 -06:00
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" ,
} )
2017-08-16 08:03:49 -05:00
}
data . NavTree = append ( data . NavTree , profileNode )
2017-08-15 13:24:16 -05:00
}
2017-01-25 06:32:26 -06:00
if setting . AlertingEnabled && ( c . OrgRole == m . ROLE_ADMIN || c . OrgRole == m . ROLE_EDITOR ) {
2016-06-16 08:21:23 -05:00
alertChildNavs := [ ] * dtos . NavLink {
2017-12-13 16:48:44 -06:00
{ Text : "Alert Rules" , Id : "alert-list" , Url : setting . AppSubUrl + "/alerting/list" , Icon : "gicon gicon-alert-rules" } ,
2017-11-30 04:31:38 -06:00
{ Text : "Notification channels" , Id : "channels" , Url : setting . AppSubUrl + "/alerting/notifications" , Icon : "gicon gicon-alert-notification-channel" } ,
2016-06-16 08:21:23 -05:00
}
2017-08-15 10:52:52 -05:00
data . NavTree = append ( data . NavTree , & dtos . NavLink {
2016-06-16 08:21:23 -05:00
Text : "Alerting" ,
2017-11-30 08:37:03 -06:00
SubTitle : "Alert rules & notifications" ,
2017-08-15 13:24:16 -05:00
Id : "alerting" ,
2017-10-14 14:17:16 -05:00
Icon : "gicon gicon-alert" ,
2016-08-16 02:52:45 -05:00
Url : setting . AppSubUrl + "/alerting/list" ,
2016-06-16 08:21:23 -05:00
Children : alertChildNavs ,
2016-05-03 09:46:10 -05:00
} )
}
2016-01-10 14:37:11 -06:00
enabledPlugins , err := plugins . GetEnabledPlugins ( c . OrgId )
2015-12-03 09:43:55 -06:00
if err != nil {
return nil , err
}
2015-12-21 16:09:27 -06:00
for _ , plugin := range enabledPlugins . Apps {
2016-01-11 11:03:08 -06:00
if plugin . Pinned {
2016-03-21 13:07:08 -05:00
appLink := & dtos . NavLink {
2016-01-11 11:03:08 -06:00
Text : plugin . Name ,
2017-08-15 13:24:16 -05:00
Id : "plugin-page-" + plugin . Id ,
2016-03-22 04:15:47 -05:00
Url : plugin . DefaultNavUrl ,
2016-01-11 11:03:08 -06:00
Img : plugin . Info . Logos . Small ,
2016-02-09 07:06:23 -06:00
}
2016-03-21 13:07:08 -05:00
for _ , include := range plugin . Includes {
2016-04-25 07:00:49 -05:00
if ! c . HasUserRole ( include . Role ) {
continue
}
2016-03-21 13:07:08 -05:00
if include . Type == "page" && include . AddToNav {
link := & dtos . NavLink {
Url : setting . AppSubUrl + "/plugins/" + plugin . Id + "/page/" + include . Slug ,
Text : include . Name ,
}
appLink . Children = append ( appLink . Children , link )
2016-03-01 04:07:51 -06:00
}
2016-04-25 07:00:49 -05:00
2016-03-21 13:07:08 -05:00
if include . Type == "dashboard" && include . AddToNav {
link := & dtos . NavLink {
Url : setting . AppSubUrl + "/dashboard/db/" + include . Slug ,
Text : include . Name ,
}
appLink . Children = append ( appLink . Children , link )
}
}
2016-09-27 07:39:51 -05:00
if len ( appLink . Children ) > 0 && c . OrgRole == m . ROLE_ADMIN {
2016-03-21 13:07:08 -05:00
appLink . Children = append ( appLink . Children , & dtos . NavLink { Divider : true } )
2017-12-13 16:48:44 -06:00
appLink . Children = append ( appLink . Children , & dtos . NavLink { Text : "Plugin Config" , Icon : "gicon gicon-cog" , Url : setting . AppSubUrl + "/plugins/" + plugin . Id + "/edit" } )
2016-02-09 07:06:23 -06:00
}
2016-04-25 07:00:49 -05:00
if len ( appLink . Children ) > 0 {
2017-08-15 10:52:52 -05:00
data . NavTree = append ( data . NavTree , appLink )
2016-04-25 07:00:49 -05:00
}
2015-10-06 04:20:50 -05:00
}
2015-08-21 02:30:39 -05:00
}
2015-11-11 00:30:07 -06:00
2017-08-15 07:49:12 -05:00
if c . OrgRole == m . ROLE_ADMIN {
cfgNode := & dtos . NavLink {
2017-11-30 08:37:03 -06:00
Id : "cfg" ,
Text : "Configuration" ,
SubTitle : "Organization: " + c . OrgName ,
2017-12-13 16:48:44 -06:00
Icon : "gicon gicon-cog" ,
2017-11-30 08:37:03 -06:00
Url : setting . AppSubUrl + "/datasources" ,
2016-02-19 21:00:29 -06:00
Children : [ ] * dtos . NavLink {
2017-08-15 07:49:12 -05:00
{
2017-08-15 10:52:52 -05:00
Text : "Data Sources" ,
2017-10-27 01:33:04 -05:00
Icon : "gicon gicon-datasources" ,
2017-08-15 10:52:52 -05:00
Description : "Add and configure data sources" ,
Id : "datasources" ,
Url : setting . AppSubUrl + "/datasources" ,
2017-08-15 07:49:12 -05:00
} ,
2017-08-15 10:52:52 -05:00
{
2017-12-13 04:21:33 -06:00
Text : "Users" ,
2017-08-15 10:52:52 -05:00
Id : "users" ,
2017-08-18 07:49:04 -05:00
Description : "Manage org members" ,
2017-12-13 16:48:44 -06:00
Icon : "gicon gicon-user" ,
2017-08-15 10:52:52 -05:00
Url : setting . AppSubUrl + "/org/users" ,
} ,
2017-08-18 07:49:04 -05:00
{
2017-11-30 08:37:03 -06:00
Text : "Teams" ,
2017-12-01 03:47:21 -06:00
Id : "teams" ,
2017-08-18 07:49:04 -05:00
Description : "Manage org groups" ,
2017-12-08 09:25:45 -06:00
Icon : "gicon gicon-team" ,
Url : setting . AppSubUrl + "/org/teams" ,
2017-08-18 07:49:04 -05:00
} ,
2017-11-30 08:37:03 -06:00
{
Text : "Plugins" ,
Id : "plugins" ,
Description : "View and configure plugins" ,
2017-12-13 16:48:44 -06:00
Icon : "gicon gicon-plugins" ,
2017-11-30 08:37:03 -06:00
Url : setting . AppSubUrl + "/plugins" ,
} ,
{
Text : "Preferences" ,
Id : "org-settings" ,
Description : "Organization preferences" ,
2017-12-13 16:48:44 -06:00
Icon : "gicon gicon-preferences" ,
2017-11-30 08:37:03 -06:00
Url : setting . AppSubUrl + "/org" ,
} ,
2017-08-15 10:52:52 -05:00
{
Text : "API Keys" ,
2017-08-15 13:24:16 -05:00
Id : "apikeys" ,
2017-08-15 10:52:52 -05:00
Description : "Create & manage API keys" ,
2017-12-13 16:48:44 -06:00
Icon : "gicon gicon-apikeys" ,
2017-08-15 10:52:52 -05:00
Url : setting . AppSubUrl + "/org/apikeys" ,
} ,
2016-02-20 11:31:09 -06:00
} ,
2017-08-15 07:49:12 -05:00
}
2017-12-01 05:51:46 -06:00
if c . IsGrafanaAdmin {
cfgNode . Children = append ( cfgNode . Children , & dtos . NavLink {
2018-01-18 11:17:58 -06:00
Divider : true , HideFromTabs : true , Id : "admin-divider" , Text : "Text" ,
2017-12-01 05:51:46 -06:00
} )
cfgNode . Children = append ( cfgNode . Children , & dtos . NavLink {
2017-12-01 06:49:15 -06:00
Text : "Server Admin" ,
HideFromTabs : true ,
SubTitle : "Manage all users & orgs" ,
Id : "admin" ,
2017-12-13 16:48:44 -06:00
Icon : "gicon gicon-shield" ,
2017-12-01 06:49:15 -06:00
Url : setting . AppSubUrl + "/admin/users" ,
2017-12-01 05:51:46 -06:00
Children : [ ] * dtos . NavLink {
2017-12-13 16:48:44 -06:00
{ Text : "Users" , Id : "global-users" , Url : setting . AppSubUrl + "/admin/users" , Icon : "gicon gicon-user" } ,
2017-12-01 06:49:15 -06:00
{ Text : "Orgs" , Id : "global-orgs" , Url : setting . AppSubUrl + "/admin/orgs" , Icon : "gicon gicon-org" } ,
2017-12-13 16:48:44 -06:00
{ Text : "Settings" , Id : "server-settings" , Url : setting . AppSubUrl + "/admin/settings" , Icon : "gicon gicon-preferences" } ,
2017-12-01 06:49:15 -06:00
{ Text : "Stats" , Id : "server-stats" , Url : setting . AppSubUrl + "/admin/stats" , Icon : "fa fa-fw fa-bar-chart" } ,
{ Text : "Style Guide" , Id : "styleguide" , Url : setting . AppSubUrl + "/styleguide" , Icon : "fa fa-fw fa-eyedropper" } ,
2017-12-01 05:51:46 -06:00
} ,
} )
}
2017-08-15 07:49:12 -05:00
2017-08-15 10:52:52 -05:00
data . NavTree = append ( data . NavTree , cfgNode )
2016-02-14 10:37:05 -06:00
}
2017-08-16 08:03:49 -05:00
data . NavTree = append ( data . NavTree , & dtos . NavLink {
Text : "Help" ,
2018-04-16 09:25:28 -05:00
SubTitle : fmt . Sprintf ( ` Grafana v%s (%s) ` , setting . BuildVersion , setting . BuildCommit ) ,
2017-08-16 08:03:49 -05:00
Id : "help" ,
Url : "#" ,
2017-12-13 16:48:44 -06:00
Icon : "gicon gicon-question" ,
2017-08-16 08:03:49 -05:00
HideFromMenu : true ,
Children : [ ] * dtos . NavLink {
{ Text : "Keyboard shortcuts" , Url : "/shortcuts" , Icon : "fa fa-fw fa-keyboard-o" , Target : "_self" } ,
{ Text : "Community site" , Url : "http://community.grafana.com" , Icon : "fa fa-fw fa-comment" , Target : "_blank" } ,
{ Text : "Documentation" , Url : "http://docs.grafana.org" , Icon : "fa fa-fw fa-file" , Target : "_blank" } ,
} ,
} )
2015-11-20 02:43:10 -06:00
return & data , nil
2015-01-29 05:10:34 -06:00
}
2018-03-07 10:54:50 -06:00
func Index ( c * m . ReqContext ) {
2018-03-22 06:37:35 -05:00
data , err := setIndexViewData ( c )
if err != nil {
2015-01-29 05:10:34 -06:00
c . Handle ( 500 , "Failed to get settings" , err )
return
}
2018-03-22 06:37:35 -05:00
c . HTML ( 200 , "index" , data )
2015-01-29 05:10:34 -06:00
}
2018-03-07 10:54:50 -06:00
func NotFoundHandler ( c * m . ReqContext ) {
2015-01-29 05:10:34 -06:00
if c . IsApiRequest ( ) {
2015-03-22 14:14:00 -05:00
c . JsonApiErr ( 404 , "Not found" , nil )
2015-01-29 05:10:34 -06:00
return
}
2018-03-22 06:37:35 -05:00
data , err := setIndexViewData ( c )
if err != nil {
2015-01-29 05:10:34 -06:00
c . Handle ( 500 , "Failed to get settings" , err )
return
}
2018-03-22 06:37:35 -05:00
c . HTML ( 404 , "index" , data )
2015-01-29 05:10:34 -06:00
}