├── .browserslistrc
├── .editorconfig
├── .gitignore
├── README.md
├── angular.json
├── dist
├── favicon.ico
├── glyphicons-halflings-regular.eot
├── glyphicons-halflings-regular.svg
├── glyphicons-halflings-regular.ttf
├── glyphicons-halflings-regular.woff
├── glyphicons-halflings-regular.woff2
├── index.html
├── main.js
├── main.js.map
├── polyfills.js
├── polyfills.js.map
├── runtime.js
├── runtime.js.map
├── styles.css
├── styles.css.map
├── vendor.js
└── vendor.js.map
├── e2e
├── app.e2e-spec.ts
├── app.po.ts
└── tsconfig.e2e.json
├── karma.conf.js
├── package-lock.json
├── package.json
├── protractor.conf.js
├── server.js
├── server
├── data
│ ├── books.json
│ └── readers.json
├── routes
│ ├── books.js
│ ├── errors.js
│ ├── index.js
│ └── readers.js
└── views
│ ├── error.jade
│ ├── index.jade
│ └── layout.jade
├── src
├── app
│ ├── add-book
│ │ ├── add-book.component.html
│ │ └── add-book.component.ts
│ ├── add-reader
│ │ ├── add-reader.component.html
│ │ └── add-reader.component.ts
│ ├── app-routing.module.ts
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── dashboard
│ │ ├── dashboard.component.html
│ │ └── dashboard.component.ts
│ ├── data.ts
│ ├── edit-book
│ │ ├── edit-book.component.html
│ │ └── edit-book.component.ts
│ ├── edit-reader
│ │ ├── edit-reader.component.html
│ │ └── edit-reader.component.ts
│ └── models
│ │ ├── book.ts
│ │ └── reader.ts
├── assets
│ └── .gitkeep
├── environments
│ ├── environment.prod.ts
│ └── environment.ts
├── favicon.ico
├── index.html
├── main.ts
├── polyfills.ts
├── styles.css
├── test.ts
└── typings.d.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.spec.json
└── tslint.json
/.browserslistrc:
--------------------------------------------------------------------------------
1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 |
5 | # For the full list of supported browsers by the Angular framework, please see:
6 | # https://angular.io/guide/browser-support
7 |
8 | # You can see what browsers were selected by your queries by running:
9 | # npx browserslist
10 |
11 | last 1 Chrome version
12 | last 1 Firefox version
13 | last 2 Edge major versions
14 | last 2 Safari major versions
15 | last 2 iOS major versions
16 | Firefox ESR
17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.
18 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | node_modules/
4 | .vscode/
5 |
6 | # compiled output
7 | /tmp
8 | /out-tsc
9 |
10 | # dependencies
11 |
12 | # IDEs and editors
13 | /.idea
14 | .project
15 | .classpath
16 | .c9/
17 | *.launch
18 | .settings/
19 | *.sublime-workspace
20 |
21 | # IDE - VSCode
22 |
23 | # misc
24 | /.sass-cache
25 | /connect.lock
26 | /coverage
27 | /libpeerconnection.log
28 | npm-debug.log
29 | testem.log
30 | /typings
31 |
32 | # e2e
33 | /e2e/*.js
34 | /e2e/*.map
35 |
36 | # System Files
37 | .DS_Store
38 | Thumbs.db
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular Services
2 |
3 | This is the official repository for my Pluralsight course titled *Angular Services*.
4 | There are separate branches named after the modules in the course that contain the code as it
5 | exists at the end of that module.
6 |
7 | I will update this repo below with any problems or small issues reported between updates to the actual course.
8 |
9 | Thanks for watching and good luck on your Angular projects!
10 |
--------------------------------------------------------------------------------
/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "booktracker": {
7 | "root": "",
8 | "sourceRoot": "src",
9 | "projectType": "application",
10 | "architect": {
11 | "build": {
12 | "builder": "@angular-devkit/build-angular:browser",
13 | "options": {
14 | "outputPath": "dist",
15 | "index": "src/index.html",
16 | "main": "src/main.ts",
17 | "tsConfig": "tsconfig.app.json",
18 | "polyfills": "src/polyfills.ts",
19 | "assets": [
20 | "src/assets",
21 | "src/favicon.ico"
22 | ],
23 | "styles": [
24 | "node_modules/bootstrap/dist/css/bootstrap.min.css",
25 | "src/styles.css"
26 | ],
27 | "scripts": [],
28 | "aot": false,
29 | "vendorChunk": true,
30 | "extractLicenses": false,
31 | "buildOptimizer": false,
32 | "sourceMap": true,
33 | "optimization": false,
34 | "namedChunks": true
35 | },
36 | "configurations": {
37 | "production": {
38 | "optimization": true,
39 | "outputHashing": "all",
40 | "sourceMap": false,
41 | "extractCss": true,
42 | "namedChunks": false,
43 | "aot": true,
44 | "extractLicenses": true,
45 | "vendorChunk": false,
46 | "buildOptimizer": true,
47 | "fileReplacements": [
48 | {
49 | "replace": "src/environments/environment.ts",
50 | "with": "src/environments/environment.prod.ts"
51 | }
52 | ]
53 | }
54 | },
55 | "defaultConfiguration": ""
56 | },
57 | "serve": {
58 | "builder": "@angular-devkit/build-angular:dev-server",
59 | "options": {
60 | "browserTarget": "booktracker:build"
61 | },
62 | "configurations": {
63 | "production": {
64 | "browserTarget": "booktracker:build:production"
65 | }
66 | }
67 | },
68 | "extract-i18n": {
69 | "builder": "@angular-devkit/build-angular:extract-i18n",
70 | "options": {
71 | "browserTarget": "booktracker:build"
72 | }
73 | },
74 | "test": {
75 | "builder": "@angular-devkit/build-angular:karma",
76 | "options": {
77 | "main": "src/test.ts",
78 | "karmaConfig": "./karma.conf.js",
79 | "polyfills": "src/polyfills.ts",
80 | "tsConfig": "src/tsconfig.spec.json",
81 | "scripts": [],
82 | "styles": [
83 | "node_modules/bootstrap/dist/css/bootstrap.min.css",
84 | "src/styles.css"
85 | ],
86 | "assets": [
87 | "src/assets",
88 | "src/favicon.ico"
89 | ]
90 | }
91 | },
92 | "lint": {
93 | "builder": "@angular-devkit/build-angular:tslint",
94 | "options": {
95 | "tsConfig": [
96 | "src/tsconfig.app.json",
97 | "src/tsconfig.spec.json"
98 | ],
99 | "exclude": []
100 | }
101 | }
102 | }
103 | },
104 | "booktracker-e2e": {
105 | "root": "e2e",
106 | "sourceRoot": "e2e",
107 | "projectType": "application",
108 | "architect": {
109 | "e2e": {
110 | "builder": "@angular-devkit/build-angular:protractor",
111 | "options": {
112 | "protractorConfig": "./protractor.conf.js",
113 | "devServerTarget": "booktracker:serve"
114 | }
115 | },
116 | "lint": {
117 | "builder": "@angular-devkit/build-angular:tslint",
118 | "options": {
119 | "tsConfig": [
120 | "e2e/tsconfig.e2e.json"
121 | ],
122 | "exclude": []
123 | }
124 | }
125 | }
126 | }
127 | },
128 | "defaultProject": "booktracker",
129 | "schematics": {
130 | "@schematics/angular:component": {
131 | "prefix": "app",
132 | "styleext": "css"
133 | },
134 | "@schematics/angular:directive": {
135 | "prefix": "app"
136 | }
137 | }
138 | }
--------------------------------------------------------------------------------
/dist/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bricewilson/angular-services/8567805366718b5ebc4ed9554f4b649a0401533b/dist/favicon.ico
--------------------------------------------------------------------------------
/dist/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bricewilson/angular-services/8567805366718b5ebc4ed9554f4b649a0401533b/dist/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/dist/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bricewilson/angular-services/8567805366718b5ebc4ed9554f4b649a0401533b/dist/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/dist/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bricewilson/angular-services/8567805366718b5ebc4ed9554f4b649a0401533b/dist/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/dist/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bricewilson/angular-services/8567805366718b5ebc4ed9554f4b649a0401533b/dist/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Book Tracker
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/dist/main.js:
--------------------------------------------------------------------------------
1 | (self["webpackChunkbooktracker"] = self["webpackChunkbooktracker"] || []).push([["main"],{
2 |
3 | /***/ 8255:
4 | /*!*******************************************************!*\
5 | !*** ./$_lazy_route_resources/ lazy namespace object ***!
6 | \*******************************************************/
7 | /***/ ((module) => {
8 |
9 | function webpackEmptyAsyncContext(req) {
10 | // Here Promise.resolve().then() is used instead of new Promise() to prevent
11 | // uncaught exception popping up in devtools
12 | return Promise.resolve().then(() => {
13 | var e = new Error("Cannot find module '" + req + "'");
14 | e.code = 'MODULE_NOT_FOUND';
15 | throw e;
16 | });
17 | }
18 | webpackEmptyAsyncContext.keys = () => ([]);
19 | webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;
20 | webpackEmptyAsyncContext.id = 8255;
21 | module.exports = webpackEmptyAsyncContext;
22 |
23 | /***/ }),
24 |
25 | /***/ 9884:
26 | /*!************************************************!*\
27 | !*** ./src/app/add-book/add-book.component.ts ***!
28 | \************************************************/
29 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
30 |
31 | "use strict";
32 | __webpack_require__.r(__webpack_exports__);
33 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
34 | /* harmony export */ "AddBookComponent": () => (/* binding */ AddBookComponent)
35 | /* harmony export */ });
36 | /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tslib */ 4762);
37 | /* harmony import */ var _raw_loader_add_book_component_html__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !raw-loader!./add-book.component.html */ 7052);
38 | /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/core */ 7716);
39 |
40 |
41 |
42 | let AddBookComponent = class AddBookComponent {
43 | constructor() { }
44 | ngOnInit() { }
45 | saveBook(formValues) {
46 | let newBook = formValues;
47 | newBook.bookID = 0;
48 | console.log(newBook);
49 | console.warn('Save new book not yet implemented.');
50 | }
51 | };
52 | AddBookComponent.ctorParameters = () => [];
53 | AddBookComponent = (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__decorate)([
54 | (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.Component)({
55 | selector: 'app-add-book',
56 | template: _raw_loader_add_book_component_html__WEBPACK_IMPORTED_MODULE_0__.default
57 | })
58 | ], AddBookComponent);
59 |
60 |
61 |
62 | /***/ }),
63 |
64 | /***/ 4808:
65 | /*!****************************************************!*\
66 | !*** ./src/app/add-reader/add-reader.component.ts ***!
67 | \****************************************************/
68 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
69 |
70 | "use strict";
71 | __webpack_require__.r(__webpack_exports__);
72 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
73 | /* harmony export */ "AddReaderComponent": () => (/* binding */ AddReaderComponent)
74 | /* harmony export */ });
75 | /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tslib */ 4762);
76 | /* harmony import */ var _raw_loader_add_reader_component_html__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !raw-loader!./add-reader.component.html */ 1699);
77 | /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/core */ 7716);
78 |
79 |
80 |
81 | let AddReaderComponent = class AddReaderComponent {
82 | constructor() { }
83 | ngOnInit() { }
84 | saveReader(formValues) {
85 | let newReader = formValues;
86 | newReader.readerID = 0;
87 | console.log(newReader);
88 | console.warn('Save new reader not yet implemented.');
89 | }
90 | };
91 | AddReaderComponent.ctorParameters = () => [];
92 | AddReaderComponent = (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__decorate)([
93 | (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.Component)({
94 | selector: 'app-add-reader',
95 | template: _raw_loader_add_reader_component_html__WEBPACK_IMPORTED_MODULE_0__.default
96 | })
97 | ], AddReaderComponent);
98 |
99 |
100 |
101 | /***/ }),
102 |
103 | /***/ 158:
104 | /*!***************************************!*\
105 | !*** ./src/app/app-routing.module.ts ***!
106 | \***************************************/
107 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
108 |
109 | "use strict";
110 | __webpack_require__.r(__webpack_exports__);
111 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
112 | /* harmony export */ "AppRoutingModule": () => (/* binding */ AppRoutingModule)
113 | /* harmony export */ });
114 | /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! tslib */ 4762);
115 | /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @angular/core */ 7716);
116 | /* harmony import */ var _angular_router__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @angular/router */ 9895);
117 | /* harmony import */ var app_add_book_add_book_component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! app/add-book/add-book.component */ 9884);
118 | /* harmony import */ var app_add_reader_add_reader_component__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! app/add-reader/add-reader.component */ 4808);
119 | /* harmony import */ var app_dashboard_dashboard_component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! app/dashboard/dashboard.component */ 7528);
120 | /* harmony import */ var app_edit_book_edit_book_component__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! app/edit-book/edit-book.component */ 445);
121 | /* harmony import */ var app_edit_reader_edit_reader_component__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! app/edit-reader/edit-reader.component */ 6236);
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 | const routes = [
131 | { path: 'dashboard', component: app_dashboard_dashboard_component__WEBPACK_IMPORTED_MODULE_2__.DashboardComponent },
132 | { path: 'addbook', component: app_add_book_add_book_component__WEBPACK_IMPORTED_MODULE_0__.AddBookComponent },
133 | { path: 'addreader', component: app_add_reader_add_reader_component__WEBPACK_IMPORTED_MODULE_1__.AddReaderComponent },
134 | { path: 'editreader/:id', component: app_edit_reader_edit_reader_component__WEBPACK_IMPORTED_MODULE_4__.EditReaderComponent },
135 | { path: 'editbook/:id', component: app_edit_book_edit_book_component__WEBPACK_IMPORTED_MODULE_3__.EditBookComponent },
136 | { path: '', redirectTo: 'dashboard', pathMatch: 'full' }
137 | ];
138 | let AppRoutingModule = class AppRoutingModule {
139 | };
140 | AppRoutingModule = (0,tslib__WEBPACK_IMPORTED_MODULE_5__.__decorate)([
141 | (0,_angular_core__WEBPACK_IMPORTED_MODULE_6__.NgModule)({
142 | imports: [_angular_router__WEBPACK_IMPORTED_MODULE_7__.RouterModule.forRoot(routes)],
143 | exports: [_angular_router__WEBPACK_IMPORTED_MODULE_7__.RouterModule]
144 | })
145 | ], AppRoutingModule);
146 |
147 |
148 |
149 | /***/ }),
150 |
151 | /***/ 5041:
152 | /*!**********************************!*\
153 | !*** ./src/app/app.component.ts ***!
154 | \**********************************/
155 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
156 |
157 | "use strict";
158 | __webpack_require__.r(__webpack_exports__);
159 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
160 | /* harmony export */ "AppComponent": () => (/* binding */ AppComponent)
161 | /* harmony export */ });
162 | /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tslib */ 4762);
163 | /* harmony import */ var _raw_loader_app_component_html__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !raw-loader!./app.component.html */ 1106);
164 | /* harmony import */ var _app_component_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./app.component.css */ 1249);
165 | /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/core */ 7716);
166 |
167 |
168 |
169 |
170 | let AppComponent = class AppComponent {
171 | constructor() {
172 | this.title = 'app';
173 | }
174 | };
175 | AppComponent = (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__decorate)([
176 | (0,_angular_core__WEBPACK_IMPORTED_MODULE_3__.Component)({
177 | selector: 'app-root',
178 | template: _raw_loader_app_component_html__WEBPACK_IMPORTED_MODULE_0__.default,
179 | styles: [_app_component_css__WEBPACK_IMPORTED_MODULE_1__.default]
180 | })
181 | ], AppComponent);
182 |
183 |
184 |
185 | /***/ }),
186 |
187 | /***/ 6747:
188 | /*!*******************************!*\
189 | !*** ./src/app/app.module.ts ***!
190 | \*******************************/
191 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
192 |
193 | "use strict";
194 | __webpack_require__.r(__webpack_exports__);
195 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
196 | /* harmony export */ "AppModule": () => (/* binding */ AppModule)
197 | /* harmony export */ });
198 | /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! tslib */ 4762);
199 | /* harmony import */ var _angular_platform_browser__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @angular/platform-browser */ 9075);
200 | /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @angular/core */ 7716);
201 | /* harmony import */ var _angular_forms__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @angular/forms */ 3679);
202 | /* harmony import */ var _add_book_add_book_component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./add-book/add-book.component */ 9884);
203 | /* harmony import */ var _add_reader_add_reader_component__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./add-reader/add-reader.component */ 4808);
204 | /* harmony import */ var _app_component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./app.component */ 5041);
205 | /* harmony import */ var _app_routing_module__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./app-routing.module */ 158);
206 | /* harmony import */ var _dashboard_dashboard_component__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./dashboard/dashboard.component */ 7528);
207 | /* harmony import */ var _edit_book_edit_book_component__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./edit-book/edit-book.component */ 445);
208 | /* harmony import */ var _edit_reader_edit_reader_component__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./edit-reader/edit-reader.component */ 6236);
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 | let AppModule = class AppModule {
221 | };
222 | AppModule = (0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([
223 | (0,_angular_core__WEBPACK_IMPORTED_MODULE_8__.NgModule)({
224 | declarations: [
225 | _app_component__WEBPACK_IMPORTED_MODULE_2__.AppComponent,
226 | _dashboard_dashboard_component__WEBPACK_IMPORTED_MODULE_4__.DashboardComponent,
227 | _add_book_add_book_component__WEBPACK_IMPORTED_MODULE_0__.AddBookComponent,
228 | _edit_reader_edit_reader_component__WEBPACK_IMPORTED_MODULE_6__.EditReaderComponent,
229 | _edit_book_edit_book_component__WEBPACK_IMPORTED_MODULE_5__.EditBookComponent,
230 | _add_reader_add_reader_component__WEBPACK_IMPORTED_MODULE_1__.AddReaderComponent
231 | ],
232 | imports: [
233 | _angular_platform_browser__WEBPACK_IMPORTED_MODULE_9__.BrowserModule,
234 | _app_routing_module__WEBPACK_IMPORTED_MODULE_3__.AppRoutingModule,
235 | _angular_forms__WEBPACK_IMPORTED_MODULE_10__.FormsModule
236 | ],
237 | providers: [],
238 | bootstrap: [_app_component__WEBPACK_IMPORTED_MODULE_2__.AppComponent]
239 | })
240 | ], AppModule);
241 |
242 |
243 |
244 | /***/ }),
245 |
246 | /***/ 7528:
247 | /*!**************************************************!*\
248 | !*** ./src/app/dashboard/dashboard.component.ts ***!
249 | \**************************************************/
250 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
251 |
252 | "use strict";
253 | __webpack_require__.r(__webpack_exports__);
254 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
255 | /* harmony export */ "DashboardComponent": () => (/* binding */ DashboardComponent)
256 | /* harmony export */ });
257 | /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tslib */ 4762);
258 | /* harmony import */ var _raw_loader_dashboard_component_html__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !raw-loader!./dashboard.component.html */ 9306);
259 | /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/core */ 7716);
260 | /* harmony import */ var app_data__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! app/data */ 8387);
261 |
262 |
263 |
264 |
265 | let DashboardComponent = class DashboardComponent {
266 | constructor() {
267 | this.allBooks = app_data__WEBPACK_IMPORTED_MODULE_1__.allBooks;
268 | this.allReaders = app_data__WEBPACK_IMPORTED_MODULE_1__.allReaders;
269 | this.mostPopularBook = app_data__WEBPACK_IMPORTED_MODULE_1__.allBooks[0];
270 | }
271 | ngOnInit() {
272 | }
273 | deleteBook(bookID) {
274 | console.warn(`Delete book not yet implemented (bookID: ${bookID}).`);
275 | }
276 | deleteReader(readerID) {
277 | console.warn(`Delete reader not yet implemented (readerID: ${readerID}).`);
278 | }
279 | };
280 | DashboardComponent.ctorParameters = () => [];
281 | DashboardComponent = (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__decorate)([
282 | (0,_angular_core__WEBPACK_IMPORTED_MODULE_3__.Component)({
283 | selector: 'app-dashboard',
284 | template: _raw_loader_dashboard_component_html__WEBPACK_IMPORTED_MODULE_0__.default
285 | })
286 | ], DashboardComponent);
287 |
288 |
289 |
290 | /***/ }),
291 |
292 | /***/ 8387:
293 | /*!*************************!*\
294 | !*** ./src/app/data.ts ***!
295 | \*************************/
296 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
297 |
298 | "use strict";
299 | __webpack_require__.r(__webpack_exports__);
300 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
301 | /* harmony export */ "allReaders": () => (/* binding */ allReaders),
302 | /* harmony export */ "allBooks": () => (/* binding */ allBooks)
303 | /* harmony export */ });
304 | const allReaders = [
305 | { readerID: 1, name: 'Marie', weeklyReadingGoal: 400, totalMinutesRead: 5600 },
306 | { readerID: 2, name: 'Daniel', weeklyReadingGoal: 210, totalMinutesRead: 3000 },
307 | { readerID: 3, name: 'Lanier', weeklyReadingGoal: 140, totalMinutesRead: 600 }
308 | ];
309 | const allBooks = [
310 | { bookID: 1, title: 'Goodnight Moon', author: 'Margaret Wise Brown', publicationYear: 1953 },
311 | { bookID: 2, title: 'Green Eggs and Ham', author: 'Dr. Seuss', publicationYear: 1960 },
312 | { bookID: 3, title: 'Where the Wild Things Are', author: 'Maurice Sendak', publicationYear: 1963 },
313 | { bookID: 4, title: 'The Hobbit', author: 'J. R. R. Tolkien', publicationYear: 1937 },
314 | { bookID: 5, title: 'Curious George', author: 'H. A. Rey', publicationYear: 1941 },
315 | { bookID: 6, title: 'Alice\'s Adventures in Wonderland', author: 'Lewis Carroll', publicationYear: 1865 },
316 | ];
317 |
318 |
319 | /***/ }),
320 |
321 | /***/ 445:
322 | /*!**************************************************!*\
323 | !*** ./src/app/edit-book/edit-book.component.ts ***!
324 | \**************************************************/
325 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
326 |
327 | "use strict";
328 | __webpack_require__.r(__webpack_exports__);
329 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
330 | /* harmony export */ "EditBookComponent": () => (/* binding */ EditBookComponent)
331 | /* harmony export */ });
332 | /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ 4762);
333 | /* harmony import */ var _raw_loader_edit_book_component_html__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !raw-loader!./edit-book.component.html */ 8367);
334 | /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/core */ 7716);
335 | /* harmony import */ var _angular_router__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/router */ 9895);
336 | /* harmony import */ var app_data__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! app/data */ 8387);
337 |
338 |
339 |
340 |
341 |
342 | let EditBookComponent = class EditBookComponent {
343 | constructor(route) {
344 | this.route = route;
345 | }
346 | ngOnInit() {
347 | let bookID = parseInt(this.route.snapshot.params['id']);
348 | this.selectedBook = app_data__WEBPACK_IMPORTED_MODULE_1__.allBooks.find(book => book.bookID === bookID);
349 | }
350 | setMostPopular() {
351 | console.warn('Setting most popular book not yet implemented.');
352 | }
353 | saveChanges() {
354 | console.warn('Save changes to book not yet implemented.');
355 | }
356 | };
357 | EditBookComponent.ctorParameters = () => [
358 | { type: _angular_router__WEBPACK_IMPORTED_MODULE_2__.ActivatedRoute }
359 | ];
360 | EditBookComponent = (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__decorate)([
361 | (0,_angular_core__WEBPACK_IMPORTED_MODULE_4__.Component)({
362 | selector: 'app-edit-book',
363 | template: _raw_loader_edit_book_component_html__WEBPACK_IMPORTED_MODULE_0__.default
364 | })
365 | ], EditBookComponent);
366 |
367 |
368 |
369 | /***/ }),
370 |
371 | /***/ 6236:
372 | /*!******************************************************!*\
373 | !*** ./src/app/edit-reader/edit-reader.component.ts ***!
374 | \******************************************************/
375 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
376 |
377 | "use strict";
378 | __webpack_require__.r(__webpack_exports__);
379 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
380 | /* harmony export */ "EditReaderComponent": () => (/* binding */ EditReaderComponent)
381 | /* harmony export */ });
382 | /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ 4762);
383 | /* harmony import */ var _raw_loader_edit_reader_component_html__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !raw-loader!./edit-reader.component.html */ 4644);
384 | /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/core */ 7716);
385 | /* harmony import */ var _angular_router__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/router */ 9895);
386 | /* harmony import */ var app_data__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! app/data */ 8387);
387 |
388 |
389 |
390 |
391 |
392 | let EditReaderComponent = class EditReaderComponent {
393 | constructor(route) {
394 | this.route = route;
395 | }
396 | ngOnInit() {
397 | let readerID = parseInt(this.route.snapshot.params['id']);
398 | this.selectedReader = app_data__WEBPACK_IMPORTED_MODULE_1__.allReaders.find(reader => reader.readerID === readerID);
399 | }
400 | saveChanges() {
401 | console.warn('Save reader not yet implemented.');
402 | }
403 | };
404 | EditReaderComponent.ctorParameters = () => [
405 | { type: _angular_router__WEBPACK_IMPORTED_MODULE_2__.ActivatedRoute }
406 | ];
407 | EditReaderComponent = (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__decorate)([
408 | (0,_angular_core__WEBPACK_IMPORTED_MODULE_4__.Component)({
409 | selector: 'app-edit-reader',
410 | template: _raw_loader_edit_reader_component_html__WEBPACK_IMPORTED_MODULE_0__.default
411 | })
412 | ], EditReaderComponent);
413 |
414 |
415 |
416 | /***/ }),
417 |
418 | /***/ 2340:
419 | /*!*****************************************!*\
420 | !*** ./src/environments/environment.ts ***!
421 | \*****************************************/
422 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
423 |
424 | "use strict";
425 | __webpack_require__.r(__webpack_exports__);
426 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
427 | /* harmony export */ "environment": () => (/* binding */ environment)
428 | /* harmony export */ });
429 | // The file contents for the current environment will overwrite these during build.
430 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
431 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
432 | // The list of which env maps to which file can be found in `.angular-cli.json`.
433 | const environment = {
434 | production: false
435 | };
436 |
437 |
438 | /***/ }),
439 |
440 | /***/ 4431:
441 | /*!*********************!*\
442 | !*** ./src/main.ts ***!
443 | \*********************/
444 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
445 |
446 | "use strict";
447 | __webpack_require__.r(__webpack_exports__);
448 | /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/core */ 7716);
449 | /* harmony import */ var _angular_platform_browser_dynamic__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/platform-browser-dynamic */ 4608);
450 | /* harmony import */ var _app_app_module__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./app/app.module */ 6747);
451 | /* harmony import */ var _environments_environment__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./environments/environment */ 2340);
452 |
453 |
454 |
455 |
456 | if (_environments_environment__WEBPACK_IMPORTED_MODULE_1__.environment.production) {
457 | (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.enableProdMode)();
458 | }
459 | (0,_angular_platform_browser_dynamic__WEBPACK_IMPORTED_MODULE_3__.platformBrowserDynamic)().bootstrapModule(_app_app_module__WEBPACK_IMPORTED_MODULE_0__.AppModule);
460 |
461 |
462 | /***/ }),
463 |
464 | /***/ 1249:
465 | /*!***********************************!*\
466 | !*** ./src/app/app.component.css ***!
467 | \***********************************/
468 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
469 |
470 | "use strict";
471 | __webpack_require__.r(__webpack_exports__);
472 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
473 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
474 | /* harmony export */ });
475 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJhcHAuY29tcG9uZW50LmNzcyJ9 */");
476 |
477 | /***/ }),
478 |
479 | /***/ 7052:
480 | /*!****************************************************************************************!*\
481 | !*** ./node_modules/raw-loader/dist/cjs.js!./src/app/add-book/add-book.component.html ***!
482 | \****************************************************************************************/
483 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
484 |
485 | "use strict";
486 | __webpack_require__.r(__webpack_exports__);
487 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
488 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
489 | /* harmony export */ });
490 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("");
491 |
492 | /***/ }),
493 |
494 | /***/ 1699:
495 | /*!********************************************************************************************!*\
496 | !*** ./node_modules/raw-loader/dist/cjs.js!./src/app/add-reader/add-reader.component.html ***!
497 | \********************************************************************************************/
498 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
499 |
500 | "use strict";
501 | __webpack_require__.r(__webpack_exports__);
502 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
503 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
504 | /* harmony export */ });
505 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("");
506 |
507 | /***/ }),
508 |
509 | /***/ 1106:
510 | /*!**************************************************************************!*\
511 | !*** ./node_modules/raw-loader/dist/cjs.js!./src/app/app.component.html ***!
512 | \**************************************************************************/
513 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
514 |
515 | "use strict";
516 | __webpack_require__.r(__webpack_exports__);
517 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
518 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
519 | /* harmony export */ });
520 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("\r\n\r\n\r\n");
521 |
522 | /***/ }),
523 |
524 | /***/ 9306:
525 | /*!******************************************************************************************!*\
526 | !*** ./node_modules/raw-loader/dist/cjs.js!./src/app/dashboard/dashboard.component.html ***!
527 | \******************************************************************************************/
528 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
529 |
530 | "use strict";
531 | __webpack_require__.r(__webpack_exports__);
532 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
533 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
534 | /* harmony export */ });
535 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("\r\n
\r\n
\r\n
\r\n
\r\n
All Books
\r\n \r\n
\r\n
\r\n {{book.title}}\r\n Edit \r\n Delete\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
All Readers
\r\n \r\n
\r\n
\r\n {{reader.name}}\r\n Edit\r\n Delete \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
Most Popular Book
\r\n \r\n
\r\n {{mostPopularBook.title}} by {{mostPopularBook.author}}\r\n
\r\n
\r\n
\r\n
\r\n
");
536 |
537 | /***/ }),
538 |
539 | /***/ 8367:
540 | /*!******************************************************************************************!*\
541 | !*** ./node_modules/raw-loader/dist/cjs.js!./src/app/edit-book/edit-book.component.html ***!
542 | \******************************************************************************************/
543 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
544 |
545 | "use strict";
546 | __webpack_require__.r(__webpack_exports__);
547 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
548 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
549 | /* harmony export */ });
550 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("");
551 |
552 | /***/ }),
553 |
554 | /***/ 4644:
555 | /*!**********************************************************************************************!*\
556 | !*** ./node_modules/raw-loader/dist/cjs.js!./src/app/edit-reader/edit-reader.component.html ***!
557 | \**********************************************************************************************/
558 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
559 |
560 | "use strict";
561 | __webpack_require__.r(__webpack_exports__);
562 | /* harmony export */ __webpack_require__.d(__webpack_exports__, {
563 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
564 | /* harmony export */ });
565 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("");
566 |
567 | /***/ })
568 |
569 | },
570 | /******/ __webpack_require__ => { // webpackRuntimeModules
571 | /******/ "use strict";
572 | /******/
573 | /******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
574 | /******/ __webpack_require__.O(0, ["vendor"], () => (__webpack_exec__(4431)));
575 | /******/ var __webpack_exports__ = __webpack_require__.O();
576 | /******/ }
577 | ]);
578 | //# sourceMappingURL=main.js.map
--------------------------------------------------------------------------------
/dist/main.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["./$_lazy_route_resources|lazy|groupOptions: {}|namespace object","./src/app/add-book/add-book.component.ts","./src/app/add-reader/add-reader.component.ts","./src/app/app-routing.module.ts","./src/app/app.component.ts","./src/app/app.module.ts","./src/app/dashboard/dashboard.component.ts","./src/app/data.ts","./src/app/edit-book/edit-book.component.ts","./src/app/edit-reader/edit-reader.component.ts","./src/environments/environment.ts","./src/main.ts","./src/app/app.component.css","./src/app/add-book/add-book.component.html","./src/app/add-reader/add-reader.component.html","./src/app/app.component.html","./src/app/dashboard/dashboard.component.html","./src/app/edit-book/edit-book.component.html","./src/app/edit-reader/edit-reader.component.html"],"names":[],"mappings":"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","file":"main.js","sourcesContent":["function webpackEmptyAsyncContext(req) {\n\t// Here Promise.resolve().then() is used instead of new Promise() to prevent\n\t// uncaught exception popping up in devtools\n\treturn Promise.resolve().then(() => {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t});\n}\nwebpackEmptyAsyncContext.keys = () => ([]);\nwebpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;\nwebpackEmptyAsyncContext.id = 8255;\nmodule.exports = webpackEmptyAsyncContext;","import { Component, OnInit } from '@angular/core';\r\n\r\nimport { Book } from \"app/models/book\";\r\n\r\n@Component({\r\n selector: 'app-add-book',\r\n templateUrl: './add-book.component.html',\r\n styles: []\r\n})\r\nexport class AddBookComponent implements OnInit {\r\n\r\n constructor() { }\r\n\r\n ngOnInit() { }\r\n\r\n saveBook(formValues: any): void {\r\n let newBook: Book = formValues;\r\n newBook.bookID = 0;\r\n console.log(newBook);\r\n console.warn('Save new book not yet implemented.');\r\n }\r\n\r\n}\r\n","import { Component, OnInit } from '@angular/core';\r\n\r\nimport { Reader } from \"app/models/reader\";\r\n\r\n@Component({\r\n selector: 'app-add-reader',\r\n templateUrl: './add-reader.component.html',\r\n styles: []\r\n})\r\nexport class AddReaderComponent implements OnInit {\r\n\r\n constructor() { }\r\n\r\n ngOnInit() { }\r\n\r\n saveReader(formValues: any): void {\r\n let newReader: Reader = formValues;\r\n newReader.readerID = 0;\r\n console.log(newReader);\r\n console.warn('Save new reader not yet implemented.');\r\n }\r\n\r\n}\r\n","import { NgModule } from '@angular/core';\r\nimport { RouterModule, Routes } from '@angular/router';\r\n\r\nimport { AddBookComponent } from \"app/add-book/add-book.component\";\r\nimport { AddReaderComponent } from \"app/add-reader/add-reader.component\";\r\nimport { DashboardComponent } from \"app/dashboard/dashboard.component\";\r\nimport { EditBookComponent } from \"app/edit-book/edit-book.component\";\r\nimport { EditReaderComponent } from \"app/edit-reader/edit-reader.component\";\r\n\r\nconst routes: Routes = [\r\n { path: 'dashboard', component: DashboardComponent },\r\n { path: 'addbook', component: AddBookComponent },\r\n { path: 'addreader', component: AddReaderComponent },\r\n { path: 'editreader/:id', component: EditReaderComponent },\r\n { path: 'editbook/:id', component: EditBookComponent },\r\n { path: '', redirectTo: 'dashboard', pathMatch: 'full' }\r\n];\r\n\r\n@NgModule({\r\n imports: [RouterModule.forRoot(routes)],\r\n exports: [RouterModule]\r\n})\r\nexport class AppRoutingModule { }\r\n","import { Component } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'app-root',\r\n templateUrl: './app.component.html',\r\n styleUrls: ['./app.component.css']\r\n})\r\nexport class AppComponent {\r\n title = 'app';\r\n}\r\n","import { BrowserModule } from '@angular/platform-browser';\r\nimport { NgModule } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\n\r\nimport { AddBookComponent } from './add-book/add-book.component';\r\nimport { AddReaderComponent } from './add-reader/add-reader.component';\r\nimport { AppComponent } from './app.component';\r\nimport { AppRoutingModule } from './app-routing.module';\r\nimport { DashboardComponent } from './dashboard/dashboard.component';\r\nimport { EditBookComponent } from './edit-book/edit-book.component';\r\nimport { EditReaderComponent } from './edit-reader/edit-reader.component';\r\n\r\n@NgModule({\r\n declarations: [\r\n AppComponent,\r\n DashboardComponent,\r\n AddBookComponent,\r\n EditReaderComponent,\r\n EditBookComponent,\r\n AddReaderComponent\r\n ],\r\n imports: [\r\n BrowserModule,\r\n AppRoutingModule,\r\n FormsModule\r\n ],\r\n providers: [],\r\n bootstrap: [AppComponent]\r\n})\r\nexport class AppModule { }\r\n","import { Component, OnInit } from '@angular/core';\r\n\r\nimport { Book } from \"app/models/book\";\r\nimport { allBooks, allReaders } from 'app/data';\r\nimport { Reader } from \"app/models/reader\";\r\n\r\n@Component({\r\n selector: 'app-dashboard',\r\n templateUrl: './dashboard.component.html',\r\n styles: []\r\n})\r\nexport class DashboardComponent implements OnInit {\r\n\r\n allBooks: Book[] = allBooks;\r\n allReaders: Reader[] = allReaders;\r\n mostPopularBook: Book = allBooks[0];\r\n\r\n constructor() { }\r\n\r\n ngOnInit() {\r\n }\r\n\r\n deleteBook(bookID: number): void {\r\n console.warn(`Delete book not yet implemented (bookID: ${bookID}).`);\r\n }\r\n\r\n deleteReader(readerID: number): void {\r\n console.warn(`Delete reader not yet implemented (readerID: ${readerID}).`);\r\n }\r\n\r\n}\r\n","import { Book } from \"app/models/book\";\r\nimport { Reader } from \"app/models/reader\";\r\n\r\nexport const allReaders: Reader[] = [\r\n { readerID: 1, name: 'Marie', weeklyReadingGoal: 400, totalMinutesRead: 5600 },\r\n { readerID: 2, name: 'Daniel', weeklyReadingGoal: 210, totalMinutesRead: 3000 },\r\n { readerID: 3, name: 'Lanier', weeklyReadingGoal: 140, totalMinutesRead: 600 }\r\n ];\r\n\r\nexport const allBooks: Book[] = [\r\n { bookID: 1, title: 'Goodnight Moon', author: 'Margaret Wise Brown', publicationYear: 1953 },\r\n { bookID: 2, title: 'Green Eggs and Ham', author: 'Dr. Seuss', publicationYear: 1960 },\r\n { bookID: 3, title: 'Where the Wild Things Are', author: 'Maurice Sendak', publicationYear: 1963 },\r\n { bookID: 4, title: 'The Hobbit', author: 'J. R. R. Tolkien', publicationYear: 1937 },\r\n { bookID: 5, title: 'Curious George', author: 'H. A. Rey', publicationYear: 1941 },\r\n { bookID: 6, title: 'Alice\\'s Adventures in Wonderland', author: 'Lewis Carroll', publicationYear: 1865 },\r\n];","import { Component, OnInit } from '@angular/core';\r\nimport { ActivatedRoute } from '@angular/router';\r\n\r\nimport { Book } from 'app/models/book';\r\nimport { allBooks } from 'app/data';\r\n\r\n@Component({\r\n selector: 'app-edit-book',\r\n templateUrl: './edit-book.component.html',\r\n styles: []\r\n})\r\nexport class EditBookComponent implements OnInit {\r\n\r\n selectedBook: Book;\r\n\r\n constructor(private route: ActivatedRoute) { }\r\n\r\n ngOnInit() {\r\n let bookID: number = parseInt(this.route.snapshot.params['id']);\r\n this.selectedBook = allBooks.find(book => book.bookID === bookID);\r\n }\r\n\r\n setMostPopular(): void {\r\n console.warn('Setting most popular book not yet implemented.');\r\n }\r\n\r\n saveChanges(): void {\r\n console.warn('Save changes to book not yet implemented.');\r\n }\r\n}\r\n","import { Component, OnInit } from '@angular/core';\r\nimport { ActivatedRoute } from '@angular/router';\r\n\r\nimport { allReaders } from 'app/data';\r\nimport { Reader } from \"app/models/reader\";\r\n\r\n@Component({\r\n selector: 'app-edit-reader',\r\n templateUrl: './edit-reader.component.html',\r\n styles: []\r\n})\r\nexport class EditReaderComponent implements OnInit {\r\n\r\n selectedReader: Reader;\r\n\r\n constructor(private route: ActivatedRoute) { }\r\n\r\n ngOnInit() {\r\n let readerID: number = parseInt(this.route.snapshot.params['id']);\r\n this.selectedReader = allReaders.find(reader => reader.readerID === readerID);\r\n }\r\n\r\n saveChanges() {\r\n console.warn('Save reader not yet implemented.');\r\n }\r\n}\r\n","// The file contents for the current environment will overwrite these during build.\r\n// The build system defaults to the dev environment which uses `environment.ts`, but if you do\r\n// `ng build --env=prod` then `environment.prod.ts` will be used instead.\r\n// The list of which env maps to which file can be found in `.angular-cli.json`.\r\n\r\nexport const environment = {\r\n production: false\r\n};\r\n","import { enableProdMode } from '@angular/core';\r\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\r\n\r\nimport { AppModule } from './app/app.module';\r\nimport { environment } from './environments/environment';\r\n\r\nif (environment.production) {\r\n enableProdMode();\r\n}\r\n\r\nplatformBrowserDynamic().bootstrapModule(AppModule);\r\n","export default \"\\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJhcHAuY29tcG9uZW50LmNzcyJ9 */\";","export default \"\";","export default \"\";","export default \"\\r\\n\\r\\n\\r\\n\";","export default \"\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
All Books
\\r\\n \\r\\n
\\r\\n
\\r\\n {{book.title}}\\r\\n Edit \\r\\n Delete\\r\\n \\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
All Readers
\\r\\n \\r\\n
\\r\\n
\\r\\n {{reader.name}}\\r\\n Edit\\r\\n Delete \\r\\n \\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
Most Popular Book
\\r\\n \\r\\n
\\r\\n {{mostPopularBook.title}} by {{mostPopularBook.author}}\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\";","export default \"\";","export default \"\";"],"sourceRoot":"webpack:///"}
--------------------------------------------------------------------------------
/dist/runtime.js:
--------------------------------------------------------------------------------
1 | /******/ (() => { // webpackBootstrap
2 | /******/ "use strict";
3 | /******/ var __webpack_modules__ = ({});
4 | /************************************************************************/
5 | /******/ // The module cache
6 | /******/ var __webpack_module_cache__ = {};
7 | /******/
8 | /******/ // The require function
9 | /******/ function __webpack_require__(moduleId) {
10 | /******/ // Check if module is in cache
11 | /******/ var cachedModule = __webpack_module_cache__[moduleId];
12 | /******/ if (cachedModule !== undefined) {
13 | /******/ return cachedModule.exports;
14 | /******/ }
15 | /******/ // Create a new module (and put it into the cache)
16 | /******/ var module = __webpack_module_cache__[moduleId] = {
17 | /******/ // no module.id needed
18 | /******/ // no module.loaded needed
19 | /******/ exports: {}
20 | /******/ };
21 | /******/
22 | /******/ // Execute the module function
23 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
24 | /******/
25 | /******/ // Return the exports of the module
26 | /******/ return module.exports;
27 | /******/ }
28 | /******/
29 | /******/ // expose the modules object (__webpack_modules__)
30 | /******/ __webpack_require__.m = __webpack_modules__;
31 | /******/
32 | /************************************************************************/
33 | /******/ /* webpack/runtime/chunk loaded */
34 | /******/ (() => {
35 | /******/ var deferred = [];
36 | /******/ __webpack_require__.O = (result, chunkIds, fn, priority) => {
37 | /******/ if(chunkIds) {
38 | /******/ priority = priority || 0;
39 | /******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
40 | /******/ deferred[i] = [chunkIds, fn, priority];
41 | /******/ return;
42 | /******/ }
43 | /******/ var notFulfilled = Infinity;
44 | /******/ for (var i = 0; i < deferred.length; i++) {
45 | /******/ var [chunkIds, fn, priority] = deferred[i];
46 | /******/ var fulfilled = true;
47 | /******/ for (var j = 0; j < chunkIds.length; j++) {
48 | /******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
49 | /******/ chunkIds.splice(j--, 1);
50 | /******/ } else {
51 | /******/ fulfilled = false;
52 | /******/ if(priority < notFulfilled) notFulfilled = priority;
53 | /******/ }
54 | /******/ }
55 | /******/ if(fulfilled) {
56 | /******/ deferred.splice(i--, 1)
57 | /******/ result = fn();
58 | /******/ }
59 | /******/ }
60 | /******/ return result;
61 | /******/ };
62 | /******/ })();
63 | /******/
64 | /******/ /* webpack/runtime/compat get default export */
65 | /******/ (() => {
66 | /******/ // getDefaultExport function for compatibility with non-harmony modules
67 | /******/ __webpack_require__.n = (module) => {
68 | /******/ var getter = module && module.__esModule ?
69 | /******/ () => (module['default']) :
70 | /******/ () => (module);
71 | /******/ __webpack_require__.d(getter, { a: getter });
72 | /******/ return getter;
73 | /******/ };
74 | /******/ })();
75 | /******/
76 | /******/ /* webpack/runtime/define property getters */
77 | /******/ (() => {
78 | /******/ // define getter functions for harmony exports
79 | /******/ __webpack_require__.d = (exports, definition) => {
80 | /******/ for(var key in definition) {
81 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
82 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
83 | /******/ }
84 | /******/ }
85 | /******/ };
86 | /******/ })();
87 | /******/
88 | /******/ /* webpack/runtime/hasOwnProperty shorthand */
89 | /******/ (() => {
90 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
91 | /******/ })();
92 | /******/
93 | /******/ /* webpack/runtime/make namespace object */
94 | /******/ (() => {
95 | /******/ // define __esModule on exports
96 | /******/ __webpack_require__.r = (exports) => {
97 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
98 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
99 | /******/ }
100 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
101 | /******/ };
102 | /******/ })();
103 | /******/
104 | /******/ /* webpack/runtime/jsonp chunk loading */
105 | /******/ (() => {
106 | /******/ // no baseURI
107 | /******/
108 | /******/ // object to store loaded and loading chunks
109 | /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
110 | /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
111 | /******/ var installedChunks = {
112 | /******/ "runtime": 0
113 | /******/ };
114 | /******/
115 | /******/ // no chunk on demand loading
116 | /******/
117 | /******/ // no prefetching
118 | /******/
119 | /******/ // no preloaded
120 | /******/
121 | /******/ // no HMR
122 | /******/
123 | /******/ // no HMR manifest
124 | /******/
125 | /******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);
126 | /******/
127 | /******/ // install a JSONP callback for chunk loading
128 | /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
129 | /******/ var [chunkIds, moreModules, runtime] = data;
130 | /******/ // add "moreModules" to the modules object,
131 | /******/ // then flag all "chunkIds" as loaded and fire callback
132 | /******/ var moduleId, chunkId, i = 0;
133 | /******/ for(moduleId in moreModules) {
134 | /******/ if(__webpack_require__.o(moreModules, moduleId)) {
135 | /******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
136 | /******/ }
137 | /******/ }
138 | /******/ if(runtime) var result = runtime(__webpack_require__);
139 | /******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
140 | /******/ for(;i < chunkIds.length; i++) {
141 | /******/ chunkId = chunkIds[i];
142 | /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
143 | /******/ installedChunks[chunkId][0]();
144 | /******/ }
145 | /******/ installedChunks[chunkIds[i]] = 0;
146 | /******/ }
147 | /******/ return __webpack_require__.O(result);
148 | /******/ }
149 | /******/
150 | /******/ var chunkLoadingGlobal = self["webpackChunkbooktracker"] = self["webpackChunkbooktracker"] || [];
151 | /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
152 | /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
153 | /******/ })();
154 | /******/
155 | /************************************************************************/
156 | /******/
157 | /******/
158 | /******/ })()
159 | ;
160 | //# sourceMappingURL=runtime.js.map
--------------------------------------------------------------------------------
/dist/runtime.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack/bootstrap","webpack/runtime/chunk loaded","webpack/runtime/compat get default export","webpack/runtime/define property getters","webpack/runtime/hasOwnProperty shorthand","webpack/runtime/make namespace object","webpack/runtime/jsonp chunk loading"],"names":[],"mappings":";;;;UAAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;UAEA;UACA;;;;;WCzBA;WACA;WACA;WACA;WACA,8BAA8B,wCAAwC;WACtE;WACA;WACA;WACA;WACA,gBAAgB,qBAAqB;WACrC;WACA;WACA,iBAAiB,qBAAqB;WACtC;WACA;WACA,IAAI;WACJ;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,E;;;;;WC1BA;WACA;WACA;WACA;WACA;WACA,gCAAgC,YAAY;WAC5C;WACA,E;;;;;WCPA;WACA;WACA;WACA;WACA,wCAAwC,yCAAyC;WACjF;WACA;WACA,E;;;;;WCPA,wF;;;;;WCAA;WACA;WACA;WACA,sDAAsD,kBAAkB;WACxE;WACA,+CAA+C,cAAc;WAC7D,E;;;;;WCNA;;WAEA;WACA;WACA;WACA;WACA;WACA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,MAAM,oBAAoB;WAC1B;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA,4G","file":"runtime.js","sourcesContent":["// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tresult = fn();\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t\"runtime\": 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tfor(moduleId in moreModules) {\n\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t}\n\t}\n\tif(runtime) var result = runtime(__webpack_require__);\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkIds[i]] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkbooktracker\"] = self[\"webpackChunkbooktracker\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));"],"sourceRoot":"webpack:///"}
--------------------------------------------------------------------------------
/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { BooktrackerPage } from './app.po';
2 |
3 | describe('booktracker App', () => {
4 | let page: BooktrackerPage;
5 |
6 | beforeEach(() => {
7 | page = new BooktrackerPage();
8 | });
9 |
10 | it('should display welcome message', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toEqual('Welcome to app!!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/e2e/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, by, element } from 'protractor';
2 |
3 | export class BooktrackerPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.css('app-root h1')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/e2e/tsconfig.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/e2e",
5 | "module": "commonjs",
6 | "target": "es5",
7 | "types": [
8 | "jasmine",
9 | "jasminewd2",
10 | "node"
11 | ]
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/0.13/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage'),
13 | require('@angular-devkit/build-angular/plugins/karma')
14 | ],
15 | client:{
16 | clearContext: false // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
20 | fixWebpackSourcePaths: true
21 | },
22 |
23 | reporters: ['progress', 'kjhtml'],
24 | port: 9876,
25 | colors: true,
26 | logLevel: config.LOG_INFO,
27 | autoWatch: true,
28 | browsers: ['Chrome'],
29 | singleRun: false
30 | });
31 | };
32 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "booktracker",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "ng": "ng",
7 | "start": "concurrently --kill-others \"ng build --watch --no-delete-output-path\" \"node server.js\"",
8 | "build": "ng build && node server.js",
9 | "test": "ng test",
10 | "lint": "ng lint",
11 | "e2e": "ng e2e"
12 | },
13 | "private": true,
14 | "dependencies": {
15 | "@angular/animations": "12.1.1",
16 | "@angular/common": "12.1.1",
17 | "@angular/compiler": "12.1.1",
18 | "@angular/core": "12.1.1",
19 | "@angular/forms": "12.1.1",
20 | "@angular/platform-browser": "12.1.1",
21 | "@angular/platform-browser-dynamic": "12.1.1",
22 | "@angular/router": "12.1.1",
23 | "rxjs": "6.6.0",
24 | "tslib": "2.0.0",
25 | "zone.js": "~0.11.4",
26 | "body-parser": "1.19.0",
27 | "bootstrap": "3.4.1",
28 | "cookie-parser": "1.4.5",
29 | "debug": "4.3.1",
30 | "express": "4.17.1",
31 | "morgan": "1.10.0",
32 | "serve-favicon": "2.5.0"
33 | },
34 | "devDependencies": {
35 | "@angular-devkit/build-angular": "12.1.1",
36 | "@angular/cli": "12.1.1",
37 | "@angular/compiler-cli": "12.1.1",
38 | "@types/jasmine": "3.6.0",
39 | "@types/node": "12.11.1",
40 | "codelyzer": "6.0.0",
41 | "jasmine-core": "3.6.0",
42 | "jasmine-spec-reporter": "5.0.0",
43 | "karma": "6.3.4",
44 | "karma-chrome-launcher": "3.1.0",
45 | "karma-coverage": "2.0.3",
46 | "karma-jasmine": "4.0.0",
47 | "karma-jasmine-html-reporter": "1.5.0",
48 | "protractor": "7.0.0",
49 | "ts-node": "8.3.0",
50 | "tslint": "6.1.0",
51 | "typescript": "4.3.5",
52 | "concurrently": "5.3.0"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration file, see link for more information
2 | // https://github.com/angular/protractor/blob/master/lib/config.ts
3 |
4 | const { SpecReporter } = require('jasmine-spec-reporter');
5 |
6 | exports.config = {
7 | allScriptsTimeout: 11000,
8 | specs: [
9 | './e2e/**/*.e2e-spec.ts'
10 | ],
11 | capabilities: {
12 | 'browserName': 'chrome'
13 | },
14 | directConnect: true,
15 | baseUrl: 'http://localhost:4200/',
16 | framework: 'jasmine',
17 | jasmineNodeOpts: {
18 | showColors: true,
19 | defaultTimeoutInterval: 30000,
20 | print: function() {}
21 | },
22 | onPrepare() {
23 | require('ts-node').register({
24 | project: 'e2e/tsconfig.e2e.json'
25 | });
26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var path = require('path');
3 | var favicon = require('serve-favicon');
4 | var logger = require('morgan');
5 | var cookieParser = require('cookie-parser');
6 | var bodyParser = require('body-parser');
7 |
8 | var routes = require('./server/routes/index');
9 | var readers = require('./server/routes/readers');
10 | var books = require('./server/routes/books');
11 | var errors = require('./server/routes/errors');
12 |
13 | var app = express();
14 |
15 | // view engine setup
16 | app.set('views', path.join(__dirname, '/server/views'));
17 | app.set('view engine', 'jade');
18 |
19 | app.use(favicon(path.join(__dirname, 'dist/favicon.ico')));
20 | app.use(logger('dev'));
21 | app.use(bodyParser.json());
22 | app.use(bodyParser.urlencoded({ extended: false }));
23 | app.use(cookieParser());
24 | app.use(express.static(path.join(__dirname, 'dist')));
25 |
26 | // app.use('/', routes);
27 | app.use('/api/readers', readers);
28 | app.use('/api/books', books);
29 | app.use('/api/errors', errors);
30 | app.get('*', function(req, res) {
31 | res.sendFile(path.join(__dirname, 'dist/index.html'));
32 | });
33 |
34 | // catch 404 and forward to error handler
35 | app.use(function(req, res, next) {
36 | var err = new Error('Not Found');
37 | err.status = 404;
38 | next(err);
39 | });
40 |
41 | // error handlers
42 |
43 | // development error handler
44 | // will print stacktrace
45 | if (app.get('env') === 'development') {
46 | app.use(function(err, req, res, next) {
47 | res.status(err.status || 500);
48 | res.render('error', {
49 | message: err.message,
50 | error: err
51 | });
52 | });
53 | }
54 |
55 | // production error handler
56 | // no stacktraces leaked to user
57 | app.use(function(err, req, res, next) {
58 | res.status(err.status || 500);
59 | res.render('error', {
60 | message: err.message,
61 | error: {}
62 | });
63 | });
64 |
65 | var debug = require('debug')('server');
66 |
67 | app.set('port', process.env.PORT || 3000);
68 |
69 | app.listen(app.get('port'));
70 |
71 | console.log('Listening on port: ' + app.get('port'));
72 |
73 | module.exports = app;
--------------------------------------------------------------------------------
/server/data/books.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "bookID": 1,
4 | "title": "Goodnight Moon",
5 | "author": "Margaret Wise Brown",
6 | "publicationYear": "1953"
7 | },
8 | {
9 | "bookID": 2,
10 | "title": "Green Eggs and Ham",
11 | "author": "Dr. Seuss",
12 | "publicationYear": "1960"
13 | },
14 | {
15 | "bookID": 3,
16 | "title": "Where the Wild Things Are",
17 | "author": "Maurice Sendak",
18 | "publicationYear": "1963"
19 | },
20 | {
21 | "bookID": 4,
22 | "title": "The Hobbit",
23 | "author": "J. R. R. Tolkien",
24 | "publicationYear": "1937"
25 | },
26 | {
27 | "bookID": 5,
28 | "title": "Curious George",
29 | "author": "H. A. Rey",
30 | "publicationYear": "1941"
31 | },
32 | {
33 | "bookID": 6,
34 | "title": "Alice's Adventures in Wonderland",
35 | "author": "Lewis Carroll",
36 | "publicationYear": "1865"
37 | }
38 | ]
--------------------------------------------------------------------------------
/server/data/readers.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "readerID": 1,
4 | "name": "Marie",
5 | "weeklyReadingGoal": 350,
6 | "totalMinutesRead": 5600
7 | },
8 | {
9 | "readerID": 2,
10 | "name": "Daniel",
11 | "weeklyReadingGoal": 210,
12 | "totalMinutesRead": 3000
13 | },
14 | {
15 | "readerID": 3,
16 | "name": "Lanier",
17 | "weeklyReadingGoal": 140,
18 | "totalMinutesRead": 600
19 | }
20 | ]
--------------------------------------------------------------------------------
/server/routes/books.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var fs = require('fs');
3 | var datafile = 'server/data/books.json';
4 | var router = express.Router();
5 |
6 | /* GET all books and POST new books */
7 | router.route('/')
8 | .get(function(req, res) {
9 | var data = getBookData();
10 | res.send(data);
11 | })
12 |
13 | .post(function(req, res) {
14 |
15 | var data = getBookData();
16 | var nextID = getNextAvailableID(data);
17 |
18 | var newBook = {
19 | bookID: nextID,
20 | title: req.body.title,
21 | author: req.body.author,
22 | publicationYear: req.body.publicationYear
23 | };
24 |
25 | data.push(newBook);
26 |
27 | saveBookData(data);
28 |
29 | // res.set('Content-Type', 'application/json');
30 | res.status(201).send(newBook);
31 | });
32 |
33 |
34 | /* GET, PUT and DELETE individual books */
35 | router.route('/:id')
36 |
37 | .get(function(req, res) {
38 |
39 | //console.log('Retrieving book id: ' + req.params.id);
40 |
41 | var data = getBookData();
42 |
43 | var matchingBooks = data.filter(function(item) {
44 | return item.bookID == req.params.id;
45 | });
46 |
47 | if(matchingBooks.length === 0) {
48 | res.sendStatus(404);
49 | } else {
50 | res.send(matchingBooks[0]);
51 | }
52 | })
53 |
54 | .delete(function(req, res) {
55 |
56 | var data = getBookData();
57 |
58 | var pos = data.map(function(e) {
59 | return e.bookID;
60 | }).indexOf(parseInt(req.params.id, 10));
61 |
62 | if (pos > -1) {
63 | data.splice(pos, 1);
64 | } else {
65 | res.sendStatus(404);
66 | }
67 |
68 | saveBookData(data);
69 | res.sendStatus(204);
70 |
71 | })
72 |
73 | .put(function(req, res) {
74 |
75 | var data = getBookData();
76 |
77 | var matchingBooks = data.filter(function(item) {
78 | return item.bookID == req.params.id;
79 | });
80 |
81 | if(matchingBooks.length === 0) {
82 | res.sendStatus(404);
83 | } else {
84 |
85 | var bookToUpdate = matchingBooks[0];
86 | bookToUpdate.title = req.body.title;
87 | bookToUpdate.author = req.body.author;
88 | bookToUpdate.publicationYear = req.body.publicationYear;
89 |
90 | saveBookData(data);
91 | res.sendStatus(204);
92 |
93 | }
94 | });
95 |
96 | function getNextAvailableID(allBooks) {
97 |
98 | var maxID = 0;
99 |
100 | allBooks.forEach(function(element, index, array) {
101 |
102 | if(element.bookID > maxID) {
103 | maxID = element.bookID;
104 | }
105 |
106 | });
107 |
108 | return ++maxID;
109 |
110 | }
111 |
112 | function getBookData() {
113 | var data = fs.readFileSync(datafile, 'utf8');
114 | return JSON.parse(data);
115 | }
116 |
117 | function saveBookData(data) {
118 | fs.writeFile(datafile, JSON.stringify(data, null, 4), function (err) {
119 | if (err) {
120 | console.log(err);
121 | }
122 | });
123 | }
124 |
125 | module.exports = router;
126 |
--------------------------------------------------------------------------------
/server/routes/errors.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var fs = require('fs');
3 | var router = express.Router();
4 |
5 | /* GET all books and POST new readers */
6 | router.route('/500')
7 | .get(function(req, res) {
8 | res.status(500).send('Book Tracker server error.');
9 | });
10 |
11 | router.route('/401')
12 | .get(function(req, res) {
13 | res.status(401).send('Book Tracker unauthorized.');
14 | });
15 |
16 | module.exports = router;
--------------------------------------------------------------------------------
/server/routes/index.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 |
4 | /* GET home page. */
5 | router.get('/', function(req, res) {
6 | res.render('index', { title: 'Express' });
7 | });
8 |
9 | module.exports = router;
10 |
--------------------------------------------------------------------------------
/server/routes/readers.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var fs = require('fs');
3 | var datafile = 'server/data/readers.json';
4 | var router = express.Router();
5 |
6 | /* GET all books and POST new readers */
7 | router.route('/')
8 | .get(function(req, res) {
9 | var data = getReaderData();
10 | res.send(data);
11 | })
12 |
13 | .post(function(req, res) {
14 |
15 | var data = getReaderData();
16 | var nextID = getNextAvailableID(data);
17 |
18 | var newReader = {
19 | readerID: nextID,
20 | name: req.body.name,
21 | weeklyReadingGoal: req.body.weeklyReadingGoal,
22 | totalMinutesRead: req.body.totalMinutesRead
23 | };
24 |
25 | data.push(newReader);
26 |
27 | saveReaderData(data);
28 |
29 | // res.set('Content-Type', 'application/json');
30 | res.status(201).send(newReader);
31 | });
32 |
33 |
34 | /* GET, PUT and DELETE individual readers */
35 | router.route('/:id')
36 |
37 | .get(function(req, res) {
38 |
39 | //console.log('Retrieving reader id: ' + req.params.id);
40 |
41 | var data = getReaderData();
42 |
43 | var matchingReaders = data.filter(function(item) {
44 | return item.readerID == req.params.id;
45 | });
46 |
47 | if(matchingReaders.length === 0) {
48 | res.sendStatus(404);
49 | } else {
50 | res.send(matchingReaders[0]);
51 | }
52 | })
53 |
54 | .delete(function(req, res) {
55 |
56 | var data = getReaderData();
57 |
58 | var pos = data.map(function(e) {
59 | return e.readerID;
60 | }).indexOf(parseInt(req.params.id, 10));
61 |
62 | if (pos > -1) {
63 | data.splice(pos, 1);
64 | } else {
65 | res.sendStatus(404);
66 | }
67 |
68 | saveReaderData(data);
69 | res.sendStatus(204);
70 |
71 | })
72 |
73 | .put(function(req, res) {
74 |
75 | var data = getReaderData();
76 |
77 | var matchingReaders = data.filter(function(item) {
78 | return item.readerID == req.params.id;
79 | });
80 |
81 | if(matchingReaders.length === 0) {
82 | res.sendStatus(404);
83 | } else {
84 |
85 | var readerToUpdate = matchingReaders[0];
86 | readerToUpdate.name = req.body.name;
87 | readerToUpdate.weeklyReadingGoal = req.body.weeklyReadingGoal;
88 | readerToUpdate.totalMinutesRead = req.body.totalMinutesRead;
89 |
90 | saveReaderData(data);
91 | res.sendStatus(204);
92 |
93 | }
94 | });
95 |
96 | function getNextAvailableID(allReaders) {
97 |
98 | var maxID = 0;
99 |
100 | allReaders.forEach(function(element, index, array) {
101 |
102 | if(element.readerID > maxID) {
103 | maxID = element.readerID;
104 | }
105 |
106 | });
107 |
108 | return ++maxID;
109 |
110 | }
111 |
112 | function getReaderData() {
113 | var data = fs.readFileSync(datafile, 'utf8');
114 | return JSON.parse(data);
115 | }
116 |
117 | function saveReaderData(data) {
118 | fs.writeFile(datafile, JSON.stringify(data, null, 4), function (err) {
119 | if (err) {
120 | console.log(err);
121 | }
122 | });
123 | }
124 |
125 | module.exports = router;
126 |
--------------------------------------------------------------------------------
/server/views/error.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= message
5 | h2= error.status
6 | pre #{error.stack}
7 |
--------------------------------------------------------------------------------
/server/views/index.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= title
5 | p Welcome to #{title}
6 |
--------------------------------------------------------------------------------
/server/views/layout.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title= title
5 | link(rel='stylesheet', href='/stylesheets/style.css')
6 | body
7 | block content
--------------------------------------------------------------------------------
/src/app/add-book/add-book.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/add-book/add-book.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | import { Book } from "app/models/book";
4 |
5 | @Component({
6 | selector: 'app-add-book',
7 | templateUrl: './add-book.component.html',
8 | styles: []
9 | })
10 | export class AddBookComponent implements OnInit {
11 |
12 | constructor() { }
13 |
14 | ngOnInit() { }
15 |
16 | saveBook(formValues: any): void {
17 | let newBook: Book = formValues;
18 | newBook.bookID = 0;
19 | console.log(newBook);
20 | console.warn('Save new book not yet implemented.');
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/app/add-reader/add-reader.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/add-reader/add-reader.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | import { Reader } from "app/models/reader";
4 |
5 | @Component({
6 | selector: 'app-add-reader',
7 | templateUrl: './add-reader.component.html',
8 | styles: []
9 | })
10 | export class AddReaderComponent implements OnInit {
11 |
12 | constructor() { }
13 |
14 | ngOnInit() { }
15 |
16 | saveReader(formValues: any): void {
17 | let newReader: Reader = formValues;
18 | newReader.readerID = 0;
19 | console.log(newReader);
20 | console.warn('Save new reader not yet implemented.');
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { RouterModule, Routes } from '@angular/router';
3 |
4 | import { AddBookComponent } from "app/add-book/add-book.component";
5 | import { AddReaderComponent } from "app/add-reader/add-reader.component";
6 | import { DashboardComponent } from "app/dashboard/dashboard.component";
7 | import { EditBookComponent } from "app/edit-book/edit-book.component";
8 | import { EditReaderComponent } from "app/edit-reader/edit-reader.component";
9 |
10 | const routes: Routes = [
11 | { path: 'dashboard', component: DashboardComponent },
12 | { path: 'addbook', component: AddBookComponent },
13 | { path: 'addreader', component: AddReaderComponent },
14 | { path: 'editreader/:id', component: EditReaderComponent },
15 | { path: 'editbook/:id', component: EditBookComponent },
16 | { path: '', redirectTo: 'dashboard', pathMatch: 'full' }
17 | ];
18 |
19 | @NgModule({
20 | imports: [RouterModule.forRoot(routes)],
21 | exports: [RouterModule]
22 | })
23 | export class AppRoutingModule { }
24 |
--------------------------------------------------------------------------------
/src/app/app.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bricewilson/angular-services/8567805366718b5ebc4ed9554f4b649a0401533b/src/app/app.component.css
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-root',
5 | templateUrl: './app.component.html',
6 | styleUrls: ['./app.component.css']
7 | })
8 | export class AppComponent {
9 | title = 'app';
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { NgModule } from '@angular/core';
3 | import { FormsModule } from '@angular/forms';
4 |
5 | import { AddBookComponent } from './add-book/add-book.component';
6 | import { AddReaderComponent } from './add-reader/add-reader.component';
7 | import { AppComponent } from './app.component';
8 | import { AppRoutingModule } from './app-routing.module';
9 | import { DashboardComponent } from './dashboard/dashboard.component';
10 | import { EditBookComponent } from './edit-book/edit-book.component';
11 | import { EditReaderComponent } from './edit-reader/edit-reader.component';
12 |
13 | @NgModule({
14 | declarations: [
15 | AppComponent,
16 | DashboardComponent,
17 | AddBookComponent,
18 | EditReaderComponent,
19 | EditBookComponent,
20 | AddReaderComponent
21 | ],
22 | imports: [
23 | BrowserModule,
24 | AppRoutingModule,
25 | FormsModule
26 | ],
27 | providers: [],
28 | bootstrap: [AppComponent]
29 | })
30 | export class AppModule { }
31 |
--------------------------------------------------------------------------------
/src/app/dashboard/dashboard.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
All Books
7 |
8 |
9 |
10 | {{book.title}}
11 | Edit
12 | Delete
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
All Readers
23 |
24 |
25 |
26 | {{reader.name}}
27 | Edit
28 | Delete
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
Most Popular Book
39 |
40 |
41 | {{mostPopularBook.title}} by {{mostPopularBook.author}}
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/app/dashboard/dashboard.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | import { Book } from "app/models/book";
4 | import { allBooks, allReaders } from 'app/data';
5 | import { Reader } from "app/models/reader";
6 |
7 | @Component({
8 | selector: 'app-dashboard',
9 | templateUrl: './dashboard.component.html',
10 | styles: []
11 | })
12 | export class DashboardComponent implements OnInit {
13 |
14 | allBooks: Book[] = allBooks;
15 | allReaders: Reader[] = allReaders;
16 | mostPopularBook: Book = allBooks[0];
17 |
18 | constructor() { }
19 |
20 | ngOnInit() {
21 | }
22 |
23 | deleteBook(bookID: number): void {
24 | console.warn(`Delete book not yet implemented (bookID: ${bookID}).`);
25 | }
26 |
27 | deleteReader(readerID: number): void {
28 | console.warn(`Delete reader not yet implemented (readerID: ${readerID}).`);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/app/data.ts:
--------------------------------------------------------------------------------
1 | import { Book } from "app/models/book";
2 | import { Reader } from "app/models/reader";
3 |
4 | export const allReaders: Reader[] = [
5 | { readerID: 1, name: 'Marie', weeklyReadingGoal: 400, totalMinutesRead: 5600 },
6 | { readerID: 2, name: 'Daniel', weeklyReadingGoal: 210, totalMinutesRead: 3000 },
7 | { readerID: 3, name: 'Lanier', weeklyReadingGoal: 140, totalMinutesRead: 600 }
8 | ];
9 |
10 | export const allBooks: Book[] = [
11 | { bookID: 1, title: 'Goodnight Moon', author: 'Margaret Wise Brown', publicationYear: 1953 },
12 | { bookID: 2, title: 'Green Eggs and Ham', author: 'Dr. Seuss', publicationYear: 1960 },
13 | { bookID: 3, title: 'Where the Wild Things Are', author: 'Maurice Sendak', publicationYear: 1963 },
14 | { bookID: 4, title: 'The Hobbit', author: 'J. R. R. Tolkien', publicationYear: 1937 },
15 | { bookID: 5, title: 'Curious George', author: 'H. A. Rey', publicationYear: 1941 },
16 | { bookID: 6, title: 'Alice\'s Adventures in Wonderland', author: 'Lewis Carroll', publicationYear: 1865 },
17 | ];
--------------------------------------------------------------------------------
/src/app/edit-book/edit-book.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/edit-book/edit-book.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute } from '@angular/router';
3 |
4 | import { Book } from 'app/models/book';
5 | import { allBooks } from 'app/data';
6 |
7 | @Component({
8 | selector: 'app-edit-book',
9 | templateUrl: './edit-book.component.html',
10 | styles: []
11 | })
12 | export class EditBookComponent implements OnInit {
13 |
14 | selectedBook: Book;
15 |
16 | constructor(private route: ActivatedRoute) { }
17 |
18 | ngOnInit() {
19 | let bookID: number = parseInt(this.route.snapshot.params['id']);
20 | this.selectedBook = allBooks.find(book => book.bookID === bookID);
21 | }
22 |
23 | setMostPopular(): void {
24 | console.warn('Setting most popular book not yet implemented.');
25 | }
26 |
27 | saveChanges(): void {
28 | console.warn('Save changes to book not yet implemented.');
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/app/edit-reader/edit-reader.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/edit-reader/edit-reader.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute } from '@angular/router';
3 |
4 | import { allReaders } from 'app/data';
5 | import { Reader } from "app/models/reader";
6 |
7 | @Component({
8 | selector: 'app-edit-reader',
9 | templateUrl: './edit-reader.component.html',
10 | styles: []
11 | })
12 | export class EditReaderComponent implements OnInit {
13 |
14 | selectedReader: Reader;
15 |
16 | constructor(private route: ActivatedRoute) { }
17 |
18 | ngOnInit() {
19 | let readerID: number = parseInt(this.route.snapshot.params['id']);
20 | this.selectedReader = allReaders.find(reader => reader.readerID === readerID);
21 | }
22 |
23 | saveChanges() {
24 | console.warn('Save reader not yet implemented.');
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/app/models/book.ts:
--------------------------------------------------------------------------------
1 | export class Book {
2 | bookID: number;
3 | title: string;
4 | author: string;
5 | publicationYear: number;
6 | }
7 |
--------------------------------------------------------------------------------
/src/app/models/reader.ts:
--------------------------------------------------------------------------------
1 | export class Reader {
2 | readerID: number;
3 | name: string;
4 | weeklyReadingGoal: number;
5 | totalMinutesRead: number;
6 | }
7 |
--------------------------------------------------------------------------------
/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bricewilson/angular-services/8567805366718b5ebc4ed9554f4b649a0401533b/src/assets/.gitkeep
--------------------------------------------------------------------------------
/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `.angular-cli.json`.
5 |
6 | export const environment = {
7 | production: false
8 | };
9 |
--------------------------------------------------------------------------------
/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bricewilson/angular-services/8567805366718b5ebc4ed9554f4b649a0401533b/src/favicon.ico
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Book Tracker
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule);
12 |
--------------------------------------------------------------------------------
/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE11 requires the following for NgClass support on SVG elements */
22 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
23 |
24 | /**
25 | * Web Animations `@angular/platform-browser/animations`
26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
28 | */
29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
30 |
31 | /**
32 | * By default, zone.js will patch all possible macroTask and DomEvents
33 | * user can disable parts of macroTask/DomEvents patch by setting following flags
34 | * because those flags need to be set before `zone.js` being loaded, and webpack
35 | * will put import in the top of bundle, so user need to create a separate file
36 | * in this directory (for example: zone-flags.ts), and put the following flags
37 | * into that file, and then add the following code before importing zone.js.
38 | * import './zone-flags';
39 | *
40 | * The flags allowed in zone-flags.ts are listed here.
41 | *
42 | * The following flags will work for all browsers.
43 | *
44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
47 | *
48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
50 | *
51 | * (window as any).__Zone_enable_cross_context_check = true;
52 | *
53 | */
54 |
55 | /***************************************************************************************************
56 | * Zone JS is required by default for Angular itself.
57 | */
58 | import 'zone.js'; // Included with Angular CLI.
59 |
60 |
61 | /***************************************************************************************************
62 | * APPLICATION IMPORTS
63 | */
64 |
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bricewilson/angular-services/8567805366718b5ebc4ed9554f4b649a0401533b/src/styles.css
--------------------------------------------------------------------------------
/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/long-stack-trace-zone';
4 | import 'zone.js/dist/proxy.js';
5 | import 'zone.js/dist/sync-test';
6 | import 'zone.js/dist/jasmine-patch';
7 | import 'zone.js/dist/async-test';
8 | import 'zone.js/dist/fake-async-test';
9 | import { getTestBed } from '@angular/core/testing';
10 | import {
11 | BrowserDynamicTestingModule,
12 | platformBrowserDynamicTesting
13 | } from '@angular/platform-browser-dynamic/testing';
14 |
15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
16 | declare const __karma__: any;
17 | declare const require: any;
18 |
19 | // Prevent Karma from running prematurely.
20 | __karma__.loaded = function () {};
21 |
22 | // First, initialize the Angular testing environment.
23 | getTestBed().initTestEnvironment(
24 | BrowserDynamicTestingModule,
25 | platformBrowserDynamicTesting()
26 | );
27 | // Then we find all the tests.
28 | const context = require.context('./', true, /\.spec\.ts$/);
29 | // And load the modules.
30 | context.keys().map(context);
31 | // Finally, start Karma to run the tests.
32 | __karma__.start();
33 |
--------------------------------------------------------------------------------
/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | /* SystemJS module definition */
2 | declare var module: NodeModule;
3 | interface NodeModule {
4 | id: string;
5 | }
6 |
--------------------------------------------------------------------------------
/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/app",
6 | "types": []
7 | },
8 | "files": [
9 | "src/main.ts",
10 | "src/polyfills.ts"
11 | ],
12 | "include": [
13 | "src/**/*.d.ts"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": "./src/",
6 | "outDir": "./dist/out-tsc",
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": true,
9 | "strictPropertyInitialization": false,
10 | "strictNullChecks": false,
11 | "noImplicitReturns": true,
12 | "noFallthroughCasesInSwitch": true,
13 | "sourceMap": true,
14 | "declaration": false,
15 | "downlevelIteration": true,
16 | "experimentalDecorators": true,
17 | "moduleResolution": "node",
18 | "importHelpers": true,
19 | "target": "es2015",
20 | "module": "es2020",
21 | "lib": [
22 | "es2018",
23 | "dom"
24 | ]
25 | },
26 | "angularCompilerOptions": {
27 | "strictInjectionParameters": true,
28 | "strictInputAccessModifiers": true,
29 | "strictTemplates": true
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/spec",
6 | "types": [
7 | "jasmine"
8 | ]
9 | },
10 | "files": [
11 | "src/test.ts",
12 | "src/polyfills.ts"
13 | ],
14 | "include": [
15 | "src/**/*.spec.ts",
16 | "src/**/*.d.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "arrow-return-shorthand": true,
7 | "callable-types": true,
8 | "class-name": true,
9 | "comment-format": [
10 | true,
11 | "check-space"
12 | ],
13 | "curly": true,
14 | "eofline": true,
15 | "forin": true,
16 | "import-blacklist": [
17 | true
18 | ],
19 | "import-spacing": true,
20 | "indent": [
21 | true,
22 | "spaces"
23 | ],
24 | "interface-over-type-literal": true,
25 | "label-position": true,
26 | "max-line-length": [
27 | true,
28 | 140
29 | ],
30 | "member-access": false,
31 | "member-ordering": [
32 | true,
33 | "static-before-instance",
34 | "variables-before-functions"
35 | ],
36 | "no-arg": true,
37 | "no-bitwise": true,
38 | "no-console": [
39 | true,
40 | "debug",
41 | "info",
42 | "time",
43 | "timeEnd",
44 | "trace"
45 | ],
46 | "no-construct": true,
47 | "no-debugger": true,
48 | "no-duplicate-super": true,
49 | "no-empty": false,
50 | "no-empty-interface": true,
51 | "no-eval": true,
52 | "no-inferrable-types": [
53 | true,
54 | "ignore-params"
55 | ],
56 | "no-misused-new": true,
57 | "no-non-null-assertion": true,
58 | "no-shadowed-variable": true,
59 | "no-string-literal": false,
60 | "no-string-throw": true,
61 | "no-switch-case-fall-through": true,
62 | "no-trailing-whitespace": true,
63 | "no-unnecessary-initializer": true,
64 | "no-unused-expression": true,
65 | "no-use-before-declare": true,
66 | "no-var-keyword": true,
67 | "object-literal-sort-keys": false,
68 | "one-line": [
69 | true,
70 | "check-open-brace",
71 | "check-catch",
72 | "check-else",
73 | "check-whitespace"
74 | ],
75 | "prefer-const": true,
76 | "quotemark": [
77 | true,
78 | "single"
79 | ],
80 | "radix": true,
81 | "semicolon": [
82 | "always"
83 | ],
84 | "triple-equals": [
85 | true,
86 | "allow-null-check"
87 | ],
88 | "typedef-whitespace": [
89 | true,
90 | {
91 | "call-signature": "nospace",
92 | "index-signature": "nospace",
93 | "parameter": "nospace",
94 | "property-declaration": "nospace",
95 | "variable-declaration": "nospace"
96 | }
97 | ],
98 | "typeof-compare": true,
99 | "unified-signatures": true,
100 | "variable-name": false,
101 | "whitespace": [
102 | true,
103 | "check-branch",
104 | "check-decl",
105 | "check-operator",
106 | "check-separator",
107 | "check-type"
108 | ],
109 | "directive-selector": [
110 | true,
111 | "attribute",
112 | "app",
113 | "camelCase"
114 | ],
115 | "component-selector": [
116 | true,
117 | "element",
118 | "app",
119 | "kebab-case"
120 | ],
121 | "use-input-property-decorator": true,
122 | "use-output-property-decorator": true,
123 | "use-host-property-decorator": true,
124 | "no-input-rename": true,
125 | "no-output-rename": true,
126 | "use-life-cycle-interface": true,
127 | "use-pipe-transform-interface": true,
128 | "component-class-suffix": true,
129 | "directive-class-suffix": true,
130 | "no-access-missing-member": true,
131 | "templates-use-public": true,
132 | "invoke-injectable": true
133 | }
134 | }
135 |
--------------------------------------------------------------------------------