mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'develop' into develop-light-theme
This commit is contained in:
commit
a16cfb4b3b
@ -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"`
|
||||
}
|
||||
|
@ -101,15 +101,17 @@ 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, HideFromTabs: 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 + "/",
|
||||
Children: dashboardChildNavs,
|
||||
@ -117,22 +119,23 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
|
||||
|
||||
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,27 @@ 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",
|
||||
},
|
||||
{
|
||||
Text: "Preferences",
|
||||
Id: "org-settings",
|
||||
Description: "Organization preferences",
|
||||
Icon: "fa fa-fw fa-sliders",
|
||||
Url: setting.AppSubUrl + "/org",
|
||||
},
|
||||
|
||||
{
|
||||
Text: "API Keys",
|
||||
Id: "apikeys",
|
||||
@ -263,16 +260,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",
|
||||
Divider: true, HideFromTabs: true,
|
||||
})
|
||||
cfgNode.Children = append(cfgNode.Children, &dtos.NavLink{
|
||||
Text: "Server Admin",
|
||||
HideFromTabs: true,
|
||||
SubTitle: "Manage all users & orgs",
|
||||
Id: "admin",
|
||||
Icon: "fa fa-fw fa-shield",
|
||||
Url: setting.AppSubUrl + "/admin/users",
|
||||
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"},
|
||||
{Text: "Users", Id: "global-users", Url: setting.AppSubUrl + "/admin/users", Icon: "icon-gf icon-gf-fw icon-gf-users"},
|
||||
{Text: "Orgs", Id: "global-orgs", Url: setting.AppSubUrl + "/admin/orgs", Icon: "gicon gicon-org"},
|
||||
{Text: "Settings", Id: "server-settings", Url: setting.AppSubUrl + "/admin/settings", Icon: "fa fa-fw fa-sliders"},
|
||||
{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"},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -68,6 +68,15 @@ func NewDashboard(title string) *Dashboard {
|
||||
return dash
|
||||
}
|
||||
|
||||
// NewDashboardFolder creates a new dashboard folder
|
||||
func NewDashboardFolder(title string) *Dashboard {
|
||||
folder := NewDashboard(title)
|
||||
folder.Data.Set("schemaVersion", 16)
|
||||
folder.Data.Set("editable", true)
|
||||
folder.Data.Set("hideControls", true)
|
||||
return folder
|
||||
}
|
||||
|
||||
// GetTags turns the tags in data json into go string array
|
||||
func (dash *Dashboard) GetTags() []string {
|
||||
return dash.Data.Get("tags").MustStringArray()
|
||||
|
@ -49,10 +49,6 @@ func ImportDashboard(cmd *ImportDashboardCommand) error {
|
||||
if dashboard, err = loadPluginDashboard(cmd.PluginId, cmd.Path); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = createDashboardFolderForPlugin(cmd, dashboard); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
dashboard = m.NewDashboardFromJson(cmd.Dashboard)
|
||||
}
|
||||
@ -93,63 +89,6 @@ func ImportDashboard(cmd *ImportDashboardCommand) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func createDashboardFolderForPlugin(cmd *ImportDashboardCommand, dashboard *m.Dashboard) error {
|
||||
var err error
|
||||
var plugin *PluginBase
|
||||
|
||||
if plugin, err = getPlugin(cmd.PluginId); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var pluginType string
|
||||
|
||||
if plugin.Type == "datasource" {
|
||||
pluginType = "Datasource"
|
||||
} else if plugin.Type == "app" {
|
||||
pluginType = "App"
|
||||
}
|
||||
|
||||
folderTitle := fmt.Sprint(pluginType, ": ", plugin.Name)
|
||||
|
||||
folderDash := simplejson.NewFromAny(map[string]interface{}{
|
||||
"schemaVersion": 16,
|
||||
"title": folderTitle,
|
||||
"editable": true,
|
||||
"hideControls": true,
|
||||
})
|
||||
|
||||
saveCmd := m.SaveDashboardCommand{
|
||||
Dashboard: folderDash,
|
||||
OrgId: cmd.OrgId,
|
||||
UserId: cmd.UserId,
|
||||
PluginId: cmd.PluginId,
|
||||
IsFolder: true,
|
||||
}
|
||||
|
||||
dashModel := saveCmd.GetDashboardModel()
|
||||
|
||||
getDashboardQuery := m.GetDashboardQuery{
|
||||
OrgId: cmd.OrgId,
|
||||
Slug: dashModel.Slug,
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(&getDashboardQuery); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if getDashboardQuery.Result != nil {
|
||||
dashboard.FolderId = getDashboardQuery.Result.Id
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(&saveCmd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dashboard.FolderId = saveCmd.Result.Id
|
||||
return nil
|
||||
}
|
||||
|
||||
type DashTemplateEvaluator struct {
|
||||
template *simplejson.Json
|
||||
inputs []ImportDashboardInput
|
||||
|
@ -13,32 +13,12 @@ import (
|
||||
)
|
||||
|
||||
func TestDashboardImport(t *testing.T) {
|
||||
|
||||
Convey("When importing plugin dashboard", t, func() {
|
||||
setting.Cfg = ini.Empty()
|
||||
sec, _ := setting.Cfg.NewSection("plugin.test-app")
|
||||
sec.NewKey("path", "../../tests/test-app")
|
||||
err := Init()
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
folderId := int64(1000)
|
||||
pluginScenario("When importing a plugin dashboard", t, func() {
|
||||
var importedDash *m.Dashboard
|
||||
var createdFolder *m.Dashboard
|
||||
|
||||
bus.AddHandler("test", func(cmd *m.SaveDashboardCommand) error {
|
||||
if cmd.IsFolder {
|
||||
createdFolder = cmd.GetDashboardModel()
|
||||
createdFolder.Id = folderId
|
||||
cmd.Result = createdFolder
|
||||
} else {
|
||||
importedDash = cmd.GetDashboardModel()
|
||||
cmd.Result = importedDash
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(cmd *m.GetDashboardQuery) error {
|
||||
importedDash = cmd.GetDashboardModel()
|
||||
cmd.Result = importedDash
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -52,7 +32,7 @@ func TestDashboardImport(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err = ImportDashboard(&cmd)
|
||||
err := ImportDashboard(&cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("should install dashboard", func() {
|
||||
@ -67,78 +47,6 @@ func TestDashboardImport(t *testing.T) {
|
||||
|
||||
panel := importedDash.Data.Get("rows").GetIndex(0).Get("panels").GetIndex(0)
|
||||
So(panel.Get("datasource").MustString(), ShouldEqual, "graphite")
|
||||
|
||||
So(importedDash.FolderId, ShouldEqual, folderId)
|
||||
})
|
||||
|
||||
Convey("should create app folder", func() {
|
||||
So(createdFolder.Title, ShouldEqual, "App: Test App")
|
||||
So(createdFolder.Id, ShouldEqual, folderId)
|
||||
})
|
||||
})
|
||||
|
||||
Convey("When re-importing plugin dashboard", t, func() {
|
||||
setting.Cfg = ini.Empty()
|
||||
sec, _ := setting.Cfg.NewSection("plugin.test-app")
|
||||
sec.NewKey("path", "../../tests/test-app")
|
||||
err := Init()
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
folderId := int64(1000)
|
||||
var importedDash *m.Dashboard
|
||||
var createdFolder *m.Dashboard
|
||||
bus.AddHandler("test", func(cmd *m.SaveDashboardCommand) error {
|
||||
if cmd.IsFolder {
|
||||
cmd.Result = cmd.GetDashboardModel()
|
||||
} else {
|
||||
importedDash = cmd.GetDashboardModel()
|
||||
cmd.Result = importedDash
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(cmd *m.GetDashboardQuery) error {
|
||||
cmd.Result = &m.Dashboard{
|
||||
Id: 1000,
|
||||
Title: "Something",
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
cmd := ImportDashboardCommand{
|
||||
PluginId: "test-app",
|
||||
Path: "dashboards/connections.json",
|
||||
OrgId: 1,
|
||||
UserId: 1,
|
||||
Inputs: []ImportDashboardInput{
|
||||
{Name: "*", Type: "datasource", Value: "graphite"},
|
||||
},
|
||||
}
|
||||
|
||||
err = ImportDashboard(&cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("should install dashboard", func() {
|
||||
So(importedDash, ShouldNotBeNil)
|
||||
|
||||
resultStr, _ := importedDash.Data.EncodePretty()
|
||||
expectedBytes, _ := ioutil.ReadFile("../../tests/test-app/dashboards/connections_result.json")
|
||||
expectedJson, _ := simplejson.NewJson(expectedBytes)
|
||||
expectedStr, _ := expectedJson.EncodePretty()
|
||||
|
||||
So(string(resultStr), ShouldEqual, string(expectedStr))
|
||||
|
||||
panel := importedDash.Data.Get("rows").GetIndex(0).Get("panels").GetIndex(0)
|
||||
So(panel.Get("datasource").MustString(), ShouldEqual, "graphite")
|
||||
|
||||
So(importedDash.FolderId, ShouldEqual, folderId)
|
||||
})
|
||||
|
||||
Convey("should not create app folder", func() {
|
||||
So(createdFolder, ShouldBeNil)
|
||||
})
|
||||
})
|
||||
|
||||
@ -177,3 +85,16 @@ func TestDashboardImport(t *testing.T) {
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func pluginScenario(desc string, t *testing.T, fn func()) {
|
||||
Convey("Given a plugin", t, func() {
|
||||
setting.Cfg = ini.Empty()
|
||||
sec, _ := setting.Cfg.NewSection("plugin.test-app")
|
||||
sec.NewKey("path", "../../tests/test-app")
|
||||
err := Init()
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey(desc, fn)
|
||||
})
|
||||
}
|
||||
|
@ -108,13 +108,3 @@ func loadPluginDashboard(pluginId, path string) (*m.Dashboard, error) {
|
||||
|
||||
return m.NewDashboardFromJson(data), nil
|
||||
}
|
||||
|
||||
func getPlugin(pluginId string) (*PluginBase, error) {
|
||||
plugin, exists := Plugins[pluginId]
|
||||
|
||||
if !exists {
|
||||
return nil, PluginNotFoundError{pluginId}
|
||||
}
|
||||
|
||||
return plugin, nil
|
||||
}
|
||||
|
@ -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"]);
|
||||
|
||||
}
|
||||
|
72
public/app/core/components/PageHeader.tsx
Normal file
72
public/app/core/components/PageHeader.tsx
Normal file
@ -0,0 +1,72 @@
|
||||
import React from 'react';
|
||||
import { NavModel, NavModelItem } from '../nav_model_srv';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export interface IProps {
|
||||
model: NavModel;
|
||||
}
|
||||
|
||||
function TabItem(tab: NavModelItem) {
|
||||
if (tab.hideFromTabs) {
|
||||
return (null);
|
||||
}
|
||||
|
||||
let tabClasses = classNames({
|
||||
'gf-tabs-link': true,
|
||||
active: tab.active,
|
||||
});
|
||||
|
||||
return (
|
||||
<li className="gf-tabs-item" key={tab.url}>
|
||||
<a className={tabClasses} href={tab.url}>
|
||||
<i className={tab.icon} />
|
||||
{tab.text}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
function Tabs({main}: {main: NavModelItem}) {
|
||||
return <ul className="gf-tabs">{main.children.map(TabItem)}</ul>;
|
||||
}
|
||||
|
||||
export default class PageHeader extends React.Component<IProps, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
renderHeaderTitle(main) {
|
||||
return (
|
||||
<div className="page-header__inner">
|
||||
<span className="page-header__logo">
|
||||
{main.icon && <i className={`page-header__icon ${main.icon}`} />}
|
||||
{main.img && <img className="page-header__img" src={main.img} />}
|
||||
</span>
|
||||
|
||||
<div className="page-header__info-block">
|
||||
<h1 className="page-header__title">{main.text}</h1>
|
||||
{main.subTitle && <div className="page-header__sub-title">{main.subTitle}</div>}
|
||||
{main.subType && (
|
||||
<div className="page-header__stamps">
|
||||
<i className={main.subType.icon} />
|
||||
{main.subType.text}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="page-header-canvas">
|
||||
<div className="page-container">
|
||||
<div className="page-header">
|
||||
{this.renderHeaderTitle(this.props.model.main)}
|
||||
{this.props.model.main.children && <Tabs main={this.props.model.main} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -85,6 +85,16 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
|
||||
}
|
||||
});
|
||||
|
||||
let sidemenuOpenSmallBreakpoint = scope.contextSrv.sidemenuSmallBreakpoint;
|
||||
body.toggleClass('sidemenu-open--xs', sidemenuOpenSmallBreakpoint);
|
||||
|
||||
scope.$watch('contextSrv.sidemenuSmallBreakpoint', newVal => {
|
||||
if (sidemenuOpenSmallBreakpoint !== scope.contextSrv.sidemenuSmallBreakpoint) {
|
||||
sidemenuOpenSmallBreakpoint = scope.contextSrv.sidemenuSmallBreakpoint;
|
||||
body.toggleClass('sidemenu-open--xs', scope.contextSrv.sidemenuSmallBreakpoint);
|
||||
}
|
||||
});
|
||||
|
||||
// tooltip removal fix
|
||||
// manage page classes
|
||||
var pageClass;
|
||||
|
@ -1,13 +1,11 @@
|
||||
<div class="page-nav">
|
||||
<div class="container">
|
||||
<div class="page-breadcrumbs">
|
||||
<a class="breadcrumb-item active" href="/">
|
||||
<i class="fa fa-home"></i>
|
||||
</a>
|
||||
<a class="breadcrumb-item" ng-href="{{::item.url}}" ng-repeat="item in ctrl.model.breadcrumbs">
|
||||
{{::item.text}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="page-breadcrumbs">
|
||||
<a class="breadcrumb-item active" href="/">
|
||||
<i class="fa fa-home"></i>
|
||||
</a>
|
||||
<a class="breadcrumb-item" ng-href="{{::item.url}}" ng-repeat="item in ctrl.model.breadcrumbs">
|
||||
{{::item.text}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -39,10 +39,10 @@ export function pageH1() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: `
|
||||
<h1>
|
||||
<i class="{{::model.node.icon}}" ng-if="::model.node.icon"></i>
|
||||
<img ng-src="{{::model.node.img}}" ng-if="::model.node.img"></i>
|
||||
{{model.node.text}}
|
||||
<h1 class="page-header__title">
|
||||
<i class="page-header__icon {{::model.header.icon}}" ng-if="::model.header.icon"></i>
|
||||
<img class="page-header__img" ng-src="{{::model.header.img}}" ng-if="::model.header.img"></i>
|
||||
{{model.header.text}}
|
||||
</h1>
|
||||
`,
|
||||
scope: {
|
||||
|
@ -8,6 +8,14 @@ export function geminiScrollbar() {
|
||||
|
||||
let scrollbar = new PerfectScrollbar(elem[0]);
|
||||
|
||||
scope.$on('$routeChangeSuccess', () => {
|
||||
elem[0].scrollTop = 0;
|
||||
});
|
||||
|
||||
scope.$on('$routeUpdate', () => {
|
||||
elem[0].scrollTop = 0;
|
||||
});
|
||||
|
||||
scope.$on('$destroy', () => {
|
||||
scrollbar.destroy();
|
||||
});
|
||||
|
@ -15,84 +15,74 @@
|
||||
ng-blur="ctrl.searchInputBlur()"
|
||||
/>
|
||||
|
||||
<div class="search-switches">
|
||||
<i class="fa fa-filter"></i>
|
||||
<a class="pointer" href="javascript:void 0;" ng-click="ctrl.showStarred()" tabindex="2">
|
||||
<i class="fa fa-remove" ng-show="ctrl.query.starred"></i>
|
||||
starred
|
||||
</a> |
|
||||
<a class="pointer" href="javascript:void 0;" ng-click="ctrl.getTags()" tabindex="3">
|
||||
<i class="fa fa-remove" ng-show="ctrl.tagsMode"></i>
|
||||
tags
|
||||
</a>
|
||||
<span ng-if="ctrl.query.tag.length">
|
||||
|
|
||||
<span ng-repeat="tagName in ctrl.query.tag">
|
||||
<a ng-click="ctrl.removeTag(tagName, $event)" tag-color-from-name="tagName" class="label label-tag">
|
||||
<i class="fa fa-remove"></i>
|
||||
{{tagName}}
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="search-field-spacer"></div>
|
||||
</div>
|
||||
|
||||
<div class="search-dropdown" ng-class="{'search-dropdown--fade-in': ctrl.openCompleted}">
|
||||
<div class="search-results-container" ng-if="ctrl.tagsMode">
|
||||
<div ng-repeat="tag in ctrl.results" class="pointer" style="width: 180px; float: left;"
|
||||
ng-class="{'selected': $index === ctrl.selectedIndex }"
|
||||
ng-click="ctrl.filterByTag(tag.term, $event)">
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="tag.term">
|
||||
<i class="fa fa-tag"></i>
|
||||
<span>{{tag.term}} ({{tag.count}})</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-dropdown">
|
||||
<div class="search-dropdown__col_1">
|
||||
<div class="search-results-container" grafana-scrollbar>
|
||||
<h6 ng-show="!ctrl.isLoading && results.length">No dashboards matching your query were found.</h6>
|
||||
|
||||
<div class="search-results-container" ng-if="!ctrl.tagsMode" grafana-scrollbar>
|
||||
<h6 ng-show="!ctrl.isLoading && results.length">No dashboards matching your query were found.</h6>
|
||||
<div ng-repeat="section in ctrl.results" class="search-section">
|
||||
<a class="search-section__header pointer" ng-hide="section.hideHeader" ng-click="ctrl.toggleFolder(section)">
|
||||
<i class="search-section__header__icon" ng-class="section.icon"></i>
|
||||
<span class="search-section__header__text">{{::section.title}}</span>
|
||||
<i class="fa fa-minus search-section__header__toggle" ng-show="section.expanded"></i>
|
||||
<i class="fa fa-plus search-section__header__toggle" ng-hide="section.expanded"></i>
|
||||
</a>
|
||||
|
||||
<div ng-repeat="section in ctrl.results" class="search-section">
|
||||
<a class="search-section__header pointer" ng-hide="section.hideHeader" ng-click="ctrl.toggleFolder(section)">
|
||||
<i class="search-section__header__icon" ng-class="section.icon"></i>
|
||||
<span class="search-section__header__text">{{::section.title}}</span>
|
||||
<i class="fa fa-minus search-section__header__toggle" ng-show="section.expanded"></i>
|
||||
<i class="fa fa-plus search-section__header__toggle" ng-hide="section.expanded"></i>
|
||||
</a>
|
||||
|
||||
<div ng-if="section.expanded">
|
||||
<a ng-repeat="item in section.items" class="search-item" ng-class="{'selected': item.selected}" ng-href="{{::item.url}}">
|
||||
<span class="search-item__icon">
|
||||
<i class="fa fa-th-large"></i>
|
||||
</span>
|
||||
<span class="search-item__body">
|
||||
<div class="search-item__body-title">{{::item.title}}</div>
|
||||
<div class="search-item__body-sub-title" ng-show="item.folderTitle && section.hideHeader">
|
||||
{{::item.folderTitle}}
|
||||
</div>
|
||||
</span>
|
||||
<span class="search-item__tags">
|
||||
<span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in item.tags" tag-color-from-name="tag" class="label label-tag">
|
||||
{{tag}}
|
||||
</span>
|
||||
</span>
|
||||
<span class="search-item__actions">
|
||||
<span class="search-item__actions__item" ng-click="ctrl.toggleStar()">
|
||||
<i class="fa" ng-class="{'fa-star': item.isStarred, 'fa-star-o': !item.isStarred}"></i>
|
||||
<div ng-if="section.expanded">
|
||||
<a ng-repeat="item in section.items" class="search-item" ng-class="{'selected': item.selected}" ng-href="{{::item.url}}">
|
||||
<span class="search-item__icon">
|
||||
<i class="fa fa-th-large"></i>
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="search-item__body">
|
||||
<div class="search-item__body-title">{{::item.title}}</div>
|
||||
<div class="search-item__body-sub-title" ng-show="item.folderTitle && section.hideHeader">
|
||||
{{::item.folderTitle}}
|
||||
</div>
|
||||
</span>
|
||||
<span class="search-item__tags">
|
||||
<span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in item.tags" tag-color-from-name="tag" class="label label-tag">
|
||||
{{tag}}
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search-button-row">
|
||||
<a class="search-button-row-explore-link" target="_blank" href="https://grafana.com/dashboards?utm_source=grafana_search">
|
||||
Find <img src="public/img/icn-dashboard-tiny.svg" width="14" /> dashboards on Grafana.com
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-dropdown__col_2">
|
||||
<div class="search-filter-box">
|
||||
<div class="search-filter-box__header">
|
||||
<i class="fa fa-filter"></i>
|
||||
Filter by:
|
||||
<a class="pointer pull-right small">
|
||||
<i class="fa fa-remove"></i> Clear
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<folder-picker initial-title="ctrl.initialFolderFilterTitle"
|
||||
on-change="ctrl.onFolderChange($folder)"
|
||||
label-class="width-4">
|
||||
</folder-picker>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-4">Tags</label>
|
||||
<bootstrap-tagsinput ng-model="ctrl.dashboard.tags" tagclass="label label-tag" placeholder="add tags">
|
||||
</bootstrap-tagsinput>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search-filter-box">
|
||||
<a class="search-button-row-explore-link" target="_blank" href="https://grafana.com/dashboards?utm_source=grafana_search">
|
||||
<img src="public/img/icn-dashboard-tiny.svg" width="20" /> Find dashboards on Grafana.com
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -9,16 +9,18 @@ export class SearchCtrl {
|
||||
selectedIndex: number;
|
||||
results: any;
|
||||
currentSearchId: number;
|
||||
tagsMode: boolean;
|
||||
showImport: boolean;
|
||||
dismiss: any;
|
||||
ignoreClose: any;
|
||||
isLoading: boolean;
|
||||
initialFolderFilterTitle: string;
|
||||
|
||||
/** @ngInject */
|
||||
constructor($scope, private $location, private $timeout, private searchSrv: SearchSrv, $rootScope) {
|
||||
$rootScope.onAppEvent('show-dash-search', this.openSearch.bind(this), $scope);
|
||||
$rootScope.onAppEvent('hide-dash-search', this.closeSearch.bind(this), $scope);
|
||||
|
||||
this.initialFolderFilterTitle = "All";
|
||||
}
|
||||
|
||||
closeSearch() {
|
||||
@ -44,14 +46,6 @@ export class SearchCtrl {
|
||||
this.query.starred = true;
|
||||
}
|
||||
|
||||
if (payload && payload.tagsMode) {
|
||||
return this.$timeout(() => {
|
||||
this.ignoreClose = false;
|
||||
this.giveSearchFocus = this.giveSearchFocus + 1;
|
||||
this.getTags();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
this.$timeout(() => {
|
||||
this.ignoreClose = false;
|
||||
this.giveSearchFocus = this.giveSearchFocus + 1;
|
||||
@ -70,14 +64,6 @@ export class SearchCtrl {
|
||||
this.moveSelection(-1);
|
||||
}
|
||||
if (evt.keyCode === 13) {
|
||||
if (this.tagsMode) {
|
||||
var tag = this.results[this.selectedIndex];
|
||||
if (tag) {
|
||||
this.filterByTag(tag.term, null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedDash = this.results[this.selectedIndex];
|
||||
if (selectedDash) {
|
||||
this.$location.search({});
|
||||
@ -93,7 +79,6 @@ export class SearchCtrl {
|
||||
}
|
||||
|
||||
searchDashboards() {
|
||||
this.tagsMode = false;
|
||||
this.currentSearchId = this.currentSearchId + 1;
|
||||
var localSearchId = this.currentSearchId;
|
||||
|
||||
@ -129,12 +114,8 @@ export class SearchCtrl {
|
||||
|
||||
getTags() {
|
||||
return this.searchSrv.getDashboardTags().then((results) => {
|
||||
this.tagsMode = !this.tagsMode;
|
||||
this.results = results;
|
||||
this.giveSearchFocus = this.giveSearchFocus + 1;
|
||||
if ( !this.tagsMode ) {
|
||||
this.search();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,12 @@
|
||||
<img src="public/img/grafana_icon.svg"></img>
|
||||
</a>
|
||||
|
||||
<a class="sidemenu__logo_small_breakpoint" ng-click="ctrl.toggleSideMenuSmallBreakpoint()">
|
||||
<img src="public/img/grafana_icon.svg"></img>
|
||||
<p class="sidemenu__close"><i class="fa fa-times"></i> Close</p>
|
||||
</a>
|
||||
|
||||
|
||||
<div class="sidemenu__top">
|
||||
<div ng-repeat="item in ::ctrl.mainLinks" class="sidemenu-item dropdown">
|
||||
<a href="{{::item.url}}" class="sidemenu-link" target="{{::item.target}}">
|
||||
|
@ -11,6 +11,7 @@ export class SideMenuCtrl {
|
||||
bottomNav: any;
|
||||
loginUrl: string;
|
||||
isSignedIn: boolean;
|
||||
smallBPSideMenuOpen = false;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $rootScope, private $location, private contextSrv, private $timeout) {
|
||||
@ -28,6 +29,10 @@ export class SideMenuCtrl {
|
||||
}
|
||||
|
||||
this.$scope.$on('$routeChangeSuccess', () => {
|
||||
if (this.smallBPSideMenuOpen) {
|
||||
this.contextSrv.setSideMenuForSmallBreakpoint(false, true);
|
||||
this.smallBPSideMenuOpen = false;
|
||||
}
|
||||
this.loginUrl = 'login?redirect=' + encodeURIComponent(this.$location.path());
|
||||
});
|
||||
}
|
||||
@ -39,6 +44,11 @@ export class SideMenuCtrl {
|
||||
});
|
||||
}
|
||||
|
||||
toggleSideMenuSmallBreakpoint() {
|
||||
this.smallBPSideMenuOpen = !this.smallBPSideMenuOpen;
|
||||
this.contextSrv.setSideMenuForSmallBreakpoint(this.smallBPSideMenuOpen, false);
|
||||
}
|
||||
|
||||
switchOrg() {
|
||||
this.$rootScope.appEvent('show-modal', {
|
||||
templateHtml: '<org-switcher dismiss="dismiss()"></org-switcher>',
|
||||
|
@ -1,19 +1,27 @@
|
||||
///<reference path="../headers/common.d.ts" />
|
||||
|
||||
import coreModule from 'app/core/core_module';
|
||||
import config from 'app/core/config';
|
||||
import _ from 'lodash';
|
||||
|
||||
export interface NavModelItem {
|
||||
title: string;
|
||||
text: string;
|
||||
url: string;
|
||||
icon?: string;
|
||||
iconUrl?: string;
|
||||
img?: string;
|
||||
id: string;
|
||||
active?: boolean;
|
||||
hideFromTabs?: boolean;
|
||||
divider?: boolean;
|
||||
children: NavModelItem[];
|
||||
}
|
||||
|
||||
export interface NavModel {
|
||||
section: NavModelItem;
|
||||
menu: NavModelItem[];
|
||||
export class NavModel {
|
||||
breadcrumbs: NavModelItem[];
|
||||
main: NavModelItem;
|
||||
node: NavModelItem;
|
||||
|
||||
constructor() {
|
||||
this.breadcrumbs = [];
|
||||
}
|
||||
}
|
||||
|
||||
export class NavModelSrv {
|
||||
@ -31,15 +39,32 @@ export class NavModelSrv {
|
||||
|
||||
getNav(...args) {
|
||||
var children = this.navItems;
|
||||
var nav = {breadcrumbs: [], node: null};
|
||||
var nav = new NavModel();
|
||||
|
||||
for (let id of args) {
|
||||
// if its a number then it's the index to use for main
|
||||
if (_.isNumber(id)) {
|
||||
nav.main = nav.breadcrumbs[id];
|
||||
break;
|
||||
}
|
||||
|
||||
let node = _.find(children, {id: id});
|
||||
nav.breadcrumbs.push(node);
|
||||
nav.node = node;
|
||||
nav.main = node;
|
||||
children = node.children;
|
||||
}
|
||||
|
||||
if (nav.main.children) {
|
||||
for (let item of nav.main.children) {
|
||||
item.active = false;
|
||||
|
||||
if (item.url === nav.node.url) {
|
||||
item.active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nav;
|
||||
}
|
||||
|
||||
|
@ -36,12 +36,11 @@ export class NewDashboardCtrl {
|
||||
meta: { canStar: false, canShare: false, isNew: true },
|
||||
dashboard: {
|
||||
title: "New dashboard",
|
||||
rows: [
|
||||
panels: [
|
||||
{
|
||||
title: 'Dashboard Row',
|
||||
height: '350px',
|
||||
panels: [],
|
||||
isNew: true,
|
||||
type: 'add-panel',
|
||||
gridPos: {x: 0, y: 0, w: 12, h: 9},
|
||||
title: 'Panel Title',
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -48,12 +48,6 @@ function setupAngularRoutes($routeProvider, $locationProvider) {
|
||||
reloadOnSearch: false,
|
||||
pageClass: 'page-dashboard',
|
||||
})
|
||||
.when('/configuration', {
|
||||
templateUrl: 'public/app/features/admin/partials/configuration_home.html',
|
||||
controller : 'ConfigurationHomeCtrl',
|
||||
controllerAs: 'ctrl',
|
||||
resolve: loadAdminBundle,
|
||||
})
|
||||
.when('/datasources', {
|
||||
templateUrl: 'public/app/features/plugins/partials/ds_list.html',
|
||||
controller : 'DataSourcesCtrl',
|
||||
|
@ -27,9 +27,10 @@ export class ContextSrv {
|
||||
isGrafanaAdmin: any;
|
||||
isEditor: any;
|
||||
sidemenu: any;
|
||||
sidemenuSmallBreakpoint = false;
|
||||
|
||||
constructor() {
|
||||
this.sidemenu = store.getBool('grafana.sidemenu', false);
|
||||
this.sidemenu = store.getBool('grafana.sidemenu', true);
|
||||
|
||||
if (!config.buildInfo) {
|
||||
config.buildInfo = {};
|
||||
@ -55,7 +56,11 @@ export class ContextSrv {
|
||||
|
||||
toggleSideMenu() {
|
||||
this.sidemenu = !this.sidemenu;
|
||||
store.set('grafana.sidemenu',this.sidemenu);
|
||||
store.set('grafana.sidemenu', this.sidemenu);
|
||||
}
|
||||
|
||||
setSideMenuForSmallBreakpoint(show: boolean, persistToggle: boolean) {
|
||||
this.sidemenuSmallBreakpoint = show;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ class AdminSettingsCtrl {
|
||||
|
||||
/** @ngInject **/
|
||||
constructor($scope, backendSrv, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 'server-settings');
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 'server-settings', 1);
|
||||
|
||||
backendSrv.get('/api/admin/settings').then(function(settings) {
|
||||
$scope.settings = settings;
|
||||
@ -24,7 +24,7 @@ class AdminHomeCtrl {
|
||||
|
||||
/** @ngInject **/
|
||||
constructor(navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin');
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ export class AdminStatsCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor(backendSrv: any, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 'server-stats');
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 'server-stats', 1);
|
||||
|
||||
backendSrv.get('/api/admin/stats').then(stats => {
|
||||
this.stats = stats;
|
||||
@ -42,16 +42,6 @@ export class AdminStatsCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
export class ConfigurationHomeCtrl {
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('cfg');
|
||||
}
|
||||
}
|
||||
|
||||
coreModule.controller('ConfigurationHomeCtrl', ConfigurationHomeCtrl);
|
||||
coreModule.controller('AdminSettingsCtrl', AdminSettingsCtrl);
|
||||
coreModule.controller('AdminHomeCtrl', AdminHomeCtrl);
|
||||
coreModule.controller('AdminStatsCtrl', AdminStatsCtrl);
|
||||
|
@ -5,7 +5,7 @@ export class AdminEditOrgCtrl {
|
||||
/** @ngInject */
|
||||
constructor($scope, $routeParams, backendSrv, $location, navModelSrv) {
|
||||
$scope.init = function() {
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'admin', 'global-orgs');
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'admin', 'global-orgs', 1);
|
||||
|
||||
if ($routeParams.id) {
|
||||
$scope.getOrg($routeParams.id);
|
||||
|
@ -8,7 +8,7 @@ export class AdminEditUserCtrl {
|
||||
$scope.user = {};
|
||||
$scope.newOrg = { name: '', role: 'Editor' };
|
||||
$scope.permissions = {};
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'admin', 'global-users');
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'admin', 'global-users', 1);
|
||||
|
||||
$scope.init = function() {
|
||||
if ($routeParams.id) {
|
||||
|
@ -5,7 +5,7 @@ export class AdminListOrgsCtrl {
|
||||
/** @ngInject */
|
||||
constructor($scope, backendSrv, navModelSrv) {
|
||||
$scope.init = function() {
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'admin', 'global-orgs');
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'admin', 'global-orgs', 1);
|
||||
$scope.getOrgs();
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,7 @@ export default class AdminListUsersCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private backendSrv, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 'global-users');
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 'global-users', 1);
|
||||
this.query = '';
|
||||
this.getUsers();
|
||||
}
|
||||
|
@ -1,35 +1,11 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
</div>
|
||||
<div class="page-container page-body">
|
||||
|
||||
<section class="card-section card-list-layout-grid">
|
||||
<ol class="card-list" >
|
||||
<li class="card-item-wrapper" ng-repeat="navItem in ctrl.navModel.node.children">
|
||||
<a class="card-item" ng-href="{{::navItem.url}}">
|
||||
<div class="card-item-header">
|
||||
<div class="card-item-type">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-item-body">
|
||||
<figure class="card-item-figure">
|
||||
<i class="{{navItem.icon}}"></i>
|
||||
</figure>
|
||||
<div class="card-item-details">
|
||||
<div class="card-item-name">
|
||||
{{navItem.text}}
|
||||
</div>
|
||||
<div class="card-item-sub-name">
|
||||
{{navItem.description}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
<div class="grafana-info-box span8">
|
||||
Grafana is a multi-tenant system where most can be configured per organization. These
|
||||
admin pages are for server admins where you can manage orgs, & all users across all orgs.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
<div class="scroll-canvas" grafana-scrollbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
</div>
|
||||
|
||||
<section class="card-section card-list-layout-grid">
|
||||
<ol class="card-list" >
|
||||
<li class="card-item-wrapper" ng-repeat="navItem in ctrl.navModel.node.children">
|
||||
<a class="card-item" ng-href="{{::navItem.url}}">
|
||||
<div class="card-item-header">
|
||||
<div class="card-item-type">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-item-body">
|
||||
<figure class="card-item-figure">
|
||||
<i class="{{navItem.icon}}"></i>
|
||||
</figure>
|
||||
<div class="card-item-details">
|
||||
<div class="card-item-name">
|
||||
{{navItem.text}}
|
||||
</div>
|
||||
<div class="card-item-sub-name">
|
||||
{{navItem.description}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
</div>
|
@ -1,9 +1,7 @@
|
||||
<navbar model="navModel"></navbar>
|
||||
<page-header model="navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<h1>Edit Organization</h1>
|
||||
</div>
|
||||
<div class="page-container page-body">
|
||||
<h2 class="page-sub-heading">Edit Organization</h2>
|
||||
|
||||
<form name="orgDetailsForm" class="gf-form-group">
|
||||
<div class="gf-form">
|
||||
|
@ -1,8 +1,9 @@
|
||||
<navbar model="navModel"></navbar>
|
||||
<page-header model="navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<h1>Edit User</h1>
|
||||
<div class="page-container page-body">
|
||||
|
||||
<div class="page-sub-heading">
|
||||
<h2>Edit User</h2>
|
||||
</div>
|
||||
|
||||
<form name="userForm" class="gf-form-group">
|
||||
@ -54,7 +55,7 @@
|
||||
<form name="addOrgForm" class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-12">Add organization</span>
|
||||
<span class="gf-form-label">Add</span>
|
||||
<input type="text" ng-model="newOrg.name" bs-typeahead="searchOrgs" required class="gf-form-input max-width-20" placeholder="organization name">
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
@ -67,12 +68,14 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<table class="grafana-options-table">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Role</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<table class="filter-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Role</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr ng-repeat="org in orgs">
|
||||
<td>
|
||||
{{org.name}} <span class="label label-info" ng-show="org.orgId === user.orgId">Current</span>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<navbar model="navModel"></navbar>
|
||||
<page-header model="navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<div class="page-container page-body">
|
||||
<div class="page-sub-heading">
|
||||
<h1>Add new user</h1>
|
||||
</div>
|
||||
|
||||
|
@ -1,8 +1,12 @@
|
||||
<navbar model="navModel"></navbar>
|
||||
<page-header model="navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<h1>Organizations</h1>
|
||||
<div class="page-container page-body">
|
||||
<div class="page-action-bar">
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
<a class="page-header__cta btn btn-success" href="org/new">
|
||||
<i class="fa fa-plus"></i>
|
||||
New Org
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<table class="filter-table form-inline">
|
||||
|
@ -1,25 +1,22 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<h1>Server settings</h1>
|
||||
<div class="page-container page-body">
|
||||
|
||||
<div class="grafana-info-box span8" style="margin: 20px 0 25px 0">
|
||||
These system settings are defined in grafana.ini or custom.ini (or overridden in ENV variables).
|
||||
To change these you currently need to restart grafana.
|
||||
</div>
|
||||
|
||||
<div class="grafana-info-box span8" style="margin: 20px 0 25px 0">
|
||||
These system settings are defined in grafana.ini or custom.ini (or overridden in ENV variables).
|
||||
To change these you currently need to restart grafana.
|
||||
</div>
|
||||
|
||||
<table class="grafana-options-table">
|
||||
<tr ng-repeat-start="(secName, secValue) in settings">
|
||||
<td class="admin-settings-section">{{secName}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr ng-repeat="(keyName, keyValue) in secValue" ng-repeat-end>
|
||||
<td style="padding-left: 25px;">{{keyName}}</td>
|
||||
<td>{{keyValue}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="filter-table">
|
||||
<tr ng-repeat-start="(secName, secValue) in settings">
|
||||
<td class="admin-settings-section">{{secName}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr ng-repeat="(keyName, keyValue) in secValue" ng-repeat-end>
|
||||
<td style="padding-left: 25px;">{{keyName}}</td>
|
||||
<td>{{keyValue}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -1,10 +1,6 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<h1>Stats</h1>
|
||||
</div>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container page-body">
|
||||
<table class="filter-table form-inline">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -1,22 +1,18 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<h1>Users</h1>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container page-body">
|
||||
<div class="page-action-bar">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">Search</label>
|
||||
<input class="gf-form-input width-15" type="text" placeholder="Find user by name/login/email" tabindex="1" give-focus="true" ng-model="ctrl.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.getUsers()" />
|
||||
</div>
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
<a class="btn btn-success" href="admin/users/create">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add new user
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="gf-form pull-right gf-form-group">
|
||||
<label class="gf-form-label">Search</label>
|
||||
<span style="position: relative;">
|
||||
<input class="gf-form-input width-15" type="text" placeholder="Find user by name/login/email" tabindex="1" give-focus="true" ng-model="ctrl.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.getUsers()" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="admin-list-table">
|
||||
<table class="filter-table form-inline">
|
||||
<thead>
|
||||
|
@ -23,7 +23,7 @@ export class AlertListCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, private $location, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('alerting');
|
||||
this.navModel = navModelSrv.getNav('alerting', 'alert-list', 0);
|
||||
|
||||
var params = $location.search();
|
||||
this.filters.state = params.state || null;
|
||||
|
@ -9,7 +9,7 @@ export class AlertNotificationEditCtrl {
|
||||
testSeverity = "critical";
|
||||
notifiers: any;
|
||||
notifierTemplateId: string;
|
||||
|
||||
isNew: boolean;
|
||||
model: any;
|
||||
defaults: any = {
|
||||
type: 'email',
|
||||
@ -23,7 +23,8 @@ export class AlertNotificationEditCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $routeParams, private backendSrv, private $location, private $templateCache, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('alerting', 'channels');
|
||||
this.navModel = navModelSrv.getNav('alerting', 'channels', 0);
|
||||
this.isNew = !this.$routeParams.id;
|
||||
|
||||
this.backendSrv.get(`/api/alert-notifiers`).then(notifiers => {
|
||||
this.notifiers = notifiers;
|
||||
|
@ -9,7 +9,7 @@ export class AlertNotificationsListCtrl {
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, navModelSrv) {
|
||||
this.loadNotifications();
|
||||
this.navModel = navModelSrv.getNav('alerting', 'channels');
|
||||
this.navModel = navModelSrv.getNav('alerting', 'channels', 0);
|
||||
}
|
||||
|
||||
loadNotifications() {
|
||||
|
@ -1,29 +1,23 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container" >
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
<div class="page-container page-body">
|
||||
|
||||
<a class="btn btn-secondary" ng-click="ctrl.openHowTo()">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
How to add an alert
|
||||
</a>
|
||||
<a class="btn btn-inverse" href="alerting/notifications" >
|
||||
<i class="fa fa-bell"></i>
|
||||
Notification channels
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">Filter by state</label>
|
||||
<div class="gf-form-select-wrapper width-13">
|
||||
<select class="gf-form-input" ng-model="ctrl.filters.state" ng-options="f.value as f.text for f in ctrl.stateFilters" ng-change="ctrl.filtersChanged()">
|
||||
</select>
|
||||
</div>
|
||||
<div class="page-action-bar">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">Filter by state</label>
|
||||
<div class="gf-form-select-wrapper width-13">
|
||||
<select class="gf-form-input" ng-model="ctrl.filters.state" ng-options="f.value as f.text for f in ctrl.stateFilters" ng-change="ctrl.filtersChanged()">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-action-bar__spacer">
|
||||
</div>
|
||||
|
||||
<a class="btn btn-secondary" ng-click="ctrl.openHowTo()">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
How to add an alert
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<section class="card-section card-list-layout-list">
|
||||
|
@ -1,9 +1,9 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
</div>
|
||||
<div class="page-container page-body">
|
||||
|
||||
<h3 class="page-sub-heading" ng-hide="ctrl.isNew">Edit Notification Channel</h3>
|
||||
<h3 class="page-sub-heading" ng-show="ctrl.isNew">New Notification Channel</h3>
|
||||
|
||||
<form name="ctrl.theForm" ng-if="ctrl.notifiers">
|
||||
<div class="gf-form-group">
|
||||
|
@ -1,10 +1,12 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container" >
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
<div class="page-container page-body">
|
||||
<div class="page-action-bar">
|
||||
<div class="page-action-bar__spacer">
|
||||
</div>
|
||||
|
||||
<a href="alerting/notification/new" class="btn btn-success pull-right">
|
||||
<a href="alerting/notification/new" class="btn btn-success">
|
||||
<i class="fa fa-plus"></i>
|
||||
New Channel
|
||||
</a>
|
||||
</div>
|
||||
|
@ -17,7 +17,7 @@ export class DashboardListCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, navModelSrv, private $q, private searchSrv: SearchSrv) {
|
||||
this.navModel = navModelSrv.getNav('dashboards', 'dashboards');
|
||||
this.navModel = navModelSrv.getNav('dashboards', 'dashboards', 0);
|
||||
this.query = {query: '', mode: 'tree', tag: [], starred: false};
|
||||
this.selectedStarredFilter = this.starredFilterOptions[0];
|
||||
|
||||
|
@ -72,8 +72,18 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
|
||||
render() {
|
||||
return (
|
||||
<div className="panel-container">
|
||||
<div className="add-panel">{this.state.panelPlugins.map(this.renderPanelItem.bind(this))}</div>
|
||||
<div className="add-panel">
|
||||
<div className="add-panel__header">
|
||||
<i className="gicon gicon-add-panel"></i>
|
||||
<span className="add-panel__title">New Panel</span>
|
||||
<span className="add-panel__sub-title">Select a visualization</span>
|
||||
</div>
|
||||
<div className="add-panel__items">
|
||||
{this.state.panelPlugins.map(this.renderPanelItem.bind(this))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,95 +1,66 @@
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner">
|
||||
|
||||
<div>
|
||||
<a class="navbar-page-btn" ng-click="ctrl.showSearch()">
|
||||
<i class="gicon gicon-dashboard"></i>
|
||||
{{ctrl.dashboard.title}}
|
||||
<i class="fa fa-caret-down"></i>
|
||||
</a>
|
||||
|
||||
<ul class="nav dash-playlist-actions" ng-if="ctrl.playlistSrv.isPlaying">
|
||||
<li>
|
||||
<a ng-click="ctrl.playlistSrv.prev()"><i class="fa fa-step-backward"></i></a>
|
||||
</li>
|
||||
<li>
|
||||
<a ng-click="ctrl.playlistSrv.stop()"><i class="fa fa-stop"></i></a>
|
||||
</li>
|
||||
<li>
|
||||
<a ng-click="ctrl.playlistSrv.next()"><i class="fa fa-step-forward"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav dashnav-action-icons">
|
||||
<li ng-show="::ctrl.dashboard.meta.canStar">
|
||||
<a class="pointer" ng-click="ctrl.starDashboard()">
|
||||
<i class="fa" ng-class="{'fa-star-o': !ctrl.dashboard.meta.isStarred, 'fa-star': ctrl.dashboard.meta.isStarred}" style="color: orange;"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li ng-show="::ctrl.dashboard.meta.canShare" class="dropdown">
|
||||
<a class="pointer" ng-click="ctrl.hideTooltip($event)" bs-tooltip="'Share dashboard'" data-placement="bottom" data-toggle="dropdown"><i class="fa fa-share-square-o"></i></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a class="pointer" ng-click="ctrl.shareDashboard(0)">
|
||||
<i class="fa fa-link"></i> Link to Dashboard
|
||||
<div class="dropdown-desc">Share an internal link to the current dashboard. Some configuration options available.</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="pointer" ng-click="ctrl.shareDashboard(1)">
|
||||
<i class="icon-gf icon-gf-snapshot"></i>Snapshot
|
||||
<div class="dropdown-desc">Interactive, publically accessible dashboard. Sensitive data is stripped out.</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="pointer" ng-click="ctrl.shareDashboard(2)">
|
||||
<i class="fa fa-cloud-upload"></i>Export
|
||||
<div class="dropdown-desc">Export the dashboard to a JSON file for others and to share on Grafana.com</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li ng-show="::ctrl.dashboard.meta.canSave">
|
||||
<a ng-click="ctrl.saveDashboard()" bs-tooltip="'Save dashboard <br> CTRL+S'" data-placement="bottom"><i class="fa fa-save"></i></a>
|
||||
</li>
|
||||
|
||||
<li ng-if="::ctrl.dashboard.snapshot.originalUrl">
|
||||
<a ng-href="{{ctrl.dashboard.snapshot.originalUrl}}" bs-tooltip="'Open original dashboard'" data-placement="bottom"><i class="fa fa-link"></i></a>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a class="pointer" data-toggle="dropdown">
|
||||
<i class="fa fa-cog"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu--navbar">
|
||||
<li ng-repeat="navItem in ::ctrl.navModel.menu" ng-class="{active: navItem.active}">
|
||||
<a class="pointer" ng-href="{{::navItem.url}}" ng-click="ctrl.navItemClicked(navItem, $event)">
|
||||
<i class="{{::navItem.icon}}" ng-show="::navItem.icon"></i>
|
||||
{{::navItem.title}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="navbar-mini-btn-wrapper" ng-show="::ctrl.dashboard.meta.canSave">
|
||||
<button class="btn btn-secondary btn-mini" ng-click="ctrl.addPanel()">
|
||||
<i class="fa fa-plus-circle"></i> Add Panel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="nav nav--grow">
|
||||
</div>
|
||||
|
||||
<ul class="nav pull-right">
|
||||
<li ng-show="ctrl.dashboard.meta.fullscreen" class="dashnav-back-to-dashboard">
|
||||
<a ng-click="ctrl.exitFullscreen()">
|
||||
Back to dashboard
|
||||
</a>
|
||||
</li>
|
||||
<li ng-if="!ctrl.dashboard.timepicker.hidden">
|
||||
<gf-time-picker dashboard="ctrl.dashboard"></gf-time-picker>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<ul class="nav dash-playlist-actions" ng-if="ctrl.playlistSrv.isPlaying">
|
||||
<li>
|
||||
<a ng-click="ctrl.playlistSrv.prev()"><i class="fa fa-step-backward"></i></a>
|
||||
</li>
|
||||
<li>
|
||||
<a ng-click="ctrl.playlistSrv.stop()"><i class="fa fa-stop"></i></a>
|
||||
</li>
|
||||
<li>
|
||||
<a ng-click="ctrl.playlistSrv.next()"><i class="fa fa-step-forward"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="navbar__spacer"></div>
|
||||
|
||||
<div class="navbar-buttons navbar-buttons--actions">
|
||||
<button class="btn navbar-button navbar-button--add-panel" ng-show="::ctrl.dashboard.meta.canSave" bs-tooltip="'Add panel'" data-placement="bottom" ng-click="ctrl.addPanel()">
|
||||
<i class="gicon gicon-add-panel"></i>
|
||||
</button>
|
||||
|
||||
<button class="btn navbar-button" ng-show="::ctrl.dashboard.meta.canStar" ng-click="ctrl.starDashboard()" bs-tooltip="'Mark as favorite'" data-placement="bottom">
|
||||
<i class="fa" ng-class="{'fa-star-o': !ctrl.dashboard.meta.isStarred, 'fa-star': ctrl.dashboard.meta.isStarred}"></i>
|
||||
</button>
|
||||
|
||||
<button class="btn navbar-button" ng-show="::ctrl.dashboard.meta.canShare" ng-click="ctrl.shareDashboard(0)" bs-tooltip="'Share dashboard'" data-placement="bottom">
|
||||
<i class="fa fa-share-square-o"></i></a>
|
||||
</button>
|
||||
|
||||
<button class="btn navbar-button" ng-show="::ctrl.dashboard.meta.canSave" ng-click="ctrl.saveDashboard()" bs-tooltip="'Save dashboard <br> CTRL+S'" data-placement="bottom">
|
||||
<i class="fa fa-save"></i>
|
||||
</button>
|
||||
|
||||
<button class="btn navbar-button" ng-if="::ctrl.dashboard.snapshot.originalUrl" ng-href="{{ctrl.dashboard.snapshot.originalUrl}}" bs-tooltip="'Open original dashboard'" data-placement="bottom">
|
||||
<i class="fa fa-link"></i>
|
||||
</button>
|
||||
|
||||
<div class="dropdown">
|
||||
<button class="btn navbar-button" data-toggle="dropdown" bs-tooltip="'Settings'" data-placement="bottom">
|
||||
<i class="fa fa-cog"></i>
|
||||
</button>
|
||||
|
||||
<ul class="dropdown-menu dropdown-menu--navbar">
|
||||
<li ng-repeat="navItem in ::ctrl.navModel.menu" ng-class="{active: navItem.active}">
|
||||
<a class="pointer" ng-href="{{::navItem.url}}" ng-click="ctrl.navItemClicked(navItem, $event)">
|
||||
<i class="{{::navItem.icon}}" ng-show="::navItem.icon"></i>
|
||||
{{::navItem.title}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<gf-time-picker class="gf-timepicker-nav" dashboard="ctrl.dashboard" ng-if="!ctrl.dashboard.timepicker.hidden"></gf-time-picker>
|
||||
|
||||
</div>
|
||||
|
||||
<dashboard-search></dashboard-search>
|
||||
|
@ -150,7 +150,7 @@ export class DashNavCtrl {
|
||||
this.dashboard.addPanel({
|
||||
type: 'add-panel',
|
||||
gridPos: {x: 0, y: 0, w: 12, h: 9},
|
||||
title: 'New Graph',
|
||||
title: 'Panel Title',
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,163 +1,131 @@
|
||||
<div class="scroll-canvas" grafana-scrollbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<div class="page-container" style="height: 95%">
|
||||
<div class="page-header">
|
||||
<h1>Dashboards</h1>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<a class="btn btn-inverse" href="/dashboard/new">
|
||||
<i class="gicon gicon-dashboard-new"></i>
|
||||
Dashboard
|
||||
</a>
|
||||
<a class="btn btn-inverse" href="/dashboard/new/?editview=new-folder">
|
||||
<i class="gicon gicon-folder-new"></i>
|
||||
Folder
|
||||
</a>
|
||||
<div class="page-container page-body">
|
||||
<div class="page-action-bar">
|
||||
<div class="gf-form gf-form--grow">
|
||||
<label class="gf-form-label">Search</label>
|
||||
<input type="text" class="gf-form-input max-width-30" placeholder="Find Dashboard by name" tabindex="1" give-focus="true" ng-model="ctrl.query.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.onQueryChange()" />
|
||||
</div>
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form width-15">
|
||||
<span style="position: relative;">
|
||||
<input type="text" class="gf-form-input" placeholder="Find Dashboard by name" tabindex="1" give-focus="true"
|
||||
ng-model="ctrl.query.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.onQueryChange()" />
|
||||
</span>
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
<a class="btn btn-success" href="/dashboard/new">
|
||||
<i class="fa fa-plus"></i>
|
||||
Dashboard
|
||||
</a>
|
||||
<a class="btn btn-success" href="/dashboard/new/?editview=new-folder">
|
||||
<i class="fa fa-plus"></i>
|
||||
Folder
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="gf-form" ng-if="ctrl.query.tag.length">
|
||||
Filters:
|
||||
<span ng-repeat="tagName in ctrl.query.tag">
|
||||
<a ng-click="ctrl.removeTag(tagName, $event)" tag-color-from-name="tagName" class="label label-tag">
|
||||
<i class="fa fa-remove"></i>
|
||||
{{tagName}}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<div class="gf-form-button-row"
|
||||
ng-show="ctrl.hasFilters">
|
||||
<button
|
||||
type="button"
|
||||
class="btn gf-form-button btn-inverse btn-small"
|
||||
ng-click="ctrl.clearFilters()">
|
||||
<i class="fa fa-close"></i> Clear current search query and filters
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-button-row">
|
||||
<button type="button"
|
||||
class="btn gf-form-button btn-secondary"
|
||||
ng-disabled="!ctrl.canMove"
|
||||
ng-click="ctrl.moveTo()"
|
||||
bs-tooltip="ctrl.canMove ? '' : 'Select a dashboard to move (cannot move folders)'" data-placement="bottom">
|
||||
<i class="fa fa-exchange"></i> Move to...
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn gf-form-button btn-inverse"
|
||||
ng-click="ctrl.delete()"
|
||||
ng-disabled="!ctrl.canDelete">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-list">
|
||||
<div class="search-results-filter-row">
|
||||
<gf-form-switch
|
||||
on-change="ctrl.onSelectAllChanged()"
|
||||
checked="ctrl.selectAllChecked"
|
||||
/>
|
||||
<div class="search-results-filter-row__filters">
|
||||
<select
|
||||
class="search-results-filter-row__filters-item gf-form-input"
|
||||
ng-model="ctrl.selectedStarredFilter"
|
||||
ng-options="t.text disable when t.disabled for t in ctrl.starredFilterOptions"
|
||||
ng-change="ctrl.onStarredFilterChange()"
|
||||
/>
|
||||
<select
|
||||
class="search-results-filter-row__filters-item gf-form-input"
|
||||
ng-model="ctrl.selectedTagFilter"
|
||||
ng-options="t.term disable when t.disabled for t in ctrl.tagFilterOptions"
|
||||
ng-change="ctrl.onTagFilterChange()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-results-container" ng-show="ctrl.sections.length > 0" grafana-scrollbar>
|
||||
<div ng-repeat="section in ctrl.sections" class="search-section">
|
||||
|
||||
<div class="gf-form" ng-if="ctrl.query.tag.length">
|
||||
Filters:
|
||||
<span ng-repeat="tagName in ctrl.query.tag">
|
||||
<a ng-click="ctrl.removeTag(tagName, $event)" tag-color-from-name="tagName" class="label label-tag">
|
||||
<i class="fa fa-remove"></i>
|
||||
{{tagName}}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<div class="gf-form-button-row"
|
||||
ng-show="ctrl.hasFilters">
|
||||
<button
|
||||
type="button"
|
||||
class="btn gf-form-button btn-inverse btn-small"
|
||||
ng-click="ctrl.clearFilters()">
|
||||
<i class="fa fa-close"></i> Clear current search query and filters
|
||||
</button>
|
||||
<div class="search-section__header__with-checkbox" ng-hide="section.hideHeader">
|
||||
<gf-form-switch
|
||||
on-change="ctrl.selectionChanged()"
|
||||
checked="section.checked">
|
||||
</gf-form-switch>
|
||||
<a class="search-section__header pointer" ng-click="ctrl.toggleFolder(section)" ng-hide="section.hideHeader">
|
||||
<i class="search-section__header__icon" ng-class="section.icon"></i>
|
||||
<span class="search-section__header__text">{{::section.title}}</span>
|
||||
<i class="fa fa-minus search-section__header__toggle" ng-show="section.expanded"></i>
|
||||
<i class="fa fa-plus search-section__header__toggle" ng-hide="section.expanded"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-button-row">
|
||||
<button type="button"
|
||||
class="btn gf-form-button btn-secondary"
|
||||
ng-disabled="!ctrl.canMove"
|
||||
ng-click="ctrl.moveTo()"
|
||||
bs-tooltip="ctrl.canMove ? '' : 'Select a dashboard to move (cannot move folders)'" data-placement="bottom">
|
||||
<i class="fa fa-exchange"></i> Move to...
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn gf-form-button btn-inverse"
|
||||
ng-click="ctrl.delete()"
|
||||
ng-disabled="!ctrl.canDelete">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-list">
|
||||
<div class="search-results-filter-row">
|
||||
<div ng-if="section.expanded">
|
||||
<div ng-repeat="item in section.items" class="search-item__with-checkbox" ng-class="{'selected': item.selected}">
|
||||
<gf-form-switch
|
||||
on-change="ctrl.onSelectAllChanged()"
|
||||
checked="ctrl.selectAllChecked"
|
||||
/>
|
||||
<div class="search-results-filter-row__filters">
|
||||
<select
|
||||
class="search-results-filter-row__filters-item gf-form-input"
|
||||
ng-model="ctrl.selectedStarredFilter"
|
||||
ng-options="t.text disable when t.disabled for t in ctrl.starredFilterOptions"
|
||||
ng-change="ctrl.onStarredFilterChange()"
|
||||
/>
|
||||
<select
|
||||
class="search-results-filter-row__filters-item gf-form-input"
|
||||
ng-model="ctrl.selectedTagFilter"
|
||||
ng-options="t.term disable when t.disabled for t in ctrl.tagFilterOptions"
|
||||
ng-change="ctrl.onTagFilterChange()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-results-container" ng-show="ctrl.sections.length > 0" grafana-scrollbar>
|
||||
<div ng-repeat="section in ctrl.sections" class="search-section">
|
||||
|
||||
<div class="search-section__header__with-checkbox" ng-hide="section.hideHeader">
|
||||
<gf-form-switch
|
||||
on-change="ctrl.selectionChanged()"
|
||||
checked="section.checked">
|
||||
</gf-form-switch>
|
||||
<a class="search-section__header pointer" ng-click="ctrl.toggleFolder(section)" ng-hide="section.hideHeader">
|
||||
<i class="search-section__header__icon" ng-class="section.icon"></i>
|
||||
<span class="search-section__header__text">{{::section.title}}</span>
|
||||
<i class="fa fa-minus search-section__header__toggle" ng-show="section.expanded"></i>
|
||||
<i class="fa fa-plus search-section__header__toggle" ng-hide="section.expanded"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div ng-if="section.expanded">
|
||||
<div ng-repeat="item in section.items" class="search-item__with-checkbox" ng-class="{'selected': item.selected}">
|
||||
<gf-form-switch
|
||||
on-change="ctrl.selectionChanged()"
|
||||
checked="item.checked" />
|
||||
<a ng-href="{{::item.url}}" class="search-item">
|
||||
<span class="search-item__icon">
|
||||
<i class="fa fa-th-large"></i>
|
||||
</span>
|
||||
<span class="search-item__body">
|
||||
<div class="search-item__body-title">{{::item.title}}</div>
|
||||
<div class="search-item__body-sub-title" ng-show="item.folderTitle && section.hideHeader">
|
||||
<i class="fa fa-folder-o"></i>
|
||||
{{::item.folderTitle}}
|
||||
</div>
|
||||
</span>
|
||||
<span class="search-item__tags">
|
||||
<span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in item.tags" tag-color-from-name="tag" class="label label-tag">
|
||||
{{tag}}
|
||||
</span>
|
||||
</span>
|
||||
<span class="search-item__actions">
|
||||
<i class="fa" ng-class="{'fa-star': item.isStarred, 'fa-star-o': !item.isStarred}"></i>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div bindonce class="search-section" ng-repeat="dashboard in ctrl.dashboards">
|
||||
<gf-form-switch
|
||||
switch-class="gf-form-switch--table-cell"
|
||||
on-change="ctrl.selectionChanged()"
|
||||
checked="dashboard.checked">
|
||||
</gf-form-switch>
|
||||
<a class="search-item pointer "
|
||||
bo-href-i="{{dashboard.url}}">
|
||||
<span class="search-item__icon">
|
||||
<i class="fa fa-th-large"></i>
|
||||
</span>
|
||||
<span class="search-result-tags">
|
||||
<span ng-click="ctrl.filterByTag(tag, $event)" bindonce ng-repeat="tag in dashboard.tags" tag-color-from-name="tag" class="label label-tag">
|
||||
{{tag}}
|
||||
</span>
|
||||
<i class="fa" bo-class="{'fa-star': dashboard.isStarred, 'fa-star-o': !dashboard.isStarred}"></i>
|
||||
</span>
|
||||
<span class="search-result-link">
|
||||
<i class="fa search-result-icon"></i>
|
||||
<span bo-text="dashboard.title" />
|
||||
</span>
|
||||
</a>
|
||||
</div> -->
|
||||
on-change="ctrl.selectionChanged()"
|
||||
checked="item.checked" />
|
||||
<a ng-href="{{::item.url}}" class="search-item">
|
||||
<span class="search-item__icon">
|
||||
<i class="fa fa-th-large"></i>
|
||||
</span>
|
||||
<span class="search-item__body">
|
||||
<div class="search-item__body-title">{{::item.title}}</div>
|
||||
<div class="search-item__body-sub-title" ng-show="item.folderTitle && section.hideHeader">
|
||||
<i class="fa fa-folder-o"></i>
|
||||
{{::item.folderTitle}}
|
||||
</div>
|
||||
</span>
|
||||
<span class="search-item__tags">
|
||||
<span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in item.tags" tag-color-from-name="tag" class="label label-tag">
|
||||
{{tag}}
|
||||
</span>
|
||||
</span>
|
||||
<span class="search-item__actions">
|
||||
<i class="fa" ng-class="{'fa-star': item.isStarred, 'fa-star-o': !item.isStarred}"></i>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<em class="muted" ng-hide="ctrl.sections.length > 0">
|
||||
No Dashboards or Folders found.
|
||||
</em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<em class="muted" ng-hide="ctrl.sections.length > 0">
|
||||
No Dashboards or Folders found.
|
||||
</em>
|
||||
|
@ -1,38 +1,26 @@
|
||||
<ul class="nav gf-timepicker-nav">
|
||||
<div class="navbar-buttons navbar-buttons--zoom">
|
||||
<button class="btn navbar-button navbar-button--tight" ng-click='ctrl.move(-1)'>
|
||||
<i class="fa fa-chevron-left"></i>
|
||||
</button>
|
||||
|
||||
<li class="dashnav-move-timeframe gf-timepicker-time-control" bs-tooltip="'Shift time backward <br> (left arrow key)'" data-placement="bottom">
|
||||
<a ng-click='ctrl.move(-1)'>
|
||||
<i class="fa fa-chevron-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="dashnav-zoom-out gf-timepicker-time-control" bs-tooltip="'Time range zoom out <br> CTRL+Z'" data-placement="bottom">
|
||||
<a ng-click='ctrl.zoom(2)'>Zoom Out</a>
|
||||
</li>
|
||||
</li>
|
||||
<li class="dashnav-move-timeframe gf-timepicker-time-control" bs-tooltip="'Shift time forward <br> (right arrow key)'" data-placement="bottom">
|
||||
<a ng-click='ctrl.move(1)'>
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
<button class="btn navbar-button" bs-tooltip="'Time range zoom out <br> CTRL+Z'" data-placement="bottom" ng-click='ctrl.zoom(2)'>
|
||||
<i class="fa fa-search-minus"></i>
|
||||
</button>
|
||||
|
||||
<li>
|
||||
<a bs-tooltip="ctrl.tooltip" data-placement="bottom" ng-click="ctrl.openDropdown()" class="gf-timepicker-nav-btn">
|
||||
<i class="fa fa-clock-o"></i>
|
||||
<span ng-bind="ctrl.rangeString"></span>
|
||||
<span ng-show="ctrl.isUtc" class="gf-timepicker-utc">
|
||||
UTC
|
||||
</span>
|
||||
<button class="btn navbar-button navbar-button--tight" ng-click='ctrl.move(1)'>
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<span ng-show="ctrl.dashboard.refresh" class="text-warning">
|
||||
Refresh every {{ctrl.dashboard.refresh}}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<div class="navbar-buttons">
|
||||
<button bs-tooltip="ctrl.tooltip" data-placement="bottom" ng-click="ctrl.openDropdown()" class="btn navbar-button gf-timepicker-nav-btn">
|
||||
<i class="fa fa-clock-o"></i>
|
||||
<span ng-bind="ctrl.rangeString"></span>
|
||||
<span ng-show="ctrl.isUtc" class="gf-timepicker-utc">UTC</span>
|
||||
<span ng-show="ctrl.dashboard.refresh" class="text-warning"> Refresh every {{ctrl.dashboard.refresh}}</span>
|
||||
</button>
|
||||
|
||||
<li class="dashnav-refresh-action">
|
||||
<a ng-click="ctrl.timeSrv.refreshDashboard()">
|
||||
<i class="fa fa-refresh"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<button class="btn navbar-button navbar-button--refresh" ng-click="ctrl.timeSrv.refreshDashboard()">
|
||||
<i class="fa fa-refresh"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -5,6 +5,7 @@ import './select_org_ctrl';
|
||||
import './change_password_ctrl';
|
||||
import './new_org_ctrl';
|
||||
import './user_invite_ctrl';
|
||||
import './user_groups_ctrl';
|
||||
import './org_api_keys_ctrl';
|
||||
import './org_details_ctrl';
|
||||
import './prefs_control';
|
||||
|
@ -8,7 +8,7 @@ export class ChangePasswordCtrl {
|
||||
$scope.command = {};
|
||||
$scope.authProxyEnabled = config.authProxyEnabled;
|
||||
$scope.ldapEnabled = config.ldapEnabled;
|
||||
$scope.navModel = navModelSrv.getNav('profile', 'change-password');
|
||||
$scope.navModel = navModelSrv.getNav('profile', 'change-password', 0);
|
||||
|
||||
$scope.changePassword = function() {
|
||||
if (!$scope.userForm.$valid) { return; }
|
||||
|
@ -5,7 +5,7 @@ export class NewOrgCtrl {
|
||||
|
||||
/** @ngInject **/
|
||||
constructor($scope, $http, backendSrv, navModelSrv) {
|
||||
$scope.navModel = navModelSrv.getOrgNav(0);
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'admin', 'global-orgs', 1);
|
||||
$scope.newOrg = {name: ''};
|
||||
|
||||
$scope.createOrg = function() {
|
||||
|
@ -4,7 +4,7 @@ export class OrgApiKeysCtrl {
|
||||
|
||||
/** @ngInject **/
|
||||
constructor ($scope, $http, backendSrv, navModelSrv) {
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'apikeys');
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'apikeys', 0);
|
||||
|
||||
$scope.roleTypes = ['Viewer', 'Editor', 'Admin'];
|
||||
$scope.token = { role: 'Viewer' };
|
||||
|
@ -6,7 +6,7 @@ export class OrgDetailsCtrl {
|
||||
constructor($scope, $http, backendSrv, contextSrv, navModelSrv) {
|
||||
$scope.init = function() {
|
||||
$scope.getOrgInfo();
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'org');
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'org-settings', 0);
|
||||
};
|
||||
|
||||
$scope.getOrgInfo = function() {
|
||||
|
@ -23,7 +23,7 @@ export class OrgUsersCtrl {
|
||||
role: 'Viewer',
|
||||
};
|
||||
|
||||
this.navModel = navModelSrv.getNav('cfg', 'users');
|
||||
this.navModel = navModelSrv.getNav('cfg', 'users', 0);
|
||||
|
||||
this.get();
|
||||
this.editor = { index: 0 };
|
||||
@ -44,8 +44,7 @@ export class OrgUsersCtrl {
|
||||
if (this.externalUserMngLinkName) {
|
||||
return this.externalUserMngLinkName;
|
||||
}
|
||||
|
||||
return "Add Members";
|
||||
return "Add Member";
|
||||
}
|
||||
|
||||
get() {
|
||||
|
@ -1,15 +1,12 @@
|
||||
<navbar model="navModel"></navbar>
|
||||
<page-header model="navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="navModel"></page-h1>
|
||||
</div>
|
||||
<div class="page-container page-body">
|
||||
<h2 class="page-sub-heading">
|
||||
Change your password
|
||||
</h2>
|
||||
|
||||
<div ng-if="ldapEnabled || authProxyEnabled">
|
||||
You cannot change password when ldap or auth proxy authentication is enabled.
|
||||
<br>
|
||||
<br>
|
||||
<a class="btn-text" href="profile">Back to profile</a>
|
||||
</div>
|
||||
|
||||
<form name="userForm" class="gf-form-group" ng-hide="ldapEnabled || authProxyEnabled">
|
||||
|
@ -1,9 +1,9 @@
|
||||
<navbar model="navModel"></navbar>
|
||||
<page-header model="navModel"></page-header>
|
||||
|
||||
<div class="page-container" ng-form="playlistEditForm">
|
||||
<div class="page-header">
|
||||
<h1>New Organization</h1>
|
||||
</div>
|
||||
<div class="page-container page-body" ng-form="playlistEditForm">
|
||||
<h2 class="page-sub-heading">
|
||||
New Organization
|
||||
</h2>
|
||||
|
||||
<p class="playlist-description">Each organization contains their own dashboards, data sources and configuration, and cannot be shared between orgs. While users may belong to more than one, mutiple organization are most frequently used in multi-tenant deployments. </p>
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
<navbar model="navModel"></navbar>
|
||||
<page-header model="navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="navModel"></page-h1>
|
||||
</div>
|
||||
<div class="page-container page-body">
|
||||
|
||||
<h3 class="page-heading">Add new</h3>
|
||||
|
||||
<form name="addTokenForm" class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form max-width-21">
|
||||
|
@ -1,26 +1,21 @@
|
||||
<navbar model="navModel"></navbar>
|
||||
<page-header model="navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="navModel"></page-h1>
|
||||
</div>
|
||||
<div class="page-container page-body">
|
||||
<h3 class="page-sub-heading">Organization profile</h3>
|
||||
|
||||
<h3 class="page-heading">General</h3>
|
||||
<form name="orgForm" class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form max-width-28">
|
||||
<span class="gf-form-label">Organization name</span>
|
||||
<input class="gf-form-input" type="text" required ng-model="org.name">
|
||||
</div>
|
||||
</div>
|
||||
<form name="orgForm" class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form max-width-28">
|
||||
<span class="gf-form-label">Organization name</span>
|
||||
<input class="gf-form-input" type="text" required ng-model="org.name">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
<button type="submit" class="btn btn-success" ng-click="update()">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<prefs-control mode="org"></prefs-control>
|
||||
|
||||
</form>
|
||||
<prefs-control mode="org"></prefs-control>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -1,34 +1,52 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<!-- <navbar model="ctrl.navModel"></navbar> -->
|
||||
<!-- -->
|
||||
<!-- <div class="page-container"> -->
|
||||
<!-- <div class="page-header"> -->
|
||||
<!-- <page-h1 model="ctrl.navModel"></page-h1> -->
|
||||
<!-- -->
|
||||
<!-- <button class="btn btn-success" ng-click="ctrl.openAddUsersView()" ng-hide="ctrl.externalUserMngLinkUrl"> -->
|
||||
<!-- <span>{{ctrl.addUsersBtnName}}</span> -->
|
||||
<!-- </button> -->
|
||||
<!-- -->
|
||||
<!-- <div class="page-header-tabs"> -->
|
||||
<!-- -->
|
||||
<!-- <a class="btn btn-inverse" ng-href="{{ctrl.externalUserMngLinkUrl}}" target="_blank" ng-if="ctrl.externalUserMngLinkUrl"> -->
|
||||
<!-- <i class="fa fa-external-link-square"></i> -->
|
||||
<!-- {{ctrl.addUsersBtnName}} -->
|
||||
<!-- </a> -->
|
||||
<!-- -->
|
||||
<!-- <ul class="gf-tabs"> -->
|
||||
<!-- <li class="gf-tabs-item"> -->
|
||||
<!-- <a class="gf-tabs-link" ng-click="ctrl.editor.index = 0" ng-class="{active: ctrl.editor.index === 0}"> -->
|
||||
<!-- Users ({{ctrl.users.length}}) -->
|
||||
<!-- </a> -->
|
||||
<!-- </li> -->
|
||||
<!-- <li class="gf-tabs-item" ng-show="ctrl.pendingInvites.length"> -->
|
||||
<!-- <a class="gf-tabs-link" ng-click="ctrl.editor.index = 1" ng-class="{active: ctrl.editor.index === 1}"> -->
|
||||
<!-- Pending Invites ({{ctrl.pendingInvites.length}}) -->
|
||||
<!-- </a> -->
|
||||
<!-- </li> -->
|
||||
<!-- </ul> -->
|
||||
<!-- </div> -->
|
||||
<!-- </div> -->
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container page-body">
|
||||
<div class="page-action-bar">
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
<button class="btn btn-inverse" ng-show="ctrl.pendingInvites.length" ng-click="ctrl.editor.index = 1">
|
||||
Pending Invites ({{ctrl.pendingInvites.length}})
|
||||
</button>
|
||||
<button class="btn btn-success" ng-click="ctrl.openAddUsersView()" ng-hide="ctrl.externalUserMngLinkUrl">
|
||||
<i class="fa fa-plus"></i>
|
||||
<span>{{ctrl.addUsersBtnName}}</span>
|
||||
</button>
|
||||
|
||||
<div class="page-header-tabs">
|
||||
|
||||
<a class="btn btn-inverse" ng-href="{{ctrl.externalUserMngLinkUrl}}" target="_blank" ng-if="ctrl.externalUserMngLinkUrl">
|
||||
<i class="fa fa-external-link-square"></i>
|
||||
{{ctrl.addUsersBtnName}}
|
||||
</a>
|
||||
|
||||
<ul class="gf-tabs">
|
||||
<li class="gf-tabs-item">
|
||||
<a class="gf-tabs-link" ng-click="ctrl.editor.index = 0" ng-class="{active: ctrl.editor.index === 0}">
|
||||
Users ({{ctrl.users.length}})
|
||||
</a>
|
||||
</li>
|
||||
<li class="gf-tabs-item" ng-show="ctrl.pendingInvites.length">
|
||||
<a class="gf-tabs-link" ng-click="ctrl.editor.index = 1" ng-class="{active: ctrl.editor.index === 1}">
|
||||
Pending Invites ({{ctrl.pendingInvites.length}})
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-inverse" ng-href="{{ctrl.externalUserMngLinkUrl}}" target="_blank" ng-if="ctrl.externalUserMngLinkUrl">
|
||||
<i class="fa fa-external-link-square"></i>
|
||||
{{ctrl.addUsersBtnName}}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="grafana-info-box" ng-if="ctrl.externalUserMngInfo">
|
||||
<span ng-bind-html="ctrl.externalUserMngInfo"></span>
|
||||
@ -41,26 +59,26 @@
|
||||
<th></th>
|
||||
<th>Login</th>
|
||||
<th>Email</th>
|
||||
<th>
|
||||
Seen
|
||||
<tip>Time since user was seen using Grafana</tip>
|
||||
</th>
|
||||
<th>
|
||||
Seen
|
||||
<tip>Time since user was seen using Grafana</tip>
|
||||
</th>
|
||||
<th>Role</th>
|
||||
<th style="width: 34px;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr ng-repeat="user in ctrl.users">
|
||||
<td class="width-4 text-center">
|
||||
<img class="filter-table__avatar" ng-src="{{user.avatarUrl}}"></img>
|
||||
</td>
|
||||
<img class="filter-table__avatar" ng-src="{{user.avatarUrl}}"></img>
|
||||
</td>
|
||||
<td>{{user.login}}</td>
|
||||
<td><span class="ellipsis">{{user.email}}</span></td>
|
||||
<td>{{user.lastSeenAtAge}}</td>
|
||||
<td>{{user.lastSeenAtAge}}</td>
|
||||
<td>
|
||||
<div class="gf-form-select-wrapper width-9">
|
||||
<select type="text" ng-model="user.role" class="gf-form-input" ng-options="f for f in ['Viewer', 'Editor', 'Read Only Editor', 'Admin']" ng-change="ctrl.updateOrgUser(user)">
|
||||
</select>
|
||||
</div>
|
||||
<div class="gf-form-select-wrapper width-9">
|
||||
<select type="text" ng-model="user.role" class="gf-form-input" ng-options="f for f in ['Viewer', 'Editor', 'Read Only Editor', 'Admin']" ng-change="ctrl.updateOrgUser(user)">
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a ng-click="ctrl.removeUser(user)" class="btn btn-danger btn-mini">
|
||||
|
@ -1,12 +1,9 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
</div>
|
||||
<div class="page-container page-body">
|
||||
<h3 class="page-sub-heading">User Profile</h3>
|
||||
|
||||
<form name="ctrl.userForm" class="gf-form-group">
|
||||
<h3 class="page-heading">Information</h3>
|
||||
|
||||
<div class="gf-form max-width-30">
|
||||
<span class="gf-form-label width-8">Name</span>
|
||||
|
@ -1,20 +1,22 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<h1>User Groups</h1>
|
||||
<div class="page-container page-body">
|
||||
<div class="page-action-bar">
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
<label class="gf-form-label">Search</label>
|
||||
<input type="text" class="gf-form-input max-width-20" placeholder="Find User Group by name" tabindex="1" give-focus="true"
|
||||
ng-model="ctrl.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.get()" />
|
||||
</div>
|
||||
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
|
||||
<a class="btn btn-success" ng-click="ctrl.openUserGroupModal()">
|
||||
<i class="fa fa-plus"></i>
|
||||
Create User Group
|
||||
Add Team
|
||||
</a>
|
||||
</div>
|
||||
<div class="gf-form width-15 gf-form-group">
|
||||
<span style="position: relative;">
|
||||
<input type="text" class="gf-form-input" placeholder="Find User Group by name" tabindex="1" give-focus="true"
|
||||
ng-model="ctrl.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.get()" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="admin-list-table">
|
||||
<table class="filter-table form-inline" ng-show="ctrl.userGroups.length > 0">
|
||||
<thead>
|
||||
@ -42,7 +44,6 @@
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
@ -14,7 +14,7 @@ export class ProfileCtrl {
|
||||
constructor(private backendSrv, private contextSrv, private $location, navModelSrv) {
|
||||
this.getUser();
|
||||
this.getUserOrgs();
|
||||
this.navModel = navModelSrv.getNav('profile');
|
||||
this.navModel = navModelSrv.getNav('profile', 'profile-settings', 0);
|
||||
}
|
||||
|
||||
getUser() {
|
||||
|
@ -15,7 +15,7 @@ export class UserGroupsCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'users');
|
||||
this.navModel = navModelSrv.getNav('cfg', 'teams', 0);
|
||||
this.get();
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container" ng-form="playlistEditForm">
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
</div>
|
||||
<div class="page-container page-body" ng-form="playlistEditForm">
|
||||
|
||||
<h3 class="page-sub-heading" ng-hide="ctrl.isNew">Edit Playlist</h3>
|
||||
<h3 class="page-sub-heading" ng-show="ctrl.isNew">New Playlist</h3>
|
||||
|
||||
<p class="playlist-description">A playlist rotates through a pre-selected list of Dashboards. A Playlist can be a great way to build situational awareness, or just show off your metrics to your team or visitors.</p>
|
||||
|
||||
@ -103,7 +103,7 @@
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
<a class="btn btn-success " ng-show="ctrl.isNew()"
|
||||
<a class="btn btn-success " ng-show="ctrl.isNew"
|
||||
ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()"
|
||||
ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Create new playlist</a>
|
||||
<a class="btn btn-success" ng-show="!ctrl.isNew()"
|
||||
|
@ -1,15 +1,15 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
<a class="btn btn-primary pull-right" href="playlists/create">
|
||||
<div class="page-container page-body">
|
||||
<div class="page-action-bar">
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
<a class="btn btn-success pull-right" href="playlists/create">
|
||||
<i class="fa fa-plus"></i>
|
||||
New Playlist
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<table class="filter-table" style="margin-top: 20px">
|
||||
<table class="filter-table">
|
||||
<thead>
|
||||
<th><strong>Name</strong></th>
|
||||
<th><strong>Start url</strong></th>
|
||||
|
@ -1,5 +1,3 @@
|
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import _ from 'lodash';
|
||||
import coreModule from '../../core/core_module';
|
||||
|
||||
@ -11,10 +9,12 @@ export class PlaylistEditCtrl {
|
||||
playlist: any = {
|
||||
interval: '5m',
|
||||
};
|
||||
|
||||
playlistItems: any = [];
|
||||
dashboardresult: any = [];
|
||||
tagresult: any = [];
|
||||
navModel: any;
|
||||
isNew: boolean;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(
|
||||
@ -24,7 +24,9 @@ export class PlaylistEditCtrl {
|
||||
$route,
|
||||
navModelSrv
|
||||
) {
|
||||
this.navModel = navModelSrv.getNav('dashboards', 'playlists');
|
||||
|
||||
this.navModel = navModelSrv.getNav('dashboards', 'playlists', 0);
|
||||
this.isNew = $route.current.params.id;
|
||||
|
||||
if ($route.current.params.id) {
|
||||
var playlistId = $route.current.params.id;
|
||||
@ -104,10 +106,6 @@ export class PlaylistEditCtrl {
|
||||
});
|
||||
}
|
||||
|
||||
isNew() {
|
||||
return !this.playlist.id;
|
||||
}
|
||||
|
||||
isPlaylistEmpty() {
|
||||
return !this.playlistItems.length;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ export class PlaylistsCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private backendSrv, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('dashboards', 'playlists');
|
||||
this.navModel = navModelSrv.getNav('dashboards', 'playlists', 0);
|
||||
|
||||
backendSrv.get('/api/playlists').then(result => {
|
||||
this.playlists = result;
|
||||
|
@ -41,7 +41,7 @@ export class DataSourceEditCtrl {
|
||||
navModelSrv,
|
||||
) {
|
||||
|
||||
this.navModel = navModelSrv.getNav('cfg', 'datasources');
|
||||
this.navModel = navModelSrv.getNav('cfg', 'datasources', 0);
|
||||
this.datasources = [];
|
||||
this.tabIndex = 0;
|
||||
|
||||
@ -58,9 +58,7 @@ export class DataSourceEditCtrl {
|
||||
this.isNew = true;
|
||||
this.current = _.cloneDeep(defaults);
|
||||
|
||||
// add to nav & breadcrumbs
|
||||
this.navModel.node = {text: 'New data source', icon: 'icon-gf icon-gf-fw icon-gf-datasources'};
|
||||
this.navModel.breadcrumbs.push(this.navModel.node);
|
||||
this.navModel.breadcrumbs.push({text: 'New'});
|
||||
|
||||
// We are coming from getting started
|
||||
if (this.$location.search().gettingstarted) {
|
||||
@ -87,7 +85,7 @@ export class DataSourceEditCtrl {
|
||||
this.backendSrv.get('/api/datasources/' + id).then(ds => {
|
||||
this.isNew = false;
|
||||
this.current = ds;
|
||||
this.navModel.node = {text: ds.name, icon: 'icon-gf icon-gf-fw icon-gf-datasources'};
|
||||
this.navModel.node = {text: ds.name, icon: 'icon-gf icon-gf-fw icon-gf-datasources', id: 'ds-new'};
|
||||
this.navModel.breadcrumbs.push(this.navModel.node);
|
||||
|
||||
if (datasourceCreated) {
|
||||
|
@ -13,7 +13,7 @@ export class DataSourcesCtrl {
|
||||
private datasourceSrv,
|
||||
private navModelSrv) {
|
||||
|
||||
this.navModel = this.navModelSrv.getNav('cfg', 'datasources');
|
||||
this.navModel = this.navModelSrv.getNav('cfg', 'datasources', 0);
|
||||
|
||||
backendSrv.get('/api/datasources').then(result => {
|
||||
this.datasources = result;
|
||||
|
@ -13,12 +13,6 @@
|
||||
{{dash.title}}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span>
|
||||
Revision: {{dash.revision}}
|
||||
<span ng-if="dash.imported" class="small">(Imported: {{dash.importedRevision}})</span>
|
||||
<span>
|
||||
</td>
|
||||
<td style="text-align: right">
|
||||
<button class="btn btn-secondary btn-small" ng-click="ctrl.import(dash, false)" ng-show="!dash.imported">
|
||||
Import
|
||||
|
@ -1,91 +1,80 @@
|
||||
<div class="scroll-canvas" grafana-scrollbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div ng-if="ctrl.current.readOnly" class="grafana-info-box span8">Disclaimer. This datasource was added by config and cannot be modified using the UI. Please contact your server admin to update this datasource.</div>
|
||||
<div class="page-container page-body">
|
||||
|
||||
<div class="page-header-tabs" ng-show="ctrl.hasDashboards">
|
||||
<ul class="gf-tabs">
|
||||
<li class="gf-tabs-item">
|
||||
<a class="gf-tabs-link" ng-click="ctrl.tabIndex = 0" ng-class="{active: ctrl.tabIndex === 0}">
|
||||
Config
|
||||
</a>
|
||||
</li>
|
||||
<li class="gf-tabs-item">
|
||||
<a class="gf-tabs-link" ng-click="ctrl.tabIndex = 1" ng-class="{active: ctrl.tabIndex === 1}">
|
||||
Dashboards
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.tabIndex === 0" class="tab-content">
|
||||
|
||||
<form name="ctrl.editForm" ng-if="ctrl.current">
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form max-width-30">
|
||||
<span class="gf-form-label width-7">Name</span>
|
||||
<input class="gf-form-input max-width-23" type="text" ng-model="ctrl.current.name" placeholder="name" required>
|
||||
<info-popover offset="0px -135px" mode="right-absolute">
|
||||
The name is used when you select the data source in panels.
|
||||
The <em>Default</em> data source is preselected in new
|
||||
panels.
|
||||
</info-popover>
|
||||
</div>
|
||||
<gf-form-switch class="gf-form" label="Default" checked="ctrl.current.isDefault" switch-class="max-width-6"></gf-form-switch>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">Type</span>
|
||||
<div class="gf-form-select-wrapper max-width-23">
|
||||
<select class="gf-form-input" ng-model="ctrl.current.type" ng-options="v.id as v.name for v in ctrl.types" ng-change="ctrl.userChangedType()"></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info gf-form-group" ng-if="ctrl.datasourceMeta.state === 'alpha'">
|
||||
This plugin is marked as being in alpha state, which means it is in early development phase and
|
||||
updates will include breaking changes.
|
||||
</div>
|
||||
|
||||
<rebuild-on-change property="ctrl.datasourceMeta.id">
|
||||
<plugin-component type="datasource-config-ctrl">
|
||||
</plugin-component>
|
||||
</rebuild-on-change>
|
||||
|
||||
<div ng-if="ctrl.testing" class="gf-form-group section">
|
||||
<h5 ng-show="!ctrl.testing.done">Testing.... <i class="fa fa-spiner fa-spin"></i></h5>
|
||||
<div class="alert-{{ctrl.testing.status}} alert" ng-show="ctrl.testing.done">
|
||||
<div class="alert-icon">
|
||||
<i class="fa fa-exclamation-triangle" ng-show="ctrl.testing.status === 'error'"></i>
|
||||
<i class="fa fa-check" ng-show="ctrl.testing.status !== 'error'"></i>
|
||||
</div>
|
||||
<div class="alert-body">
|
||||
<div class="alert-title">{{ctrl.testing.message}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
<button type="submit" class="btn btn-success" ng-disabled="ctrl.current.readOnly" ng-click="ctrl.saveChanges()">Save</button>
|
||||
<button type="submit" class="btn btn-danger" ng-disabled="ctrl.current.readOnly" ng-show="!ctrl.isNew" ng-click="ctrl.delete()">
|
||||
Delete
|
||||
</button>
|
||||
<a class="btn btn-link" href="datasources">Cancel</a>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div ng-if="ctrl.tabIndex === 1" class="tab-content">
|
||||
<dashboard-import-list plugin="ctrl.datasourceMeta" datasource="ctrl.current"></dashboard-import-list>
|
||||
<div ng-if="ctrl.current.readOnly" class="page-action-bar">
|
||||
<div class="grafana-info-box span8">
|
||||
Disclaimer. This datasource was added by config and cannot be modified using the UI. Please contact your server admin to update this datasource.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="page-sub-heading" ng-hide="ctrl.isNew">Edit Data Source</h3>
|
||||
<h3 class="page-sub-heading" ng-show="ctrl.isNew">New Data Source</h3>
|
||||
|
||||
<form name="ctrl.editForm" ng-if="ctrl.current">
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form max-width-30">
|
||||
<span class="gf-form-label width-7">Name</span>
|
||||
<input class="gf-form-input max-width-23" type="text" ng-model="ctrl.current.name" placeholder="name" required>
|
||||
<info-popover offset="0px -135px" mode="right-absolute">
|
||||
The name is used when you select the data source in panels.
|
||||
The <em>Default</em> data source is preselected in new
|
||||
panels.
|
||||
</info-popover>
|
||||
</div>
|
||||
<gf-form-switch class="gf-form" label="Default" checked="ctrl.current.isDefault" switch-class="max-width-6"></gf-form-switch>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">Type</span>
|
||||
<div class="gf-form-select-wrapper max-width-23">
|
||||
<select class="gf-form-input" ng-model="ctrl.current.type" ng-options="v.id as v.name for v in ctrl.types" ng-change="ctrl.userChangedType()"></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info gf-form-group" ng-if="ctrl.datasourceMeta.state === 'alpha'">
|
||||
This plugin is marked as being in alpha state, which means it is in early development phase and
|
||||
updates will include breaking changes.
|
||||
</div>
|
||||
|
||||
<rebuild-on-change property="ctrl.datasourceMeta.id">
|
||||
<plugin-component type="datasource-config-ctrl">
|
||||
</plugin-component>
|
||||
</rebuild-on-change>
|
||||
|
||||
<div ng-if="ctrl.hasDashboards">
|
||||
<h3 class="section-heading">Bundled Plugin Dashboards</h3>
|
||||
<div class="section">
|
||||
<dashboard-import-list plugin="ctrl.datasourceMeta" datasource="ctrl.current"></dashboard-import-list>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.testing" class="gf-form-group section">
|
||||
<h5 ng-show="!ctrl.testing.done">Testing.... <i class="fa fa-spiner fa-spin"></i></h5>
|
||||
<div class="alert-{{ctrl.testing.status}} alert" ng-show="ctrl.testing.done">
|
||||
<div class="alert-icon">
|
||||
<i class="fa fa-exclamation-triangle" ng-show="ctrl.testing.status === 'error'"></i>
|
||||
<i class="fa fa-check" ng-show="ctrl.testing.status !== 'error'"></i>
|
||||
</div>
|
||||
<div class="alert-body">
|
||||
<div class="alert-title">{{ctrl.testing.message}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
<button type="submit" class="btn btn-success" ng-disabled="ctrl.current.readOnly" ng-click="ctrl.saveChanges()">Save</button>
|
||||
<button type="submit" class="btn btn-danger" ng-disabled="ctrl.current.readOnly" ng-show="!ctrl.isNew" ng-click="ctrl.delete()">
|
||||
Delete
|
||||
</button>
|
||||
<a class="btn btn-link" href="datasources">Cancel</a>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
<div class="gf-form-group">
|
||||
<h3 class="page-heading">HTTP settings</h3>
|
||||
<h3 class="page-heading">HTTP</h3>
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form max-width-30">
|
||||
@ -38,39 +38,38 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="page-heading">HTTP Auth</h3>
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<gf-form-switch class="gf-form" label="Basic Auth" checked="current.basicAuth" label-class="width-8" switch-class="max-width-6"></gf-form-switch>
|
||||
<gf-form-switch class="gf-form" label="With Credentials" tooltip="Whether credentials such as cookies or auth headers should be sent with cross-site requests." checked="current.withCredentials" label-class="width-11" switch-class="max-width-6"></gf-form-switch>
|
||||
</div>
|
||||
<div class="gf-form-inline">
|
||||
<gf-form-switch class="gf-form" ng-if="current.access=='proxy'" label="TLS Client Auth" label-class="width-8" checked="current.jsonData.tlsAuth" switch-class="max-width-6"></gf-form-switch>
|
||||
<gf-form-switch class="gf-form" ng-if="current.access=='proxy'" label="With CA Cert" tooltip="Needed for verifing self-signed TLS Certs" checked="current.jsonData.tlsAuthWithCACert" label-class="width-11" switch-class="max-width-6"></gf-form-switch>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="page-heading">Auth</h3>
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<gf-form-switch class="gf-form" ng-if="current.access=='proxy'" label="Skip TLS Verification (Insecure)" label-class="width-16" checked="current.jsonData.tlsSkipVerify" switch-class="max-width-6"></gf-form-switch>
|
||||
<gf-form-switch class="gf-form" label="Basic Auth" checked="current.basicAuth" label-class="width-8" switch-class="max-width-6"></gf-form-switch>
|
||||
<gf-form-switch class="gf-form" label="With Credentials" tooltip="Whether credentials such as cookies or auth headers should be sent with cross-site requests." checked="current.withCredentials" label-class="width-11" switch-class="max-width-6"></gf-form-switch>
|
||||
</div>
|
||||
<div class="gf-form-inline">
|
||||
<gf-form-switch class="gf-form" ng-if="current.access=='proxy'" label="TLS Client Auth" label-class="width-8" checked="current.jsonData.tlsAuth" switch-class="max-width-6"></gf-form-switch>
|
||||
<gf-form-switch class="gf-form" ng-if="current.access=='proxy'" label="With CA Cert" tooltip="Needed for verifing self-signed TLS Certs" checked="current.jsonData.tlsAuthWithCACert" label-class="width-11" switch-class="max-width-6"></gf-form-switch>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-inline">
|
||||
<gf-form-switch class="gf-form" ng-if="current.access=='proxy'" label="Skip TLS Verification (Insecure)" label-class="width-16" checked="current.jsonData.tlsSkipVerify" switch-class="max-width-6"></gf-form-switch>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group" ng-if="current.basicAuth">
|
||||
<h6>Basic Auth Details</h6>
|
||||
<div class="gf-form" ng-if="current.basicAuth">
|
||||
<span class="gf-form-label width-7">
|
||||
User
|
||||
</span>
|
||||
<input class="gf-form-input max-width-21" type="text" ng-model='current.basicAuthUser' placeholder="user" required></input>
|
||||
</div>
|
||||
<div class="gf-form" ng-if="current.basicAuth">
|
||||
<span class="gf-form-label width-7">
|
||||
User
|
||||
</span>
|
||||
<input class="gf-form-input max-width-21" type="text" ng-model='current.basicAuthUser' placeholder="user" required></input>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">
|
||||
Password
|
||||
</span>
|
||||
<input class="gf-form-input max-width-21" type="password" ng-model='current.basicAuthPassword' placeholder="password" required></input>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">
|
||||
Password
|
||||
</span>
|
||||
<input class="gf-form-input max-width-21" type="password" ng-model='current.basicAuthPassword' placeholder="password" required></input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group" ng-if="(current.jsonData.tlsAuth || current.jsonData.tlsAuthWithCACert) && current.access=='proxy'">
|
||||
|
@ -1,48 +1,46 @@
|
||||
<div class="scroll-canvas" grafana-scrollbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<a class="page-header__cta btn btn-success" href="datasources/new">
|
||||
Add data source
|
||||
</a>
|
||||
</div>
|
||||
<div class="page-container page-body">
|
||||
<div class="page-action-bar">
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
<a class="page-header__cta btn btn-success" href="datasources/new">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add data source
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<section class="card-section" layout-mode>
|
||||
<layout-selector></layout-selector>
|
||||
|
||||
<ol class="card-list" >
|
||||
<li class="card-item-wrapper" ng-repeat="ds in ctrl.datasources">
|
||||
<a class="card-item" href="datasources/edit/{{ds.id}}/">
|
||||
<div class="card-item-header">
|
||||
<div class="card-item-type">
|
||||
{{ds.type}}
|
||||
<section class="card-section" layout-mode>
|
||||
<layout-selector></layout-selector>
|
||||
<ol class="card-list">
|
||||
<li class="card-item-wrapper" ng-repeat="ds in ctrl.datasources">
|
||||
<a class="card-item" href="datasources/edit/{{ds.id}}/">
|
||||
<div class="card-item-header">
|
||||
<div class="card-item-type">
|
||||
{{ds.type}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-item-body">
|
||||
<figure class="card-item-figure">
|
||||
<img ng-src="{{ds.typeLogoUrl}}">
|
||||
</figure>
|
||||
<div class="card-item-details">
|
||||
<div class="card-item-name">
|
||||
{{ds.name}}
|
||||
<span ng-if="ds.isDefault">
|
||||
<span class="btn btn-secondary btn-mini">default</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="card-item-sub-name">
|
||||
{{ds.url}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-item-body">
|
||||
<figure class="card-item-figure">
|
||||
<img ng-src="{{ds.typeLogoUrl}}">
|
||||
</figure>
|
||||
<div class="card-item-details">
|
||||
<div class="card-item-name">
|
||||
{{ds.name}}
|
||||
<span ng-if="ds.isDefault">
|
||||
<span class="btn btn-secondary btn-mini">default</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="card-item-sub-name">
|
||||
{{ds.url}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<div ng-if="ctrl.datasources.length === 0">
|
||||
<em>No data sources defined</em>
|
||||
</div>
|
||||
<div ng-if="ctrl.datasources.length === 0">
|
||||
<em>No data sources defined</em>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,62 +1,42 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container" ng-init="ctrl.init()">
|
||||
<div class="page-header">
|
||||
<div class="plugin-header">
|
||||
<span class="plugin-header-logo">
|
||||
<img ng-src="{{ctrl.model.info.logos.large}}">
|
||||
</span>
|
||||
|
||||
<div class="plugin-header-info-block">
|
||||
<h1 class="plugin-header-name">{{ctrl.model.name}}</h1>
|
||||
<div class="plugin-header-author">By {{ctrl.model.info.author.name}}</div>
|
||||
<div class="plugin-header-stamps">
|
||||
<span class="plugin-header-stamps-type">
|
||||
<i class="{{ctrl.pluginIcon}}"></i> {{ctrl.model.type}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="gf-tabs">
|
||||
<li class="gf-tabs-item" ng-repeat="tab in ctrl.tabs">
|
||||
<a class="gf-tabs-link" ng-click="ctrl.tabIndex = $index" ng-class="{active: ctrl.tabIndex === $index}">
|
||||
{{::tab}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container page-body" ng-init="ctrl.init()">
|
||||
<div class="page-action-bar">
|
||||
<button class="btn" ng-repeat="tab in ctrl.tabs" ng-class="{'btn-secondary': ctrl.tabIndex === $index, 'btn-inverse': ctrl.tabIndex !== $index}" ng-click="ctrl.tabIndex = $index">
|
||||
{{tab}}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<div class="tab-content page-content-with-sidebar" ng-if="ctrl.tabs[ctrl.tabIndex] === 'Readme'">
|
||||
<div class="sidebar-container">
|
||||
|
||||
<div class="tab-content sidebar-content" ng-if="ctrl.tabs[ctrl.tabIndex] === 'Readme'">
|
||||
<div ng-bind-html="ctrl.readmeHtml" class="markdown-html">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-content page-content-with-sidebar" ng-if="ctrl.tabs[ctrl.tabIndex] === 'Config'">
|
||||
<div class="tab-content sidebar-content" ng-if="ctrl.tabs[ctrl.tabIndex] === 'Config'">
|
||||
<div ng-if="ctrl.model.id">
|
||||
<plugin-component type="app-config-ctrl"></plugin-component>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
<button type="submit" class="btn btn-success" ng-click="ctrl.enable()" ng-show="!ctrl.model.enabled">Enable</button>
|
||||
<button type="submit" class="btn btn-success" ng-click="ctrl.update()" ng-show="ctrl.model.enabled">Update</button>
|
||||
<button type="submit" class="btn btn-danger" ng-click="ctrl.disable()" ng-show="ctrl.model.enabled">Disable</button>
|
||||
</div>
|
||||
<div class="gf-form-button-row">
|
||||
<button type="submit" class="btn btn-success" ng-click="ctrl.enable()" ng-show="!ctrl.model.enabled">Enable</button>
|
||||
<button type="submit" class="btn btn-success" ng-click="ctrl.update()" ng-show="ctrl.model.enabled">Update</button>
|
||||
<button type="submit" class="btn btn-danger" ng-click="ctrl.disable()" ng-show="ctrl.model.enabled">Disable</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-content page-content-with-sidebar" ng-if="ctrl.tabs[ctrl.tabIndex] === 'Dashboards'">
|
||||
<dashboard-import-list plugin="ctrl.model"></dashboard-import-list>
|
||||
<div class="tab-content sidebar.content" ng-if="ctrl.tabs[ctrl.tabIndex] === 'Dashboards'">
|
||||
<dashboard-import-list plugin="ctrl.model"></dashboard-import-list>
|
||||
</div>
|
||||
|
||||
<aside class="page-sidebar">
|
||||
<section class="page-sidebar-section">
|
||||
<h4>Version</h4>
|
||||
<span>{{ctrl.model.info.version}}</span>
|
||||
<div ng-show="ctrl.model.hasUpdate">
|
||||
<div ng-show="ctrl.model.hasUpdate">
|
||||
<a ng-click="ctrl.updateAvailable()" bs-tooltip="ctrl.model.latestVersion">Update Available!</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="page-sidebar-section" ng-show="ctrl.model.type === 'app'">
|
||||
<h5>Includes</h4>
|
||||
|
@ -1,65 +1,81 @@
|
||||
<div class="scroll-canvas" grafana-scrollbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
<i class="icon-gf icon-gf-apps"></i>
|
||||
Plugins <span class="muted small">(currently installed)</span>
|
||||
</h1>
|
||||
<!-- <div class="page-header-canvas"> -->
|
||||
<!-- <div class="page-container"> -->
|
||||
<!-- <navbar model="ctrl.navModel"></navbar> -->
|
||||
<!-- -->
|
||||
<!-- <div class="page-header"> -->
|
||||
<!-- <page-h1 model="ctrl.navModel"></page-h1> -->
|
||||
<!-- -->
|
||||
<!-- <div class="page-header-tabs"> -->
|
||||
<!-- <ul class="gf-tabs"> -->
|
||||
<!-- <li class="gf-tabs-item"> -->
|
||||
<!-- <a class="gf-tabs-link" href="plugins?type=panel" ng-class="{active: ctrl.tabIndex === 0}"> -->
|
||||
<!-- <i class="icon-gf icon-gf-panel"></i> -->
|
||||
<!-- Panels -->
|
||||
<!-- </a> -->
|
||||
<!-- </li> -->
|
||||
<!-- <li class="gf-tabs-item"> -->
|
||||
<!-- <a class="gf-tabs-link" href="plugins?type=datasource" ng-class="{active: ctrl.tabIndex === 1}"> -->
|
||||
<!-- <i class="gicon gicon-datasources"></i> -->
|
||||
<!-- Data sources -->
|
||||
<!-- </a> -->
|
||||
<!-- </li> -->
|
||||
<!-- <li class="gf-tabs-item"> -->
|
||||
<!-- <a class="gf-tabs-link" href="plugins?type=app" ng-class="{active: ctrl.tabIndex === 2}"> -->
|
||||
<!-- <i class="icon-gf icon-gf-apps"></i> -->
|
||||
<!-- Apps -->
|
||||
<!-- </a> -->
|
||||
<!-- </li> -->
|
||||
<!-- </ul> -->
|
||||
<!-- -->
|
||||
<!-- <a class="get-more-plugins-link pull-right" href="https://grafana.com/plugins?utm_source=grafana_plugin_list" target="_blank"> -->
|
||||
<!-- Find more <img src="public/img/icn-plugins-tiny.svg" />plugins on Grafana.com -->
|
||||
<!-- </a> -->
|
||||
<!-- </div> -->
|
||||
<!-- </div> -->
|
||||
<!-- </div> -->
|
||||
<!-- </div> -->
|
||||
|
||||
<div class="page-header-tabs">
|
||||
<ul class="gf-tabs">
|
||||
<li class="gf-tabs-item">
|
||||
<a class="gf-tabs-link" href="plugins?type=panel" ng-class="{active: ctrl.tabIndex === 0}">
|
||||
Panels
|
||||
</a>
|
||||
</li>
|
||||
<li class="gf-tabs-item">
|
||||
<a class="gf-tabs-link" href="plugins?type=datasource" ng-class="{active: ctrl.tabIndex === 1}">
|
||||
Data sources
|
||||
</a>
|
||||
</li>
|
||||
<li class="gf-tabs-item">
|
||||
<a class="gf-tabs-link" href="plugins?type=app" ng-class="{active: ctrl.tabIndex === 2}">
|
||||
Apps
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="page-container page-body">
|
||||
<div class="page-action-bar">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">Search</label>
|
||||
<input type="text" class="gf-form-input width-20" ng-model="ctrl.searchQuery" ng-change="ctrl.onQueryUpdated()" />
|
||||
</div>
|
||||
|
||||
<a class="get-more-plugins-link" href="https://grafana.com/plugins?utm_source=grafana_plugin_list" target="_blank">
|
||||
Find more <img src="public/img/icn-plugins-tiny.svg" />plugins on Grafana.com
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="card-section" layout-mode>
|
||||
<layout-selector></layout-selector>
|
||||
|
||||
<ol class="card-list" >
|
||||
<li class="card-item-wrapper" ng-repeat="plugin in ctrl.plugins">
|
||||
<a class="card-item" href="plugins/{{plugin.id}}/edit">
|
||||
<div class="card-item-header">
|
||||
<div class="card-item-type">
|
||||
<i class="icon-gf icon-gf-{{plugin.type}}"></i>
|
||||
{{plugin.type}}
|
||||
</div>
|
||||
<div class="card-item-notice" ng-show="plugin.hasUpdate">
|
||||
<span bs-tooltip="plugin.latestVersion">Update available!</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-item-body">
|
||||
<figure class="card-item-figure">
|
||||
<img ng-src="{{plugin.info.logos.small}}">
|
||||
</figure>
|
||||
<div class="card-item-details">
|
||||
<div class="card-item-name">{{plugin.name}}</div>
|
||||
<div class="card-item-sub-name">By {{plugin.info.author.name}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
<a class="btn btn-success" href="https://grafana.com/plugins?utm_source=grafana_plugin_list" target="_blank">
|
||||
Find more plugins on Grafana.com
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<section class="card-section" layout-mode>
|
||||
<layout-selector></layout-selector>
|
||||
|
||||
<ol class="card-list" >
|
||||
<li class="card-item-wrapper" ng-repeat="plugin in ctrl.plugins">
|
||||
<a class="card-item" href="plugins/{{plugin.id}}/edit">
|
||||
<div class="card-item-header">
|
||||
<div class="card-item-type">
|
||||
<i class="icon-gf icon-gf-{{plugin.type}}"></i>
|
||||
{{plugin.type}}
|
||||
</div>
|
||||
<div class="card-item-notice" ng-show="plugin.hasUpdate">
|
||||
<span bs-tooltip="plugin.latestVersion">Update available!</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-item-body">
|
||||
<figure class="card-item-figure">
|
||||
<img ng-src="{{plugin.info.logos.small}}">
|
||||
</figure>
|
||||
<div class="card-item-details">
|
||||
<div class="card-item-name">{{plugin.name}}</div>
|
||||
<div class="card-item-sub-name">By {{plugin.info.author.name}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
</div>
|
||||
|
@ -27,7 +27,7 @@ export class PluginEditCtrl {
|
||||
$routeParams,
|
||||
navModelSrv,
|
||||
) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'plugins');
|
||||
this.navModel = navModelSrv.getNav('cfg', 'plugins', 0);
|
||||
this.model = {};
|
||||
this.pluginId = $routeParams.pluginId;
|
||||
this.tabIndex = 0;
|
||||
|
@ -1,34 +1,28 @@
|
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
|
||||
export class PluginListCtrl {
|
||||
plugins: any[];
|
||||
tabIndex: number;
|
||||
navModel: any;
|
||||
searchQuery: string;
|
||||
allPlugins: any[];
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv: any, $location, navModelSrv) {
|
||||
this.tabIndex = 0;
|
||||
this.navModel = navModelSrv.getNav('cfg', 'plugins');
|
||||
this.navModel = navModelSrv.getNav('cfg', 'plugins', 0);
|
||||
|
||||
var pluginType = $location.search().type || 'panel';
|
||||
switch (pluginType) {
|
||||
case "datasource": {
|
||||
this.tabIndex = 1;
|
||||
break;
|
||||
}
|
||||
case "app": {
|
||||
this.tabIndex = 2;
|
||||
break;
|
||||
}
|
||||
case "panel":
|
||||
default:
|
||||
this.tabIndex = 0;
|
||||
}
|
||||
|
||||
this.backendSrv.get('api/plugins', {embedded: 0, type: pluginType}).then(plugins => {
|
||||
this.backendSrv.get('api/plugins', {embedded: 0}).then(plugins => {
|
||||
this.plugins = plugins;
|
||||
this.allPlugins = plugins;
|
||||
});
|
||||
}
|
||||
|
||||
onQueryUpdated() {
|
||||
let regex = new RegExp(this.searchQuery, 'ig');
|
||||
this.plugins = _.filter(this.allPlugins, item => {
|
||||
return regex.test(item.name) || regex.test(item.type);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,7 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
</div>
|
||||
|
||||
<table class="filter-table" style="margin-top: 20px">
|
||||
<div class="page-container page-body">
|
||||
<table class="filter-table">
|
||||
<thead>
|
||||
<th><strong>Name</strong></th>
|
||||
<th><strong>Snapshot url</strong></th>
|
||||
|
@ -9,7 +9,7 @@ export class SnapshotsCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $rootScope, private backendSrv, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('dashboards', 'snapshots');
|
||||
this.navModel = navModelSrv.getNav('dashboards', 'snapshots', 0);
|
||||
this.backendSrv.get('/api/dashboard/snapshots').then(result => {
|
||||
this.snapshots = result;
|
||||
});
|
||||
|
@ -1,34 +1,10 @@
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<page-h1 model="ctrl.navModel"></page-h1>
|
||||
<div class="page-container page-body">
|
||||
|
||||
<a class="btn btn-success" ng-click="ctrl.switchTheme()">
|
||||
<i class="fa fa-random"></i>
|
||||
Switch theme
|
||||
</a>
|
||||
<h3 class="page-heading">Buttons</h3>
|
||||
|
||||
<div class="page-header-tabs">
|
||||
<ul class="gf-tabs">
|
||||
<li class="gf-tabs-item" ng-repeat="page in ctrl.pages">
|
||||
<a class="gf-tabs-link" href="styleguide/{{page}}" ng-class="{active: ctrl.page[page]}">{{page}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" ng-if="ctrl.page.colors">
|
||||
<ul>
|
||||
<li class="style-guide-color-card" ng-repeat="color in ctrl.colors" style="background-color: {{color.value}}">
|
||||
<strong>${{color.name}}</strong>
|
||||
<em>{{color.value}}</em>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" ng-if="ctrl.page.buttons">
|
||||
<div class="tab-pane">
|
||||
<div ng-repeat="variant in ctrl.buttonVariants" class="row">
|
||||
<div ng-repeat="btnSize in ctrl.buttonSizes" class="style-guide-button-list p-a-2 col-md-4">
|
||||
<button ng-repeat="buttonName in ctrl.buttonNames" class="btn btn{{variant}}{{buttonName}} {{btnSize}}">
|
||||
@ -38,7 +14,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane style-guide-icon-list" ng-if="ctrl.page.icons">
|
||||
<div class="tab-pane style-guide-icon-list">
|
||||
<div class="row">
|
||||
<div ng-repeat="icon in ctrl.icons" class="col-md-2 col-sm-3 col-xs-4">
|
||||
<i class="icon-gf icon-gf-{{icon}}" bs-tooltip="'icon-gf icon-gf-{{icon}}'"></i>
|
||||
@ -46,13 +22,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane style-guide-plugin-authoring" ng-if="ctrl.page.plugins">
|
||||
<p>From grafana 3.0 it's very easy to develop your own plugins and share them with other grafana users.</p>
|
||||
<p>More information about plugin development can be found at <a href="http://docs.grafana.org/plugins/developing/development/" target="_blank">docs.grafana.org</a></p>
|
||||
</div>
|
||||
<h3 class="page-heading">Forms</h3>
|
||||
|
||||
<div class="tab-pane" ng-if="ctrl.page.forms">
|
||||
forms
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">Label</label>
|
||||
<input type="text" class="gf-form-input" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -8,7 +8,7 @@ class StyleGuideCtrl {
|
||||
theme: string;
|
||||
buttonNames = ['primary', 'secondary', 'inverse', 'success', 'warning', 'danger'];
|
||||
buttonSizes = ['btn-small', '', 'btn-large'];
|
||||
buttonVariants = ['-', '-outline-'];
|
||||
buttonVariants = ['-'];
|
||||
icons: any = [];
|
||||
page: any;
|
||||
pages = ['colors', 'buttons', 'icons', 'plugins'];
|
||||
@ -16,7 +16,7 @@ class StyleGuideCtrl {
|
||||
|
||||
/** @ngInject **/
|
||||
constructor(private $http, private $routeParams, private backendSrv, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 'styleguide');
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 'styleguide', 1);
|
||||
this.theme = config.bootData.user.lightTheme ? 'light': 'dark';
|
||||
this.page = {};
|
||||
|
||||
|
@ -85,6 +85,7 @@
|
||||
@import "components/code_editor";
|
||||
@import "components/dashboard_grid";
|
||||
@import "components/dashboard_list";
|
||||
@import "components/page_header";
|
||||
|
||||
|
||||
// PAGES
|
||||
|
@ -1,95 +1,49 @@
|
||||
|
||||
.dashnav-back-to-dashboard {
|
||||
.navbar-buttons--zoom {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar-page-btn {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.gf-timepicker-nav-btn {
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
.navbar-buttons--actions {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Media queries
|
||||
// ---------------------
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
// div.panel {
|
||||
// width: 100% !important;
|
||||
// padding: 0px !important;
|
||||
// }
|
||||
// .panel-margin {
|
||||
// margin-right: 0;
|
||||
// margin-left: 0;
|
||||
// }
|
||||
body {
|
||||
padding: 0;
|
||||
}
|
||||
.page-dashboard .navbar-page-btn {
|
||||
max-width: 200px;
|
||||
}
|
||||
.gf-timepicker-nav-btn {
|
||||
max-width: 120px;
|
||||
}
|
||||
.dashnav-zoom-out,
|
||||
.dashnav-move-timeframe,
|
||||
.dashnav-action-icons {
|
||||
display: none;
|
||||
}
|
||||
.page-container {
|
||||
padding: ($spacer * 1) ($spacer * 2);
|
||||
}
|
||||
|
||||
.dash-row-menu-container {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(xs) {
|
||||
.page-dashboard .navbar-page-btn {
|
||||
@include media-breakpoint-up(sm) {
|
||||
.navbar-page-btn {
|
||||
max-width: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
// form styles
|
||||
@include media-breakpoint-up(md) {
|
||||
.page-dashboard .navbar-page-btn {
|
||||
max-width: 280px;
|
||||
}
|
||||
.gf-timepicker-nav-btn {
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
.dashnav-move-timeframe {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panel-in-fullscreen {
|
||||
.dashnav-action-icons {
|
||||
display: none;
|
||||
}
|
||||
.dashnav-back-to-dashboard {
|
||||
display: block;
|
||||
}
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
.page-dashboard .navbar-page-btn {
|
||||
max-width: 290px;
|
||||
@include media-breakpoint-up(md) {
|
||||
.navbar-buttons--actions {
|
||||
display: flex;
|
||||
}
|
||||
.navbar-page-btn {
|
||||
max-width: 325px;
|
||||
}
|
||||
.gf-timepicker-nav-btn {
|
||||
max-width: 240px;
|
||||
}
|
||||
.dashnav-zoom-out {
|
||||
display: block;
|
||||
}
|
||||
.dashnav-move-timeframe {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(xl) {
|
||||
.panel-in-fullscreen {
|
||||
.dashnav-action-icons {
|
||||
display: block;
|
||||
}
|
||||
@include media-breakpoint-up(lg) {
|
||||
.navbar-buttons--zoom {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.page-dashboard .navbar-page-btn {
|
||||
.navbar-page-btn {
|
||||
max-width: none;
|
||||
}
|
||||
.gf-timepicker-nav-btn {
|
||||
|
@ -15,7 +15,7 @@ $dark-3: #262628;
|
||||
$dark-4: #333333;
|
||||
$dark-5: #444444;
|
||||
$gray-1: #555555;
|
||||
$gray-2: #7B7B7B;
|
||||
$gray-2: #8e8e8e;
|
||||
$gray-3: #b3b3b3;
|
||||
$gray-4: #D8D9DA;
|
||||
$gray-5: #ECECEC;
|
||||
@ -51,7 +51,8 @@ $critical: #ed2e18;
|
||||
// Scaffolding
|
||||
// -------------------------
|
||||
$body-bg: rgb(23,24,25);
|
||||
$page-bg: $dark-2;
|
||||
$page-bg: rgb(22, 23, 25);
|
||||
|
||||
$body-color: $gray-4;
|
||||
$text-color: $gray-4;
|
||||
$text-color-strong: $white;
|
||||
@ -64,7 +65,7 @@ $text-shadow-faint: 1px 1px 4px rgb(45, 45, 45);
|
||||
|
||||
// gradients
|
||||
$brand-gradient: linear-gradient(to right, rgba(255,213,0,0.7) 0%, rgba(255,68,0,0.7) 99%, rgba(255,68,0,0.7) 100%);
|
||||
$page-gradient: linear-gradient(180deg, #222426 10px, rgba(15, 15, 16, .03) 100px, rgba(10, 10, 11, .03));
|
||||
$page-gradient: linear-gradient(180deg, #222426 10px, rgb(22, 23, 25) 100px);
|
||||
|
||||
// Links
|
||||
// -------------------------
|
||||
@ -97,6 +98,11 @@ $panel-drop-zone-bg: repeating-linear-gradient(-128deg, #111, #111 10px, #191
|
||||
$panel-header-hover-bg: $dark-4;
|
||||
$panel-header-menu-hover-bg: $dark-5;
|
||||
|
||||
// page header
|
||||
$page-header-bg: linear-gradient(90deg, #292a2d, black);
|
||||
$page-header-shadow: inset 0px -4px 14px $dark-2;
|
||||
$page-header-border-color: $dark-4;
|
||||
|
||||
$divider-border-color: #555;
|
||||
|
||||
// Graphite Target Editor
|
||||
@ -121,8 +127,9 @@ $list-item-link-color: $text-color;
|
||||
$list-item-shadow: $card-shadow;
|
||||
|
||||
// Scrollbars
|
||||
$scrollbarBackground: #3a3a3a;
|
||||
$scrollbarBackground: #404357;
|
||||
$scrollbarBackground2: #3a3a3a;
|
||||
|
||||
$scrollbarBorder: black;
|
||||
|
||||
// Tables
|
||||
@ -180,6 +187,7 @@ $input-invalid-border-color: lighten($red, 5%);
|
||||
|
||||
// Search
|
||||
$search-shadow: 0 0 35px 0 $body-bg;
|
||||
$search-filter-box-bg: $gray-blue;
|
||||
|
||||
// Dropdowns
|
||||
// -------------------------
|
||||
@ -274,7 +282,7 @@ $alert-warning-bg: linear-gradient(90deg, #d44939, #e0603d);
|
||||
$alert-info-bg: linear-gradient(100deg, #1a4552, #00374a);
|
||||
|
||||
// popover
|
||||
$popover-bg: $panel-bg;
|
||||
$popover-bg: $page-bg;
|
||||
$popover-color: $text-color;
|
||||
$popover-border-color: $dark-4;
|
||||
$popover-shadow: 0 0 20px black;
|
||||
@ -300,7 +308,7 @@ $checkboxImageUrl: '../img/checkbox.png';
|
||||
$info-box-background: linear-gradient(100deg, #1a4552, #00374a);
|
||||
|
||||
// footer
|
||||
$footer-link-color: $gray-1;
|
||||
$footer-link-color: $gray-2;
|
||||
$footer-link-hover: $gray-4;
|
||||
|
||||
// collapse box
|
||||
|
@ -102,6 +102,8 @@ $brand-gradient: linear-gradient(to right, rgba(255,213,0,1.0) 0%, rgba(255,68,0
|
||||
//$page-gradient: linear-gradient(120deg, transparent 40%, darken($gray-6, 4%) 98%);
|
||||
$page-gradient: linear-gradient(120deg, $gray-7 40%, $gray-6 98%);
|
||||
//$page-gradient: $gray-7;
|
||||
// $page-gradient: linear-gradient(-60deg, transparent 70%, darken($page-bg, 4%) 98%);
|
||||
$page-header-bg: linear-gradient(90deg, #292a2d, black);
|
||||
|
||||
// Links
|
||||
// -------------------------
|
||||
@ -135,6 +137,11 @@ $panel-drop-zone-bg: repeating-linear-gradient(-128deg, $body-bg, $body-bg 10px,
|
||||
$panel-header-hover-bg: $gray-6;
|
||||
$panel-header-menu-hover-bg: $gray-4;
|
||||
|
||||
// Page header
|
||||
$page-header-bg: linear-gradient(90deg, #292a2d, black);
|
||||
$page-header-shadow: inset 0px -4px 14px $dark-2;
|
||||
$page-header-border-color: $dark-4;
|
||||
|
||||
$divider-border-color: $gray-2;
|
||||
|
||||
// Graphite Target Editor
|
||||
@ -238,6 +245,7 @@ $breadcrumb-hover-hl: #d9dadd;
|
||||
|
||||
// search
|
||||
$search-shadow: 0 5px 30px 0 $gray-4;
|
||||
$search-filter-box-bg: $gray-4;
|
||||
|
||||
// Dropdowns
|
||||
// -------------------------
|
||||
@ -322,7 +330,7 @@ $alert-warning-bg: linear-gradient(90deg, #d44939, #e04d3d);
|
||||
$alert-info-bg: $blue-dark;
|
||||
|
||||
// popover
|
||||
$popover-bg: $panel-bg;
|
||||
$popover-bg: $page-bg;
|
||||
$popover-color: $text-color;
|
||||
$popover-border-color: $gray-5;
|
||||
$popover-shadow: 0 0 20px $white;
|
||||
|
@ -86,11 +86,12 @@ $font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||
$font-family-base: $font-family-sans-serif !default;
|
||||
|
||||
$font-size-root: 14px !default;
|
||||
$font-size-base: 13px !default;
|
||||
|
||||
$font-size-base: 1rem !default;
|
||||
$font-size-lg: 1.25rem !default;
|
||||
$font-size-sm: .875rem !default;
|
||||
$font-size-xs: .75rem !default;
|
||||
$font-size-lg: 18px !default;
|
||||
$font-size-md: 15px !default;
|
||||
$font-size-sm: 11px !default;
|
||||
$font-size-xs: 9px !default;
|
||||
|
||||
$line-height-base: 1.5 !default;
|
||||
$font-weight-semi-bold: 500;
|
||||
@ -159,9 +160,9 @@ $table-cell-padding: 4px 10px !default;
|
||||
$table-sm-cell-padding: .3rem !default;
|
||||
|
||||
// Forms
|
||||
$input-padding-x: .75rem !default;
|
||||
$input-padding-y: .6rem !default;
|
||||
$input-line-height: 1.35rem !default;
|
||||
$input-padding-x: 10px !default;
|
||||
$input-padding-y: 8px !default;
|
||||
$input-line-height: 19px !default;
|
||||
|
||||
$input-btn-border-width: 1px;
|
||||
$input-border-radius: 0 $border-radius $border-radius 0 !default;
|
||||
@ -172,11 +173,11 @@ $label-border-radius: $border-radius 0 0 $border-radius !default;
|
||||
$label-border-radius-lg: $border-radius-lg 0 0 $border-radius-lg !default;
|
||||
$label-border-radius-sm: $border-radius-sm 0 0 $border-radius-sm !default;
|
||||
|
||||
$input-padding-x-sm: .5rem !default;
|
||||
$input-padding-y-sm: .25rem !default;
|
||||
$input-padding-x-sm: 7px !default;
|
||||
$input-padding-y-sm: 4px !default;
|
||||
|
||||
$input-padding-x-lg: 1.5rem !default;
|
||||
$input-padding-y-lg: .75rem !default;
|
||||
$input-padding-x-lg: 20px !default;
|
||||
$input-padding-y-lg: 10px !default;
|
||||
|
||||
$input-height: (($font-size-base * $line-height-base) + ($input-padding-y * 2)) !default;
|
||||
$input-height-lg: (($font-size-lg * $line-height-lg) + ($input-padding-y-lg * 2)) !default;
|
||||
@ -197,10 +198,14 @@ $form-icon-danger: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www
|
||||
// Used for a bird's eye view of components dependent on the z-axis
|
||||
// Try to avoid customizing these :)
|
||||
$zindex-dropdown: 1000;
|
||||
$zindex-tooltip: 1020;
|
||||
$zindex-navbar-fixed: 1030;
|
||||
$zindex-navbar-fixed: 1020;
|
||||
$zindex-tooltip: 1030;
|
||||
$zindex-modal-backdrop: 1040;
|
||||
$zindex-modal: 1050;
|
||||
$zindex-typeahead: 1060;
|
||||
$zindex-sidemenu : $zindex-navbar-fixed + 5;
|
||||
|
||||
|
||||
|
||||
// Buttons
|
||||
//
|
||||
@ -224,9 +229,8 @@ $side-menu-width: 60px;
|
||||
// dashboard
|
||||
$panel-margin: 10px;
|
||||
$dashboard-padding: $panel-margin * 2;
|
||||
$panel-padding: 0px 10px 5px 10px;
|
||||
|
||||
// tabs
|
||||
$tabs-padding-top: 0.6rem;
|
||||
$tabs-padding-bottom: 0.4rem;
|
||||
$tabs-top-margin: 0.5rem;
|
||||
$tabs-padding: 9px 15px 9px;
|
||||
|
||||
|
@ -43,5 +43,18 @@
|
||||
background-image: url('../img/icons_#{$theme-name}_theme/icon_add_panel.svg');
|
||||
}
|
||||
|
||||
.gicon-alert-notification-channel {
|
||||
background-image: url('../img/icons_#{$theme-name}_theme/icon_notification_channels.svg');
|
||||
}
|
||||
|
||||
.gicon-user-group {
|
||||
background-image: url('../img/icons_#{$theme-name}_theme/icon_user_group.svg');
|
||||
}
|
||||
|
||||
.gicon-org {
|
||||
background-image: url('../img/icons_#{$theme-name}_theme/icon_org.svg');
|
||||
}
|
||||
|
||||
.gicon-zoom-out {
|
||||
background-image: url('../img/icons_#{$theme-name}_theme/icon_zoom_out.svg');
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
@include media-breakpoint-down(sm) {
|
||||
.react-grid-layout {
|
||||
height: 100% !important;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
position: relative;
|
||||
top: -3px;
|
||||
width: 250px;
|
||||
font-size: 80%;
|
||||
font-size: $font-size-sm;
|
||||
margin-left: 22px;
|
||||
color: $gray-2;
|
||||
white-space: normal;
|
||||
@ -91,7 +91,6 @@
|
||||
color: $link-color-disabled;
|
||||
position: relative;
|
||||
top: 3px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.gicon {
|
||||
@ -300,7 +299,7 @@
|
||||
// Typeahead
|
||||
// ---------
|
||||
.typeahead {
|
||||
z-index: 1051;
|
||||
z-index: $zindex-typeahead;
|
||||
margin-top: 2px; // give it some space to breathe
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
.footer {
|
||||
color: $footer-link-color;
|
||||
padding: 5rem 0 1rem 0;
|
||||
font-size: $font-size-xs;
|
||||
font-size: $font-size-sm;
|
||||
width: 98%; /* was causing horiz scrollbars - need to examine */
|
||||
|
||||
a {
|
||||
|
@ -1,4 +1,5 @@
|
||||
$gf-form-margin: 3px;
|
||||
$input-border: 1px solid $input-border-color;
|
||||
|
||||
.gf-form {
|
||||
margin-bottom: $gf-form-margin;
|
||||
@ -20,6 +21,15 @@ $gf-form-margin: 3px;
|
||||
&--flex-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&--alt {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
.gf-form-label {
|
||||
padding: 4px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-disabled {
|
||||
@ -115,7 +125,7 @@ $gf-form-margin: 3px;
|
||||
background-color: $input-bg;
|
||||
background-image: none;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid $input-border-color;
|
||||
border: $input-border;
|
||||
@include border-radius($input-border-radius-sm);
|
||||
@include box-shadow($input-box-shadow);
|
||||
white-space: nowrap;
|
||||
@ -268,6 +278,7 @@ $gf-form-margin: 3px;
|
||||
position: relative;
|
||||
background-color: $input-bg;
|
||||
padding-right: $input-padding-x;
|
||||
border: $input-border;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
@ -279,6 +290,10 @@ $gf-form-margin: 3px;
|
||||
content: '\f0d7';
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.gf-form-input {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-help-icon {
|
||||
|
@ -23,7 +23,7 @@
|
||||
position: fixed;
|
||||
z-index: $zindex-modal;
|
||||
width: 100%;
|
||||
background-color: $panel-bg;
|
||||
background: $page-bg;
|
||||
@include box-shadow(0 3px 7px rgba(0,0,0,0.3));
|
||||
@include background-clip(padding-box);
|
||||
outline: none;
|
||||
@ -37,13 +37,10 @@
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
background-color: $body-bg;
|
||||
@include brand-bottom-border();
|
||||
@include clearfix();
|
||||
|
||||
.gf-tabs-link.active {
|
||||
background-color: $panel-bg;
|
||||
}
|
||||
background: $page-header-bg;
|
||||
box-shadow: $page-header-shadow;
|
||||
border-bottom: 1px solid $page-header-border-color;
|
||||
@include clearfix();
|
||||
}
|
||||
|
||||
.modal-header-title {
|
||||
|
@ -1,19 +1,14 @@
|
||||
|
||||
.navbar {
|
||||
display: block;
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
padding-left: $side-menu-width;
|
||||
box-shadow: $navbarShadow;
|
||||
z-index: 1;
|
||||
background: $navbarBackground;
|
||||
}
|
||||
|
||||
.navbar-inner {
|
||||
min-height: $navbarHeight;
|
||||
// box-shadow: $navbarShadow;
|
||||
z-index: $zindex-navbar-fixed;
|
||||
// background: $navbarBackground;
|
||||
height: $navbarHeight;
|
||||
padding-right: $spacer;
|
||||
display: flex;
|
||||
@include clearfix();
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.sidemenu-open {
|
||||
@ -22,47 +17,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.navbar .nav {
|
||||
position: relative;
|
||||
left: 0;
|
||||
float: left;
|
||||
|
||||
&--grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.navbar .nav > li {
|
||||
float: left;
|
||||
}
|
||||
|
||||
// Links
|
||||
.navbar .nav > li > a {
|
||||
float: none;
|
||||
padding: 17px 13px 13px;
|
||||
color: $navbarLinkColor;
|
||||
text-decoration: none;
|
||||
|
||||
.fa { font-size: 115%; }
|
||||
}
|
||||
|
||||
// Hover/focus
|
||||
.navbar .nav > li > a:focus,
|
||||
.navbar .nav > li > a:hover {
|
||||
color: $navbarLinkColorHover;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
// Active nav items
|
||||
.navbar .nav > .active > a,
|
||||
.navbar .nav > .active > a:hover,
|
||||
.navbar .nav > .active > a:focus {
|
||||
color: $navbarLinkColorActive;
|
||||
text-decoration: none;
|
||||
background-color: $navbarLinkBackgroundActive;
|
||||
}
|
||||
|
||||
.navbar-page-btn {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
@ -106,3 +60,54 @@
|
||||
.navbar-mini-btn-wrapper {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.navbar-buttons {
|
||||
height: $navbarHeight;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-right: $spacer;
|
||||
}
|
||||
|
||||
.navbar__spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.navbar-button {
|
||||
@include buttonBackground($btn-inverse-bg, $btn-inverse-bg-hl, $btn-inverse-text-color);
|
||||
|
||||
display: inline-block;
|
||||
font-weight: $btn-font-weight;
|
||||
padding: 8px 11px;
|
||||
line-height: 16px;
|
||||
color: $text-muted;
|
||||
border: 1px solid #151515;
|
||||
margin-right: 1px;
|
||||
white-space: nowrap;
|
||||
|
||||
.gicon {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.fa {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&--add-panel {
|
||||
padding: 5px 10px;
|
||||
|
||||
.gicon {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
&--tight {
|
||||
padding: 9px 4px;
|
||||
|
||||
.fa {
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
159
public/sass/components/_page_header.scss
Normal file
159
public/sass/components/_page_header.scss
Normal file
@ -0,0 +1,159 @@
|
||||
|
||||
.page-header-canvas {
|
||||
background: $page-header-bg;
|
||||
box-shadow: $page-header-shadow;
|
||||
border-bottom: 1px solid $page-header-border-color;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
padding: 2.5rem 0 0 0;
|
||||
|
||||
.btn {
|
||||
float: right;
|
||||
margin-left: 1rem;
|
||||
|
||||
// better align icons
|
||||
.fa {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-header__inner {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
margin-bottom: 2.5rem;
|
||||
}
|
||||
|
||||
.page-header__title {
|
||||
font-size: $font-size-h2;
|
||||
margin-bottom: 1px;
|
||||
padding-top: $spacer;
|
||||
}
|
||||
|
||||
.page-header__img {
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
top: 10px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.page-header__icon {
|
||||
font-size: 50px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
position: relative;
|
||||
|
||||
&.fa {
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
&.gicon {
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
&.icon-gf {
|
||||
top: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.page-header__logo {
|
||||
margin: 0 $spacer;
|
||||
}
|
||||
|
||||
.page-header__sub-title {
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.page-header-stamps-type {
|
||||
color: $link-color-disabled;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.page-breadcrumbs {
|
||||
display: flex;
|
||||
padding: 10px 0;
|
||||
line-height: 0.5;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
display: inline-block;
|
||||
box-shadow: 0 0 15px 1px rgba(0, 0, 0, 0.35);
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
counter-reset: flag;
|
||||
}
|
||||
|
||||
.breadcrumb-item {
|
||||
@include gradientBar($btn-inverse-bg, $btn-inverse-bg-hl, $btn-inverse-text-color);
|
||||
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
display: block;
|
||||
float: left;
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
padding: 0 7px 0 37px;
|
||||
position: relative;
|
||||
box-shadow: $card-shadow;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 10px;
|
||||
border-radius: 5px 0 0 5px; /*to match with the parent's radius*/
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
&:first-child::before {
|
||||
left: 14px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 5px 5px 0; /*this was to prevent glitches on hover*/
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:hover {
|
||||
background: #333;
|
||||
background: linear-gradient(#333, #000);
|
||||
}
|
||||
|
||||
&.active::after,
|
||||
&:hover::after {
|
||||
background: #333;
|
||||
background: linear-gradient(135deg, #333, #000);
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -14px; // half of square's length
|
||||
|
||||
// same dimension as the line-height of .breadcrumb-item
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
|
||||
transform: scale(0.707) rotate(45deg);
|
||||
// we need to prevent the arrows from getting buried under the next link
|
||||
z-index: 1;
|
||||
|
||||
// background same as links but the gradient will be rotated to compensate with the transform applied
|
||||
background: linear-gradient(135deg, $btn-inverse-bg, $btn-inverse-bg-hl);
|
||||
|
||||
// stylish arrow design using box shadow
|
||||
box-shadow: 2px -2px 0 2px rgb(35, 31, 31), 3px -3px 0 2px rgba(255, 255, 255, 0.1);
|
||||
|
||||
// 5px - for rounded arrows and
|
||||
// 50px - to prevent hover glitches on the border created using shadows*/
|
||||
border-radius: 0 5px 0 50px;
|
||||
}
|
||||
|
||||
// we dont need an arrow after the last link
|
||||
&:last-child::after {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,47 @@
|
||||
|
||||
.add-panel {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.add-panel__header {
|
||||
padding: 5px 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
font-size: 30px;
|
||||
margin-right: $spacer;
|
||||
}
|
||||
}
|
||||
|
||||
.add-panel__title {
|
||||
font-size: $font-size-md;
|
||||
margin-right: $spacer/2;
|
||||
}
|
||||
|
||||
.add-panel__sub-title {
|
||||
font-style: italic;
|
||||
color: $text-muted;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.add-panel__items {
|
||||
padding: 3px 8px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
height: calc(100% - 43px);
|
||||
align-content: flex-start;
|
||||
justify-content: space-around;
|
||||
padding: 3px 0;
|
||||
}
|
||||
|
||||
.add-panel__item {
|
||||
background: $card-background;
|
||||
box-shadow: $card-shadow;
|
||||
|
||||
border: $panel-border;
|
||||
border-radius: 3px;
|
||||
padding: $spacer/3 $spacer;
|
||||
width: 31%;
|
||||
height: 60px;
|
||||
|
@ -71,7 +71,7 @@
|
||||
}
|
||||
|
||||
.ps__thumb-y {
|
||||
@include gradient-vertical($blue, lighten($blue, 20%));
|
||||
@include gradient-vertical($scrollbarBackground, $scrollbarBackground2);
|
||||
border-radius: 6px;
|
||||
width: 6px;
|
||||
/* there must be 'right' for ps__thumb-y */
|
||||
|
@ -6,7 +6,7 @@
|
||||
top: $navbarHeight;
|
||||
z-index: $zindex-modal-backdrop;
|
||||
background-color: $black;
|
||||
@include opacity(70);
|
||||
@include opacity(75);
|
||||
}
|
||||
|
||||
.search-container {
|
||||
@ -44,12 +44,6 @@
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.search-switches {
|
||||
flex-grow: 1;
|
||||
padding: 1rem 1rem 0.75rem 1rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.search-field-icon {
|
||||
font-size: $font-size-lg;
|
||||
padding: 1rem 1rem 0.75rem 1.5rem;
|
||||
@ -57,18 +51,45 @@
|
||||
|
||||
.search-dropdown {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 800px;
|
||||
background: $page-bg;
|
||||
flex-direction: row;
|
||||
height: calc(100% - #{$navbarHeight});
|
||||
}
|
||||
|
||||
.search-dropdown__col_1 {
|
||||
background: $page-bg;
|
||||
max-width: 700px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.search-dropdown__col_2 {
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.search-filter-box {
|
||||
background: $search-filter-box-bg;
|
||||
border-radius: 2px;
|
||||
padding: $spacer*1.5;
|
||||
max-width: 340px;
|
||||
margin-bottom: $spacer * 1.5;
|
||||
margin-left: $spacer * 1.5;
|
||||
}
|
||||
|
||||
.search-filter-box__header {
|
||||
border-bottom: 1px solid $dark-5;
|
||||
margin-bottom: $spacer * 1.5;
|
||||
}
|
||||
|
||||
.search-results-container {
|
||||
height: 100%;
|
||||
display: block;
|
||||
padding: $spacer;
|
||||
position: relative;
|
||||
flex-grow: 10;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.label-tag {
|
||||
margin-left: 6px;
|
||||
@ -84,9 +105,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.search-section {
|
||||
background: $panel-bg;
|
||||
border: $panel-border;
|
||||
padding: $panel-padding;
|
||||
margin-bottom: 3px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.search-section__header {
|
||||
font-size: $font-size-h6;
|
||||
padding: 0.6rem 0;
|
||||
padding: 8px 0 2px 0;
|
||||
color: $text-color-weak;
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
@ -105,7 +134,7 @@
|
||||
}
|
||||
|
||||
.search-section__header__icon {
|
||||
padding: 3px 10px;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.search-section__header__toggle {
|
||||
@ -170,24 +199,34 @@
|
||||
}
|
||||
|
||||
.search-item__tags {
|
||||
padding: 8px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.search-item__actions {
|
||||
flex: 0 0 auto;
|
||||
padding: 0 10px 0 0;
|
||||
}
|
||||
|
||||
.search-item__actions__item {
|
||||
display: none;
|
||||
display: inline-block;
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
transition: all 0.2s ease-in-out;
|
||||
.fa-star, .fa-star-o {
|
||||
color: $orange;
|
||||
line-height: 37px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-item:hover {
|
||||
.search-item__actions__item {
|
||||
opacity: 0.8;
|
||||
width: 15px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.search-button-row {
|
||||
text-align: center;
|
||||
padding: $spacer*2 $spacer;
|
||||
background: $panel-bg;
|
||||
}
|
||||
|
@ -4,26 +4,34 @@
|
||||
flex-flow: column;
|
||||
flex-direction: column;
|
||||
width: $side-menu-width;
|
||||
background: $navbarBackground;
|
||||
z-index: 10;
|
||||
|
||||
z-index: $zindex-sidemenu;
|
||||
a:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sidemenu__logo_small_breakpoint {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidemenu__close {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sidemenu-open {
|
||||
.sidemenu {
|
||||
background: $side-menu-bg;
|
||||
position: initial;
|
||||
height: auto;
|
||||
box-shadow: $side-menu-shadow;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.sidemenu__top,
|
||||
.sidemenu__bottom {
|
||||
display: block;
|
||||
@include media-breakpoint-up(sm) {
|
||||
.sidemenu-open {
|
||||
.sidemenu {
|
||||
background: $side-menu-bg;
|
||||
position: initial;
|
||||
height: auto;
|
||||
box-shadow: $side-menu-shadow;
|
||||
position: relative;
|
||||
z-index: $zindex-sidemenu;
|
||||
}
|
||||
.sidemenu__top,
|
||||
.sidemenu__bottom {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,21 +50,23 @@
|
||||
position: relative;
|
||||
@include left-brand-border();
|
||||
|
||||
&.active,
|
||||
&:hover {
|
||||
background-color: $side-menu-item-hover-bg;
|
||||
@include left-brand-border-gradient();
|
||||
@include media-breakpoint-up(sm) {
|
||||
&.active,
|
||||
&:hover {
|
||||
background-color: $side-menu-item-hover-bg;
|
||||
@include left-brand-border-gradient();
|
||||
|
||||
.dropdown-menu {
|
||||
margin: 0;
|
||||
display: block;
|
||||
opacity: 0;
|
||||
top: 0px;
|
||||
// important to overlap it otherwise it can be hidden
|
||||
// again by the mouse getting outside the hover space
|
||||
left: $side-menu-width - 2px;
|
||||
@include animation('dropdown-anim 150ms ease-in-out 100ms forwards');
|
||||
z-index: 1;
|
||||
.dropdown-menu {
|
||||
margin: 0;
|
||||
display: block;
|
||||
opacity: 0;
|
||||
top: 0px;
|
||||
// important to overlap it otherwise it can be hidden
|
||||
// again by the mouse getting outside the hover space
|
||||
left: $side-menu-width - 2px;
|
||||
@include animation('dropdown-anim 150ms ease-in-out 100ms forwards');
|
||||
z-index: $zindex-sidemenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,7 +164,7 @@ li.sidemenu-org-switcher {
|
||||
}
|
||||
}
|
||||
|
||||
.sidemenu__logo {
|
||||
.sidemenu__logo, .sidemenu__logo_small_breakpoint {
|
||||
display: block;
|
||||
padding: 0.4rem 1.0rem 0.4rem 0.65rem;
|
||||
min-height: $navbarHeight;
|
||||
@ -172,3 +182,84 @@ li.sidemenu-org-switcher {
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(xs) {
|
||||
.sidemenu-open {
|
||||
.navbar {
|
||||
padding-left: 60px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.sidemenu-open--xs {
|
||||
.sidemenu {
|
||||
width: 100%;
|
||||
background: $side-menu-bg;
|
||||
position: initial;
|
||||
height: auto;
|
||||
box-shadow: $side-menu-shadow;
|
||||
position: relative;
|
||||
z-index: $zindex-sidemenu;
|
||||
}
|
||||
|
||||
.sidemenu__close {
|
||||
display: block;
|
||||
font-size: $font-size-md;
|
||||
}
|
||||
|
||||
.sidemenu__top,
|
||||
.sidemenu__bottom {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.sidemenu {
|
||||
.sidemenu__logo {
|
||||
display: none;
|
||||
}
|
||||
.sidemenu__logo_small_breakpoint {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
|
||||
&:hover {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.sidemenu__top {
|
||||
padding-top: 0rem;
|
||||
}
|
||||
|
||||
.side-menu-header {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.sidemenu-link {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.sidemenu-icon {
|
||||
display: none
|
||||
}
|
||||
|
||||
.dropdown-menu--sidemenu {
|
||||
display: block;
|
||||
position: unset;
|
||||
width: 100%;
|
||||
float: none;
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
> li > a {
|
||||
padding-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.sidemenu__bottom {
|
||||
.dropdown-menu--sidemenu {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,10 @@
|
||||
}
|
||||
|
||||
.tabbed-view-header {
|
||||
background: $page-header-bg;
|
||||
box-shadow: $page-header-shadow;
|
||||
border-bottom: 1px solid $page-header-border-color;
|
||||
@include clearfix();
|
||||
@include brand-bottom-border();
|
||||
}
|
||||
|
||||
.tabbed-view-title {
|
||||
@ -34,7 +36,7 @@
|
||||
margin: 0;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
padding: ($tabs-padding-top + $tabs-top-margin) $spacer $tabs-padding-bottom;
|
||||
padding: $tabs-padding;
|
||||
color: $text-color;
|
||||
i {
|
||||
font-size: 120%;
|
||||
|
@ -1,41 +1,8 @@
|
||||
.nav-tabs-alt {
|
||||
& > li > a {
|
||||
color: darken($link-color, 20%);
|
||||
}
|
||||
|
||||
li > a:hover {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
li.active > a,
|
||||
li.active > a:focus,
|
||||
li.active > a:hover {
|
||||
@include border-radius(3px);
|
||||
border: 1px solid $divider-border-color;
|
||||
background-color: transparent;
|
||||
border-bottom: 1px solid $page-bg;
|
||||
color: $link-color;
|
||||
}
|
||||
|
||||
li.disabled > a {
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
.open .dropdown-toggle {
|
||||
background-color: #060606;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
padding: 10px;
|
||||
background-color: $panel-bg;
|
||||
}
|
||||
}
|
||||
|
||||
.gf-tabs {
|
||||
@include clearfix();
|
||||
float: left;
|
||||
margin: $tabs-top-margin 0 0 0;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.gf-tabs-item {
|
||||
@ -44,13 +11,17 @@
|
||||
}
|
||||
|
||||
.gf-tabs-link {
|
||||
padding: $tabs-padding-top $spacer $tabs-padding-bottom $spacer;
|
||||
padding: $tabs-padding;
|
||||
margin-right: $spacer/2;
|
||||
border: 1px solid transparent;
|
||||
position: relative;
|
||||
display: block;
|
||||
border: solid transparent;
|
||||
border-width: 2px 1px 1px;
|
||||
border-radius: 3px 3px 0 0;
|
||||
|
||||
@include border-radius(2px 2px 0 0);
|
||||
i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
@ -60,20 +31,9 @@
|
||||
&.active,
|
||||
&.active:hover,
|
||||
&.active:focus {
|
||||
@include border-radius(3px);
|
||||
border-color: rgba(216, 131, 40, 0.77);
|
||||
border-bottom: 1px solid $page-bg;
|
||||
border-color: $orange $dark-4 transparent;
|
||||
background: $page-bg;
|
||||
color: $link-color;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-tabs-wrapper {
|
||||
@include brand-bottom-border();
|
||||
@include clearfix();
|
||||
}
|
||||
|
||||
.form-tabs-content {
|
||||
padding: $spacer*2 $spacer;
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
.nav.gf-timepicker-nav {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.timepicker-timestring {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.gf-timepicker-nav {
|
||||
flex-wrap: nowrap;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.gf-timepicker-nav-btn {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.gf-timepicker-dropdown {
|
||||
@ -118,14 +118,3 @@
|
||||
@extend .fa-chevron-left;
|
||||
}
|
||||
|
||||
.gf-timepicker-time-control {
|
||||
font-size: $font-size-sm;
|
||||
a {
|
||||
padding: 18px 7px 13px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dashnav-move-timeframe {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
@ -21,33 +21,22 @@
|
||||
|
||||
.playlist-active,
|
||||
.user-activity-low {
|
||||
.react-resizable-handle
|
||||
.add-row-panel-hint,
|
||||
.dash-row-menu-container,
|
||||
.panel-drop-zone
|
||||
.dashnav-refresh-action,
|
||||
.dashnav-zoom-out,
|
||||
.navbar-button--refresh,
|
||||
.navbar-buttons--zoom,
|
||||
.navbar-buttons--actions,
|
||||
.panel-menu-container,
|
||||
.dashnav-action-icons,
|
||||
.panel-info-corner--info,
|
||||
.panel-info-corner--links,
|
||||
.dashnav-move-timeframe {
|
||||
.panel-info-corner--links {
|
||||
opacity: 0;
|
||||
transition: all 1.5s ease-in-out 1s;
|
||||
}
|
||||
|
||||
// navbar buttons
|
||||
.navbar {
|
||||
border-color: transparent;
|
||||
background: transparent;
|
||||
transition: all 1.5s ease-in-out 1s;
|
||||
.fa {
|
||||
opacity: 0;
|
||||
transition: all 1.5s ease-in-out 1s;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar {
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.navbar-page-btn {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user