Forráskód Böngészése

ux: work on page header

Torkel Ödegaard 8 éve
szülő
commit
74ceb76ec0

+ 1 - 0
pkg/api/dtos/index.go

@@ -24,6 +24,7 @@ type NavLink struct {
 	Id           string     `json:"id,omitempty"`
 	Id           string     `json:"id,omitempty"`
 	Text         string     `json:"text,omitempty"`
 	Text         string     `json:"text,omitempty"`
 	Description  string     `json:"description,omitempty"`
 	Description  string     `json:"description,omitempty"`
+	SubTitle     string     `json:"subTitle,omitempty"`
 	Icon         string     `json:"icon,omitempty"`
 	Icon         string     `json:"icon,omitempty"`
 	Img          string     `json:"img,omitempty"`
 	Img          string     `json:"img,omitempty"`
 	Url          string     `json:"url,omitempty"`
 	Url          string     `json:"url,omitempty"`

+ 44 - 41
pkg/api/index.go

@@ -104,7 +104,7 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
 		{Text: "Home", Url: setting.AppSubUrl + "/", Icon: "fa fa-fw fa-home"},
 		{Text: "Home", Url: setting.AppSubUrl + "/", Icon: "fa fa-fw fa-home"},
 		{Text: "Playlists", Id: "playlists", Url: setting.AppSubUrl + "/playlists", Icon: "fa fa-fw fa-film"},
 		{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: "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"},
+		{Text: "Dashboard List", Id: "dashboards", Url: setting.AppSubUrl + "/dashboards", Icon: "fa fa-fw fa-bars"},
 	}
 	}
 
 
 	data.NavTree = append(data.NavTree, &dtos.NavLink{
 	data.NavTree = append(data.NavTree, &dtos.NavLink{
@@ -146,6 +146,7 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
 
 
 		data.NavTree = append(data.NavTree, &dtos.NavLink{
 		data.NavTree = append(data.NavTree, &dtos.NavLink{
 			Text:     "Alerting",
 			Text:     "Alerting",
+			SubTitle: "Alert rules & notifications",
 			Id:       "alerting",
 			Id:       "alerting",
 			Icon:     "gicon gicon-alert",
 			Icon:     "gicon gicon-alert",
 			Url:      setting.AppSubUrl + "/alerting/list",
 			Url:      setting.AppSubUrl + "/alerting/list",
@@ -202,10 +203,11 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
 
 
 	if c.OrgRole == m.ROLE_ADMIN {
 	if c.OrgRole == m.ROLE_ADMIN {
 		cfgNode := &dtos.NavLink{
 		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{
 			Children: []*dtos.NavLink{
 				{
 				{
 					Text:        "Data Sources",
 					Text:        "Data Sources",
@@ -218,25 +220,6 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
 						{Text: "New", Url: setting.AppSubUrl + "/datasources", Icon: "fa fa-fw fa-plus"},
 						{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",
 					Text:        "Members",
 					Id:          "users",
 					Id:          "users",
@@ -245,12 +228,32 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
 					Url:         setting.AppSubUrl + "/org/users",
 					Url:         setting.AppSubUrl + "/org/users",
 				},
 				},
 				{
 				{
-					Text:        "Groups",
+					Text:        "Teams",
 					Id:          "users",
 					Id:          "users",
 					Description: "Manage org groups",
 					Description: "Manage org groups",
-					Icon:        "fa fa-fw fa-users",
+					Icon:        "gicon gicon-user-group",
 					Url:         setting.AppSubUrl + "/org/user-groups",
 					Url:         setting.AppSubUrl + "/org/user-groups",
 				},
 				},
+				{
+					Text:        "Plugins",
+					Id:          "plugins",
+					Description: "View and configure plugins",
+					Icon:        "icon-gf icon-gf-fw icon-gf-apps",
+					Url:         setting.AppSubUrl + "/plugins",
+					// Children: []*dtos.NavLink{
+					// 	{Text: "Panels", Url: setting.AppSubUrl + "/plugins?type=panel", Icon: "fa fa-fw fa-stop"},
+					// 	{Text: "Data sources", Url: setting.AppSubUrl + "/plugins?type=datasource", Icon: "icon-gf icon-gf-datasources"},
+					// 	{Text: "Apps", Url: setting.AppSubUrl + "/plugins?type=app", Icon: "icon-gf icon-gf-apps"},
+					// },
+				},
+				{
+					Text:        "Preferences",
+					Id:          "org-settings",
+					Description: "Organization preferences",
+					Icon:        "fa fa-fw fa-sliders",
+					Url:         setting.AppSubUrl + "/org",
+				},
+
 				{
 				{
 					Text:        "API Keys",
 					Text:        "API Keys",
 					Id:          "apikeys",
 					Id:          "apikeys",
@@ -261,21 +264,21 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
 			},
 			},
 		}
 		}
 
 
-		if c.IsGrafanaAdmin {
-			cfgNode.Children = append(cfgNode.Children, &dtos.NavLink{
-				Text: "Server Admin",
-				Id:   "admin",
-				Icon: "fa fa-fw fa-shield",
-				Url:  setting.AppSubUrl + "/admin",
-				Children: []*dtos.NavLink{
-					{Text: "Users", Id: "global-users", Url: setting.AppSubUrl + "/admin/users"},
-					{Text: "Orgs", Id: "global-orgs", Url: setting.AppSubUrl + "/admin/orgs"},
-					{Text: "Server Settings", Id: "server-settings", Url: setting.AppSubUrl + "/admin/settings"},
-					{Text: "Server Stats", Id: "server-stats", Url: setting.AppSubUrl + "/admin/stats"},
-					{Text: "Style Guide", Id: "styleguide", Url: setting.AppSubUrl + "/styleguide"},
-				},
-			})
-		}
+		// if c.IsGrafanaAdmin {
+		// 	cfgNode.Children = append(cfgNode.Children, &dtos.NavLink{
+		// 		Text: "Server Admin",
+		// 		Id:   "admin",
+		// 		Icon: "fa fa-fw fa-shield",
+		// 		Url:  setting.AppSubUrl + "/admin",
+		// 		Children: []*dtos.NavLink{
+		// 			{Text: "Users", Id: "global-users", Url: setting.AppSubUrl + "/admin/users"},
+		// 			{Text: "Orgs", Id: "global-orgs", Url: setting.AppSubUrl + "/admin/orgs"},
+		// 			{Text: "Server Settings", Id: "server-settings", Url: setting.AppSubUrl + "/admin/settings"},
+		// 			{Text: "Server Stats", Id: "server-stats", Url: setting.AppSubUrl + "/admin/stats"},
+		// 			{Text: "Style Guide", Id: "styleguide", Url: setting.AppSubUrl + "/styleguide"},
+		// 		},
+		// 	})
+		// }
 
 
 		data.NavTree = append(data.NavTree, cfgNode)
 		data.NavTree = append(data.NavTree, cfgNode)
 	}
 	}

+ 2 - 0
public/app/core/angular_wrappers.ts

@@ -1,8 +1,10 @@
 import { react2AngularDirective } from 'app/core/utils/react2angular';
 import { react2AngularDirective } from 'app/core/utils/react2angular';
 import { PasswordStrength } from './components/PasswordStrength';
 import { PasswordStrength } from './components/PasswordStrength';
+import PageHeader from './components/PageHeader';
 
 
 export function registerAngularDirectives() {
 export function registerAngularDirectives() {
 
 
   react2AngularDirective('passwordStrength', PasswordStrength, ['password']);
   react2AngularDirective('passwordStrength', PasswordStrength, ['password']);
+  react2AngularDirective('pageHeader', PageHeader, ['model', "noTabs"]);
 
 
 }
 }

+ 88 - 0
public/app/core/components/PageHeader.tsx

@@ -0,0 +1,88 @@
+import React from 'react';
+import { NavModel } from '../nav_model_srv';
+import classNames  from 'classnames';
+
+export interface IProps {
+  model: NavModel;
+}
+
+export default class PageHeader extends React.Component<IProps, any> {
+  constructor(props) {
+    super(props);
+  }
+
+  renderBreadcrumb(breadcrumb) {
+    return (
+      <a className="breadcrumb-item" href={breadcrumb.url} key={breadcrumb.id}>
+        {breadcrumb.text}
+      </a>
+    );
+  }
+
+  renderTab(tab) {
+    let tabClasses = classNames({
+      'gf-tabs-link': true,
+      'active': tab.active,
+    });
+
+    console.log(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>
+    );
+  }
+
+  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}></i>
+              {main.subType.text}
+            </div>
+          )}
+        </div>
+      </div>
+    );
+  }
+
+  render() {
+    return (
+      <div className="page-header-canvas">
+        <div className="page-container">
+          <div className="page-nav">
+            <div className="page-breadcrumbs">
+              <a className="breadcrumb-item active" href="/">
+                <i className="fa fa-home" />
+              </a>
+              {this.props.model.breadcrumbs.map(this.renderBreadcrumb)}
+            </div>
+          </div>
+
+          <div className="page-header">
+            {this.renderHeaderTitle(this.props.model.main)}
+
+            {this.props.model.main.children && (
+              <ul className="gf-tabs">
+              {this.props.model.main.children.map(this.renderTab)}
+              </ul>
+            )}
+          </div>
+        </div>
+      </div>
+    );
+  }
+}

+ 20 - 8
public/app/core/nav_model_srv.ts

@@ -1,5 +1,3 @@
-///<reference path="../headers/common.d.ts" />
-
 import coreModule from 'app/core/core_module';
 import coreModule from 'app/core/core_module';
 import config from 'app/core/config';
 import config from 'app/core/config';
 import _ from 'lodash';
 import _ from 'lodash';
@@ -9,20 +7,18 @@ export interface NavModelItem {
   url: string;
   url: string;
   icon?: string;
   icon?: string;
   img?: string;
   img?: string;
+  active?: boolean;
+  children: NavModelItem[];
 }
 }
 
 
 export class NavModel {
 export class NavModel {
   breadcrumbs: NavModelItem[];
   breadcrumbs: NavModelItem[];
-  header: NavModelItem;
+  main: NavModelItem;
   node: NavModelItem;
   node: NavModelItem;
 
 
   constructor() {
   constructor() {
     this.breadcrumbs = [];
     this.breadcrumbs = [];
   }
   }
-
-  setPageHeaderIndex(index: number) {
-    this.header = this.breadcrumbs[index];
-  }
 }
 }
 
 
 export class NavModelSrv {
 export class NavModelSrv {
@@ -43,13 +39,29 @@ export class NavModelSrv {
     var nav = new NavModel();
     var nav = new NavModel();
 
 
     for (let id of args) {
     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});
       let node = _.find(children, {id: id});
       nav.breadcrumbs.push(node);
       nav.breadcrumbs.push(node);
       nav.node = node;
       nav.node = node;
-      nav.header = node;
+      nav.main = node;
       children = node.children;
       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;
     return nav;
   }
   }
 
 

+ 1 - 9
public/app/features/admin/partials/configuration_home.html

@@ -1,12 +1,4 @@
-<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>
-  </div>
-</div>
+<page-header model="ctrl.navModel" no-tabs="true"></page-header>
 
 
 <div class="page-container page-body">
 <div class="page-container page-body">
 	<section class="card-section card-list-layout-grid">
 	<section class="card-section card-list-layout-grid">

+ 1 - 2
public/app/features/alerting/alert_list_ctrl.ts

@@ -23,8 +23,7 @@ export class AlertListCtrl {
 
 
   /** @ngInject */
   /** @ngInject */
   constructor(private backendSrv, private $location, navModelSrv) {
   constructor(private backendSrv, private $location, navModelSrv) {
-    this.navModel = navModelSrv.getNav('alerting', 'alert-list');
-    this.navModel.setPageHeaderIndex(0);
+    this.navModel = navModelSrv.getNav('alerting', 'alert-list', 0);
 
 
     var params = $location.search();
     var params = $location.search();
     this.filters.state = params.state || null;
     this.filters.state = params.state || null;

+ 1 - 2
public/app/features/alerting/notifications_list_ctrl.ts

@@ -9,8 +9,7 @@ export class AlertNotificationsListCtrl {
   /** @ngInject */
   /** @ngInject */
   constructor(private backendSrv, navModelSrv) {
   constructor(private backendSrv, navModelSrv) {
     this.loadNotifications();
     this.loadNotifications();
-    this.navModel = navModelSrv.getNav('alerting', 'channels');
-    this.navModel.setPageHeaderIndex(0);
+    this.navModel = navModelSrv.getNav('alerting', 'channels', 0);
   }
   }
 
 
   loadNotifications() {
   loadNotifications() {

+ 1 - 25
public/app/features/alerting/partials/alert_list.html

@@ -1,28 +1,4 @@
-<div class="page-header-canvas">
-  <div class="page-container" >
-    <navbar model="ctrl.navModel"></navbar>
-
-    <div class="page-header">
-      <page-h1 model="ctrl.navModel" class="page-header__heading"></page-h1>
-
-      <ul class="gf-tabs">
-        <li class="gf-tabs-item">
-          <a class="gf-tabs-link active" href="alerting">
-            <i class="fa fa-fw fa-list-ul"></i>
-            Alert Rules
-          </a>
-        </li>
-        <li class="gf-tabs-item">
-          <a class="gf-tabs-link" href="alerting/notifications">
-            <i class="gicon gicon-alert-notification-channel"></i>
-            Notification channels
-          </a>
-        </li>
-      </ul>
-
-    </div>
-  </div>
-</div>
+<page-header model="ctrl.navModel"></page-header>
 
 
 <div class="page-container page-body">
 <div class="page-container page-body">
 
 

+ 1 - 24
public/app/features/alerting/partials/notifications_list.html

@@ -1,27 +1,4 @@
-<div class="page-header-canvas">
-  <div class="page-container" >
-    <navbar model="ctrl.navModel"></navbar>
-
-    <div class="page-header">
-      <page-h1 model="ctrl.navModel" class="page-header__heading"></page-h1>
-
-      <ul class="gf-tabs">
-        <li class="gf-tabs-item">
-          <a class="gf-tabs-link" href="alerting">
-            <i class="fa fa-fw fa-list-ul"></i>
-            Alert Rules
-          </a>
-        </li>
-        <li class="gf-tabs-item">
-          <a class="gf-tabs-link active" href="alerting/notifications">
-            <i class="gicon gicon-alert-notification-channel"></i>
-            Notification channels
-          </a>
-        </li>
-      </ul>
-    </div>
-  </div>
-</div>
+<page-header model="ctrl.navModel"></page-header>
 
 
 <div class="page-container page-body">
 <div class="page-container page-body">
 	<div class="page-action-bar">
 	<div class="page-action-bar">

+ 1 - 1
public/app/features/org/org_details_ctrl.ts

@@ -6,7 +6,7 @@ export class OrgDetailsCtrl {
   constructor($scope, $http, backendSrv, contextSrv, navModelSrv) {
   constructor($scope, $http, backendSrv, contextSrv, navModelSrv) {
     $scope.init = function() {
     $scope.init = function() {
       $scope.getOrgInfo();
       $scope.getOrgInfo();
-      $scope.navModel = navModelSrv.getNav('cfg', 'org');
+      $scope.navModel = navModelSrv.getNav('cfg', 'org-settings', 0);
     };
     };
 
 
     $scope.getOrgInfo = function() {
     $scope.getOrgInfo = function() {

+ 42 - 17
public/app/features/org/partials/orgDetails.html

@@ -1,26 +1,51 @@
-<navbar model="navModel"></navbar>
+<!-- <div class="page&#45;header&#45;canvas"> -->
+<!--   <div class="page&#45;container" > -->
+<!--     <navbar model="navModel"></navbar> -->
+<!--  -->
+<!--     <div class="page&#45;header"> -->
+<!--       <page&#45;h1 model="navModel"></page&#45;h1> -->
+<!--  -->
+<!--       <ul class="gf&#45;tabs"> -->
+<!--         <li class="gf&#45;tabs&#45;item"> -->
+<!--           <a class="gf&#45;tabs&#45;link active" href="org"> -->
+<!--             <i class="fa fa&#45;fw fa&#45;sliders"></i> -->
+<!--             Preferences -->
+<!--           </a> -->
+<!--         </li> -->
+<!--         <li class="gf&#45;tabs&#45;item"> -->
+<!--           <a class="gf&#45;tabs&#45;link" href="org/users"> -->
+<!--             <i class="icon&#45;gf icon&#45;gf&#45;fw icon&#45;gf&#45;users"></i> -->
+<!--             Members -->
+<!--           </a> -->
+<!--         </li> -->
+<!--         <li class="gf&#45;tabs&#45;item"> -->
+<!--           <a class="gf&#45;tabs&#45;link" href="org/user&#45;groups"> -->
+<!--             <i class="gicon gicon&#45;user&#45;group"></i> -->
+<!--             Teams -->
+<!--           </a> -->
+<!--         </li> -->
+<!--       </ul> -->
+<!--     </div> -->
+<!--   </div> -->
+<!-- </div> -->
 
 
-<div class="page-container">
-	<div class="page-header">
-		<page-h1 model="navModel"></page-h1>
-	</div>
+<page-header model="navModel"></page-header>
 
 
-	<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>
+<div class="page-container page-body">
+  <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>
 
 
     <div class="gf-form-button-row">
     <div class="gf-form-button-row">
       <button type="submit" class="btn btn-success" ng-click="update()">Save</button>
       <button type="submit" class="btn btn-success" ng-click="update()">Save</button>
     </div>
     </div>
-	</form>
-
-	<prefs-control mode="org"></prefs-control>
-
+  </form>
+  <prefs-control mode="org"></prefs-control>
 </div>
 </div>
 
 
 
 

+ 1 - 1
public/app/features/plugins/ds_list_ctrl.ts

@@ -13,7 +13,7 @@ export class DataSourcesCtrl {
     private datasourceSrv,
     private datasourceSrv,
     private navModelSrv) {
     private navModelSrv) {
 
 
-    this.navModel = this.navModelSrv.getNav('cfg', 'datasources');
+    this.navModel = this.navModelSrv.getNav('cfg', 'datasources', 0);
 
 
     backendSrv.get('/api/datasources').then(result => {
     backendSrv.get('/api/datasources').then(result => {
       this.datasources = result;
       this.datasources = result;

+ 1 - 10
public/app/features/plugins/partials/ds_list.html

@@ -1,13 +1,4 @@
-<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>
-  </div>
-</div>
+<page-header model="ctrl.navModel"></page-header>
 
 
 <div class="page-container page-body">
 <div class="page-container page-body">
   <div class="page-action-bar">
   <div class="page-action-bar">

+ 1 - 0
public/sass/_variables.dark.scss

@@ -52,6 +52,7 @@ $critical:              #ed2e18;
 // -------------------------
 // -------------------------
 $body-bg:  			   	    rgb(23,24,25);
 $body-bg:  			   	    rgb(23,24,25);
 $page-bg:  			   	    rgb(22, 23, 25);
 $page-bg:  			   	    rgb(22, 23, 25);
+
 $body-color:   		 	    $gray-4;
 $body-color:   		 	    $gray-4;
 $text-color:   	   		  $gray-4;
 $text-color:   	   		  $gray-4;
 $text-color-strong: 	  $white;
 $text-color-strong: 	  $white;

+ 4 - 0
public/sass/base/_icons.scss

@@ -47,5 +47,9 @@
   background-image: url('../img/icons_#{$theme-name}_theme/icon_notification_channels.svg');
   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');
+}
+
 
 
 
 

+ 26 - 14
public/sass/components/_page_header.scss

@@ -20,27 +20,30 @@
   }
   }
 }
 }
 
 
-.page-header__title {
-  font-size: $font-size-h2;
+.page-header__inner {
   flex-grow: 1;
   flex-grow: 1;
+  display: flex;
   margin-bottom: 2.5rem;
   margin-bottom: 2.5rem;
-  line-height: 50px;
+}
+
+.page-header__title {
+  font-size: $font-size-h2;
+  margin-bottom: 1px;
+  padding-top: $spacer;
 }
 }
 
 
 .page-header__img {
 .page-header__img {
   border-radius: 50%;
   border-radius: 50%;
-  margin-right: 0.5rem;
   position: relative;
   position: relative;
   top: -3px;
   top: -3px;
-  width: 50px;
-  height: 50px;
+  width: 65px;
+  height: 65px;
 }
 }
 
 
 .page-header__icon {
 .page-header__icon {
-  font-size: 150%;
-  margin-right: 0.5rem;
-  width: 50px;
-  height: 50px;
+  font-size: 70px;
+  width: 65;
+  height: 65;
   position: relative;
   position: relative;
 
 
   &.fa {
   &.fa {
@@ -52,10 +55,19 @@
   }
   }
 }
 }
 
 
-.page-heading {
-  font-size: 1.25rem;
-  margin-top: 0;
-  margin-bottom: $spacer * 0.7;
+.page-header__logo {
+  margin-right: $spacer/2;
 }
 }
 
 
+.page-header-info-block {
+}
+
+.page-header__sub-title {
+  color: $text-muted;
+}
+
+.page-header-stamps-type {
+  color: $link-color-disabled;
+  text-transform: uppercase;
+}
 
 

+ 6 - 0
public/sass/layout/_page.scss

@@ -42,6 +42,12 @@
   }
   }
 }
 }
 
 
+.page-heading {
+  font-size: 1.25rem;
+  margin-top: 0;
+  margin-bottom: $spacer * 0.7;
+}
+
 .page-action-bar {
 .page-action-bar {
   margin-bottom: $spacer * 2;
   margin-bottom: $spacer * 2;
   display: flex;
   display: flex;

+ 12 - 38
public/sass/pages/_plugins.scss

@@ -1,41 +1,3 @@
-.plugin-header {
-  @include clearfix();
-
-  padding: $spacer 0 $spacer/2 0;
-  margin-bottom: 2rem;
-}
-
-.plugin-header-logo {
-  float: left;
-  width: 7rem;
-  img {
-    width: 7rem;
-  }
-  margin-right: $spacer;
-}
-
-.plugin-header-info-block {
-  float: left;
-}
-
-.plugin-header-author {
-}
-
-.plugin-header-stamps-type {
-  color: $link-color-disabled;
-  text-transform: uppercase;
-}
-
-.plugin-info-list-item {
-  img {
-    width: 16px;
-  }
-
-  white-space: nowrap;
-  max-width: $page-sidebar-width;
-  text-overflow: ellipsis;
-  overflow: hidden;
-}
 
 
 .get-more-plugins-link {
 .get-more-plugins-link {
   color: $gray-3;
   color: $gray-3;
@@ -55,3 +17,15 @@
     display: none;
     display: none;
   }
   }
 }
 }
+
+.plugin-info-list-item {
+  img {
+    width: 16px;
+  }
+
+  white-space: nowrap;
+  max-width: $page-sidebar-width;
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+