WorkShop 

Index

1. What is it?

2. Components

3. Installation

4. Application Scaffolding

5. What offers Angular Basic?

6. Let's make something awesome

7. Production phase

What it is?

Angular Basic begins from the need to create projects with the sole aim of being more productive, to solve all tasks that are not really development and guide the developer in using best practices.

Thank you Alfred

While we're saving the world, Angular Basic takes care of us

Components

The web components are fully functional and independent parts that works individually or interacts with other components.

Components: concept

<ab-navbar>

<ab-cover-image>

<ab-layout>

<ab-guide-item>

Ready?

Download

Install

Run!

git clone https://github.com/serenity-frontstack/angular-basic.git
npm install & bower install
gulp serve

App scaffolding

src

app

assets

index.html

is our application startup file. This file is generated dynamically. Our dependencies, styles, javascript and templateCache are injected on it.

Dynamic Index.html

src

app

assets

index.html

The assets folder will contain all of our global resources used in our application. Keep it organized ;)

App scaffolding

css

fonts

images

App scaffolding

src

app

assets

index.html

Application folder

components

features

filters

services

app.config.js

app.constants.js

app.environment.js

app.module.js

app.run.js

app.route.js

App scaffolding

src

app

assets

index.html

Application folder

components

features

filters

services

app.config.js

app.constants.js

app.environment.js

app.module.js

app.run.js

app.route.js

app.environment.js is a dynamic file of constants, it is generated everytime we serve or build the project depending of each arguments we give to gulp task. 

App scaffolding

src

app

assets

index.html

Application folder

components

features

filters

services

app.config.js

app.constants.js

app.environment.js

app.module.js

app.run.js

app.route.js

Everything is a component. We divide the components in two types, Components and Features. Features are the father of all his children, they normally have routing modules. On the other hand, Components folder contains all individuals components re-used on every place of your application.

App scaffolding

src

app

assets

index.html

Application folder

components

features

filters

services

assets

name.component.js

name.componet.spec.js

name.html

name.service.js

name.service.spec.js

name.css

name.route.js

prefix-componentname

What offers Angular Basic?

Preview

Build

Tests

Docs

Env Config

1. Preview

What offers Angular Basic?

  • LiveReload: every change you made on your code will be reflected on your browser.
  • Synchronized browser behaviour.
  • App version preview
    • DEV preview from Src folder
    • PRO preview from dist folder

2. Build

What offers Angular Basic?

  • gulp build --dev
  • gulp build --pro

COMPACTED

MINIFIED

COMPACTED

Used to debug code easier

Prepare for production

TEMPLATES JS

TEMPLATES JS

3. Test

What offers Angular Basic?

  • Code quality testing
  • Functional testing
  • Unit testing

ESLINT

+

3. Test

What offers Angular Basic?

  • Unit testing Coverage

Angular Basic provides configuration for build our applications with minimun coverage thresholds and requirements.

If those parameters doesn't pass our test and thresholds, the application won't be built.

4. Documentation

What offers Angular Basic?

  • API docs service
  • Angular Basic simplify the way that application components are documented.
  • The documentation process take place at development time.
  • The doc generated is interactive & useful for future evolution and maintainability.

5. Environment Config

What offers Angular Basic?

config/app.config.json

src/app/app.enviroment.js

  • API endpoints, constants, ...
  • Angular Basic allows to setup different application parameter simplifying the testing and deployment on each environment.
  • Autogenerated angular constants module 

Show me the code!

 gulp serve --dev

*Looks how index.html and app.environment.js has been generated dynamically

Let's make

something awesome!

InstaPics component

Feature component

First of all we are going to create a feature component inside the features folder. 

Step 1

features / ab-insta-pics / ab-insta-pics.component.js

(function() {
  'use strict';

  angular
    .module('app')
    .component('abInstaPics', {
      templateUrl: 'app/features/ab-insta-pics/ab-insta-pics.html',
      controller: InstaPicsController,
      controllerAs: 'vm'
    });

    /** @ngInject */
    function InstaPicsController(abInstaPictures, navbarPaths, toastr, creation) {
      var vm = this;
      vm.pageData = {
        section: 'Insta Pictures',
        pictures: abInstaPictures.getPics(),
        creationDate: creation.getDate(),
        brand: 'Angular Basic',
        paths: navbarPaths.getPaths()
      };
    }
})();

Step 1

features / ab-insta-pics / ab-insta-pics.html

<div layout="vertical">
  <md-content layout-fill>
    <header>

      <ab-navbar 
          creation-date="vm.pageData.creationDate" 
          brand="vm.pageData.brand" 
          paths="vm.pageData.paths">
      </ab-navbar>

    </header>   
    <div class="mdl-layout  mdl-js-layout background-grey">
      <main class="mdl-layout__content"> 
        <div class="mdl-grid">
          <md-card class="mdl-cell mdl-cell--4-col-desktop mdl-cell--8-col-tablet mdl-cell--4-col-phone" 
                ng-repeat="picture in vm.pageData.pictures">  
    
            <ab-picture picture="picture"></ab-picture>

          </md-card>
        </div>
      </main>
    </div>
  </md-content>
</div>

Step 1

navbar component

picture component

features / ab-insta-pics / ab-insta-pics.service.js

(function() {
  'use strict';

  angular
      .module('app')
      .service('abInstaPictures', pictures);

  /** @ngInject */
  function pictures() {
    var data = [
      {
        'url': 'https://cdn.pastemagazine.com/www/system/images/photo_albums/instagram-photographers/large/8-ig-photog-fagfrag.jpg?1384968217',
        'title': 'My beautiful semaphore',
        'like': false
      },
      {
        'url': 'http://i.amz.mshcdn.com/kl6WpszKWhL3lMM26iJBXKZNBpk=/fit-in/850x850/http%3A%2F%2Fmashable.com%2Fwp-content%2Fgallery%2Fbest-instagram-images%2F1mattrubin.jpg',
        'title': 'My beautiful car',
        'like': false
      },
      {
        'url': 'http://www.cestchristine.com/wp-content/uploads/2012/06/c8f1fe32667511e180c9123138016265_7.jpg',
        'title': 'My beautiful palm tree',
        'like': false
      },
      {
        'url': 'https://i.kinja-img.com/gawker-media/image/upload/s--aqzWMB91--/17jvp3a19o6gpjpg.jpg',
        'title': 'My beautiful rain',
        'like': false
      },
      {
        'url': 'http://media.vogue.com/r/h_480,w_480//wp-content/uploads/2015/02/13/02-karlie-kloss-taylor-swift-best-friends-bff.jpg',
        'title': 'My beautiful jump',
        'like': false
      },
      {
        'url': 'https://cdn.pastemagazine.com/www/system/images/photo_albums/instagram-photographers/large/8-ig-photog-fagfrag.jpg?1384968217',
        'title': 'My beautiful laugh',
        'like': false
      },
      {
        'url': 'http://www.wix.com/blog/wp-content/uploads/2013/05/Instagram_10_514.jpg',
        'title': 'My beautiful painting',
        'like': false
      },
      {
        'url': 'http://cdn.shutterbug.com/images/styles/600_wide/public/Shark-Week-Instagram.jpg?itok=w0rYc4f-',
        'title': 'My beautiful shark',
        'like': false
      },
      {
        'url': 'https://tid.al/blog/wp-content/uploads/2015/09/best-instagram-marketing-brands.jpg',
        'title': 'My beautiful glasses',
        'like': false
      }
    ];

    this.getPics = getPics;

    function getPics() {
      return data;
    }
  }

})();

Step 1

features / ab-insta-pics / ab-insta-pics.route.js

(function() {
  'use strict';

  angular
    .module('app')
    .config(routeConfig);

  function routeConfig($stateProvider) {    
    $stateProvider
        .state('instaPics', {
          url: '/instaPics',
          template: '<ab-insta-pics></ab-insta-pics>'
        });              
  }

})();

Step 1

features / ab-insta-pics / ab-insta-pics.css

.background-grey{
    background-color: #867892;
    background-size: cover;
}

Step 1

services / navbarPaths.service.js

Step 1

We have to add our new feature to our navbar component. To do that, we have mocked the paths of our navbar inside the navbarPaths service.

Add this lines inside the variable paths as a new element of the array:

{
    url: '#instaPics',
    name: 'InstaPics',
    icon: 'photo'
}

Component

In the next step, we are going to create a component inside the components folder.

Step 2

components / ab-picture / ab-picture.component.js

(function() {
  'use strict';

  angular
    .module('app')
    .component('abPicture', {
      templateUrl: 'app/components/ab-picture/ab-picture.html',
      controller: ABPictureController,
      controllerAs: 'vm',
      bindings:{
          picture : '<'
      }
    });

    /** @ngInject */
    function ABPictureController() {
      var vm = this;
      vm.setPictureLike = setPictureLike;
      
      function setPictureLike( picture ){
        picture.like = picture.like === true ? false : true;
      }
    }
  
})();

Step 2

components / ab-picture / ab-picture.html

<div class="image-container" ng-class='{active: vm.picture.like === true}' ng-dblclick="vm.setPictureLike( vm.picture )">
<img ng-src="{{ vm.picture.url }}" alt="{{ vm.picture.title }}" ng-dblclick="vm.setPictureLike( vm.picture )">
<div class="heart-container noselect">
    <img src="data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJMYXllcl8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCINCgkgd2lkdGg9IjEwMHB4IiBoZWlnaHQ9Ijg3LjVweCIgdmlld0JveD0iMCAwIDEwMCA4Ny41IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAgODcuNSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNTAsMTkuMUMzNy0xMS4yLDAuMi00LjEsMCwzMS4xYy0wLjEsMTkuMyw0OC44LDUyLjEsNTAuMSw1Ni40YzEuMS00LjMsNTAuMS0zNy4zLDUwLTU2LjYNCglDOTkuOC00LjQsNjIuMy0xMCw1MCwxOS4xeiIvPg0KPC9zdmc+DQo=" alt="heart" id="js-heart-image"/>
  </div>
</div>
<md-card-footer>
  <label class="insta-pic-label">{{vm.picture.title}}</label>
  <md-button class="right md-icon-button" aria-label="Favorite" ng-click='vm.setPictureLike( vm.picture )'>
      <i class="material-icons md-48"  ng-class='{active: vm.picture.like === true}'>favorite</i>
  </md-button>
</md-card-footer>

Step 2

components / ab-picture / ab-picture.css

.insta-pic-label{
    position: relative;
    top: 10px;
}

.image-container {
  position: relative;
  overflow: hidden;
  
}
.image-container:focus{
    outline-color: transparent;
}
.image-container > img {
  display: block;
  max-width: 100%;
}

.image-container .heart-container {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 50%;
  left: 50%;
  margin: -50% 0 0 -50%;
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
}

.noselect {
  -webkit-touch-callout: none; /* iOS Safari */
  -webkit-user-select: none;   /* Chrome/Safari/Opera */
  -khtml-user-select: none;    /* Konqueror */
  -moz-user-select: none;      /* Firefox */
  -ms-user-select: none;       /* Internet Explorer/Edge */
  user-select: none;           /* Non-prefixed version, currently
                                  not supported by any browser */
}

.image-container .heart-container:before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
}

.image-container .heart-container > img {
  display: inline-block;
  width: 100px;
  height: 88px;
  opacity: 0;
  vertical-align: middle;
  -webkit-transition: all .5s ease-in;
  transition: all .5s ease-in;
}

.image-container.active .heart-container > img {
  opacity: 1;
}

Step 2

Done!

To Production?

Test?    Build?    Docs?

Test

gulp serve
gulp test
gulp protractor

ESLINT

Build

gulp build

Docs

gulp serve:apidoc

Questions

Links

by

Workshop Angular Basic

By Serenity FrontStack

Workshop Angular Basic

  • 774