├── .editorconfig ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── karma-shim.js ├── karma.conf.js ├── package.json ├── protractor.conf.js ├── src ├── app │ ├── app.component.e2e-spec.js │ ├── app.component.html │ ├── app.component.scss │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── app.routing.ts │ └── shared │ │ ├── api.service.spec.ts │ │ ├── api.service.ts │ │ ├── dropdown.directive.ts │ │ ├── filter-pipe.ts │ │ ├── index.ts │ │ └── letter-bold.pipe.ts ├── main.ts ├── polyfills.ts ├── public │ ├── img │ │ ├── angular.png │ │ └── favicon.ico │ ├── index.html │ └── service-worker.js ├── style │ └── app.scss └── vendor.ts ├── tsconfig.json ├── tslint.json ├── typedoc.json └── webpack.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 2 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Users Environment Variables 23 | .lock-wscript 24 | 25 | # OS generated files # 26 | .DS_Store 27 | ehthumbs.db 28 | Icon? 29 | Thumbs.db 30 | 31 | # Node Files # 32 | /node_modules 33 | /bower_components 34 | 35 | # Coverage # 36 | /coverage/ 37 | 38 | # Typing # 39 | /src/typings/tsd/ 40 | /typings/ 41 | /tsd_typings/ 42 | 43 | # Dist # 44 | /dist 45 | /public/__build__/ 46 | /src/*/__build__/ 47 | __build__/** 48 | .webpack.json 49 | 50 | # Doc # 51 | /doc/ 52 | 53 | # IDE # 54 | .idea/ 55 | *.swp 56 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | # 04 October 2016 4 | 5 | - Migrate to webpack 2 6 | 7 | # 18 September 2016 8 | 9 | - Using `awesome-typescript-loader` instead of `ts-loader`. 10 | 11 | # 5 September 2016 12 | 13 | - Migration to TS2 and @types 14 | 15 | ## 1 September 2016 16 | 17 | - Using RC6. 18 | 19 | ## 28 August 2016 20 | 21 | - Adding webpack-dashboard. 22 | 23 | ## 23 August 2016 24 | 25 | - Adding HMR support. 26 | 27 | ## 3 July 2016 28 | 29 | - Use html5mode instead of hash navigation. 30 | 31 | ## 24 June 2016 32 | 33 | - Be able to import Component's templates and styles without using require. 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ryan Lesson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Custom-autocomplete | [Lesson on Coding](https://www.youtube.com/watch?v=9MN-pi2GMw4) 2 | A custom autocomplete built with angular 4 frame work 3 | 4 | ### Running the app 5 | * clone/download the application. 6 | * run `npm install` 7 | * run `npm start` 8 | 9 | The angular skeleton: https://github.com/preboot/angular-webpack. 10 | -------------------------------------------------------------------------------- /karma-shim.js: -------------------------------------------------------------------------------- 1 | Error.stackTraceLimit = Infinity; 2 | 3 | require('core-js/client/shim'); 4 | require('reflect-metadata'); 5 | 6 | require('ts-helpers'); 7 | 8 | require('zone.js/dist/zone'); 9 | require('zone.js/dist/long-stack-trace-zone'); 10 | require('zone.js/dist/proxy'); 11 | require('zone.js/dist/sync-test'); 12 | require('zone.js/dist/jasmine-patch'); 13 | require('zone.js/dist/async-test'); 14 | require('zone.js/dist/fake-async-test'); 15 | 16 | /* 17 | Ok, this is kinda crazy. We can use the the context method on 18 | require that webpack created in order to tell webpack 19 | what files we actually want to require or import. 20 | Below, context will be a function/object with file names as keys. 21 | using that regex we are saying look in client/app and find 22 | any file that ends with '.spec.ts' and get its path. By passing in true 23 | we say do this recursively 24 | */ 25 | var appContext = require.context('./src', true, /\.spec\.ts/); 26 | 27 | // get all the files, for each file, call the context function 28 | // that will require the file and load it up here. Context will 29 | // loop and require those spec files here 30 | appContext.keys().forEach(appContext); 31 | 32 | // Select BrowserDomAdapter. 33 | // see https://github.com/AngularClass/angular2-webpack-starter/issues/124 34 | // Somewhere in the test setup 35 | var testing = require('@angular/core/testing'); 36 | var browser = require('@angular/platform-browser-dynamic/testing'); 37 | 38 | testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting()); 39 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | var webpackConfig = require('./webpack.config'); 4 | 5 | var ENV = process.env.npm_lifecycle_event; 6 | var isTestWatch = ENV === 'test-watch'; 7 | 8 | module.exports = function (config) { 9 | var _config = { 10 | 11 | // base path that will be used to resolve all patterns (eg. files, exclude) 12 | basePath: '', 13 | 14 | // frameworks to use 15 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 16 | frameworks: ['jasmine'], 17 | 18 | // list of files / patterns to load in the browser 19 | files: [ 20 | { pattern: './karma-shim.js', watched: false } 21 | ], 22 | 23 | // list of files to exclude 24 | exclude: [], 25 | 26 | // preprocess matching files before serving them to the browser 27 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 28 | preprocessors: { 29 | './karma-shim.js': ['webpack', 'sourcemap'] 30 | }, 31 | 32 | webpack: webpackConfig, 33 | 34 | webpackMiddleware: { 35 | // webpack-dev-middleware configuration 36 | // i. e. 37 | stats: 'errors-only' 38 | }, 39 | 40 | webpackServer: { 41 | noInfo: true // please don't spam the console when running in karma! 42 | }, 43 | 44 | // test results reporter to use 45 | // possible values: 'dots', 'progress', 'mocha' 46 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 47 | reporters: ["mocha"], 48 | 49 | // web server port 50 | port: 9876, 51 | 52 | // enable / disable colors in the output (reporters and logs) 53 | colors: true, 54 | 55 | // level of logging 56 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 57 | logLevel: config.LOG_INFO, 58 | 59 | // enable / disable watching file and executing tests whenever any file changes 60 | autoWatch: false, 61 | 62 | // start these browsers 63 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 64 | browsers: ['Chrome'], 65 | 66 | // Continuous Integration mode 67 | // if true, Karma captures browsers, runs the tests and exits 68 | singleRun: true 69 | }; 70 | 71 | if (!isTestWatch) { 72 | _config.reporters.push("coverage"); 73 | 74 | _config.coverageReporter = { 75 | dir: 'coverage/', 76 | reporters: [{ 77 | type: 'json', 78 | dir: 'coverage', 79 | subdir: 'json', 80 | file: 'coverage-final.json' 81 | }] 82 | }; 83 | } 84 | 85 | config.set(_config); 86 | 87 | }; 88 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "clean": "rimraf node_modules doc dist && npm cache clean", 7 | "clean-install": "npm run clean && npm install", 8 | "clean-start": "npm run clean-install && npm start", 9 | "watch": "webpack --watch --progress --profile", 10 | "build": "rimraf dist && webpack --progress --profile --bail", 11 | "server": "webpack-dev-server --inline --progress --port 8080", 12 | "webdriver-update": "webdriver-manager update", 13 | "webdriver-start": "webdriver-manager start", 14 | "lint": "tslint --force \"src/**/*.ts\"", 15 | "e2e": "protractor", 16 | "e2e-live": "protractor --elementExplorer", 17 | "pretest": "npm run lint", 18 | "test": "karma start", 19 | "posttest": "remap-istanbul -i coverage/json/coverage-final.json -o coverage/html -t html", 20 | "test-watch": "karma start --no-single-run --auto-watch", 21 | "ci": "npm run e2e && npm run test", 22 | "docs": "typedoc --options typedoc.json src/app/app.component.ts", 23 | "start": "npm run server", 24 | "start:hmr": "npm run server -- --hot", 25 | "postinstall": "npm run webdriver-update" 26 | }, 27 | "dependencies": { 28 | "@angular/common": "~4.2.6", 29 | "@angular/compiler": "~4.2.6", 30 | "@angular/core": "~4.2.6", 31 | "@angular/forms": "~4.2.6", 32 | "@angular/http": "~4.2.6", 33 | "@angular/platform-browser": "~4.2.6", 34 | "@angular/platform-browser-dynamic": "~4.2.6", 35 | "@angular/router": "~4.2.6", 36 | "core-js": "^2.4.1", 37 | "reflect-metadata": "^0.1.3", 38 | "tslib": "^1.7.1", 39 | "rxjs": "^5.0.1", 40 | "zone.js": "^0.8.10" 41 | }, 42 | "devDependencies": { 43 | "@angularclass/hmr": "^1.0.1", 44 | "@angularclass/hmr-loader": "^3.0.2", 45 | "@types/jasmine": "^2.5.41", 46 | "@types/node": "^6.0.38", 47 | "@types/selenium-webdriver": "2.53.39", 48 | "angular2-template-loader": "^0.6.0", 49 | "autoprefixer": "^6.3.2", 50 | "awesome-typescript-loader": "^3.1.2", 51 | "codelyzer": "2.0.0", 52 | "copy-webpack-plugin": "^4.0.0", 53 | "css-loader": "^0.28.4", 54 | "extract-text-webpack-plugin": "^2.0.0-beta.4", 55 | "file-loader": "^0.10.0", 56 | "html-loader": "^0.4.0", 57 | "html-webpack-plugin": "^2.8.1", 58 | "istanbul-instrumenter-loader": "^0.2.0", 59 | "jasmine-core": "^2.3.4", 60 | "jasmine-spec-reporter": "^3.2.0", 61 | "json-loader": "^0.5.3", 62 | "karma": "1.4.1", 63 | "karma-chrome-launcher": "^2.0.0", 64 | "karma-coverage": "^1.0.0", 65 | "karma-jasmine": "^1.0.2", 66 | "karma-mocha-reporter": "^2.0.3", 67 | "karma-remap-istanbul": "0.2.1", 68 | "karma-sourcemap-loader": "^0.3.7", 69 | "karma-webpack": "2.0.2", 70 | "node-sass": "^4.5.0", 71 | "null-loader": "0.1.1", 72 | "postcss-loader": "^1.1.0", 73 | "protractor": "^4.0.10", 74 | "raw-loader": "0.5.1", 75 | "remap-istanbul": "^0.6.4", 76 | "rimraf": "^2.5.1", 77 | "sass-loader": "^6.0.1", 78 | "shelljs": "^0.7.0", 79 | "style-loader": "^0.13.0", 80 | "ts-helpers": "^1.1.1", 81 | "tslint": "^4.3.1", 82 | "tslint-loader": "^3.3.0", 83 | "typedoc": "^0.5.1", 84 | "typescript": "^2.3.1", 85 | "url-loader": "^0.5.6", 86 | "webpack": "2.2.1", 87 | "webpack-dev-server": "2.3.0" 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | baseUrl: 'http://localhost:8080/', 3 | 4 | specs: [ 5 | 'src/**/*.e2e-spec.js' 6 | ], 7 | exclude: [], 8 | 9 | framework: 'jasmine2', 10 | 11 | allScriptsTimeout: 110000, 12 | 13 | jasmineNodeOpts: { 14 | showTiming: true, 15 | showColors: true, 16 | isVerbose: false, 17 | includeStackTrace: false, 18 | defaultTimeoutInterval: 400000 19 | }, 20 | directConnect: true, 21 | 22 | capabilities: { 23 | 'browserName': 'chrome' 24 | }, 25 | 26 | onPrepare: function () { 27 | var SpecReporter = require('jasmine-spec-reporter').SpecReporter; 28 | // add jasmine spec reporter 29 | jasmine.getEnv().addReporter(new SpecReporter({displayStacktrace: true})); 30 | 31 | browser.ignoreSynchronization = true; 32 | }, 33 | 34 | 35 | /** 36 | * Angular 2 configuration 37 | * 38 | * useAllAngular2AppRoots: tells Protractor to wait for any angular2 apps on the page instead of just the one matching 39 | * `rootEl` 40 | * 41 | */ 42 | useAllAngular2AppRoots: true 43 | }; 44 | -------------------------------------------------------------------------------- /src/app/app.component.e2e-spec.js: -------------------------------------------------------------------------------- 1 | describe('App', function () { 2 | 3 | beforeEach(function () { 4 | browser.get('/'); 5 | }); 6 | 7 | it('should have a title', function () { 8 | expect(browser.getTitle()).toEqual("Angular 2 App | ng2-webpack"); 9 | }); 10 | 11 | it('should have
', function () { 12 | expect(element(by.css('my-app header')).isPresent()).toEqual(true); 13 | }); 14 | 15 | it('should have
', function () { 16 | expect(element(by.css('my-app main')).isPresent()).toEqual(true); 17 | }); 18 | 19 | it('should have a main title', function () { 20 | expect(element(by.css('main h1')).getText()).toEqual('Hello from Angular 2!'); 21 | }); 22 | 23 | it('should have