diff --git a/.angular-cli.json b/.angular-cli.json index ebd0e2b..5588e40 100644 --- a/.angular-cli.json +++ b/.angular-cli.json @@ -28,6 +28,30 @@ "dev": "environments/environment.ts", "prod": "environments/environment.prod.ts" } + }, + { + "name": "universal", + "platform": "server", + "root": "src", + "outDir": "dist-server", + "assets": [ + "assets", + "favicon.ico" + ], + "index": "index.html", + "main": "main.server.ts", + "tsconfig": "tsconfig.server.json", + "prefix": "app", + "styles": [ + "../node_modules/bootstrap/dist/css/bootstrap.min.css", + "styles.css" + ], + "scripts": [], + "environmentSource": "environments/environment.ts", + "environments": { + "dev": "environments/environment.ts", + "prod": "environments/environment.prod.ts" + } } ], "e2e": { diff --git a/dist-server/favicon.ico b/dist-server/favicon.ico new file mode 100644 index 0000000..8081c7c Binary files /dev/null and b/dist-server/favicon.ico differ diff --git a/dist-server/main.bundle.js b/dist-server/main.bundle.js new file mode 100644 index 0000000..43a8e5e --- /dev/null +++ b/dist-server/main.bundle.js @@ -0,0 +1 @@ +!function(n,l){for(var e in l)n[e]=l[e]}(exports,function(n){function l(t){if(e[t])return e[t].exports;var u=e[t]={i:t,l:!1,exports:{}};return n[t].call(u.exports,u,u.exports,l),u.l=!0,u.exports}var e={};return l.m=n,l.c=e,l.d=function(n,e,t){l.o(n,e)||Object.defineProperty(n,e,{configurable:!1,enumerable:!0,get:t})},l.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return l.d(e,"a",e),e},l.o=function(n,l){return Object.prototype.hasOwnProperty.call(n,l)},l.p="",l(l.s=0)}({"+TiV":function(n,l,e){"use strict";function t(n){return i.\u0275vid(0,[(n()(),i.\u0275eld(0,0,null,null,20,"a",[["class","list-group-item clearfix"],["routerLinkActive","active"],["style","cursor: pointer;"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(n,l,e){var t=!0;return"click"===l&&(t=!1!==i.\u0275nov(n,1).onClick(e.button,e.ctrlKey,e.metaKey,e.shiftKey)&&t),t},null,null)),i.\u0275did(1,671744,[[2,4]],0,r.RouterLinkWithHref,[r.Router,r.ActivatedRoute,d.LocationStrategy],{routerLink:[0,"routerLink"]},null),i.\u0275pad(2,1),i.\u0275did(3,1720320,null,2,r.RouterLinkActive,[r.Router,i.ElementRef,i.Renderer2,i.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),i.\u0275qud(603979776,1,{links:1}),i.\u0275qud(603979776,2,{linksWithHrefs:1}),(n()(),i.\u0275ted(-1,null,["\n "])),(n()(),i.\u0275eld(7,0,null,null,7,"div",[["class","pull-left"]],null,null,null,null,null)),(n()(),i.\u0275ted(-1,null,["\n "])),(n()(),i.\u0275eld(9,0,null,null,1,"h4",[["class","list-group-item-heading"]],null,null,null,null,null)),(n()(),i.\u0275ted(10,null,["",""])),(n()(),i.\u0275ted(-1,null,["\n "])),(n()(),i.\u0275eld(12,0,null,null,1,"p",[["class","list-group-item-text"]],null,null,null,null,null)),(n()(),i.\u0275ted(13,null,["",""])),(n()(),i.\u0275ted(-1,null,["\n "])),(n()(),i.\u0275ted(-1,null,["\n "])),(n()(),i.\u0275eld(16,0,null,null,3,"span",[["class","pull-right"]],null,null,null,null,null)),(n()(),i.\u0275ted(-1,null,["\n "])),(n()(),i.\u0275eld(18,0,null,null,0,"img",[["class","img-responsive"],["style","max-height: 50px;"]],[[8,"src",4],[8,"alt",0]],null,null,null,null)),(n()(),i.\u0275ted(-1,null,["\n "])),(n()(),i.\u0275ted(-1,null,["\n"]))],function(n,l){n(l,1,0,n(l,2,0,l.component.index)),n(l,3,0,"active")},function(n,l){var e=l.component;n(l,0,0,i.\u0275nov(l,1).target,i.\u0275nov(l,1).href),n(l,10,0,e.recipe.name),n(l,13,0,e.recipe.description),n(l,18,0,e.recipe.imagePath,i.\u0275inlineInterpolate(1,"",e.recipe.name,""))})}function u(n){return i.\u0275vid(0,[(n()(),i.\u0275eld(0,0,null,null,1,"app-recipe-item",[],null,null,null,t,a)),i.\u0275did(1,114688,null,0,s.RecipeItemComponent,[],null,null)],function(n,l){n(l,1,0)},null)}var o=e("fcOI"),i=e("OQ0P"),r=e("A7Ap"),d=e("yv0u"),s=e("RTBL"),a=i.\u0275crt({encapsulation:0,styles:[o.styles],data:{}});l.RenderType_RecipeItemComponent=a,l.View_RecipeItemComponent_0=t,l.View_RecipeItemComponent_Host_0=u,l.RecipeItemComponentNgFactory=i.\u0275ccf("app-recipe-item",s.RecipeItemComponent,u,{recipe:"recipe",index:"index"},{},[])},0:function(n,l,e){n.exports=e("Zq8w")},"02xY":function(n,l){n.exports=require("@angular/forms")},"0uTX":function(n,l,e){"use strict";Object.defineProperty(l,"__esModule",{value:!0}),e("AZ97");var t=e("byqd");l.ShoppingListComponent=function(){function n(n){this.store=n}return n.prototype.ngOnInit=function(){this.shoppingListState=this.store.select("shoppingList")},n.prototype.onEditItem=function(n){this.store.dispatch(new t.StartEdit(n))},n}()},"19KG":function(n,l,e){"use strict";function t(n){return r.\u0275vid(0,[(n()(),r.\u0275eld(0,0,null,null,1,"a",[["class","list-group-item"],["style","cursor: pointer;"]],null,[[null,"click"]],function(n,l,e){var t=!0;return"click"===l&&(t=!1!==n.component.onEditItem(n.context.index)&&t),t},null,null)),(n()(),r.\u0275ted(1,null,["\n "," (",")\n "]))],null,function(n,l){n(l,1,0,l.context.$implicit.name,l.context.$implicit.amount)})}function u(n){return r.\u0275vid(0,[(n()(),r.\u0275eld(0,0,null,null,16,"div",[["class","row"]],null,null,null,null,null)),(n()(),r.\u0275ted(-1,null,["\n "])),(n()(),r.\u0275eld(2,0,null,null,13,"div",[["class","col-xs-10"]],null,null,null,null,null)),(n()(),r.\u0275ted(-1,null,["\n "])),(n()(),r.\u0275eld(4,0,null,null,1,"app-shopping-edit",[],null,null,null,d.View_ShoppingEditComponent_0,d.RenderType_ShoppingEditComponent)),r.\u0275did(5,245760,null,0,s.ShoppingEditComponent,[a.Store],null,null),(n()(),r.\u0275ted(-1,null,["\n "])),(n()(),r.\u0275eld(7,0,null,null,0,"hr",[],null,null,null,null,null)),(n()(),r.\u0275ted(-1,null,["\n "])),(n()(),r.\u0275eld(9,0,null,null,5,"ul",[["class","list-group"]],null,null,null,null,null)),(n()(),r.\u0275ted(-1,null,["\n "])),(n()(),r.\u0275and(16777216,null,null,2,null,t)),r.\u0275did(12,802816,null,0,c.NgForOf,[r.ViewContainerRef,r.TemplateRef,r.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),r.\u0275pid(131072,c.AsyncPipe,[r.ChangeDetectorRef]),(n()(),r.\u0275ted(-1,null,["\n "])),(n()(),r.\u0275ted(-1,null,["\n "])),(n()(),r.\u0275ted(-1,null,["\n"]))],function(n,l){var e=l.component;n(l,5,0),n(l,12,0,r.\u0275unv(l,12,0,r.\u0275nov(l,13).transform(e.shoppingListState)).ingredients)},null)}function o(n){return r.\u0275vid(0,[(n()(),r.\u0275eld(0,0,null,null,1,"app-shopping-list",[],null,null,null,u,m)),r.\u0275did(1,114688,null,0,p.ShoppingListComponent,[a.Store],null,null)],function(n,l){n(l,1,0)},null)}var i=e("Up2r"),r=e("OQ0P"),d=e("nUum"),s=e("G5OU"),a=e("AZ97"),c=e("yv0u"),p=e("0uTX"),m=r.\u0275crt({encapsulation:0,styles:[i.styles],data:{}});l.RenderType_ShoppingListComponent=m,l.View_ShoppingListComponent_0=u,l.View_ShoppingListComponent_Host_0=o,l.ShoppingListComponentNgFactory=r.\u0275ccf("app-shopping-list",p.ShoppingListComponent,o,{},{},[])},"5QUg":function(n,l,e){"use strict";Object.defineProperty(l,"__esModule",{value:!0}),l.ShoppingListModule=function(){}},"6M6Y":function(n,l){n.exports=require("rxjs/add/operator/do")},"8IlT":function(n,l,e){"use strict";Object.defineProperty(l,"__esModule",{value:!0}),l.RecipesModule=function(){}},"8e9l":function(n,l){n.exports=require("tslib")},"8wGh":function(n,l){n.exports=require("@angular/animations/browser")},"9Q1K":function(n,l,e){"use strict";function t(n){return i.\u0275vid(0,[(n()(),i.\u0275eld(0,0,null,null,1,"h2",[],null,null,null,null,null)),(n()(),i.\u0275ted(-1,null,["Welcome to the Recipe Book"]))],null,null)}function u(n){return i.\u0275vid(0,[(n()(),i.\u0275eld(0,0,null,null,1,"app-home",[],null,null,null,t,d)),i.\u0275did(1,114688,null,0,r.HomeComponent,[],null,null)],function(n,l){n(l,1,0)},null)}var o=e("o67W"),i=e("OQ0P"),r=e("m7Co"),d=i.\u0275crt({encapsulation:0,styles:[o.styles],data:{}});l.RenderType_HomeComponent=d,l.View_HomeComponent_0=t,l.View_HomeComponent_Host_0=u,l.HomeComponentNgFactory=i.\u0275ccf("app-home",r.HomeComponent,u,{},{},[])},A7Ap:function(n,l){n.exports=require("@angular/router")},ASwt:function(n,l){n.exports=require("@angular/platform-server")},AYCW:function(n,l,e){"use strict";var t=e("8e9l").__decorate,u=e("8e9l").__metadata;Object.defineProperty(l,"__esModule",{value:!0});var o=e("GflJ");e("QQqw"),e("EJZF"),e("YQf1"),e("Ir0Z"),e("AZ97");var i=e("zAtt");l.RecipeEffects=function(){function n(n,l,e){var t=this;this.actions$=n,this.httpClient=l,this.store=e,this.baseUrl="https://my-recipe-book-cb837.firebaseio.com/",this.recipeFetch=this.actions$.ofType(i.FETCH_RECIPES).switchMap(function(n){return t.httpClient.get(t.baseUrl+"recipes.json")}).map(function(n){return{type:i.SET_RECIPES,payload:n}}),this.recipeStore=this.actions$.ofType(i.STORE_RECIPES).withLatestFrom(this.store.select("recipes")).switchMap(function(n){return t.httpClient.put(t.baseUrl+"recipes.json",n[1].recipes)})}return t([o.Effect(),u("design:type",Object)],n.prototype,"recipeFetch",void 0),t([o.Effect({dispatch:!1}),u("design:type",Object)],n.prototype,"recipeStore",void 0),n}()},AZ97:function(n,l){n.exports=require("@ngrx/store")},DI2O:function(n,l,e){"use strict";Object.defineProperty(l,"__esModule",{value:!0}),l.RecipesComponent=function(){function n(){}return n.prototype.ngOnInit=function(){},n}()},EJZF:function(n,l){n.exports=require("rxjs/add/operator/switchMap")},G5OU:function(n,l,e){"use strict";Object.defineProperty(l,"__esModule",{value:!0}),e("02xY"),e("AZ97");var t=e("mxkr"),u=e("byqd");l.ShoppingEditComponent=function(){function n(n){this.store=n,this.editMode=!1}return n.prototype.ngOnInit=function(){var n=this;this.subscription=this.store.select("shoppingList").subscribe(function(l){l.editedIngredientIndex>-1?(n.editedItem=l.editedIngredient,n.editMode=!0,n.shoppingListForm.setValue({name:n.editedItem.name,amount:n.editedItem.amount})):n.editMode=!1})},n.prototype.onSubmit=function(n){var l=n.value,e=new t.Ingredient(l.name,l.amount);this.store.dispatch(this.editMode?new u.UpdateIngredient(e):new u.AddIngredient(e)),this.editMode=!1,n.reset()},n.prototype.onClear=function(){this.shoppingListForm.reset(),this.editMode=!1},n.prototype.onDelete=function(){this.store.dispatch(new u.DeleteIngredient),this.onClear()},n.prototype.ngOnDestroy=function(){this.store.dispatch(new u.StopEdit),this.subscription.unsubscribe()},n}()},GJF7:function(n,l,e){"use strict";l.styles=[""]},GflJ:function(n,l){n.exports=require("@ngrx/effects")},GrDH:function(n,l,e){"use strict";var t=e("OQ0P"),u=e("8IlT"),o=e("Xt3F"),i=e("ktxa"),r=e("Oq3J"),d=e("i/IN"),s=e("yv0u"),a=e("02xY"),c=e("q6lm"),p=e("AZ97"),m=e("A7Ap"),g=e("OKzv"),f=e("T2Au"),v=e("xzcb"),C=e("AYCW"),R=e("GflJ"),h=e("Ir0Z"),S=e("DI2O"),E=e("WXLR"),_=e("ZA/m"),y=e("WsQm");l.RecipesModuleNgFactory=t.\u0275cmf(u.RecipesModule,[],function(n){return t.\u0275mod([t.\u0275mpd(512,t.ComponentFactoryResolver,t.\u0275CodegenComponentFactoryResolver,[[8,[o.RecipesComponentNgFactory,i.RecipeStartComponentNgFactory,r.RecipeEditComponentNgFactory,d.RecipeDetailComponentNgFactory]],[3,t.ComponentFactoryResolver],t.NgModuleRef]),t.\u0275mpd(4608,s.NgLocalization,s.NgLocaleLocalization,[t.LOCALE_ID,[2,s.\u0275a]]),t.\u0275mpd(4608,a.FormBuilder,a.FormBuilder,[]),t.\u0275mpd(4608,a.\u0275i,a.\u0275i,[]),t.\u0275mpd(4608,c.AuthGuard,c.AuthGuard,[p.Store]),t.\u0275mpd(512,s.CommonModule,s.CommonModule,[]),t.\u0275mpd(512,a.\u0275ba,a.\u0275ba,[]),t.\u0275mpd(512,a.ReactiveFormsModule,a.ReactiveFormsModule,[]),t.\u0275mpd(512,m.RouterModule,m.RouterModule,[[2,m.\u0275a],[2,m.Router]]),t.\u0275mpd(512,g.RecipesRoutingModule,g.RecipesRoutingModule,[]),t.\u0275mpd(512,f.SharedModule,f.SharedModule,[]),t.\u0275mpd(1024,p.STORE_FEATURES,function(){return[{key:"recipes",reducerFactory:p.combineReducers,metaReducers:[],initialState:void 0}]},[]),t.\u0275mpd(1024,p._FEATURE_REDUCERS,function(){return[v.recipeReducer]},[]),t.\u0275mpd(1024,p._FEATURE_REDUCERS_TOKEN,function(n){return[n]},[p._FEATURE_REDUCERS]),t.\u0275mpd(1024,p.FEATURE_REDUCERS,function(n,l,e){return[p._createFeatureReducers(n,l,e)]},[t.Injector,p._FEATURE_REDUCERS,p._FEATURE_REDUCERS_TOKEN]),t.\u0275mpd(131584,p.StoreFeatureModule,p.StoreFeatureModule,[p.STORE_FEATURES,p.FEATURE_REDUCERS,p.ReducerManager]),t.\u0275mpd(512,C.RecipeEffects,C.RecipeEffects,[R.Actions,h.HttpClient,p.Store]),t.\u0275mpd(1024,R.\u0275f,function(n){return[R.\u0275a(n)]},[C.RecipeEffects]),t.\u0275mpd(512,R.\u0275d,R.\u0275d,[R.\u0275c,R.\u0275f,[2,p.StoreModule]]),t.\u0275mpd(512,u.RecipesModule,u.RecipesModule,[]),t.\u0275mpd(1024,m.ROUTES,function(){return[[{path:"",component:S.RecipesComponent,children:[{path:"",component:E.RecipeStartComponent},{path:"new",component:_.RecipeEditComponent,canActivate:[c.AuthGuard]},{path:":id",component:y.RecipeDetailComponent},{path:":id/edit",component:_.RecipeEditComponent,canActivate:[c.AuthGuard]}]}]]},[])])})},"H6/C":function(n,l,e){"use strict";var t=this&&this.__assign||Object.assign||function(n){for(var l,e=1,t=arguments.length;e { + console.log('Listening on port 3000'); +}); \ No newline at end of file diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 0b0b23e..f9361df 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -21,7 +21,7 @@ import { AuthEffects } from './auth/ngrx/auth.effects'; AppComponent ], imports: [ - BrowserModule, + BrowserModule.withServerTransition({appId: 'my-recipebook-app'}), HttpClientModule, AppRoutingModule, SharedModule, diff --git a/src/app/app.server.module.ts b/src/app/app.server.module.ts new file mode 100644 index 0000000..3c338d3 --- /dev/null +++ b/src/app/app.server.module.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { ServerModule } from '@angular/platform-server'; + +import { AppModule } from "./app.module"; +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + AppModule, + ServerModule + ], + bootstrap: [AppComponent] +}) +export class AppServerModule {} \ No newline at end of file diff --git a/src/main.server.ts b/src/main.server.ts new file mode 100644 index 0000000..7cd4421 --- /dev/null +++ b/src/main.server.ts @@ -0,0 +1,4 @@ +import { enableProdMode } from '@angular/core'; +export { AppServerModule } from './app/app.server.module'; + +enableProdMode() \ No newline at end of file diff --git a/src/tsconfig.server.json b/src/tsconfig.server.json new file mode 100644 index 0000000..61a4a64 --- /dev/null +++ b/src/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "baseUrl": "./", + "module": "commonjs", + "types": [] + }, + "exclude": [ + "test.ts", + "**/*.spec.ts" + ], + "angularCompilerOptions": { + "entryModule": "app/app.server.module#AppServerModule" + } +} + \ No newline at end of file