├── .gitignore ├── LICENSE.txt ├── README.md ├── app ├── actions │ ├── cart-actions.ts │ ├── film-actions.ts │ ├── part-actions.ts │ └── user-actions.ts ├── app.component.ts ├── app.module.ts ├── components │ ├── admin-component.ts │ ├── films-component.ts │ └── shopping-component.ts ├── main.ts ├── reducers │ ├── app-reducer.ts │ ├── cart-reducer.ts │ ├── films-reducer.ts │ ├── part-reducer.ts │ ├── parts-reducer.ts │ └── users-reducer.ts ├── services │ ├── film.service.ts │ └── user.service.ts └── views │ ├── admin │ ├── user-view.ts │ └── users-view.ts │ ├── catalog │ ├── add-part-view.ts │ ├── cart-view.ts │ └── parts-view.ts │ └── film │ ├── film-selection-view.ts │ └── film-view.ts ├── config.js ├── gulpfile.js ├── images ├── Angular2WithRedux.gif └── Angular2WithRedux.png ├── index.html ├── package.json ├── tasks ├── dist.js └── typings.js ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | jspm_packages 4 | node_modules 5 | typings 6 | typings.json 7 | 8 | npm-debug.log 9 | 10 | *.iml 11 | .idea/ 12 | .idea_modules/ 13 | 14 | app/**/*.js 15 | app/**/*.js.map 16 | 17 | test/**/*.js 18 | test/**/*.js.map 19 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 InfomediaLtd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular2 Redux Example 2 | 3 | Example project for using pure Redux with Angular 2 and TypeScript. This project also uses the [angular2-redux](https://github.com/InfomediaLtd/angular2-redux) helper utility library. 4 | 5 | Demo: [http://angular2-redux-example.surge.sh](http://angular2-redux-example.surge.sh/) 6 | ![](https://raw.githubusercontent.com/InfomediaLtd/angular2-redux-example/master/images/Angular2WithRedux.gif) 7 | 8 | To set up locally, install with [jspm](http://jspm.io/): 9 | ```sh 10 | jspm install 11 | ``` 12 | 13 | Run with [live-server](https://www.npmjs.com/package/live-server): 14 | ```sh 15 | live-server 16 | ``` 17 | -------------------------------------------------------------------------------- /app/actions/cart-actions.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@angular/core"; 2 | import {Actions,AppStore} from "angular2-redux"; 3 | 4 | export enum CartActionTypes { 5 | ADD_TO_CART = "ADD_TO_CART" as any, 6 | REMOVE_FROM_CART = "REMOVE_FROM_CART" as any 7 | }; 8 | 9 | export interface CartAction { 10 | type:string; 11 | id?:string; 12 | } 13 | 14 | @Injectable() 15 | export class CartActions extends Actions { 16 | 17 | constructor(appStore:AppStore) { 18 | super(appStore); 19 | } 20 | 21 | addToCart(id) { 22 | return {type: CartActionTypes.ADD_TO_CART, id}; 23 | }; 24 | 25 | removeFromCart(id) { 26 | return {type: CartActionTypes.REMOVE_FROM_CART, id}; 27 | }; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/actions/film-actions.ts: -------------------------------------------------------------------------------- 1 | import {Http} from "@angular/http"; 2 | import {Injectable} from "@angular/core"; 3 | import {Actions,AppStore} from "angular2-redux"; 4 | import {FilmService} from "../services/film.service"; 5 | import 'rxjs/add/operator/map'; 6 | 7 | export enum FilmActionTypes { 8 | REQUEST_FILMS = "REQUEST_FILMS" as any, 9 | RECEIVE_FILMS = "RECEIVE_FILMS" as any, 10 | REQUEST_FILM = "REQUEST_FILM" as any, 11 | RECEIVE_FILM = "RECEIVE_FILM" as any, 12 | RECEIVE_NUMBER_OF_FILMS = "RECEIVE_NUMBER_OF_FILMS" as any, 13 | CURRENT_FILM = "CURRENT_FILM" as any 14 | }; 15 | 16 | export interface FilmAction { 17 | type:string; 18 | count?; 19 | films?; 20 | film?; 21 | currentIndex?; 22 | } 23 | 24 | @Injectable() 25 | export class FilmActions extends Actions { 26 | 27 | constructor(private filmService:FilmService, appStore:AppStore) { 28 | super(appStore); 29 | } 30 | 31 | fetchFilms() { 32 | return (dispatch) => { 33 | dispatch(this.requestFilms()); 34 | 35 | this.filmService.get() 36 | .map(json => { 37 | dispatch(this.receiveFilms(json.results)); 38 | dispatch(this.receiveNumberOfFilms(json.count)); 39 | }) 40 | .subscribe(); 41 | }; 42 | } 43 | 44 | fetchFilm(index) { 45 | return (dispatch) => { 46 | dispatch(this.requestFilm()); 47 | 48 | this._http.get(`${BASE_URL}${index + 1}/`) 49 | .map(result => result.json()) 50 | .map(json => { 51 | dispatch(this.receiveFilm(json)); 52 | }) 53 | .subscribe(); 54 | }; 55 | } 56 | 57 | requestFilms() { 58 | return {type: FilmActionTypes.REQUEST_FILMS}; 59 | } 60 | 61 | receiveFilms(films) { 62 | return { 63 | type: FilmActionTypes.RECEIVE_FILMS, 64 | films 65 | } 66 | } 67 | 68 | receiveNumberOfFilms(count) { 69 | return { 70 | type: FilmActionTypes.RECEIVE_NUMBER_OF_FILMS, 71 | count 72 | } 73 | } 74 | 75 | requestFilm() { 76 | return {type: FilmActionTypes.REQUEST_FILM}; 77 | } 78 | 79 | receiveFilm(film) { 80 | return { 81 | type: FilmActionTypes.RECEIVE_FILM, 82 | film 83 | } 84 | } 85 | 86 | setCurrentFilm(currentIndex) { 87 | return { 88 | type: FilmActionTypes.CURRENT_FILM, 89 | currentIndex 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /app/actions/part-actions.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@angular/core"; 2 | import {Actions,AppStore} from "angular2-redux"; 3 | 4 | export const ADD_PART = 'ADD_PART'; 5 | 6 | export enum PartActionTypes { 7 | ADD_PART = "ADD_PART" as any 8 | }; 9 | 10 | export interface PartAction { 11 | type:String; 12 | id?:number; 13 | name?:string; 14 | } 15 | 16 | @Injectable() 17 | export class PartActions extends Actions { 18 | private id:number = 11; 19 | 20 | constructor(appStore:AppStore) { 21 | super(appStore); 22 | } 23 | 24 | addPart(name) { 25 | return {type: PartActionTypes.ADD_PART, id: ++this.id, name}; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/actions/user-actions.ts: -------------------------------------------------------------------------------- 1 | import {Http} from "@angular/http"; 2 | import {Injectable} from "@angular/core"; 3 | import {Actions,AppStore} from "angular2-redux"; 4 | import {UserService} from "../services/user.service"; 5 | import 'rxjs/add/operator/map'; 6 | 7 | export enum UserActionTypes { 8 | REQUEST_USERS = "REQUEST_USERS" as any, 9 | RECEIVE_USERS = "RECEIVE_USERS" as any, 10 | CURRENT_USER = "CURRENT_USER" as any, 11 | SET_FILM_FILTER = "SET_FILM_FILTER" as any 12 | }; 13 | 14 | export interface UserAction { 15 | type:string; 16 | users?; 17 | updated?:Date; 18 | current?; 19 | filmFilter?:string; 20 | } 21 | 22 | @Injectable() 23 | export class UserActions extends Actions { 24 | 25 | constructor(private userService:UserService, appStore:AppStore) { 26 | super(appStore); 27 | } 28 | 29 | fetchUsers() { 30 | return (dispatch) => { 31 | dispatch(this.requestUsers()); 32 | this.userService.get() 33 | .map(result => dispatch(this.receiveUsers(result))) 34 | .subscribe(); 35 | }; 36 | } 37 | 38 | requestUsers() { 39 | return {type: UserActionTypes.REQUEST_USERS}; 40 | } 41 | 42 | receiveUsers(users) { 43 | return { 44 | type: UserActionTypes.RECEIVE_USERS, 45 | users, 46 | updated: Date.now() 47 | } 48 | } 49 | 50 | setCurrentUser(current) { 51 | return { 52 | type: UserActionTypes.CURRENT_USER, 53 | current 54 | } 55 | } 56 | 57 | setFilmFilter(filmFilter) { 58 | return { 59 | type: UserActionTypes.SET_FILM_FILTER, 60 | filmFilter: filmFilter 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core' 2 | import {AppStore} from "angular2-redux"; 3 | 4 | @Component({ 5 | selector: 'my-app', 6 | template: ` 7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 | 15 |
16 |
17 | ` 18 | }) 19 | export class AppComponent { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/app.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core' 2 | import {BrowserModule} from '@angular/platform-browser' 3 | import {HttpModule} from "@angular/http" 4 | import {RouterModule} from '@angular/router' 5 | import {MaterialModule} from '@angular/material' 6 | import {FormsModule} from '@angular/forms' 7 | import {MaterialModule} from '@angular/material' 8 | 9 | import {AppComponent} from './app.component' 10 | 11 | import {AdminComponent} from "./components/admin-component"; 12 | import {ShoppingComponent} from "./components/shopping-component"; 13 | import {FilmsComponent} from "./components/films-component"; 14 | import {UsersView} from "./views/admin/users-view"; 15 | import {UserView} from "./views/admin/user-view"; 16 | import {FilmSelectionView} from "./views/film/film-selection-view"; 17 | import {FilmView} from "./views/film/film-view"; 18 | import {PartsView} from "./views/catalog/parts-view"; 19 | import {CartView} from "./views/catalog/cart-view"; 20 | import {AddPartsView} from "./views/catalog/add-part-view"; 21 | import {SimpleList} from 'angular2-simple-list'; 22 | 23 | import {UserService} from "./services/user.service"; 24 | import {FilmService} from "./services/film.service"; 25 | 26 | import {AppStore,createAppStoreFactoryWithOptions} from "angular2-redux"; 27 | import reducers from "./reducers/app-reducer" 28 | import {PartActions} from "./actions/part-actions"; 29 | import {CartActions} from "./actions/cart-actions"; 30 | import {UserActions} from "./actions/user-actions"; 31 | import {FilmActions} from "./actions/film-actions"; 32 | 33 | const appStoreFactory = createAppStoreFactoryWithOptions({ 34 | reducers, 35 | debug:true 36 | }); 37 | @NgModule({ 38 | imports: [ 39 | BrowserModule, 40 | HttpModule, 41 | FormsModule, 42 | MaterialModule.forRoot(), 43 | RouterModule 44 | ], 45 | declarations: [AppComponent,ShoppingComponent, AdminComponent, FilmsComponent, UsersView, UserView, FilmSelectionView, FilmView, PartsView, CartView, AddPartsView, SimpleList], 46 | providers: [UserService, FilmService, PartActions, CartActions, UserActions, FilmActions, { provide: AppStore, useFactory: appStoreFactory }], 47 | bootstrap: [AppComponent] 48 | }) 49 | export class AppModule { 50 | 51 | } 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /app/components/admin-component.ts: -------------------------------------------------------------------------------- 1 | import {Component,OnDestroy} from '@angular/core' 2 | import {AppStore} from "angular2-redux"; 3 | import {UserActions} from "../actions/user-actions"; 4 | import {createSelector} from 'reselect'; 5 | import {usersListSelector,currentUserSelector,filterSelector} from "../reducers/users-reducer"; 6 | import {currentFilmSelector} from "../reducers/films-reducer"; 7 | import {Subscription} from "rxjs"; 8 | 9 | @Component({ 10 | selector: 'admin', 11 | template: ` 12 |

Users

13 | Turn filter {{filmFilter?"off":"on"}} 14 | 15 |
16 |

Current User

17 |
18 | 19 | ` 20 | }) 21 | export class AdminComponent implements OnDestroy { 22 | 23 | private currentUser$ = null; 24 | 25 | private usersToShow = null; 26 | private filmFilter = null; 27 | 28 | private setCurrentUser; 29 | private setFilmFilter; 30 | 31 | private usersSubscription:Subscription; 32 | private filmFilterSubscription:Subscription; 33 | //private unsubscribeFromStore:()=>void; 34 | 35 | constructor(appStore:AppStore, userActions:UserActions) { 36 | 37 | this.setCurrentUser = userActions.createDispatcher(userActions.setCurrentUser); 38 | this.setFilmFilter = userActions.createDispatcher(userActions.setFilmFilter); 39 | 40 | const usersToShowSelector = AdminComponent.createUsersToShowSelector(); 41 | 42 | this.currentUser$ = appStore.select(currentUserSelector); 43 | 44 | this.usersSubscription = appStore.select(usersToShowSelector).subscribe(usersToShow => { 45 | this.usersToShow = usersToShow; 46 | }); 47 | this.filmFilterSubscription = appStore.select(state=>state.users.filmFilter).subscribe(filmFilter => { 48 | this.filmFilter = filmFilter; 49 | }) 50 | /*this.unsubscribeFromStore = appStore.subscribe((state) => { 51 | this.usersToShow = usersToShowSelector(state); 52 | this.filmFilter = state.users.filmFilter; 53 | });*/ 54 | 55 | appStore.dispatch(userActions.fetchUsers()); 56 | 57 | } 58 | 59 | private static createUsersToShowSelector() { 60 | const currentFilmWithFilterSelector = createSelector(filterSelector, currentFilmSelector, 61 | (filmFilter, currentFilm) => filmFilter && currentFilm ? currentFilm : null 62 | ); 63 | return createSelector(usersListSelector, currentFilmWithFilterSelector, 64 | (users, currentFilm) => currentFilm ? users.filter(AdminComponent.getFilter(currentFilm)) : users 65 | ); 66 | }; 67 | 68 | private static getFilter(film) { 69 | const urlsInFilm = film.characters.reduce((urls, url) => Object.assign(urls, {[url]:true}) ); 70 | return user => urlsInFilm[user.url]; 71 | }; 72 | 73 | public ngOnDestroy() { 74 | this.usersSubscription.unsubscribe(); 75 | this.filmFilterSubscription.unsubscribe(); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /app/components/films-component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core' 2 | import {AppStore} from "angular2-redux"; 3 | import {FilmActions} from "../actions/film-actions"; 4 | import {currentFilmSelector,filmsCountSelector,isFetchingFilmSelector} from "../reducers/films-reducer"; 5 | 6 | @Component({ 7 | selector: 'films-component', 8 | template: ` 9 |

Films

10 | 11 |
12 | 13 |
14 | 15 | ` 16 | }) 17 | export class FilmsComponent { 18 | 19 | private filmsCount$; 20 | private currentFilm$ = null; 21 | private isFetchingCurrentFilm = false; 22 | 23 | private unsubscribeFromStore:()=>void; 24 | 25 | constructor(private _appStore:AppStore, 26 | private _filmActions:FilmActions) { 27 | 28 | this.filmsCount$ = _appStore.select(filmsCountSelector); 29 | this.currentFilm$ = _appStore.select(currentFilmSelector); 30 | 31 | _appStore.select(isFetchingFilmSelector).subscribe(isFetchingFilm => { 32 | this.isFetchingCurrentFilm = isFetchingFilm; 33 | }); 34 | 35 | _appStore.dispatch(_filmActions.fetchFilms()); 36 | } 37 | 38 | setCurrentFilm(index) { 39 | this._appStore.dispatch(this._filmActions.setCurrentFilm(index)); 40 | this._appStore.dispatch(this._filmActions.fetchFilm(index )); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /app/components/shopping-component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core' 2 | import {AppStore} from "angular2-redux"; 3 | import {CartActions} from "../actions/cart-actions"; 4 | import {PartActions} from "../actions/part-actions"; 5 | import {createSelector} from 'reselect'; 6 | import {partsSelector,partsByIdSelector} from "../reducers/parts-reducer"; 7 | import {cartSelector} from "../reducers/cart-reducer"; 8 | 9 | const partsInCartSelector = createSelector(cartSelector, partsByIdSelector, (cart, partsById) => cart.map(id => partsById[id])); 10 | 11 | @Component({ 12 | selector: 'shopping', 13 | template: ` 14 |

Parts

15 | 16 | 17 |
18 |

Cart

19 | 20 | ` 21 | }) 22 | export class ShoppingComponent { 23 | 24 | private parts$ = null; 25 | private partsInCart$ = null; 26 | 27 | private addPart; 28 | private addPartToCart; 29 | private removePartFromCart; 30 | 31 | private unsubscribeFromStore:()=>void; 32 | 33 | constructor(appStore:AppStore, partActions:PartActions, cartActions:CartActions) { 34 | 35 | this.addPart = partActions.createDispatcher(partActions.addPart); 36 | this.addPartToCart = cartActions.createDispatcher(cartActions.addToCart); 37 | this.removePartFromCart = cartActions.createDispatcher(cartActions.removeFromCart); 38 | 39 | this.parts$ = appStore.select(partsSelector); 40 | this.partsInCart$ = appStore.select(partsInCartSelector); 41 | 42 | ShoppingComponent.createInitialSetOfParts(appStore, partActions); 43 | 44 | } 45 | 46 | private static createInitialSetOfParts(appStore, partActions) { 47 | appStore.dispatch(partActions.addPart("Bumper")); 48 | appStore.dispatch(partActions.addPart("MP3 Player")); 49 | appStore.dispatch(partActions.addPart("Mirror")); 50 | appStore.dispatch(partActions.addPart("Hood")); 51 | }; 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/main.ts: -------------------------------------------------------------------------------- 1 | import 'zone.js' 2 | import 'reflect-metadata' 3 | 4 | import "bootstrap/css/bootstrap.css!" 5 | import '@angular/material/core/theming/prebuilt/deeppurple-amber.css!'; 6 | 7 | import {platformBrowserDynamic} from '@angular/platform-browser-dynamic' 8 | import {AppModule} from './app.module' 9 | 10 | platformBrowserDynamic().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /app/reducers/app-reducer.ts: -------------------------------------------------------------------------------- 1 | import parts from "./parts-reducer" 2 | import cart from "./cart-reducer" 3 | import users from "./users-reducer" 4 | import films from "./films-reducer" 5 | 6 | export default { parts, cart, users, films }; -------------------------------------------------------------------------------- /app/reducers/cart-reducer.ts: -------------------------------------------------------------------------------- 1 | import {CartActionTypes,CartAction} from '../actions/cart-actions'; 2 | 3 | export default (state = [], action:CartAction = {type:"?"}) => { 4 | 5 | switch (action.type) { 6 | case CartActionTypes.ADD_TO_CART: 7 | return [...state, action.id]; 8 | case CartActionTypes.REMOVE_FROM_CART: 9 | return state.filter(id => id !== action.id); 10 | default: 11 | return state; 12 | } 13 | }; 14 | 15 | export const cartSelector = state => state.cart 16 | -------------------------------------------------------------------------------- /app/reducers/films-reducer.ts: -------------------------------------------------------------------------------- 1 | import {FilmActionTypes,FilmAction} from '../actions/film-actions'; 2 | 3 | export default (state = [], action:FilmAction = {type:"?"}) => { 4 | switch (action.type) { 5 | case FilmActionTypes.REQUEST_FILMS: 6 | return {...state, isFetchingFilms: true}; 7 | case FilmActionTypes.RECEIVE_FILMS: 8 | return {...state, isFetchingFilms: false, list: action.films}; 9 | case FilmActionTypes.REQUEST_FILM: 10 | return {...state, isFetchingFilm: true}; 11 | case FilmActionTypes.RECEIVE_FILM: 12 | return {...state, isFetchingFilm: false, currentFilm: action.film}; 13 | case FilmActionTypes.RECEIVE_NUMBER_OF_FILMS: 14 | return {...state, count: action.count}; 15 | case FilmActionTypes.CURRENT_FILM: 16 | return {...state, current: action.currentIndex}; 17 | default: 18 | return state; 19 | } 20 | }; 21 | 22 | export const currentFilmSelector = state => state.films.currentFilm 23 | export const filmsCountSelector = state => state.films.count 24 | export const isFetchingFilmSelector = state => state.films.isFetchingFilm 25 | 26 | -------------------------------------------------------------------------------- /app/reducers/part-reducer.ts: -------------------------------------------------------------------------------- 1 | import {PartActionTypes,PartAction} from '../actions/part-actions'; 2 | 3 | export default (state:any = {}, action:PartAction = {type:"?"}) => { 4 | switch (action.type) { 5 | case PartActionTypes.ADD_PART: 6 | return {id: action.id, name: action.name}; 7 | default: 8 | return state; 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /app/reducers/parts-reducer.ts: -------------------------------------------------------------------------------- 1 | import {PartActionTypes,PartAction} from '../actions/part-actions'; 2 | import partReducer from "./part-reducer" 3 | 4 | export default (state = [], action:PartAction = {type:"?"}) => { 5 | switch (action.type) { 6 | case PartActionTypes.ADD_PART: 7 | return [...state, partReducer(null, action)]; 8 | default: 9 | return state; 10 | } 11 | }; 12 | 13 | 14 | const partsByIdReducer = (partsById, part) => ({...partsById, [part.id]:part}); 15 | 16 | export const partsSelector = state => state.parts 17 | export const partsByIdSelector = state => state.parts.reduce(partsByIdReducer, {}); 18 | -------------------------------------------------------------------------------- /app/reducers/users-reducer.ts: -------------------------------------------------------------------------------- 1 | import {UserActionTypes,UserAction} from '../actions/user-actions'; 2 | 3 | export default (state = {}, action:UserAction = {type:"?"}) => { 4 | switch (action.type) { 5 | case UserActionTypes.REQUEST_USERS: 6 | return {...state, isFetching: true}; 7 | case UserActionTypes.RECEIVE_USERS: 8 | return {...state, isFetching: false, list: action.users, updated: action.updated}; 9 | case UserActionTypes.CURRENT_USER: 10 | return {...state, current: action.current}; 11 | case UserActionTypes.SET_FILM_FILTER: 12 | return {...state, filmFilter: action.filmFilter}; 13 | default: 14 | return state; 15 | } 16 | }; 17 | 18 | export const currentUserSelector = state => state.users.current 19 | export const filterSelector = state => state.users.filmFilter 20 | export const usersListSelector = state => state.users.list 21 | -------------------------------------------------------------------------------- /app/services/film.service.ts: -------------------------------------------------------------------------------- 1 | import {Http} from "@angular/http"; 2 | import {Injectable, Inject} from "@angular/core"; 3 | import 'rxjs/add/operator/map'; 4 | import {Observable} from "rxjs/Rx"; 5 | 6 | const BASE_URL = "http://swapi.co/api/films/"; 7 | 8 | @Injectable() 9 | export class FilmService { 10 | 11 | constructor(private _http:Http) { 12 | } 13 | 14 | get():Observable { 15 | return this._http.get(`${BASE_URL}`) 16 | .map(result => result.json()) 17 | .map(json => json.results); 18 | } 19 | } -------------------------------------------------------------------------------- /app/services/user.service.ts: -------------------------------------------------------------------------------- 1 | import {Http} from "@angular/http"; 2 | import {Injectable, Inject} from "@angular/core"; 3 | import 'rxjs/add/operator/map'; 4 | import {Observable} from "rxjs/Rx"; 5 | 6 | const BASE_URL:string = "http://swapi.co/api/people/"; 7 | 8 | @Injectable() 9 | export class UserService { 10 | 11 | constructor(private _http:Http) { 12 | } 13 | 14 | get():Observable { 15 | return this._http.get(`${BASE_URL}`) 16 | .map(result => result.json()) 17 | .map(json => json.results); 18 | } 19 | } -------------------------------------------------------------------------------- /app/views/admin/user-view.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, ChangeDetectionStrategy} from '@angular/core' 2 | 3 | @Component({ 4 | selector: 'user', 5 | template: ` 6 |
7 |
8 | Name: 9 |
10 |
11 | Hair: 12 |
13 |
14 | Gender: 15 |
16 |
17 | Eyes: 18 |
19 |
20 | `, 21 | changeDetection:ChangeDetectionStrategy.OnPush 22 | }) 23 | export class UserView { 24 | @Input() data = {}; 25 | } -------------------------------------------------------------------------------- /app/views/admin/users-view.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, ChangeDetectionStrategy, EventEmitter} from '@angular/core' 2 | 3 | @Component({ 4 | selector: 'users', 5 | template: ` 6 | 10 | `, 11 | changeDetection:ChangeDetectionStrategy.OnPush 12 | }) 13 | export class UsersView { 14 | @Input() data = {}; 15 | @Output() current:EventEmitter = new EventEmitter(); 16 | 17 | getContent(user:any):string { return user.name; } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app/views/catalog/add-part-view.ts: -------------------------------------------------------------------------------- 1 | import {Component, Output, EventEmitter, ChangeDetectionStrategy} from '@angular/core' 2 | 3 | @Component({ 4 | selector: 'add-part', 5 | template: ` 6 |
7 |
8 | 9 |
10 | 11 |
12 | `, 13 | changeDetection:ChangeDetectionStrategy.OnPush 14 | }) 15 | export class AddPartsView { 16 | 17 | @Output() add:EventEmitter = new EventEmitter(); 18 | 19 | private onSubmit($event, value) { 20 | $event.preventDefault(); 21 | this.add.emit(value); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/views/catalog/cart-view.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, EventEmitter, ChangeDetectionStrategy} from '@angular/core' 2 | 3 | @Component({ 4 | selector: 'cart', 5 | template: ` 6 |

Empty :(

7 | 8 | 9 | 14 | 15 | 16 |
10 | 13 | {{part.name}}
17 | `, 18 | changeDetection:ChangeDetectionStrategy.OnPush 19 | }) 20 | export class CartView { 21 | 22 | @Input() parts = []; 23 | @Output() removeFromCart:EventEmitter = new EventEmitter(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /app/views/catalog/parts-view.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, EventEmitter, ChangeDetectionStrategy} from '@angular/core' 2 | import {createSelector} from 'reselect'; 3 | 4 | const partsInCartLookupSelector = createSelector(partsInCart => partsInCart, 5 | partsInCart => partsInCart.reduce((partsInCartLookup, part) => Object.assign(partsInCartLookup, {[part.id]:true}), {}) 6 | ); 7 | 8 | @Component({ 9 | selector: 'parts', 10 | template: ` 11 | 12 | 13 | 19 | 20 | 21 |
14 | 18 | {{part.name}}
22 | `, 23 | changeDetection: ChangeDetectionStrategy.OnPush 24 | }) 25 | export class PartsView { 26 | 27 | private partsInCartLookup = {}; 28 | 29 | @Input() parts = []; 30 | @Output() addToCart:EventEmitter = new EventEmitter(); 31 | 32 | @Input() 33 | set partsInCart(partsInCart) { 34 | this.partsInCartLookup = partsInCartLookupSelector(partsInCart); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/views/film/film-selection-view.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, ChangeDetectionStrategy, EventEmitter} from '@angular/core' 2 | 3 | @Component({ 4 | selector: 'film-selection', 5 | template: ` 6 | 14 | `, 15 | styles: [` 16 | .vehicle-selection { 17 | margin-right:8px; 18 | } 19 | `], 20 | changeDetection:ChangeDetectionStrategy.OnPush 21 | }) 22 | export class FilmSelectionView { 23 | 24 | private currentSelection = null; 25 | private list; 26 | 27 | @Output() current:EventEmitter = new EventEmitter(); 28 | 29 | @Input() set count(count) { 30 | this.list = (count>0?Array.apply(null, Array(count)).map((x, index) => index):[]); 31 | } 32 | 33 | private select(item) { 34 | this.currentSelection = item; 35 | this.current.emit(item); 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/views/film/film-view.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, ChangeDetectionStrategy, EventEmitter} from '@angular/core' 2 | 3 | @Component({ 4 | selector: 'film', 5 | template: ` 6 | loading... 7 |

{{data?.opening_crawl}}

8 | `, 9 | styles: [` 10 | .blink { 11 | margin-left:10px; 12 | animation: blink .75s linear infinite; 13 | } 14 | @keyframes blink { 15 | 0% { opacity: 1; } 16 | 50% { opacity: 1; } 17 | 50.01% { opacity: 0; } 18 | 100% { opacity: 0; } 19 | } 20 | `], 21 | changeDetection:ChangeDetectionStrategy.OnPush 22 | }) 23 | export class FilmView { 24 | 25 | @Input() data = null; 26 | @Input() loading = false; 27 | 28 | } -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | System.config({ 2 | baseURL: "/", 3 | defaultJSExtensions: true, 4 | transpiler: "typescript", 5 | typescriptOptions: { 6 | "module": "commonjs", 7 | "emitDecoratorMetadata": true 8 | }, 9 | paths: { 10 | "npm:*": "jspm_packages/npm/*", 11 | "github:*": "jspm_packages/github/*" 12 | }, 13 | 14 | packages: { 15 | "app": { 16 | "main": "main", 17 | "defaultExtension": "ts" 18 | }, 19 | "angular2-simple-list": { 20 | "main": "src/index.ts", 21 | "defaultExtension": "ts" 22 | } 23 | }, 24 | 25 | map: { 26 | "@angular/common": "npm:@angular/common@2.3.0", 27 | "@angular/compiler": "npm:@angular/compiler@2.3.0", 28 | "@angular/core": "npm:@angular/core@2.3.0", 29 | "@angular/forms": "npm:@angular/forms@2.3.0", 30 | "@angular/http": "npm:@angular/http@2.3.0", 31 | "@angular/material": "npm:@angular/material@2.0.0-alpha.9-experimental-pizza", 32 | "@angular/platform-browser": "npm:@angular/platform-browser@2.3.0", 33 | "@angular/platform-browser-dynamic": "npm:@angular/platform-browser-dynamic@2.3.0", 34 | "@angular/router": "npm:@angular/router@3.3.0", 35 | "@angular/router-deprecated": "npm:@angular/router-deprecated@2.0.0-rc.1", 36 | "angular2-redux": "npm:angular2-redux@4.0.0", 37 | "angular2-simple-list": "github:InfomediaLtd/angular2-simple-list@master", 38 | "bootstrap": "github:twbs/bootstrap@3.3.7", 39 | "clean-css": "npm:clean-css@3.4.21", 40 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 41 | "css": "github:systemjs/plugin-css@0.1.32", 42 | "redux": "npm:redux@3.6.0", 43 | "redux-thunk": "npm:redux-thunk@1.0.3", 44 | "reflect-metadata": "npm:reflect-metadata@0.1.8", 45 | "reselect": "npm:reselect@2.5.4", 46 | "rxjs": "npm:rxjs@5.0.0-rc.4", 47 | "ts": "github:frankwallis/plugin-typescript@2.6.0", 48 | "typescript": "npm:typescript@2.1.4", 49 | "zone.js": "npm:zone.js@0.6.26", 50 | "github:InfomediaLtd/angular2-simple-list@master": { 51 | "@angular/common": "npm:@angular/common@2.3.0", 52 | "@angular/compiler": "npm:@angular/compiler@2.3.0", 53 | "@angular/core": "npm:@angular/core@2.3.0", 54 | "@angular/forms": "npm:@angular/forms@2.3.0", 55 | "@angular/http": "npm:@angular/http@2.3.0", 56 | "@angular/material": "npm:@angular/material@2.0.0-alpha.9-experimental-pizza", 57 | "@angular/platform-browser": "npm:@angular/platform-browser@2.3.0", 58 | "@angular/platform-browser-dynamic": "npm:@angular/platform-browser-dynamic@2.3.0", 59 | "@angular/router": "npm:@angular/router@3.3.0", 60 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 61 | "css": "github:systemjs/plugin-css@0.1.32", 62 | "reflect-metadata": "npm:reflect-metadata@0.1.8", 63 | "rxjs": "npm:rxjs@5.0.0-rc.4", 64 | "text": "github:systemjs/plugin-text@0.0.9", 65 | "zone.js": "npm:zone.js@0.6.26" 66 | }, 67 | "github:frankwallis/plugin-typescript@2.6.0": { 68 | "typescript": "npm:typescript@1.7.5" 69 | }, 70 | "github:jspm/nodelibs-assert@0.1.0": { 71 | "assert": "npm:assert@1.4.1" 72 | }, 73 | "github:jspm/nodelibs-buffer@0.1.0": { 74 | "buffer": "npm:buffer@3.6.0" 75 | }, 76 | "github:jspm/nodelibs-constants@0.1.0": { 77 | "constants-browserify": "npm:constants-browserify@0.0.1" 78 | }, 79 | "github:jspm/nodelibs-crypto@0.1.0": { 80 | "crypto-browserify": "npm:crypto-browserify@3.11.0" 81 | }, 82 | "github:jspm/nodelibs-events@0.1.1": { 83 | "events": "npm:events@1.0.2" 84 | }, 85 | "github:jspm/nodelibs-http@1.7.1": { 86 | "Base64": "npm:Base64@0.2.1", 87 | "events": "github:jspm/nodelibs-events@0.1.1", 88 | "inherits": "npm:inherits@2.0.1", 89 | "stream": "github:jspm/nodelibs-stream@0.1.0", 90 | "url": "github:jspm/nodelibs-url@0.1.0", 91 | "util": "github:jspm/nodelibs-util@0.1.0" 92 | }, 93 | "github:jspm/nodelibs-https@0.1.0": { 94 | "https-browserify": "npm:https-browserify@0.0.0" 95 | }, 96 | "github:jspm/nodelibs-net@0.1.2": { 97 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 98 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 99 | "http": "github:jspm/nodelibs-http@1.7.1", 100 | "net": "github:jspm/nodelibs-net@0.1.2", 101 | "process": "github:jspm/nodelibs-process@0.1.2", 102 | "stream": "github:jspm/nodelibs-stream@0.1.0", 103 | "timers": "github:jspm/nodelibs-timers@0.1.0", 104 | "util": "github:jspm/nodelibs-util@0.1.0" 105 | }, 106 | "github:jspm/nodelibs-os@0.1.0": { 107 | "os-browserify": "npm:os-browserify@0.1.2" 108 | }, 109 | "github:jspm/nodelibs-path@0.1.0": { 110 | "path-browserify": "npm:path-browserify@0.0.0" 111 | }, 112 | "github:jspm/nodelibs-process@0.1.2": { 113 | "process": "npm:process@0.11.9" 114 | }, 115 | "github:jspm/nodelibs-querystring@0.1.0": { 116 | "querystring": "npm:querystring@0.2.0" 117 | }, 118 | "github:jspm/nodelibs-stream@0.1.0": { 119 | "stream-browserify": "npm:stream-browserify@1.0.0" 120 | }, 121 | "github:jspm/nodelibs-string_decoder@0.1.0": { 122 | "string_decoder": "npm:string_decoder@0.10.31" 123 | }, 124 | "github:jspm/nodelibs-timers@0.1.0": { 125 | "timers-browserify": "npm:timers-browserify@1.4.2" 126 | }, 127 | "github:jspm/nodelibs-url@0.1.0": { 128 | "url": "npm:url@0.10.3" 129 | }, 130 | "github:jspm/nodelibs-util@0.1.0": { 131 | "util": "npm:util@0.10.3" 132 | }, 133 | "github:jspm/nodelibs-vm@0.1.0": { 134 | "vm-browserify": "npm:vm-browserify@0.0.4" 135 | }, 136 | "github:twbs/bootstrap@3.3.7": { 137 | "jquery": "npm:jquery@3.1.1" 138 | }, 139 | "npm:@angular/common@2.0.0-rc.1": { 140 | "@angular/core": "npm:@angular/core@2.0.0-rc.1", 141 | "process": "github:jspm/nodelibs-process@0.1.2" 142 | }, 143 | "npm:@angular/common@2.3.0": { 144 | "@angular/core": "npm:@angular/core@2.3.0" 145 | }, 146 | "npm:@angular/compiler@2.0.0-rc.1": { 147 | "@angular/core": "npm:@angular/core@2.0.0-rc.1", 148 | "process": "github:jspm/nodelibs-process@0.1.2" 149 | }, 150 | "npm:@angular/compiler@2.3.0": { 151 | "@angular/core": "npm:@angular/core@2.3.0", 152 | "process": "github:jspm/nodelibs-process@0.1.2" 153 | }, 154 | "npm:@angular/core@2.0.0-rc.1": { 155 | "process": "github:jspm/nodelibs-process@0.1.2", 156 | "rxjs": "npm:rxjs@5.0.0-beta.6", 157 | "zone.js": "npm:zone.js@0.6.26" 158 | }, 159 | "npm:@angular/core@2.3.0": { 160 | "process": "github:jspm/nodelibs-process@0.1.2", 161 | "rxjs": "npm:rxjs@5.0.0-rc.4", 162 | "zone.js": "npm:zone.js@0.7.2" 163 | }, 164 | "npm:@angular/forms@2.3.0": { 165 | "@angular/common": "npm:@angular/common@2.3.0", 166 | "@angular/core": "npm:@angular/core@2.3.0", 167 | "process": "github:jspm/nodelibs-process@0.1.2" 168 | }, 169 | "npm:@angular/http@2.3.0": { 170 | "@angular/core": "npm:@angular/core@2.3.0", 171 | "@angular/platform-browser": "npm:@angular/platform-browser@2.3.0", 172 | "rxjs": "npm:rxjs@5.0.0-rc.4" 173 | }, 174 | "npm:@angular/material@2.0.0-alpha.9-experimental-pizza": { 175 | "@angular/common": "npm:@angular/common@2.3.0", 176 | "@angular/core": "npm:@angular/core@2.3.0", 177 | "@types/hammerjs": "npm:@types/hammerjs@2.0.33", 178 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 179 | "process": "github:jspm/nodelibs-process@0.1.2" 180 | }, 181 | "npm:@angular/platform-browser-dynamic@2.3.0": { 182 | "@angular/common": "npm:@angular/common@2.3.0", 183 | "@angular/compiler": "npm:@angular/compiler@2.3.0", 184 | "@angular/core": "npm:@angular/core@2.3.0", 185 | "@angular/platform-browser": "npm:@angular/platform-browser@2.3.0" 186 | }, 187 | "npm:@angular/platform-browser@2.0.0-rc.1": { 188 | "@angular/common": "npm:@angular/common@2.0.0-rc.1", 189 | "@angular/compiler": "npm:@angular/compiler@2.0.0-rc.1", 190 | "@angular/core": "npm:@angular/core@2.0.0-rc.1", 191 | "process": "github:jspm/nodelibs-process@0.1.2" 192 | }, 193 | "npm:@angular/platform-browser@2.3.0": { 194 | "@angular/common": "npm:@angular/common@2.3.0", 195 | "@angular/core": "npm:@angular/core@2.3.0", 196 | "process": "github:jspm/nodelibs-process@0.1.2" 197 | }, 198 | "npm:@angular/router-deprecated@2.0.0-rc.1": { 199 | "@angular/common": "npm:@angular/common@2.0.0-rc.1", 200 | "@angular/core": "npm:@angular/core@2.0.0-rc.1", 201 | "@angular/platform-browser": "npm:@angular/platform-browser@2.0.0-rc.1" 202 | }, 203 | "npm:@angular/router@3.3.0": { 204 | "@angular/common": "npm:@angular/common@2.3.0", 205 | "@angular/core": "npm:@angular/core@2.3.0", 206 | "@angular/platform-browser": "npm:@angular/platform-browser@2.3.0", 207 | "process": "github:jspm/nodelibs-process@0.1.2", 208 | "rxjs": "npm:rxjs@5.0.0-rc.4" 209 | }, 210 | "npm:amdefine@1.0.1": { 211 | "fs": "github:jspm/nodelibs-fs@0.1.2", 212 | "module": "github:jspm/nodelibs-module@0.1.0", 213 | "path": "github:jspm/nodelibs-path@0.1.0", 214 | "process": "github:jspm/nodelibs-process@0.1.2" 215 | }, 216 | "npm:angular2-redux@4.0.0": { 217 | "redux": "npm:redux@3.6.0", 218 | "redux-thunk": "npm:redux-thunk@2.1.0", 219 | "rxjs": "npm:rxjs@5.0.0-beta.12" 220 | }, 221 | "npm:asn1.js@4.9.0": { 222 | "bn.js": "npm:bn.js@4.11.6", 223 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 224 | "inherits": "npm:inherits@2.0.1", 225 | "minimalistic-assert": "npm:minimalistic-assert@1.0.0", 226 | "vm": "github:jspm/nodelibs-vm@0.1.0" 227 | }, 228 | "npm:assert@1.4.1": { 229 | "assert": "github:jspm/nodelibs-assert@0.1.0", 230 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 231 | "process": "github:jspm/nodelibs-process@0.1.2", 232 | "util": "npm:util@0.10.3" 233 | }, 234 | "npm:bn.js@4.11.6": { 235 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 236 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 237 | }, 238 | "npm:browserify-aes@1.0.6": { 239 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 240 | "buffer-xor": "npm:buffer-xor@1.0.3", 241 | "cipher-base": "npm:cipher-base@1.0.3", 242 | "create-hash": "npm:create-hash@1.1.2", 243 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 244 | "evp_bytestokey": "npm:evp_bytestokey@1.0.0", 245 | "fs": "github:jspm/nodelibs-fs@0.1.2", 246 | "inherits": "npm:inherits@2.0.1", 247 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 248 | }, 249 | "npm:browserify-cipher@1.0.0": { 250 | "browserify-aes": "npm:browserify-aes@1.0.6", 251 | "browserify-des": "npm:browserify-des@1.0.0", 252 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 253 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 254 | "evp_bytestokey": "npm:evp_bytestokey@1.0.0" 255 | }, 256 | "npm:browserify-des@1.0.0": { 257 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 258 | "cipher-base": "npm:cipher-base@1.0.3", 259 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 260 | "des.js": "npm:des.js@1.0.0", 261 | "inherits": "npm:inherits@2.0.1", 262 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 263 | }, 264 | "npm:browserify-rsa@4.0.1": { 265 | "bn.js": "npm:bn.js@4.11.6", 266 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 267 | "constants": "github:jspm/nodelibs-constants@0.1.0", 268 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 269 | "randombytes": "npm:randombytes@2.0.3", 270 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 271 | }, 272 | "npm:browserify-sign@4.0.0": { 273 | "bn.js": "npm:bn.js@4.11.6", 274 | "browserify-rsa": "npm:browserify-rsa@4.0.1", 275 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 276 | "create-hash": "npm:create-hash@1.1.2", 277 | "create-hmac": "npm:create-hmac@1.1.4", 278 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 279 | "elliptic": "npm:elliptic@6.3.2", 280 | "inherits": "npm:inherits@2.0.1", 281 | "parse-asn1": "npm:parse-asn1@5.0.0", 282 | "stream": "github:jspm/nodelibs-stream@0.1.0" 283 | }, 284 | "npm:buffer-xor@1.0.3": { 285 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 286 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 287 | }, 288 | "npm:buffer@3.6.0": { 289 | "base64-js": "npm:base64-js@0.0.8", 290 | "child_process": "github:jspm/nodelibs-child_process@0.1.0", 291 | "fs": "github:jspm/nodelibs-fs@0.1.2", 292 | "ieee754": "npm:ieee754@1.1.8", 293 | "isarray": "npm:isarray@1.0.0", 294 | "process": "github:jspm/nodelibs-process@0.1.2" 295 | }, 296 | "npm:cipher-base@1.0.3": { 297 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 298 | "inherits": "npm:inherits@2.0.1", 299 | "stream": "github:jspm/nodelibs-stream@0.1.0", 300 | "string_decoder": "github:jspm/nodelibs-string_decoder@0.1.0", 301 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 302 | }, 303 | "npm:clean-css@3.4.21": { 304 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 305 | "commander": "npm:commander@2.8.1", 306 | "fs": "github:jspm/nodelibs-fs@0.1.2", 307 | "http": "github:jspm/nodelibs-http@1.7.1", 308 | "https": "github:jspm/nodelibs-https@0.1.0", 309 | "os": "github:jspm/nodelibs-os@0.1.0", 310 | "path": "github:jspm/nodelibs-path@0.1.0", 311 | "process": "github:jspm/nodelibs-process@0.1.2", 312 | "source-map": "npm:source-map@0.4.4", 313 | "url": "github:jspm/nodelibs-url@0.1.0", 314 | "util": "github:jspm/nodelibs-util@0.1.0" 315 | }, 316 | "npm:commander@2.8.1": { 317 | "child_process": "github:jspm/nodelibs-child_process@0.1.0", 318 | "events": "github:jspm/nodelibs-events@0.1.1", 319 | "fs": "github:jspm/nodelibs-fs@0.1.2", 320 | "graceful-readlink": "npm:graceful-readlink@1.0.1", 321 | "path": "github:jspm/nodelibs-path@0.1.0", 322 | "process": "github:jspm/nodelibs-process@0.1.2" 323 | }, 324 | "npm:constants-browserify@0.0.1": { 325 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 326 | }, 327 | "npm:core-util-is@1.0.2": { 328 | "buffer": "github:jspm/nodelibs-buffer@0.1.0" 329 | }, 330 | "npm:create-ecdh@4.0.0": { 331 | "bn.js": "npm:bn.js@4.11.6", 332 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 333 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 334 | "elliptic": "npm:elliptic@6.3.2" 335 | }, 336 | "npm:create-hash@1.1.2": { 337 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 338 | "cipher-base": "npm:cipher-base@1.0.3", 339 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 340 | "fs": "github:jspm/nodelibs-fs@0.1.2", 341 | "inherits": "npm:inherits@2.0.1", 342 | "ripemd160": "npm:ripemd160@1.0.1", 343 | "sha.js": "npm:sha.js@2.4.8" 344 | }, 345 | "npm:create-hmac@1.1.4": { 346 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 347 | "create-hash": "npm:create-hash@1.1.2", 348 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 349 | "inherits": "npm:inherits@2.0.1", 350 | "stream": "github:jspm/nodelibs-stream@0.1.0" 351 | }, 352 | "npm:crypto-browserify@3.11.0": { 353 | "browserify-cipher": "npm:browserify-cipher@1.0.0", 354 | "browserify-sign": "npm:browserify-sign@4.0.0", 355 | "create-ecdh": "npm:create-ecdh@4.0.0", 356 | "create-hash": "npm:create-hash@1.1.2", 357 | "create-hmac": "npm:create-hmac@1.1.4", 358 | "diffie-hellman": "npm:diffie-hellman@5.0.2", 359 | "inherits": "npm:inherits@2.0.1", 360 | "pbkdf2": "npm:pbkdf2@3.0.9", 361 | "public-encrypt": "npm:public-encrypt@4.0.0", 362 | "randombytes": "npm:randombytes@2.0.3", 363 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 364 | }, 365 | "npm:des.js@1.0.0": { 366 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 367 | "inherits": "npm:inherits@2.0.1", 368 | "minimalistic-assert": "npm:minimalistic-assert@1.0.0" 369 | }, 370 | "npm:diffie-hellman@5.0.2": { 371 | "bn.js": "npm:bn.js@4.11.6", 372 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 373 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 374 | "miller-rabin": "npm:miller-rabin@4.0.0", 375 | "randombytes": "npm:randombytes@2.0.3", 376 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 377 | }, 378 | "npm:elliptic@6.3.2": { 379 | "bn.js": "npm:bn.js@4.11.6", 380 | "brorand": "npm:brorand@1.0.6", 381 | "hash.js": "npm:hash.js@1.0.3", 382 | "inherits": "npm:inherits@2.0.1", 383 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 384 | }, 385 | "npm:evp_bytestokey@1.0.0": { 386 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 387 | "create-hash": "npm:create-hash@1.1.2", 388 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 389 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 390 | }, 391 | "npm:graceful-readlink@1.0.1": { 392 | "fs": "github:jspm/nodelibs-fs@0.1.2" 393 | }, 394 | "npm:hash.js@1.0.3": { 395 | "inherits": "npm:inherits@2.0.1" 396 | }, 397 | "npm:https-browserify@0.0.0": { 398 | "http": "github:jspm/nodelibs-http@1.7.1" 399 | }, 400 | "npm:inherits@2.0.1": { 401 | "util": "github:jspm/nodelibs-util@0.1.0" 402 | }, 403 | "npm:isarray@1.0.0": { 404 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 405 | }, 406 | "npm:loose-envify@1.3.0": { 407 | "fs": "github:jspm/nodelibs-fs@0.1.2", 408 | "js-tokens": "npm:js-tokens@2.0.0", 409 | "process": "github:jspm/nodelibs-process@0.1.2", 410 | "stream": "github:jspm/nodelibs-stream@0.1.0", 411 | "util": "github:jspm/nodelibs-util@0.1.0" 412 | }, 413 | "npm:miller-rabin@4.0.0": { 414 | "bn.js": "npm:bn.js@4.11.6", 415 | "brorand": "npm:brorand@1.0.6" 416 | }, 417 | "npm:os-browserify@0.1.2": { 418 | "os": "github:jspm/nodelibs-os@0.1.0" 419 | }, 420 | "npm:parse-asn1@5.0.0": { 421 | "asn1.js": "npm:asn1.js@4.9.0", 422 | "browserify-aes": "npm:browserify-aes@1.0.6", 423 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 424 | "create-hash": "npm:create-hash@1.1.2", 425 | "evp_bytestokey": "npm:evp_bytestokey@1.0.0", 426 | "pbkdf2": "npm:pbkdf2@3.0.9", 427 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 428 | }, 429 | "npm:path-browserify@0.0.0": { 430 | "process": "github:jspm/nodelibs-process@0.1.2" 431 | }, 432 | "npm:pbkdf2@3.0.9": { 433 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 434 | "create-hmac": "npm:create-hmac@1.1.4", 435 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 436 | "process": "github:jspm/nodelibs-process@0.1.2" 437 | }, 438 | "npm:process@0.11.9": { 439 | "assert": "github:jspm/nodelibs-assert@0.1.0", 440 | "fs": "github:jspm/nodelibs-fs@0.1.2", 441 | "vm": "github:jspm/nodelibs-vm@0.1.0" 442 | }, 443 | "npm:public-encrypt@4.0.0": { 444 | "bn.js": "npm:bn.js@4.11.6", 445 | "browserify-rsa": "npm:browserify-rsa@4.0.1", 446 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 447 | "create-hash": "npm:create-hash@1.1.2", 448 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 449 | "parse-asn1": "npm:parse-asn1@5.0.0", 450 | "randombytes": "npm:randombytes@2.0.3" 451 | }, 452 | "npm:punycode@1.3.2": { 453 | "process": "github:jspm/nodelibs-process@0.1.2" 454 | }, 455 | "npm:randombytes@2.0.3": { 456 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 457 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 458 | "process": "github:jspm/nodelibs-process@0.1.2", 459 | "systemjs-json": "github:systemjs/plugin-json@0.1.2" 460 | }, 461 | "npm:readable-stream@1.1.14": { 462 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 463 | "core-util-is": "npm:core-util-is@1.0.2", 464 | "events": "github:jspm/nodelibs-events@0.1.1", 465 | "inherits": "npm:inherits@2.0.1", 466 | "isarray": "npm:isarray@0.0.1", 467 | "process": "github:jspm/nodelibs-process@0.1.2", 468 | "stream-browserify": "npm:stream-browserify@1.0.0", 469 | "string_decoder": "npm:string_decoder@0.10.31" 470 | }, 471 | "npm:redux@3.6.0": { 472 | "lodash": "npm:lodash@4.17.2", 473 | "lodash-es": "npm:lodash-es@4.17.2", 474 | "loose-envify": "npm:loose-envify@1.3.0", 475 | "process": "github:jspm/nodelibs-process@0.1.2", 476 | "symbol-observable": "npm:symbol-observable@1.0.4" 477 | }, 478 | "npm:ripemd160@1.0.1": { 479 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 480 | "process": "github:jspm/nodelibs-process@0.1.2" 481 | }, 482 | "npm:rxjs@5.0.0-beta.12": { 483 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 484 | "process": "github:jspm/nodelibs-process@0.1.2", 485 | "symbol-observable": "npm:symbol-observable@1.0.4" 486 | }, 487 | "npm:rxjs@5.0.0-beta.6": { 488 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 489 | "process": "github:jspm/nodelibs-process@0.1.2" 490 | }, 491 | "npm:rxjs@5.0.0-rc.4": { 492 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 493 | "process": "github:jspm/nodelibs-process@0.1.2", 494 | "symbol-observable": "npm:symbol-observable@1.0.4" 495 | }, 496 | "npm:sha.js@2.4.8": { 497 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 498 | "fs": "github:jspm/nodelibs-fs@0.1.2", 499 | "inherits": "npm:inherits@2.0.1", 500 | "process": "github:jspm/nodelibs-process@0.1.2" 501 | }, 502 | "npm:source-map-support@0.4.6": { 503 | "assert": "github:jspm/nodelibs-assert@0.1.0", 504 | "buffer": "github:jspm/nodelibs-buffer@0.1.0", 505 | "child_process": "github:jspm/nodelibs-child_process@0.1.0", 506 | "fs": "github:jspm/nodelibs-fs@0.1.2", 507 | "module": "github:jspm/nodelibs-module@0.1.0", 508 | "path": "github:jspm/nodelibs-path@0.1.0", 509 | "process": "github:jspm/nodelibs-process@0.1.2", 510 | "querystring": "github:jspm/nodelibs-querystring@0.1.0", 511 | "source-map": "npm:source-map@0.5.6" 512 | }, 513 | "npm:source-map@0.4.4": { 514 | "amdefine": "npm:amdefine@1.0.1", 515 | "process": "github:jspm/nodelibs-process@0.1.2" 516 | }, 517 | "npm:source-map@0.5.6": { 518 | "process": "github:jspm/nodelibs-process@0.1.2" 519 | }, 520 | "npm:stream-browserify@1.0.0": { 521 | "events": "github:jspm/nodelibs-events@0.1.1", 522 | "inherits": "npm:inherits@2.0.1", 523 | "readable-stream": "npm:readable-stream@1.1.14" 524 | }, 525 | "npm:string_decoder@0.10.31": { 526 | "buffer": "github:jspm/nodelibs-buffer@0.1.0" 527 | }, 528 | "npm:timers-browserify@1.4.2": { 529 | "process": "npm:process@0.11.9" 530 | }, 531 | "npm:typescript@2.1.4": { 532 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 533 | "net": "github:jspm/nodelibs-net@0.1.2", 534 | "os": "github:jspm/nodelibs-os@0.1.0", 535 | "source-map-support": "npm:source-map-support@0.4.6" 536 | }, 537 | "npm:url@0.10.3": { 538 | "assert": "github:jspm/nodelibs-assert@0.1.0", 539 | "punycode": "npm:punycode@1.3.2", 540 | "querystring": "npm:querystring@0.2.0", 541 | "util": "github:jspm/nodelibs-util@0.1.0" 542 | }, 543 | "npm:util@0.10.3": { 544 | "inherits": "npm:inherits@2.0.1", 545 | "process": "github:jspm/nodelibs-process@0.1.2" 546 | }, 547 | "npm:vm-browserify@0.0.4": { 548 | "indexof": "npm:indexof@0.0.1" 549 | }, 550 | "npm:zone.js@0.6.26": { 551 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 552 | "events": "github:jspm/nodelibs-events@0.1.1", 553 | "fs": "github:jspm/nodelibs-fs@0.1.2", 554 | "process": "github:jspm/nodelibs-process@0.1.2", 555 | "timers": "github:jspm/nodelibs-timers@0.1.0" 556 | }, 557 | "npm:zone.js@0.7.2": { 558 | "crypto": "github:jspm/nodelibs-crypto@0.1.0", 559 | "events": "github:jspm/nodelibs-events@0.1.1", 560 | "fs": "github:jspm/nodelibs-fs@0.1.2", 561 | "process": "github:jspm/nodelibs-process@0.1.2", 562 | "timers": "github:jspm/nodelibs-timers@0.1.0" 563 | } 564 | } 565 | }); 566 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var requireDir = require("require-dir"); 2 | requireDir("./tasks", { recurse: true }); 3 | -------------------------------------------------------------------------------- /images/Angular2WithRedux.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InfomediaLtd/angular2-redux-example/a655c6c3cab7170165440a2b622280cae2a72b53/images/Angular2WithRedux.gif -------------------------------------------------------------------------------- /images/Angular2WithRedux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InfomediaLtd/angular2-redux-example/a655c6c3cab7170165440a2b622280cae2a72b53/images/Angular2WithRedux.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Angular 2 with Redux 6 | 7 | 8 | 9 | 10 |

Angular 2 with Redux

11 | 12 |
13 | Loading... 14 |
15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "dist": "gulp dist", 4 | "postinstall-bak": "jspm install && npm run typings", 5 | "typings": "rm -rf typings && gulp typings && typings install" 6 | }, 7 | "jspm": { 8 | "dependencies": { 9 | "@angular/common": "npm:@angular/common@^2.3.0", 10 | "@angular/compiler": "npm:@angular/compiler@^2.3.0", 11 | "@angular/core": "npm:@angular/core@^2.3.0", 12 | "@angular/forms": "npm:@angular/forms@^2.3.0", 13 | "@angular/http": "npm:@angular/http@^2.3.0", 14 | "@angular/material": "npm:@angular/material@^2.0.0-alpha.10", 15 | "@angular/platform-browser": "npm:@angular/platform-browser@^2.3.0", 16 | "@angular/platform-browser-dynamic": "npm:@angular/platform-browser-dynamic@^2.3.0", 17 | "@angular/router": "npm:@angular/router@^3.3.0", 18 | "angular2-redux": "npm:angular2-redux@^4.0.0", 19 | "angular2-simple-list": "github:InfomediaLtd/angular2-simple-list@master", 20 | "bootstrap": "github:twbs/bootstrap@^3.3.6", 21 | "crypto": "github:jspm/nodelibs-crypto@^0.1.0", 22 | "css": "github:systemjs/plugin-css@^0.1.20", 23 | "redux": "npm:redux@^3.0.4", 24 | "redux-thunk": "npm:redux-thunk@^1.0.0", 25 | "reflect-metadata": "npm:reflect-metadata@^0.1.2", 26 | "reselect": "npm:reselect@^2.0.2", 27 | "rxjs": "npm:rxjs@5.0.0-rc.4", 28 | "ts": "github:frankwallis/plugin-typescript@^2.1.4", 29 | "zone.js": "npm:zone.js@^0.6.10" 30 | }, 31 | "devDependencies": { 32 | "clean-css": "npm:clean-css@^3.4.9", 33 | "typescript": "npm:typescript@^2.1.4" 34 | } 35 | }, 36 | "typingsDependencies": { 37 | "registry": [ 38 | "redux", 39 | "redux-thunk" 40 | ], 41 | "file": [ 42 | "jspm_packages/npm/angular2-redux@VERSION/dist/index.d.ts", 43 | "jspm_packages/github/InfomediaLtd/angular2-simple-list@VERSION/app/index.d.ts" 44 | ] 45 | }, 46 | "devDependencies": { 47 | "@angular/common": "^2.3.0", 48 | "@angular/compiler": "^2.3.0", 49 | "@angular/core": "^2.3.0", 50 | "@angular/http": "^2.3.0", 51 | "@angular/platform-browser": "^2.3.0", 52 | "@angular/platform-browser-dynamic": "^2.3.0", 53 | "clean-css": "^3.4.9", 54 | "gulp": "^3.9.0", 55 | "gulp-concat": "^2.6.0", 56 | "gulp-insert": "^0.5.0", 57 | "gulp-replace": "^0.5.4", 58 | "gulp-rimraf": "^0.2.0", 59 | "gulp-run": "^1.6.12", 60 | "gulp-shell": "^0.5.1", 61 | "gulp-tslint": "^4.2.2", 62 | "gulp-tslint-stylish": "^1.1.1", 63 | "gulp-uglify": "^1.5.1", 64 | "jspm": "^0.16.33", 65 | "require-dir": "^0.3.0", 66 | "run-sequence": "^1.1.5", 67 | "rxjs": "5.0.0-rc.4", 68 | "tslint": "^3.2.1", 69 | "tslint-eslint-rules": "^1.0.1", 70 | "typescript": "^2.1.4" 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tasks/dist.js: -------------------------------------------------------------------------------- 1 | var gulp = require("gulp"); 2 | var rimraf = require("gulp-rimraf"); 3 | var shell = require("gulp-shell"); 4 | var runSequence = require("run-sequence"); 5 | var replace = require("gulp-replace"); 6 | var insert = require("gulp-insert"); 7 | var concat = require("gulp-concat"); 8 | var uglify = require("gulp-uglify"); 9 | var tslint = require("gulp-tslint"); 10 | var tslintStylish = require('gulp-tslint-stylish'); 11 | 12 | var paths = { 13 | dist: "./dist", 14 | sources: "app/**/*.ts", 15 | sourcesToCopy: ["index.html"], 16 | targetHTML: "./dist/index.html", 17 | targetJS: "index.js", 18 | targetMinifiedJS: "index.min.js" 19 | }; 20 | 21 | // lint 22 | gulp.task("lint", function() { 23 | return gulp.src(paths.sources) 24 | .pipe(tslint()) 25 | .pipe(tslint.report(tslintStylish, { 26 | emitError: true, 27 | sort: true, 28 | bell: true 29 | })); 30 | }); 31 | 32 | // Delete the dist directory 33 | gulp.task("clean", function() { 34 | return gulp.src(paths.dist, {read: false}).pipe(rimraf({ force: true })); 35 | }); 36 | 37 | // copy required sources to the dist folder 38 | gulp.task("copy", function(){ 39 | return gulp.src(paths.sourcesToCopy).pipe(gulp.dest(paths.dist)); 40 | }); 41 | 42 | // bundle the app with jspm 43 | gulp.task("bundle", 44 | shell.task(["jspm bundle-sfx app/main.ts " + paths.dist + "/" + paths.targetJS]) 45 | ); 46 | 47 | // minify the bundle 48 | gulp.task("minify", function() { 49 | return gulp.src(paths.targetJS, {cwd: paths.dist}) 50 | .pipe(uglify({mangle:false})) 51 | .pipe(concat("index.min.js")) 52 | .pipe(gulp.dest(paths.dist)); 53 | }); 54 | 55 | // update index.html to point to the minified bundle 56 | gulp.task("update-target-html", function(){ 57 | return gulp.src([paths.targetHTML]) 58 | // remove scripts 59 | .pipe(replace(//g, "")) 60 | .pipe(replace(//g, "")) 61 | .pipe(replace(//g, "")) 62 | // cleanup 63 | .pipe(replace(/\n\n/g, "\n")) 64 | // link bundle script 65 | .pipe(insert.append("\n")) 66 | .pipe(gulp.dest(paths.dist)) 67 | }); 68 | 69 | // entry point - run tasks in a sequence 70 | gulp.task("dist", function(callback) { 71 | runSequence( 72 | // "lint", 73 | "clean", 74 | "copy", 75 | "bundle", 76 | "minify", 77 | "update-target-html", 78 | function (error) { 79 | if (error) { 80 | console.log(error.message); 81 | } else { 82 | console.log("FINISHED SUCCESSFULLY"); 83 | } 84 | callback(error); 85 | }); 86 | }); 87 | -------------------------------------------------------------------------------- /tasks/typings.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var fs = require("fs"); 3 | 4 | gulp.task("typings", function() { 5 | var typingsDependencies = JSON.parse(fs.readFileSync("package.json")).typingsDependencies; 6 | 7 | var result = {"devDependencies": {},"ambientDevDependencies": {}}; 8 | 9 | // generate dt dependencies 10 | typingsDependencies && (typingsDependencies.registry||[]).forEach(value => { 11 | result.ambientDevDependencies[value] = "github:DefinitelyTyped/DefinitelyTyped/" + value + "/" + value + ".d.ts"; 12 | }); 13 | 14 | // generate local d.ts dependencies 15 | typingsDependencies && (typingsDependencies.file||[]).forEach((path) => { 16 | var dependencyName = path.replace(/@VERSION.*/, ""); 17 | var parentPath = dependencyName.replace(/[^\/]*$/, ""); 18 | var namePrefix = dependencyName.replace(parentPath,""); 19 | var matchingFolders = fs.readdirSync(parentPath) 20 | .filter(name => name.startsWith(namePrefix+"@")) 21 | .filter(name => fs.lstatSync(parentPath + "/" + name).isDirectory()); 22 | if (matchingFolders.length > 0) { 23 | result.devDependencies[namePrefix] = "file:" + path.replace(/VERSION/, matchingFolders[0].replace(/.*@/,"")); 24 | } else { 25 | console.log("Couldn't find a single match for '" + path + "' in " + parentPath); 26 | } 27 | }); 28 | 29 | fs.writeFile("typings.json", JSON.stringify(result, null, 4), err => console.log(err||"Created typings.json")); 30 | }); 31 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES5", 4 | "module": "commonjs", 5 | "sourceMap": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "removeComments": false, 9 | "noImplicitAny": false, 10 | "outDir": "build" 11 | }, 12 | "exclude": [ 13 | "jspm_packages", 14 | "node_modules", 15 | "dist", 16 | "typings/main.d.ts", 17 | "typings/main" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": "node_modules/tslint-eslint-rules/dist/rules", 3 | "rules": { 4 | "no-constant-condition": true 5 | }, 6 | "rules": { 7 | "class-name": true, 8 | "curly": true, 9 | "eofline": true, 10 | "forin": true, 11 | "indent": [true, "spaces"], 12 | "label-position": true, 13 | "label-undefined": true, 14 | "max-line-length": [true, 140], 15 | "member-access": true, 16 | "member-ordering": [true, 17 | "public-before-private", 18 | "static-before-instance", 19 | "variables-before-functions" 20 | ], 21 | "no-arg": true, 22 | "no-bitwise": true, 23 | "no-console": [true, 24 | "debug", 25 | "info", 26 | "time", 27 | "timeEnd", 28 | "trace" 29 | ], 30 | "no-construct": true, 31 | "no-debugger": true, 32 | "no-duplicate-key": true, 33 | "no-duplicate-variable": true, 34 | "no-empty": true, 35 | "no-eval": true, 36 | "no-inferrable-types": true, 37 | "no-shadowed-variable": true, 38 | "no-string-literal": true, 39 | "no-switch-case-fall-through": true, 40 | "no-trailing-comma": true, 41 | "no-unused-expression": true, 42 | "no-unused-variable": true, 43 | "no-unreachable": true, 44 | "no-use-before-declare": true, 45 | "no-var-keyword": true, 46 | "one-line": [true, 47 | "check-open-brace", 48 | "check-catch", 49 | "check-else", 50 | "check-whitespace" 51 | ], 52 | "quotemark": [true, "double"], 53 | "radix": true, 54 | "triple-equals": [true, "allow-null-check"], 55 | "typedef-whitespace": [true, { 56 | "call-signature": "nospace", 57 | "index-signature": "nospace", 58 | "parameter": "nospace", 59 | "property-declaration": "nospace", 60 | "variable-declaration": "nospace" 61 | }], 62 | "variable-name": false, 63 | "whitespace": [true, 64 | "check-branch", 65 | "check-decl", 66 | "check-operator", 67 | "check-module", 68 | "check-seperator", 69 | "check-typecast" 70 | ], 71 | "no-constant-condition": true, 72 | "valid-typeof": true, 73 | "use-isnan": true, 74 | "no-duplicate-case": true, 75 | "no-sparse-array": true, 76 | "no-extra-semi": true, 77 | "no-extra-boolean-cast": true, 78 | "no-ex-assign": true, 79 | "no-unexpected-multiline": true, 80 | "no-invalid-regexp": true, 81 | "no-inner-declarations": [true, "both"], 82 | "no-regex-spaces": true, 83 | "no-empty-character-class": true, 84 | "no-control-regex": true, 85 | "no-irregular-whitespace": true, 86 | "valid-jsdoc": true 87 | } 88 | } 89 | --------------------------------------------------------------------------------