Bläddra i källkod

ux(): added card layout selector and list view mode, #4364

Torkel Ödegaard 9 år sedan
förälder
incheckning
c411714546

+ 74 - 0
public/app/core/components/layout_selector/layout_selector.ts

@@ -0,0 +1,74 @@
+///<reference path="../../../headers/common.d.ts" />
+
+import config from 'app/core/config';
+import store from 'app/core/store';
+import _ from 'lodash';
+import $ from 'jquery';
+import coreModule from 'app/core/core_module';
+
+var template = `
+<div class="layout-selector">
+  <button ng-click="ctrl.listView()" ng-class="{active: ctrl.mode === 'list'}">
+    <i class="fa fa-list"></i>
+  </button>
+  <button ng-click="ctrl.gridView()" ng-class="{active: ctrl.mode === 'grid'}">
+    <i class="fa fa-th"></i>
+  </button>
+</div>
+`;
+
+export class LayoutSelectorCtrl {
+  mode: string;
+
+  /** @ngInject **/
+  constructor(private $rootScope) {
+    this.mode = store.get('grafana.list.layout.mode') || 'grid';
+  }
+
+  listView() {
+    this.mode = 'list';
+    store.set('grafana.list.layout.mode', 'list');
+    this.$rootScope.appEvent('layout-mode-changed', 'list');
+  }
+
+  gridView() {
+    this.mode = 'grid';
+    store.set('grafana.list.layout.mode', 'grid');
+    this.$rootScope.appEvent('layout-mode-changed', 'grid');
+  }
+
+}
+
+/** @ngInject **/
+export function layoutSelector() {
+  return {
+    restrict: 'E',
+    controller: LayoutSelectorCtrl,
+    bindToController: true,
+    controllerAs: 'ctrl',
+    scope: {},
+    template: template,
+  };
+}
+
+/** @ngInject **/
+export function layoutMode($rootScope) {
+  return {
+    restrict: 'A',
+    scope: {},
+    link: function(scope, elem) {
+      var layout = store.get('grafana.list.layout.mode') || 'grid';
+      var className = 'card-list-layout-' + layout;
+      elem.addClass(className);
+
+      $rootScope.onAppEvent('layout-mode-changed', (evt, newLayout) => {
+        elem.removeClass(className);
+        className = 'card-list-layout-' + newLayout;
+        elem.addClass(className);
+      }, scope);
+    }
+  };
+}
+
+coreModule.directive('layoutSelector', layoutSelector);
+coreModule.directive('layoutMode', layoutMode);

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

@@ -28,6 +28,7 @@ import {infoPopover} from './components/info_popover';
 import {colorPicker} from './components/colorpicker';
 import {navbarDirective} from './components/navbar/navbar';
 import {arrayJoin} from './directives/array_join';
+import {layoutSelector} from './components/layout_selector/layout_selector';
 import 'app/core/controllers/all';
 import 'app/core/services/all';
 import 'app/core/routes/routes';
@@ -42,5 +43,6 @@ export {
   navbarDirective,
   searchDirective,
   colorPicker,
+  layoutSelector,
   infoPopover
 };

+ 5 - 3
public/app/features/plugins/partials/plugin_list.html

@@ -26,8 +26,10 @@
 		</div>
 	</div>
 
-	<section class="card-section">
-		<ol class="card-list">
+	<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">
@@ -36,7 +38,7 @@
 					</div>
 					<div class="card-item-body">
 						<figure class="card-item-figure">
-							<img src="{{plugin.info.logos.small}}">
+							<img ng-src="{{plugin.info.logos.small}}">
 						</figure>
 						<div class="card-item-details">
 							<div class="card-item-name" href="plugins/{{plugin.id}}/edit">{{plugin.name}}</div>

+ 78 - 20
public/sass/components/_cards.scss

@@ -1,4 +1,27 @@
-
+.layout-selector {
+  text-align: right;
+  margin: 0 $spacer*1.5 $spacer;
+  position: relative;
+  top: -0.5rem;
+
+  button {
+    background: $input-label-bg;
+    color: $text-color-weak;
+    border: none;
+    padding: 0.5rem;
+    line-height: 1;
+    font-size: 130%;
+
+    &:focus {
+      outline: none;
+    }
+
+    &.active {
+      background-color: lighten($input-label-bg, 5%);
+      color: $link-color;
+    }
+  }
+}
 
 .card-section {
   margin-bottom: $spacer*2;
@@ -11,15 +34,9 @@
   list-style-type: none;
 }
 
-.card-item-wrapper {
-  width: 100%;
-  padding: 0 1.5rem 1.5rem 0rem;
-}
-
 .card-item {
   display: block;
   height: 100%;
-  min-height: 12rem;
   background: $card-background;
   box-shadow: $card-shadow;
   padding: 1rem;
@@ -30,13 +47,6 @@
   }
 }
 
-.card-item-figure {
-  margin: 0 $spacer $spacer 0;
-  img {
-    width: 6rem;
-  }
-}
-
 .card-item-body {
   display: flex;
 }
@@ -51,23 +61,71 @@
 
 .card-item-name {
   color: $headings-color;
-  font-size: $font-size-h3;
 }
 
 .card-item-sub-name {
   color: $text-color-weak;
 }
 
-@include media-breakpoint-up(md) {
+.card-list-layout-grid {
+
   .card-item-wrapper {
-    width: 50%;
+    width: 100%;
+    padding: 0 1.5rem 1.5rem 0rem;
+  }
+
+  .card-item-figure {
+    margin: 0 $spacer $spacer 0;
+    img {
+      width: 6rem;
+    }
+  }
+
+  .card-item-name {
+    font-size: $font-size-h3;
+  }
+
+  @include media-breakpoint-up(md) {
+    .card-item-wrapper {
+      width: 50%;
+    }
+  }
+
+  @include media-breakpoint-up(lg) {
+    .card-item-wrapper {
+      width: 33.333333%;
+    }
   }
 }
 
-@include media-breakpoint-up(lg) {
+.card-list-layout-list {
+
   .card-item-wrapper {
-    width: 33%;
+    width: 100%;
+    padding: 0 0 1.5rem 0rem;
+  }
+
+  .card-item-header {
+    float: right;
+  }
+
+  .card-item-figure {
+    margin: 0 $spacer 0 0;
+    img {
+      width: 3.5rem;
+    }
+  }
+
+  .card-item-name {
+    font-size: $font-size-h4;
   }
-}
 
+  .card-item-sub-name {
+    font-size: $font-size-sm;
+  }
+
+  .layout-selector {
+    margin-right: 0;
+  }
+}