Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rapidly Build Enterprise Apps in Angular 2 with Covalent

Rapidly Build Enterprise Apps in Angular 2 with Covalent

created for the Austin AngularJS Meetup, this deck walks through what Covalent is, why we made it and how to rapidly build an app staring with our Angular 2.0 Material Design quickstart

Kyle Ledbetter

October 10, 2016
Tweet

More Decks by Kyle Ledbetter

Other Decks in Technology

Transcript

  1. WHO AM I Kyle Ledbetter UX Director Built UI platforms

    and products for Joomla, eBay, Sears and now Teradata. @kyleledbetter Key Experience Handle
  2. MISSION UI PLATFORM MISSION To build an atomic, standardized, reusable

    UI component platform for Teradata to use for all user interfaces, while collaborating in an open source model.
  3. (Plus you have to manufacture the pole) A bus factor

    of 1 As many as we can teach (Advanced poles are provided for us) (Constantly getting improvements) WHY DO WE WANT A PLATFORM?
  4. WHY MATERIAL DESIGN (and Angular-Material)? BOTTOM LINE: UNIVERSAL DESIGN SPEC

    COMPLETE CODE FRAMEWORK (that we get for “free”) GLOBAL DEV ADOPTION GLOBAL FAMILIARITY FANTASTIC ACCESSIBILITY EXTREMELY AGILE CYCLES WE FOCUS ON PRODUCT FEATURES & EASE OF USE IS OUR BRAND
  5. WHY ANGULAR 2.0? MODERN APP DEVELOPMENT BACKEND CODE CONCEPTS COMMAND

    LINE TOOLS & TESTING CONTRIBUTE TO OPEN SOURCE NATIVE MOBILE & DESKTOP ATTRACT NEW HIRES BOTTOM LINE: WE BECOME MORE PRODUCTIVE AND BECOME INDUSTRY LEADERS
  6. WHY DO THIS AT ALL? IT’S A LOT OF WORK

    & COORDINATION cross-team sharing of components, standards & personnel
  7. WHAT IF WE DON’T? IT’S EASY TO STAY IN A

    SILO because of learning curves & deadlines Bootstrap LESS jQuery Java Covalent SCSS Angular 2.0 Foundation SASS Angular 1.5
  8. What & Why? Material Design Spec + + Angular 2.0

    Platform Angular-Material 2 Framework
  9. OUR APPROACH IS BASED ON ATOMIC DESIGN LOGO LOGO ATOMS

    button MOLECULES search ORGANISMS header TEMPLATES dashboard PAGES your product our UI library is comprised of the molecular (or Covalent) bonds that we build on top of the atoms provided by Angular-Material WHY THE NAME COVALENT?
  10. WE INCLUDE THINGS EVERYONE NEEDS INCLUDED IN COVALENT PHASE 1

    (released) PHASE 2 (Oct 14) PHASE 3 Quickstart App Data Tables Covalent App Templates Style & Brand Guide 4 Layouts + Flexbox Grid Dynamic JSON Forms Page Transition Animation Design Patterns (Cards, etc) Stepper (Wizard) D3 (v4) Charts Desktop Hybrid Apps 750+ Font Ligature Icons Expansion Panels CSS Material Color Palette Syntax Highlighting Detailed Documentation Component Loaders Angular 2 Best Practices File Upload Button/Input Github Deployment Custom Pipes (Filters) Mock API Server Mobile Hybrid Apps Sketch/Axure Templates ANGULAR-MATERIAL 2.0 Angular 2.0 Angular CLI TypeScript + ES6 Protractor + Karma a11y Native Desktop + Mobile
  11. COVALENT DOES ALL THE BUSY WORK SO YOU CAN START

    BUILDING YOUR APP COVALENT VALUE
  12. EcmaScript 6 (ES6 or ES2015) class Hamburger { constructor() {

    // This is the constructor. } listToppings() { // This is a method. } } // Return a promise which resolves after the specified interval function delay(interval) { return new Promise(function(resolve) { setTimeout(resolve, interval); }); } var oneSecondDelay = delay(1000); import { Component } from '@angular/core'; export class Angular2Component { } setTimeout(() => { // This prints "Max" since arrow functions bind to our current "this" context. console.log(this.name); }); var name = 'Sam'; var age = 42; console.log(`hello my name is ${name}, and I am ${age} years old`); for(let i in thing) { // i is available } // i is NOT available Classes Promises Modules Arrow Functions Template Strings Variables object-oriented programming for asynchronous computations allows @import & @export for anonymous functions string literal with backticks let instead of var let instead of var used to describe the blueprint of an object a value which may be available now, or in the future, or never easily export an isolated module and import into another new arrow notation can be used to define anonymous functions more simply can include newlines, and there is a new mechanism for inserting variables avoid variables leaking into the rest of the function
  13. TYPESCRIPT TypeScript is a superset of ES6 all ES6 features

    are part of TypeScript, but not all TypeScript features are part of ES6 define the type in your javascript can be used to represent any non-primitive JavaScript object functions that are invoked with a prefixed @ symbol linting for TypeScript Typings Interfaces Decorators TSLint
  14. ANGULAR 2.0 Angular 2.0 not the Angular of yesterday encapsulated

    views, patterns and elements attach behavior to components via attributes data modifiers connect UI to API and more Components Directives Pipes Services
  15. COVALENT USAGE ACROSS TERADATA Platform Team Supports Platform Lighthouse UIs

    1st “Customers” Consume & Extend Consume & Extend UX UDA Lighthouse UDA Products Customer Solutions Teradata Corp AppCenter, Listener, WLA Viewpoint, Ecosystem, QueryGrid Customer Facing Teams Analytical Solutions Professional Services Support & Services Customer Support Other Product Teams TD Management Console Teradata Studio Teradata Analytics Teradata Unity Information Technology
  16. OPEN SOURCE CONTRIBUTION MODEL COVALENT REPO OPEN SOURCE CONSUMERS OPEN

    SOURCE CONTRIBUTORS REPORT BUGS & REQUEST FEATURES EXTEND WITH NEW COMPONENTS PULL REQUEST CONTRIBUTIONS Public Collaborators open source contributors Bug reports, feature requests, and pull requests from outside contributors internal product teams Internal Teradata product teams extending Covalent for everyone.
  17. APPROVAL PROCESS for new feature requests FEATURE REQUESTS either directly

    in spec or by spirit can most products use it or just yours? more votes moves it up the queue even if it’s not perfect, PRs fasttrack features Does it follow Material Design? Is it platform worthy? Prioritized by likes Can your team open a PR?
  18. MATERIAL DESIGN LAYOUTS 4 MATERIAL DESIGN LAYOUTS Responsive, simple to

    implement type=“nav-view” type=“nav-list” type=“card-over” type=“manage-list”
  19. RESPONSIVE FLEXBOX LAYOUT Virtually any width or position (Ported from

    Angular-Material v1.x) layout=“row” layout=“column” flex flex
  20. COVALENT DATA FOR RAPID PROTOTYPING LOCAL GO API SERVER *IN

    APP* custom mock data + CRUD! npm run start api
  21. STEPPER WIZARD-LIKE MULTIPLE STEPS great for complex forms <td-step #step

    label="Label" sublabel="Sublabel" [active]="active" [disabled] ="disabled" [state]="state" (activated)="activeE vent()" (deactivated)="deactiveEvent()"> <template td-step-content> ... add content that will be shown when the step is "active" </template> <template td-step-actions> <button (click)="step.close()">Close</ button> </template> <template td-step-summary> ... add summary that will be shown when step in is "complete" state (optional) </template> </td-step>
  22. EXPANSION PANELS ACCORDIONS ON STEROIDS used invidually or grouped <td-expansion-panel

    label="Google" sublabel="1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA"> <td-expansion-summary> <md-list> <md-list-item> <md-icon md-list-avatar>pin_drop</md- icon> <h3 md-line>Google</h3> <h4 md-line>Headquarters</h4> <p md-line> 1600 Amphitheatre Pkwy<br/>Mountain View, CA 94043, USA </p> </md-list-item> </md-list> </td-expansion-summary> <form class="md-padding"> ... </form> </td-expansion-panel>
  23. FILE UPLOAD SIMPLE FILE UPLOAD BUTTON click or drag’n’drop single

    or multiple files <td-file-upload defaultColor="accent" activeColor="warn" cancelColor="primary" (upload)="uploadEvent($event)" accept=".ext,.anotherExt" [disabled]="disabled" multiple> </td-file-upload>
  24. CHIPS & AUTOCOMPLETE TAG-LIKE CHIPS OR AUTOCOMPLETE FORM until they

    are released in material2 <td-chips placeholder="Enter string" [items]="items" [(ngModel)]="model" [readOnly]="readOnly" (add)="add($event)" (remove)="remove($event)" requireMatch> </td-chips>
  25. LOADING MASK & PROGRESS PROGRESS LOADERS WITH MASKS progress bars

    or circular loaders <template tdLoading="stringName" loadingType="circular" loadingMode="circular"> <div> ... </div> </template> <template tdLoading="stringName" loadingType="linear" loadingMode="linear"> <div> ... </div> </template>
  26. SYNTAX HIGHLIGHTING CODE SNIPPET HIGHLIGHTING using highlight.js <td-highlight lang="html"> <h1>hello

    world!</h1> <span>{{property}}</span> </td-highlight> <td-highlight lang="scss"> pre { display: block; overflow-x: auto; padding: 0; margin: 0; background: #002451; ... } </td-highlight>
  27. JSON OBJECT TREE COLLAPSIBLE JSON TREE to display nested key:value

    pairs <td-json-formatter [data]="object" [levelsOpen]="1"> </td-json-formatter> ... }) export class Demo { object: any = { property: 'value', array: [1, 2, 3] }; }
  28. MARKDOWN MARKDOWN IN ANGULAR 2 for docs or blogs <td-markdown>

    <pre><code> # Heading (H1) ## Sub Heading (H2) ### Steps (H3) ###List Items * One * Two * Three Emphasis, aka italics, with *asterisks* or _underscores_. Strong emphasis, aka bold, with **asterisks** or __underscores__. Combined emphasis with **asterisks and _underscores_**. </code></pre> </td-markdown>
  29. MEDIA QUERIES MEDIA QUERIES FOR NG ATTRIBUTES add/remove attributes on

    the DOM for breakpoints <div tdMediaToggle=“gt-xs" [mediaClasses]="['classOne', 'classTwo']" [mediaAttributes]="{title: 'tooltip'}" [mediaStyles]="{color: 'red'}"> ... </div>
  30. HTTP WRAPPERS EASIER INTERCEPTOR EXPERIENCE wraps ng2 Http service import

    { Injectable } from '@angular/core'; import { IHttpInterceptor } from '@covalent/http'; @Injectable() export class CustomInterceptor implements IHttpInterceptor { onRequest(requestOptions: RequestOptionsArgs): RequestOptionsArgs { ... // do something to requestOptions return requestOptions; } onResponse(response: Response): Response { ... // check response status and do something return response; } onResponseError(error: Response): Response { ... // check error status and do something return error; } }
  31. PIPES DISPLAY DATA MORE INTELLIGENTLY digits, filesize, time ago, truncate

    & more {{ item.users | digits }} {{ item.filesize | bytes }} {{ item.timestamp | timeAgo }} {{ item.timestamp | timeDifference }} {{ item.title | truncate:50 }}
  32. SIMPLE DIALOGS SIMPLE DIALOG TEMPLATES easier than the core material2

    dialogs export class Demo { constructor(private _dialogService: TdDialogService, private _viewContainerRef: ViewContainerRef) { this._dialogService.setDefaultViewContainerRe f(_viewContainerRef); } openAlert(): void { this._dialogService.openAlert({ message: 'Alert using a default ViewContainerRef.', }); } }
  33. COMING SOON: D3 CHARTS COMPONENT D3 v4 CHARTS IN ANGULAR

    2.0 COMPONENTS with Material Design colors, depth & transitions <td-charts chartTitle="Sales Bar Chart" bottomAxisTitle="Day Offset" leftAxisTitle="Sales" [grid]="true" [ticks]="true" [shadowDepth]="['125%', 2, 0, 2]" shadowColor="rgba(0, 0, 0, 0.54)" fillOpacity="1"> <td-chart-bar [colors]="['cyan', 'indigo']" dataSrc="chart-data/data.csv" bottomAxis="salesperson" columns="sales" [transition]="true" transitionDuration="750" transitionDelay="50"> </td-chart-bar> </td-charts>
  34. COMING SOON: DATATABLES COMPONENT MATERIAL DESIGN DATA TABLES IN ANGULAR

    2 search, sort, select & more <td-data-table [data]="data" [columns]="columns" [multiple]="multiple" [rowSelection]="rowSelection" [sortBy]="sortBy" [sortOrder]="sortOrder" search="true" title="Search and pagination enabled" pageSize="5" (sortChanged)="sortChanged($event)"> </td-data-table>
  35. LEARN THE OFFICIAL SPEC LEARN MATERIAL DESIGN INSIDE & OUT

    it’s not just a skin or a coat of paint
  36. CLONE THE QUICKSTART & INSTALL https://teradata.github.io/covalent/#/docs > git clone https://github.com/Teradata/covalent-quickstart.git

    meetup > cd meetup clone the repo and enter the directory > npm i installs the node dependencies > ng serve ** NG Live Development Server is running on http://localhost:4200. ** Child html-webpack-plugin for "index.html": Asset Size Chunks Chunk Names index.html 2.81 kB 0 webpack: bundle is now VALID.
  37. CUSTOMIZE MOCK API WITH COVALENT DATA https://teradata.github.io/covalent/#/docs/mock-data mock-api/ schemas/ items.yaml

    mock-api/ datum/ colors.text initial_entries: 4 randomize: false item_id: _uuid_ color: _color_ name: _firstname_ _lastname_ description: _activity_ icon: _icon_ created: _itemtimestamp_ red pink purple deep-purple indigo blue light-blue cyan
  38. RUN COVALENT DATA API SERVER > npm run start-api INFO[0000]

    ################################################################## INFO[0000] ######## ######## INFO[0000] ######## Teradata Covalent Atomic Data mock API server ######## INFO[0000] ######## Copyright 2016 by Teradata. All rights reserved. ######## INFO[0000] ######## This software is covered under the MIT license. ######## INFO[0000] ######## ######## INFO[0000] ################################################################## (in a new Terminal tab)
  39. COVALENT TO THE RESCUE (ALREADY) USE A COVALENT TRUNCATE PIPE

    Change To to fix the material2 list item overflow <p md-line> {{item.description}} </p> <p md-line> {{item.description | truncate:20 }} </p>
  40. CUSTOMIZE THE ANGULAR-MATERIAL THEME CHANGE 3 SIMPLE COLORS & HUES

    following the material color spec src/ app/ styles.scss theme.scss @import '~@angular/material/core/theming/all-theme'; // Include the base styles for Angular Material core @include md-core(); // Define the palettes for your theme using the Material Design palettes $primary: md-palette($md-red, 600); $accent: md-palette($md-teal, A700); $warn: md-palette($md-orange, 800); // Create the theme object (a Sass map containing all of the palettes). $theme: md-light-theme($primary, $accent, $warn); // Include theme styles for core and each component used in your app. @include angular-material-theme($theme);
  41. CUSTOMIZE THE LOGO & TITLE CHANGE SIDENAV LOGO & TITLE

    using your custom image & text src/ app/ main/ main.component.html <td-layout #layout logo="assets/icons/meetup.svg" title="Austin AngularJS" displayName="Firstname Lastname" (logout)="logout()"> <md-nav-list menu-items> <template let-item let-last="last" ngFor [ngForOf]="routes"> <a md-list-item [routerLink]="[item.route]" (click)="layout.close()"><md- icon>{{item.icon}}</md-icon>{{item.title}}</a> </template> </md-nav-list> <router-outlet></router-outlet> </td-layout>
  42. CUSTOMIZE THE LOGO & TITLE CHANGE TOP TOOLBAR LOGO &

    TITLE using your custom image & text src/ app/ dashboard/ dashboard.componen <td-layout-nav logo="assets/icons/meetup.svg"> <div toolbar-content layout="row" layout-align="center center" flex> <span>Austin AngularJS</span> <span flex></span> <a md-icon-button md-tooltip="Docs" href="https:// teradata.github.io/covalent/" target="_blank"><md- icon>chrome_reader_mode</md-icon></a> <a md-icon-button md-tooltip="Github" href="https://github.com/ teradata/covalent" target="_blank"><md-icon svgSrc="assets/icons/ github.svg"></md-icon></a> </div> ...
  43. CUSTOMIZE THE TOOLBAR ICONS src/ app/ dashboard/ dashboard.componen <td-layout-nav logo="assets/icons/meetup.svg">

    <div toolbar-content layout="row" layout-align="center center" flex> <span>Austin AngularJS</span> <span flex></span> <a md-icon-button md-tooltip="Add Meetup"><md-icon>add</md-icon></a> <a md-icon-button md-tooltip="Notifications"><md-icon>notifications</md-icon></a> <a md-icon-button md-tooltip="Profile"><md-icon>person</md-icon></a> </div> ...
  44. LET’S START DESIGNING IN CODE! <div layout="row" layout-wrap> <div flex-xs="50"

    flex-gt-xs="25"> <md-card> <md-card-content class="text-center"> <div class="md-headline">{{ '1639'| digits }} <md-icon>group</md-icon></div> <div class="md-subhead">Members</div> </md-card-content> </md-card> </div> <div flex-xs="50" flex-gt-xs="25"> <md-card> <md-card-content class="text-center"> <div class="md-headline">{{ '14'| digits }} <md-icon>chat</md-icon></div> <div class="md-subhead">Group Reviews</div> </md-card-content> </md-card> </div> <div flex-xs="50" flex-gt-xs="25"> <md-card> <md-card-content class="text-center"> Flexbox layout, Material typography & icons, Covalent classes
  45. FLEXBOX LAYOUT <div layout="column" layout-gt-xs="row"> <div flex-gt-xs="60"> </div> <div flex-gt-xs="40">

    </div> </div> layout=“column” layout-gt-xs=“row” flex-gt-xs=“60” flex-gt-xs=“40” 60/40 layout only wider than extra-small
  46. TABS, TEMPLATES, LISTS, OH MY! <md-tab-group> <md-tab> <template md-tab-label>Upcoming</template> <template

    md-tab-content> <md-nav-list class="will-load"> <template tdLoading="items.load"> <template let-item let-last="last" ngFor [ngForOf]="items"> <a md-list-item [routerLink]="['../item', item.item_id]"> <span md-list-avatar md-tooltip="Going" class="bgc-teal-A700 tc-teal-50" layout="column" layout-align="center center"> {{item.attendees}} </span> <h3 md-line> {{item.title}} </h3> <h4 md-line> {{item.description | truncate:50}} </h4> <p md-line> {{item.address}} </p> <span flex></span> <span class="md-caption text-right" flex="20"> <div> {{item.date | date }} </div> <div class="tc-grey-500"> 6:00 PM </div> </span> </a> <md-divider *ngIf="!last" md-inset></md-divider> </template> </template>
  47. USER LIST FROM USER SERVICE <md-card> <md-card-title>Members</md-card-title> <md-card-subtitle>members of this

    Meetup</md-card-subtitle> <md-divider></md-divider> <md-list class="will-load"> <template tdLoading="users.load"> <template let-item let-last="last" ngFor [ngForOf]="users"> <md-list-item layout-align="row"> <md-icon md-list-avatar>account_circle</md-icon> <h3 md-line> {{item.display_name}} </h3> <h4 md-line> {{item.email}} </h4> <p md-line> Joined: {{item.created}} </p> </md-list-item> <md-divider *ngIf="!last" md-inset></md-divider> </template> </template> </md-list> <md-divider></md-divider> <md-card-actions> <a md-button color="accent" class="text-upper" [routerLink]="['/users']"> <span>View More</span> </a>
  48. UPDATE MAIN COMPONENT CLASS src/ app/ main/ main.component.ts routes: Object[]

    = [{ title: 'Home', route: '/', icon: 'home', }, { title: 'Members', route: '/members', icon: 'people', }, { title: 'Sponsors', route: '/sponsors', icon: 'business', }, { title: 'Photos', route: '/photos', icon: 'collections', }, { title: 'Pages', route: '/pages', icon: 'description', }, { title: 'Discussions',
  49. UPDATE ANGULAR ROUTES src/ app/ app.routes.ts const routes: Routes =

    [ {path: 'login', component: LoginComponent}, {path: '', component: MainComponent, children: [{ component: DashboardComponent, path: '', }, {path: 'dashboard-product', component: DashboardProductComponent}, {path: 'item/:id', component: DetailComponent}, {path: 'logs', component: LogsComponent}, {path: 'form', component: FormComponent}, {path: ‘members’, children: [ {path: '', component: UsersComponent}, {path: 'add', component: UsersFormComponent}, {path: ':id/delete', component: UsersFormComponent}, {path: ':id/edit', component: UsersFormComponent}, ]}, ]}, ];
  50. UPDATE DETAIL COMPONENT CLASS src/ detail/ detail.component.ts import { ItemsService,

    UsersService } from '../../services'; export class DetailComponent implements OnInit { item: Object = {}; users: Object[]; constructor(private _router: Router, private _itemsService: ItemsService, private _usersService: UsersService, private _route: ActivatedRoute, private _location: Location) {} goBack(): void { this._location.back(); } ngOnInit(): void { this._usersService.query().subscribe((users: Object[]) => { this.users = users; }); this._route.params.subscribe((params: {id: string}) => { let itemId: string = params.id;
  51. NOW WE HAVE THE MEETUP INFO & USERS MINIMAL UPDATES

    TO CUSTOMIZE toolbar, item info & users
  52. ADDING EXPANSION PANELS src/ detail/ detail.component.html <td-expansion-panel label="Meetup info" sublabel="open

    for detailed info"> /* summary content in td-expansion-summary */ <td-expansion-summary> <div class="md-padding"> Organzied by {{item.name}} at 6:00 PM on {{item.date | date}} </div> </td-expansion-summary> /* insert any content you want here for the expansion */ <md-list> .... </md-list> </td-expansion-panel>