浏览代码

Added icon font generation to build pipelines. IconComponent implementation. IconComponent used in IconButtonComponent. Using SearchBarComponent in AutoCompleteComponent implementation

Joe Hawkins 8 年之前
父节点
当前提交
c76eeed86e

+ 1 - 1
src/main/angular/README.md

@@ -15,7 +15,7 @@ Run the following commands
 * `npm run build` Starts a production build
 * `npm start` Starts the development environment, which watches your 
 system for any file changes and rebuilds automatically. It also serves
-the dist/ folder from http://localhost:8080/
+the dist/ folder from http://localhost:4000/
 * `npm run clean` Cleans dist/ directory
 * `npm test` Starts test environment, which will watch your system for 
 any file changes, rebuild your code, and run unit tests

+ 1 - 0
src/main/angular/images/icons/m_file-tree.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M3,3H9V7H3V3M15,10H21V14H15V10M15,17H21V21H15V17M13,13H7V18H13V20H7L5,20V9H7V11H13V13Z" /></svg>

+ 1 - 0
src/main/angular/images/icons/m_table-large.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M4,3H20C21.1,3 22,3.9 22,5V20C22,21.1 21.1,22 20,22H4C2.9,22 2,21.1 2,20V5C2,3.9 2.9,3 4,3M4,7V10H8V7H4M10,7V10H14V7H10M20,10V7H16V10H20M4,12V15H8V12H4M4,20H8V17H4V20M10,12V15H14V12H10M10,20H14V17H10V20M20,20V17H16V20H20M20,12H16V15H20V12Z" /></svg>

+ 1 - 0
src/main/angular/images/icons/m_view-grid.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M3,11H11V3H3M3,21H11V13H3M13,21H21V13H13M13,3V11H21V3" /></svg>

+ 3 - 0
src/main/angular/karma.conf.js

@@ -11,9 +11,12 @@ module.exports = function (config) {
         frameworks: [ 'jasmine' ],
 
         // list of files / patterns to load in the browser
+        // Don't forget to add this to webpack.dev.js
         files: [
             'node_modules/angular/angular.js',
             'node_modules/angular-mocks/angular-mocks.js',
+            'node_modules/angular-sanitize/angular-sanitize.js',
+            'node_modules/angular-translate/dist/angular-translate.js',
             'vendor/angular-ui-router.js',
             'src/main.ts',
             'src/**/*.test.ts'

+ 2 - 2
src/main/angular/package.json

@@ -17,8 +17,7 @@
   },
   "author": "",
   "license": "ISC",
-  "dependencies": {
-  },
+  "dependencies": {},
   "devDependencies": {
     "@types/angular": "1.5.8",
     "@types/angular-mocks": "1.5.5",
@@ -34,6 +33,7 @@
     "copy-webpack-plugin": "3.0.1",
     "css-loader": "0.25.0",
     "file-loader": "0.9.0",
+    "fontgen-loader": "0.2.1",
     "html-loader": "0.4.4",
     "html-webpack-plugin": "2.22.0",
     "jasmine": "2.5.2",

+ 10 - 0
src/main/angular/src/icons.json

@@ -0,0 +1,10 @@
+{
+  "baseClass": "icon",
+  "classPrefix": "icon_",
+  "files": [ "../images/icons/**/*.svg" ],
+  "fixedWidth": true,
+  "fontName": "icons",
+  "html": true,
+  "normalize": true,
+  "types": [ "eot", "woff", "ttf", "svg" ]
+}

+ 3 - 0
src/main/angular/src/main.dev.ts

@@ -5,6 +5,9 @@ import PeopleService from './services/people.service.dev';
 import routes from './routes';
 import uiRouter from 'angular-ui-router';
 
+// fontgen-loader needs this :(
+require('./icons.json');
+
 module('app', [
     uiRouter,
     peopleSearchModule,

+ 3 - 0
src/main/angular/src/main.ts

@@ -6,6 +6,9 @@ import routes from './routes';
 import translationsLoader from './services/translations-loader.factory';
 import uiRouter from 'angular-ui-router';
 
+// fontgen-loader needs this :(
+require('./icons.json');
+
 module('app', [
     uiRouter,
     peopleSearchModule,

+ 5 - 2
src/main/angular/src/peoplesearch/orgchart-search.component.scss

@@ -35,11 +35,14 @@ org-chart-search {
         }
 
         > mf-auto-complete {
-          > input {
-            max-width: 360px;
+          max-width: 360px;
+
+          > mf-search-bar {
+            max-width: 100%;
           }
 
           > .results {
+            min-width: 100%;
             width: auto;
           }
         }

+ 1 - 1
src/main/angular/src/peoplesearch/peoplesearch-cards.component.html

@@ -1,7 +1,7 @@
 <mf-app-bar>
     <div class="page-content-title" translate="Title_PeopleSearch">People Search</div>
     <span flex></span>
-    <mf-icon-button class="fa fa-th-large" ng-click="$ctrl.gotoTableView()"></mf-icon-button>
+    <mf-icon-button icon="table-large" ng-click="$ctrl.gotoTableView()"></mf-icon-button>
 </mf-app-bar>
 
 <mf-search-bar search-text="$ctrl.query" auto-focus></mf-search-bar>

+ 1 - 1
src/main/angular/src/peoplesearch/peoplesearch-table.component.html

@@ -1,7 +1,7 @@
 <mf-app-bar>
     <div class="page-content-title" translate="Title_PeopleSearch">People Search</div>
     <span flex></span>
-    <mf-icon-button class="fa fa-list-alt" ng-click="$ctrl.gotoCardsView()"></mf-icon-button>
+    <mf-icon-button icon="view-grid" ng-click="$ctrl.gotoCardsView()"></mf-icon-button>
 </mf-app-bar>
 
 <mf-search-bar search-text="$ctrl.query" auto-focus></mf-search-bar>

+ 4 - 5
src/main/angular/src/ux/auto-complete.component.html

@@ -1,6 +1,5 @@
-<input type="text"
-       placeholder="Search"
-       ng-model="$ctrl.query"
-       ng-keydown="$ctrl.onInputKeyDown($event)"
-       ng-focus="$ctrl.onInputFocus()" />
+<mf-search-bar search-text="$ctrl.query"
+               ng-keydown="$ctrl.onInputKeyDown($event)"
+               ng-focus="$ctrl.onInputFocus()"
+               auto-focus></mf-search-bar>
 <ng-transclude></ng-transclude>

+ 4 - 2
src/main/angular/src/ux/auto-complete.component.scss

@@ -2,8 +2,8 @@ mf-auto-complete {
   display: block;
   position: relative;
 
-  > input {
-    box-sizing: border-box;
+  > mf-search-bar {
+    height: 100%;
     width: 100%;
     max-width: 100%;
   }
@@ -26,6 +26,7 @@ mf-auto-complete {
     z-index: 1;
 
     > li {
+      box-sizing: border-box;
       cursor: pointer;
       height: 24px;
       line-height: 24px;
@@ -33,6 +34,7 @@ mf-auto-complete {
       padding: 0 10px;
       text-overflow: ellipsis;
       white-space: nowrap;
+      width: 100%;
 
       &:hover {
         background-color: #eef2f2;

+ 3 - 8
src/main/angular/src/ux/icon-button.component.scss

@@ -1,34 +1,29 @@
 $mf-icon-button-color: #808080;
-$mf-icon-button-size: 20px;
+$mf-icon-button-size: 24px;
 $mf-icon-button-bg-color: transparent;
 
 $mf-icon-button-hover-bg-color: #f6f9f8;
-//$mf-icon-button-hover-border-color: #dae1e1;
 $mf-icon-button-hover-border-color: #0088ce;
 $mf-icon-button-hover-color: #0088ce;
 
 mf-icon-button {
   background-color: $mf-icon-button-bg-color;
   border: 1px solid transparent;
+  box-sizing: border-box;
   color: $mf-icon-button-color;
   cursor: pointer;
   display: block;
   flex: 0 0 $mf-icon-button-size;
   height: $mf-icon-button-size;
-  padding: 2px;
   width: $mf-icon-button-size;
 
-  &.fa {
-    font-size: 20px;
-  }
-
   &:hover {
     background-color: $mf-icon-button-hover-bg-color;
     border-color: $mf-icon-button-hover-border-color;
     color: $mf-icon-button-hover-color;
   }
 
-  > img {
+  > mf-icon {
     height: 100%;
     width: 100%;
   }

+ 2 - 12
src/main/angular/src/ux/icon-button.component.ts

@@ -5,16 +5,6 @@ import { Component } from '../component';
         icon: '@'
     },
     stylesheetUrl: require('ux/icon-button.component.scss'),
-    template: `<img ng-src="{{$ctrl.getIconSrc()}}" />`
+    template: `<mf-icon icon="{{$ctrl.icon}}"></mf-icon>`
 })
-export default class IconButtonComponent {
-    icon: string;
-
-    getIconSrc() {
-        if (this.icon) {
-            return `/images/icons/m_${this.icon}.svg`;
-        }
-
-        return null;
-    }
-}
+export default class IconButtonComponent {}

+ 21 - 0
src/main/angular/src/ux/icon.component.scss

@@ -0,0 +1,21 @@
+mf-icon {
+  display: inline-block;
+  font-size: 20px;
+  height: 24px;
+  position: relative;
+  vertical-align: top;
+  width: 24px;
+
+  > i {
+    color: inherit;
+    position: absolute;
+    text-align: center;
+    top: 50%;
+    transform: translateY(-50%);
+    width: 100%;
+
+    &:before {
+      color: inherit;
+    }
+  }
+}

+ 20 - 0
src/main/angular/src/ux/icon.component.ts

@@ -0,0 +1,20 @@
+import { Component } from '../component';
+
+@Component({
+    bindings: {
+        icon: '@'
+    },
+    stylesheetUrl: require('ux/icon.component.scss'),
+    template: `<i class="icon" ng-class="$ctrl.getIconClass()" />`
+})
+export default class IconComponent {
+    icon: string;
+
+    getIconClass() {
+        if (this.icon) {
+            return `icon_m_${this.icon}`;
+        }
+
+        return null;
+    }
+}

+ 1 - 1
src/main/angular/src/ux/search-bar.component.html

@@ -4,5 +4,5 @@
        title="Search Box"
        autocomplete="off" />
 <span class="placeholder" ng-hide="$ctrl.searchText">{{$ctrl.placeholder || 'Search' }}</span>
-<mf-icon-button icon="close" ng-click="$ctrl.clearSearchText()"></mf-icon-button>
+<mf-icon icon="close" ng-click="$ctrl.clearSearchText()"></mf-icon>
 <!-- loader graphic -->

+ 11 - 8
src/main/angular/src/ux/search-bar.component.scss

@@ -2,30 +2,33 @@ $mf-search-bar-height: 21px;
 
 mf-search-bar {
   display: inline-block;
+  height: $mf-search-bar-height;
   position: relative;
 
   > input {
-    height: $mf-search-bar-height;
+    height: 100%;
+    line-height: 100%;
     box-sizing: border-box;
     width: 100%;
   }
 
   > .placeholder {
     color: rgba(0, 0, 0, 0.50);
-    height: $mf-search-bar-height;
-    line-height: $mf-search-bar-height;
     left: 2px;
     position: absolute;
-    top: 0;
+    top: 50%;
+    transform: translateY(-50%);
   }
 
-  > mf-icon-button {
-    border: none;
+  > mf-icon {
+    cursor: pointer;
+    font-size: 16px;
     height: $mf-search-bar-height - 2px;
     padding: 0;
     position: absolute;
-    right: 5px;
-    top: 1px;
+    right: 1px;
+    top: 50%;
+    transform: translateY(-50%);
     width: $mf-search-bar-height - 2px;
 
     &:hover {

+ 6 - 6
src/main/angular/src/ux/table.directive.html

@@ -18,12 +18,12 @@
             <th ng-repeat="column in table.getVisibleColumns()">
                 <div class="column-header">
                     <span class="label" ng-bind="column.label" ng-click="table.sortOnColumn(column)"></span>
-                    <mf-icon-button icon="chevron-down"
-                                    ng-if="table.sortColumn === column && table.sortReverse"
-                                    ng-click="table.reverseSort()"></mf-icon-button>
-                    <mf-icon-button icon="chevron-up"
-                                    ng-if="table.sortColumn === column && !table.sortReverse"
-                                    ng-click="table.reverseSort()"></mf-icon-button>
+                    <mf-icon icon="chevron-down"
+                             ng-if="table.sortColumn === column && table.sortReverse"
+                             ng-click="table.reverseSort()"></mf-icon>
+                    <mf-icon icon="chevron-up"
+                             ng-if="table.sortColumn === column && !table.sortReverse"
+                             ng-click="table.reverseSort()"></mf-icon>
                 </div>
             </th>
         </tr>

+ 2 - 6
src/main/angular/src/ux/table.directive.scss

@@ -70,16 +70,12 @@ mf-table {
         flex-flow: row nowrap;
         vertical-align: middle;
 
-        > mf-icon-button {
+        > mf-icon {
           border: none;
+          font-size: 17px;
           height: 17px;
           padding: 0;
           width: 17px;
-
-          > img {
-            height: 100%;
-            width: 100%;
-          }
         }
 
         > .label {

+ 2 - 0
src/main/angular/src/ux/ux.module.ts

@@ -2,6 +2,7 @@ import { module } from 'angular';
 import AppBarComponent from './app-bar.component';
 import AutoCompleteComponent from './auto-complete.component';
 import IconButtonComponent from './icon-button.component';
+import IconComponent from './icon.component';
 import SearchBarComponent from './search-bar.component';
 import TableDirectiveFactory from './table.directive';
 import TableColumnDirectiveFactory from './table-column.directive';
@@ -12,6 +13,7 @@ module(moduleName, [ ])
     .component('mfAppBar', AppBarComponent)
     .component('mfAutoComplete', AutoCompleteComponent)
     .component('mfIconButton', IconButtonComponent)
+    .component('mfIcon', IconComponent)
     .component('mfSearchBar', SearchBarComponent)
     .directive('mfTable', TableDirectiveFactory)
     .directive('mfTableColumn', TableColumnDirectiveFactory);

+ 8 - 0
src/main/angular/webpack.build.js

@@ -4,5 +4,13 @@ var webpackMerge = require('webpack-merge');
 module.exports = webpackMerge(commonConfig, {
     entry: {
         'peoplesearch.ng': './src/main'
+    },
+    module: {
+        loaders: [
+            {
+                test: /icons\.json$/,
+                loaders: ['style','css', 'fontgen?fileName=fonts/[fontname]-[hash][ext]' ]
+            }
+        ]
     }
 });

+ 0 - 9
src/main/angular/webpack.common.js

@@ -1,4 +1,3 @@
-var CopyWebpackPlugin = require('copy-webpack-plugin');
 var HtmlWebpackPlugin = require('html-webpack-plugin');
 var WriteFileWebpackPlugin = require('write-file-webpack-plugin');
 var autoPrefixer = require('autoprefixer');
@@ -66,14 +65,6 @@ module.exports = {
         path: outDir
     },
     plugins: [
-        new CopyWebpackPlugin([
-            { from: 'vendor/angular-ui-router.js', to: 'vendor/' },
-            { from: 'node_modules/angular/angular.js', to: 'vendor/' },
-            { from: 'node_modules/angular-sanitize/angular-sanitize.js', to: 'vendor/' },
-            { from: 'node_modules/angular-translate/dist/angular-translate.js', to: 'vendor/' },
-            { from: 'images/', to: 'images/' }
-        ]),
-
         new HtmlWebpackPlugin({
             template: 'index.html',
             inject: 'body'

+ 20 - 1
src/main/angular/webpack.dev.js

@@ -1,8 +1,27 @@
 var commonConfig = require('./webpack.common.js');
+var CopyWebpackPlugin = require('copy-webpack-plugin');
 var webpackMerge = require('webpack-merge');
 
 module.exports = webpackMerge(commonConfig, {
     entry: {
         'peoplesearch.ng': './src/main.dev'
-    }
+    },
+    module: {
+        loaders: [
+            {
+                test: /icons\.json$/,
+                loaders: ['style','css', 'fontgen?fileName=fonts/[fontname][ext]' ]
+            }
+        ]
+    },
+    plugins: [
+        // Don't forget to add this to karma.conf.js
+        new CopyWebpackPlugin([
+            { from: 'vendor/angular-ui-router.js', to: 'vendor/' },
+            { from: 'node_modules/angular/angular.js', to: 'vendor/' },
+            { from: 'node_modules/angular-sanitize/angular-sanitize.js', to: 'vendor/' },
+            { from: 'node_modules/angular-translate/dist/angular-translate.js', to: 'vendor/' },
+            { from: 'images/avatars', to: 'images/avatars' }
+        ])
+    ]
 });