├── .clang-format
├── .editorconfig
├── .gitignore
├── .vscode
├── launch.json
└── settings.json
├── angular-cli-build.js
├── angular-cli.json
├── config
├── environment.dev.ts
├── environment.js
├── environment.prod.ts
├── karma-test-shim.js
├── karma.conf.js
└── protractor.conf.js
├── e2e
├── app.e2e.ts
├── app.po.ts
├── tsconfig.json
└── typings.d.ts
├── firebase.json
├── package.json
├── public
└── .npmignore
├── src
├── app
│ ├── +issues
│ │ ├── +filter
│ │ │ ├── filter.component.css
│ │ │ ├── filter.component.html
│ │ │ ├── filter.component.spec.ts
│ │ │ ├── filter.component.ts
│ │ │ ├── index.ts
│ │ │ └── shared
│ │ │ │ └── index.ts
│ │ ├── +list
│ │ │ ├── index.ts
│ │ │ ├── issue-row
│ │ │ │ ├── index.ts
│ │ │ │ ├── issue-row.component.css
│ │ │ │ ├── issue-row.component.html
│ │ │ │ ├── issue-row.component.spec.ts
│ │ │ │ └── issue-row.component.ts
│ │ │ ├── list.component.css
│ │ │ ├── list.component.html
│ │ │ ├── list.component.spec.ts
│ │ │ ├── list.component.ts
│ │ │ ├── not-pending-removal.pipe.spec.ts
│ │ │ ├── not-pending-removal.pipe.ts
│ │ │ ├── shared
│ │ │ │ └── index.ts
│ │ │ └── toolbar
│ │ │ │ ├── index.ts
│ │ │ │ ├── toolbar.component.css
│ │ │ │ ├── toolbar.component.html
│ │ │ │ ├── toolbar.component.spec.ts
│ │ │ │ └── toolbar.component.ts
│ │ ├── +triage
│ │ │ ├── index.ts
│ │ │ ├── is-checked.pipe.spec.ts
│ │ │ ├── is-checked.pipe.ts
│ │ │ ├── shared
│ │ │ │ └── index.ts
│ │ │ ├── to-date.pipe.spec.ts
│ │ │ ├── to-date.pipe.ts
│ │ │ ├── triage.component.css
│ │ │ ├── triage.component.html
│ │ │ ├── triage.component.spec.ts
│ │ │ └── triage.component.ts
│ │ ├── index.ts
│ │ ├── issues.component.css
│ │ ├── issues.component.html
│ │ ├── issues.component.spec.ts
│ │ ├── issues.component.ts
│ │ └── shared
│ │ │ └── index.ts
│ ├── +login
│ │ ├── index.ts
│ │ ├── login.component.css
│ │ ├── login.component.html
│ │ ├── login.component.spec.ts
│ │ ├── login.component.ts
│ │ └── shared
│ │ │ └── index.ts
│ ├── +repo-selector
│ │ ├── index.ts
│ │ ├── repo-selector-row
│ │ │ ├── index.ts
│ │ │ ├── repo-selector-row.component.css
│ │ │ ├── repo-selector-row.component.html
│ │ │ ├── repo-selector-row.component.spec.ts
│ │ │ └── repo-selector-row.component.ts
│ │ ├── repo-selector.component.css
│ │ ├── repo-selector.component.html
│ │ ├── repo-selector.component.spec.ts
│ │ ├── repo-selector.component.ts
│ │ └── shared
│ │ │ └── index.ts
│ ├── environment.ts
│ ├── filter-store.service.spec.ts
│ ├── filter-store.service.ts
│ ├── github.service.spec.ts
│ ├── github.service.ts
│ ├── index.ts
│ ├── issue-zero.component.css
│ ├── issue-zero.component.html
│ ├── issue-zero.component.spec.ts
│ ├── issue-zero.component.ts
│ ├── repo-params.service.spec.ts
│ ├── repo-params.service.ts
│ └── shared
│ │ ├── config.ts
│ │ ├── index.ts
│ │ ├── store.ts
│ │ └── types.ts
├── favicon.ico
├── icons
│ ├── android-chrome-144x144.png
│ ├── android-chrome-192x192.png
│ ├── android-chrome-36x36.png
│ ├── android-chrome-48x48.png
│ ├── android-chrome-72x72.png
│ ├── android-chrome-96x96.png
│ ├── apple-touch-icon-114x114.png
│ ├── apple-touch-icon-120x120.png
│ ├── apple-touch-icon-144x144.png
│ ├── apple-touch-icon-152x152.png
│ ├── apple-touch-icon-180x180.png
│ ├── apple-touch-icon-57x57.png
│ ├── apple-touch-icon-60x60.png
│ ├── apple-touch-icon-72x72.png
│ ├── apple-touch-icon-76x76.png
│ ├── apple-touch-icon-precomposed.png
│ ├── apple-touch-icon.png
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon-96x96.png
│ ├── icon.png
│ ├── mstile-144x144.png
│ ├── mstile-150x150.png
│ ├── mstile-310x150.png
│ ├── mstile-310x310.png
│ ├── mstile-70x70.png
│ └── safari-pinned-tab.svg
├── index.html
├── main-app-shell.ts
├── main.ts
├── manifest.webapp
├── system-config.ts
├── system-import.js
├── tsconfig.json
└── typings.d.ts
├── tslint.json
└── typings.json
/.clang-format:
--------------------------------------------------------------------------------
1 | Language: JavaScript
2 | BasedOnStyle: Google
3 | ColumnLimit: 100
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | end_of_line = lf
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.md]
13 | max_line_length = 0
14 | trim_trailing_whitespace = false
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 |
7 | # dependencies
8 | /node_modules
9 | /bower_components
10 |
11 | # IDEs and editors
12 | /.idea
13 |
14 | # misc
15 | /.sass-cache
16 | /connect.lock
17 | /coverage/*
18 | /libpeerconnection.log
19 | npm-debug.log
20 | testem.log
21 | /typings
22 |
23 | # e2e
24 | /e2e/*.js
25 | /e2e/*.map
26 |
27 | #System Files
28 | .DS_Store
29 | Thumbs.db
30 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Launch",
6 | "type": "node",
7 | "request": "launch",
8 | "program": "${workspaceRoot}/node_modules/.bin/ng",
9 | "stopOnEntry": false,
10 | "args": ["serve"],
11 | "cwd": "${workspaceRoot}",
12 | "preLaunchTask": null,
13 | "runtimeExecutable": null,
14 | "runtimeArgs": [
15 | "--nolazy"
16 | ],
17 | "env": {
18 | "NODE_ENV": "development"
19 | },
20 | "externalConsole": false,
21 | "sourceMaps": false,
22 | "outDir": null
23 | },
24 | {
25 | "name": "ChildProc",
26 | "type": "node",
27 | "request": "launch",
28 | "program": "${workspaceRoot}/node_modules/angular2-broccoli-prerender/dist/child_proc.js",
29 | "stopOnEntry": false,
30 | "args": [ "/Users/crossj/Projects/issue-zero/node_modules/angular2-broccoli-prerender/dist/child_proc.js",
31 | "--sourceHtml=/Users/crossj/Projects/issue-zero/tmp/app_shell_plugin-input_base_path-yrSu8NXb.tmp/0/index.html",
32 | "--optionsPath=/Users/crossj/Projects/issue-zero/tmp/app_shell_plugin-input_base_path-yrSu8NXb.tmp/0/main-app-shell",
33 | "--outputIndexPath=/Users/crossj/Projects/issue-zero/tmp/app_shell_plugin-output_path-nPBVCEAe.tmp/index.html" ],
34 | "cwd": "${workspaceRoot}",
35 | "preLaunchTask": null,
36 | "runtimeExecutable": null,
37 | "runtimeArgs": [
38 | "--nolazy"
39 | ],
40 | "env": {
41 | "NODE_ENV": "development"
42 | },
43 | "externalConsole": false,
44 | "sourceMaps": false,
45 | "outDir": null
46 | },
47 | {
48 | "name": "Attach",
49 | "type": "node",
50 | "request": "attach",
51 | "port": 5858,
52 | "address": "localhost",
53 | "restart": false,
54 | "sourceMaps": false,
55 | "outDir": null,
56 | "localRoot": "${workspaceRoot}",
57 | "remoteRoot": null
58 | }
59 | ]
60 | }
61 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "files.watcherExclude": {
4 | "**/.git/objects/**": true,
5 | "**/node_modules/**": true,
6 | "tmp/": true,
7 | "dist/": true,
8 | "typings/": true
9 | },
10 | "search.exclude": {
11 | "**/.git": true,
12 | "**/.DS_Store": true,
13 | "tmp/": true,
14 | "node_modules": true,
15 | "typings/": true
16 | }
17 | }
--------------------------------------------------------------------------------
/angular-cli-build.js:
--------------------------------------------------------------------------------
1 | /* global require, module */
2 |
3 | var Angular2App = require('angular-cli/lib/broccoli/angular2-app');
4 |
5 | module.exports = function(defaults) {
6 | return new Angular2App(defaults, {
7 | vendorNpmFiles: [
8 | 'systemjs/dist/system-polyfills.js',
9 | 'systemjs/dist/system.src.js',
10 | 'zone.js/dist/*.js',
11 | 'es6-shim/es6-shim.js',
12 | 'reflect-metadata/*.js',
13 | 'rxjs/**/*.js',
14 | '@angular/**/*.js',
15 | '@angular2-material/**/*.+(js|map|css|svg)',
16 | 'angularfire2/**/*.js',
17 | 'firebase/lib/firebase-web.js',
18 | 'hammerjs/hammer.min.js',
19 | 'material-design-icons/navigation/svg/production/ic_menu_24px.svg',
20 | 'material-design-icons/navigation/svg/production/ic_arrow_back_24px.svg',
21 | 'material-design-icons/content/svg/production/ic_filter_list_24px.svg',
22 | 'material-design-icons/action/svg/production/ic_delete_24px.svg',
23 | '@ngrx/**/*.js'
24 | ]
25 | });
26 | };
27 |
--------------------------------------------------------------------------------
/angular-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "project": {
3 | "version": "1.0.0-beta.2-mobile.2",
4 | "name": "issue-zero"
5 | },
6 | "apps": [
7 | {
8 | "main": "src/main.ts",
9 | "tsconfig": "src/tsconfig.json",
10 | "mobile": true
11 | }
12 | ],
13 | "addons": [],
14 | "packages": [],
15 | "e2e": {
16 | "protractor": {
17 | "config": "config/protractor.conf.js"
18 | }
19 | },
20 | "test": {
21 | "karma": {
22 | "config": "config/karma.conf.js"
23 | }
24 | },
25 | "defaults": {
26 | "prefix": "app",
27 | "sourceDir": "src"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/config/environment.dev.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: false
3 | };
4 |
--------------------------------------------------------------------------------
/config/environment.js:
--------------------------------------------------------------------------------
1 | /* jshint node: true */
2 |
3 | module.exports = function(environment) {
4 | return {
5 | environment: environment,
6 | baseURL: '/',
7 | locationType: 'auto'
8 | };
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/config/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/config/karma-test-shim.js:
--------------------------------------------------------------------------------
1 | /*global jasmine, __karma__, window*/
2 | Error.stackTraceLimit = Infinity;
3 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
4 |
5 | __karma__.loaded = function () {
6 | };
7 |
8 | var distPath = '/base/dist/';
9 | var appPath = distPath + 'app/';
10 |
11 | function isJsFile(path) {
12 | return path.slice(-3) == '.js';
13 | }
14 |
15 | function isSpecFile(path) {
16 | return path.slice(-8) == '.spec.js';
17 | }
18 |
19 | function isAppFile(path) {
20 | return isJsFile(path) && (path.substr(0, appPath.length) == appPath);
21 | }
22 |
23 | var allSpecFiles = Object.keys(window.__karma__.files)
24 | .filter(isSpecFile)
25 | .filter(isAppFile);
26 |
27 | // Load our SystemJS configuration.
28 | System.config({
29 | baseURL: distPath
30 | });
31 |
32 | System.import('system-config.js').then(function() {
33 | // Load and configure the TestComponentBuilder.
34 | return Promise.all([
35 | System.import('@angular/core/testing'),
36 | System.import('@angular/platform-browser-dynamic/testing')
37 | ]).then(function (providers) {
38 | var testing = providers[0];
39 | var testingBrowser = providers[1];
40 |
41 | testing.setBaseTestProviders(testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
42 | testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
43 | });
44 | }).then(function() {
45 | // Finally, load all spec files.
46 | // This will run the tests directly.
47 | return Promise.all(
48 | allSpecFiles.map(function (moduleName) {
49 | return System.import(moduleName);
50 | }));
51 | }).then(__karma__.start, __karma__.error);
--------------------------------------------------------------------------------
/config/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function (config) {
2 | config.set({
3 | basePath: '..',
4 | frameworks: ['jasmine'],
5 | plugins: [
6 | require('karma-jasmine'),
7 | require('karma-chrome-launcher')
8 | ],
9 | customLaunchers: {
10 | // chrome setup for travis CI using chromium
11 | Chrome_travis_ci: {
12 | base: 'Chrome',
13 | flags: ['--no-sandbox']
14 | }
15 | },
16 | files: [
17 | { pattern: 'dist/vendor/es6-shim/es6-shim.js', included: true, watched: false },
18 | { pattern: 'dist/vendor/zone.js/dist/zone.js', included: true, watched: false },
19 | { pattern: 'dist/vendor/reflect-metadata/Reflect.js', included: true, watched: false },
20 | { pattern: 'dist/vendor/systemjs/dist/system-polyfills.js', included: true, watched: false },
21 | { pattern: 'dist/vendor/systemjs/dist/system.src.js', included: true, watched: false },
22 | { pattern: 'dist/vendor/zone.js/dist/async-test.js', included: true, watched: false },
23 |
24 | { pattern: 'config/karma-test-shim.js', included: true, watched: true },
25 |
26 | // Distribution folder.
27 | { pattern: 'dist/**/*', included: false, watched: true }
28 | ],
29 | exclude: [
30 | // Vendor packages might include spec files. We don't want to use those.
31 | 'dist/vendor/**/*.spec.js'
32 | ],
33 | preprocessors: {},
34 | reporters: ['progress'],
35 | port: 9876,
36 | colors: true,
37 | logLevel: config.LOG_INFO,
38 | autoWatch: true,
39 | browsers: ['Chrome'],
40 | singleRun: false
41 | });
42 | };
43 |
--------------------------------------------------------------------------------
/config/protractor.conf.js:
--------------------------------------------------------------------------------
1 | /*global jasmine */
2 | var SpecReporter = require('jasmine-spec-reporter');
3 |
4 | exports.config = {
5 | allScriptsTimeout: 11000,
6 | specs: [
7 | '../e2e/**/*.e2e.ts'
8 | ],
9 | capabilities: {
10 | 'browserName': 'chrome'
11 | },
12 | directConnect: true,
13 | baseUrl: 'http://localhost:4200/',
14 | framework: 'jasmine',
15 | jasmineNodeOpts: {
16 | showColors: true,
17 | defaultTimeoutInterval: 30000,
18 | print: function() {}
19 | },
20 | useAllAngular2AppRoots: true,
21 | beforeLaunch: function() {
22 | require('ts-node').register({
23 | project: 'e2e'
24 | });
25 | },
26 | onPrepare: function() {
27 | jasmine.getEnv().addReporter(new SpecReporter());
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/e2e/app.e2e.ts:
--------------------------------------------------------------------------------
1 | import { IssueZeroPage } from './app.po';
2 |
3 | describe('issue-zero App', function() {
4 | let page: IssueZeroPage;
5 |
6 | beforeEach(() => {
7 | page = new IssueZeroPage();
8 | });
9 |
10 | it('should display message saying app works', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toEqual('issue-zero works!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/e2e/app.po.ts:
--------------------------------------------------------------------------------
1 | export class IssueZeroPage {
2 | navigateTo() {
3 | return browser.get('/');
4 | }
5 |
6 | getParagraphText() {
7 | return element(by.css('issue-zero-app h1')).getText();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "mapRoot": "",
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "noEmitOnError": true,
11 | "noImplicitAny": false,
12 | "rootDir": ".",
13 | "sourceMap": true,
14 | "sourceRoot": "/",
15 | "target": "es5"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/e2e/typings.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "firebase": "issue-zero",
3 | "public": "dist",
4 | "ignore": [
5 | "firebase.json",
6 | "**/.*",
7 | "**/node_modules/**"
8 | ],
9 | "rewrites": [{
10 | "source": "/issues",
11 | "destination": "/index.html"
12 | },{
13 | "source": "/login",
14 | "destination": "/index.html"
15 | },{
16 | "source": "/issues/*/**",
17 | "destination": "/index.html"
18 | },{
19 | "source": "/repo-selector",
20 | "destination": "/index.html"
21 | }]
22 | }
23 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "issue-zero",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "angular-cli": {},
6 | "scripts": {
7 | "start": "ng server",
8 | "postinstall": "typings install",
9 | "lint": "tslint \"src/**/*.ts\"",
10 | "format": "clang-format -i -style=file --glob=src/**/*.ts",
11 | "test": "ng test",
12 | "pree2e": "webdriver-manager update",
13 | "e2e": "protractor"
14 | },
15 | "private": true,
16 | "dependencies": {
17 | "@angular/app-shell": "0.0.0",
18 | "@angular/common": "2.0.0-rc.1",
19 | "@angular/compiler": "2.0.0-rc.1",
20 | "@angular/core": "2.0.0-rc.1",
21 | "@angular/http": "2.0.0-rc.1",
22 | "@angular/platform-browser": "2.0.0-rc.1",
23 | "@angular/platform-browser-dynamic": "2.0.0-rc.1",
24 | "@angular/router": "2.0.0-rc.1",
25 | "@angular2-material/button": "^2.0.0-alpha.4",
26 | "@angular2-material/card": "^2.0.0-alpha.4",
27 | "@angular2-material/checkbox": "^2.0.0-alpha.4",
28 | "@angular2-material/core": "^2.0.0-alpha.4",
29 | "@angular2-material/icon": "^2.0.0-alpha.4",
30 | "@angular2-material/input": "^2.0.0-alpha.4",
31 | "@angular2-material/list": "^2.0.0-alpha.4",
32 | "@angular2-material/progress-circle": "^2.0.0-alpha.4",
33 | "@angular2-material/sidenav": "^2.0.0-alpha.4",
34 | "@angular2-material/toolbar": "^2.0.0-alpha.4",
35 | "@ngrx/store": "^1.5.0",
36 | "angular-cli": "^1.0.0-beta.4",
37 | "angularfire2": "^2.0.0-beta.0",
38 | "es6-shim": "^0.35.0",
39 | "firebase": "^2.4.2",
40 | "hammerjs": "^2.0.8",
41 | "material-design-icons": "^2.2.3",
42 | "reflect-metadata": "0.1.3",
43 | "rxjs": "5.0.0-beta.6",
44 | "systemjs": "0.19.26",
45 | "zone.js": "^0.6.12"
46 | },
47 | "devDependencies": {
48 | "@angular/platform-server": "2.0.0-rc.1",
49 | "@angular/router-deprecated": "2.0.0-rc.1",
50 | "@angular/service-worker": "^0.2.0",
51 | "angular2-broccoli-prerender": "^0.11.0",
52 | "angular2-universal": "^0.100.3",
53 | "angular2-universal-polyfills": "^0.4.1",
54 | "preboot": "^2.0.10",
55 | "angular-cli": "^1.0.0-beta.2-mobile.2",
56 | "clang-format": "^1.0.35",
57 | "codelyzer": "0.0.14",
58 | "ember-cli-inject-live-reload": "^1.4.0",
59 | "jasmine-core": "^2.4.1",
60 | "jasmine-spec-reporter": "^2.4.0",
61 | "karma": "^0.13.15",
62 | "karma-chrome-launcher": "^0.2.3",
63 | "karma-jasmine": "^0.3.8",
64 | "protractor": "^3.3.0",
65 | "ts-node": "^0.5.5",
66 | "tslint": "^3.6.0",
67 | "typescript": "^1.8.10",
68 | "typings": "^0.8.1"
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/public/.npmignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/issue-zero/b5628226a783157630a2a2ed76137c9f3bf09d36/public/.npmignore
--------------------------------------------------------------------------------
/src/app/+issues/+filter/filter.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/issue-zero/b5628226a783157630a2a2ed76137c9f3bf09d36/src/app/+issues/+filter/filter.component.css
--------------------------------------------------------------------------------
/src/app/+issues/+filter/filter.component.html:
--------------------------------------------------------------------------------
1 |
2 | filter works!
3 |
4 |
--------------------------------------------------------------------------------
/src/app/+issues/+filter/filter.component.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | beforeEach,
3 | beforeEachProviders,
4 | describe,
5 | expect,
6 | it,
7 | inject,
8 | } from '@angular/core/testing';
9 | import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing';
10 | import { Component } from '@angular/core';
11 | import { By } from '@angular/platform-browser';
12 | import { FilterComponent } from './filter.component';
13 |
14 | describe('Component: Filter', () => {
15 | let builder: TestComponentBuilder;
16 |
17 | beforeEachProviders(() => [FilterComponent]);
18 | beforeEach(inject([TestComponentBuilder], function (tcb: TestComponentBuilder) {
19 | builder = tcb;
20 | }));
21 |
22 | it('should inject the component', inject([FilterComponent],
23 | (component: FilterComponent) => {
24 | expect(component).toBeTruthy();
25 | }));
26 |
27 | it('should create the component', inject([], () => {
28 | return builder.createAsync(FilterComponentTestController)
29 | .then((fixture: ComponentFixture) => {
30 | let query = fixture.debugElement.query(By.directive(FilterComponent));
31 | expect(query).toBeTruthy();
32 | expect(query.componentInstance).toBeTruthy();
33 | });
34 | }));
35 | });
36 |
37 | @Component({
38 | selector: 'test',
39 | template: `
40 |
41 | `,
42 | directives: [FilterComponent]
43 | })
44 | class FilterComponentTestController {
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/src/app/+issues/+filter/filter.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 | import {ROUTER_DIRECTIVES} from '@angular/router-deprecated';
3 | import {MdToolbar} from '@angular2-material/toolbar';
4 | import {MD_CARD_DIRECTIVES} from '@angular2-material/card';
5 | import {MdIcon} from '@angular2-material/icon';
6 | import { MdAnchor, MdButton } from '@angular2-material/button';
7 | import {Observable} from 'rxjs/Observable';
8 |
9 | import {
10 | FilterStoreService,
11 | Filter as ServiceFilter,
12 | UnlabeledCriteria,
13 | LabelCriteria,
14 | Criteria
15 | } from '../../filter-store.service';
16 | import {GithubService} from '../../github.service';
17 | import {RepoParamsService} from '../../repo-params.service';
18 |
19 | @Component({
20 | template: `
21 |
22 |
27 | Untriaged Issue Filter
28 |
29 |
30 |
31 | {{criteria.name}}
32 |
33 |
34 |
44 |
45 |
46 |
47 |
52 |
53 |
54 |
55 |
61 |
62 | `,
63 | styles: [`
64 | .fill-remaining-space {
65 | flex: 1 1 auto;
66 | }
67 | .back-link {
68 | color: rgba(0, 0, 0, 0.870588)
69 | }
70 | `],
71 | directives: [MdIcon, MdToolbar, MD_CARD_DIRECTIVES, ROUTER_DIRECTIVES, MdAnchor, MdButton],
72 | providers: [FilterStoreService, GithubService, RepoParamsService]
73 | })
74 | export class FilterComponent {
75 | filter: ServiceFilter;
76 | labels: any[];
77 | org: string;
78 | repo: string;
79 | repoFull: string;
80 | availableCriteria: any[] = [LabelCriteria, UnlabeledCriteria];
81 | constructor(
82 | public filterStore: FilterStoreService,
83 | public gh: GithubService,
84 | private repoParams: RepoParamsService) {
85 | var {org, repo} = repoParams.getRepo();
86 | this.org = org;
87 | this.repo = repo;
88 | this.repoFull = `${this.org}/${this.repo}`;
89 | this.filter = this.filterStore.getFilter(this.repoFull);
90 | gh.fetchLabels(this.repoFull)
91 | .take(1)
92 | .subscribe(labels => this.labels = labels);
93 | }
94 |
95 | fetchLabels(): Observable {
96 | return this.gh.fetchLabels(this.repoFull);
97 | }
98 |
99 | updateLabelCriteria(idx: number, evt: any) {
100 | this.filter.updateCriteria(idx, {
101 | type: 'hasLabel',
102 | name: 'Has label',
103 | label: evt.target.value,
104 | query: 'label:%s'
105 | });
106 | }
107 |
108 | onChange(evt) {
109 | this.filter.addCriteria(this.availableCriteria
110 | .filter((c: Criteria) => c.name === evt.target.value)[0]);
111 |
112 | }
113 |
114 | labelTrack(label: any): string {
115 | return label.type + label.label;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/app/+issues/+filter/index.ts:
--------------------------------------------------------------------------------
1 | export { FilterComponent } from './filter.component';
2 |
--------------------------------------------------------------------------------
/src/app/+issues/+filter/shared/index.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/issue-zero/b5628226a783157630a2a2ed76137c9f3bf09d36/src/app/+issues/+filter/shared/index.ts
--------------------------------------------------------------------------------
/src/app/+issues/+list/index.ts:
--------------------------------------------------------------------------------
1 | export { ListComponent } from './list.component';
2 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/issue-row/index.ts:
--------------------------------------------------------------------------------
1 | export { IssueRowComponent } from './issue-row.component';
2 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/issue-row/issue-row.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/issue-zero/b5628226a783157630a2a2ed76137c9f3bf09d36/src/app/+issues/+list/issue-row/issue-row.component.css
--------------------------------------------------------------------------------
/src/app/+issues/+list/issue-row/issue-row.component.html:
--------------------------------------------------------------------------------
1 |
2 | issue-row works!
3 |
4 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/issue-row/issue-row.component.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | beforeEach,
3 | beforeEachProviders,
4 | describe,
5 | expect,
6 | it,
7 | inject,
8 | } from '@angular/core/testing';
9 | import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing';
10 | import { Component } from '@angular/core';
11 | import { By } from '@angular/platform-browser';
12 | import { IssueRowComponent } from './issue-row.component';
13 |
14 | describe('Component: IssueRow', () => {
15 | let builder: TestComponentBuilder;
16 |
17 | beforeEachProviders(() => [IssueRowComponent]);
18 | beforeEach(inject([TestComponentBuilder], function (tcb: TestComponentBuilder) {
19 | builder = tcb;
20 | }));
21 |
22 | it('should inject the component', inject([IssueRowComponent],
23 | (component: IssueRowComponent) => {
24 | expect(component).toBeTruthy();
25 | }));
26 |
27 | it('should create the component', inject([], () => {
28 | return builder.createAsync(IssueRowComponentTestController)
29 | .then((fixture: ComponentFixture) => {
30 | let query = fixture.debugElement.query(By.directive(IssueRowComponent));
31 | expect(query).toBeTruthy();
32 | expect(query.componentInstance).toBeTruthy();
33 | });
34 | }));
35 | });
36 |
37 | @Component({
38 | selector: 'test',
39 | template: `
40 |
41 | `,
42 | directives: [IssueRowComponent]
43 | })
44 | class IssueRowComponentTestController {
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/issue-row/issue-row.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | AfterViewInit,
3 | Component,
4 | ElementRef,
5 | EventEmitter,
6 | Input,
7 | Output
8 | } from '@angular/core';
9 | import {MD_LIST_DIRECTIVES} from '@angular2-material/list';
10 |
11 | import {GithubService} from '../../../github.service';
12 | import {Issue} from '../../../shared';
13 |
14 | @Component({
15 | selector: 'issue-row',
16 | template: `
17 |
18 |
19 | TRIAGE
20 |
21 |
22 | CLOSE
23 |
24 |
25 |
32 |
33 | {{issue.title}}
34 |
35 | @{{issue.user.login}}
36 | -
37 | {{issue.body}}
38 |
39 |
40 | `,
41 | styles: [`
42 | [md-line].secondary {
43 | color: rgba(0,0,0,0.54);
44 | }
45 |
46 | .hidden {
47 | display: flex;
48 | flex-direction: column;
49 | align-items: center;
50 | justify-content: center;
51 | text-align: center;
52 | color: white;
53 | height: 72px;
54 | width: 0;
55 |
56 | }
57 |
58 | .hidden.leave {
59 | transition: width 0.3s;
60 | }
61 |
62 | .hidden span {
63 | height: 16px;
64 | display: inline-block;
65 | vertical-align: middle;
66 | }
67 |
68 | .hidden-triage {
69 | float:left;
70 | background: #090;
71 | }
72 |
73 | .hidden-close {
74 | background: #c00;
75 | float: right;
76 | }
77 |
78 | md-list-item.leave {
79 | transition: left 0.3s;
80 | }
81 | `],
82 | providers: [GithubService],
83 | directives: [MD_LIST_DIRECTIVES],
84 | pipes: []
85 | })
86 | export class IssueRowComponent implements AfterViewInit {
87 | @Input('issue') issue: Issue;
88 | @Output('close') close = new EventEmitter();
89 | @Output('triage') triage = new EventEmitter();
90 | touchStartCoords: {x: number, y: number};
91 | listItemNativeEl: HTMLElement;
92 | triageNativeEl: HTMLElement;
93 | closeNativeEl: HTMLElement;
94 |
95 | constructor(public el: ElementRef, public gh: GithubService) {}
96 |
97 | onTouchStart (evt) {
98 | this.closeNativeEl.classList.remove('leave');
99 | this.triageNativeEl.classList.remove('leave');
100 | this.listItemNativeEl.classList.remove('leave');
101 | this.listItemNativeEl.style.position = 'relative';
102 | this.listItemNativeEl.style.display = 'block';
103 | this.listItemNativeEl.style.left = '0';
104 | var coords = evt.targetTouches[0];
105 | this.touchStartCoords = {
106 | x: coords.clientX,
107 | y: coords.clientY
108 | };
109 | }
110 |
111 | onTouchMove (evt) {
112 | var {pageX} = evt.targetTouches[0];
113 | var left = pageX - this.touchStartCoords.x;
114 |
115 |
116 | if (left > 0) {
117 | this.closeNativeEl.style.width = '0';
118 | this.triageNativeEl.style.width = `${left}px`;
119 | this.listItemNativeEl.style.left = '0';
120 | } else {
121 | // TODO(jeffbcross): fix the truncating as it's dragged off screen
122 | this.triageNativeEl.style.width = '0';
123 | this.listItemNativeEl.style.left = `${left}px`;
124 | this.closeNativeEl.style.width = `${Math.abs(left)}px`;
125 | }
126 | }
127 |
128 | onTouchEnd (evt) {
129 | this.closeNativeEl.classList.add('leave');
130 | this.triageNativeEl.classList.add('leave');
131 | this.listItemNativeEl.classList.add('leave');
132 | this.listItemNativeEl.style.left = '0';
133 | this.closeNativeEl.style.width = '0';
134 | this.triageNativeEl.style.width = '0';
135 | }
136 |
137 | ngAfterViewInit () {
138 | this.listItemNativeEl = this.el.nativeElement.querySelector('md-list-item');
139 | this.triageNativeEl = this.el.nativeElement.querySelector('.hidden-triage');
140 | this.closeNativeEl = this.el.nativeElement.querySelector('.hidden-close');
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/list.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/issue-zero/b5628226a783157630a2a2ed76137c9f3bf09d36/src/app/+issues/+list/list.component.css
--------------------------------------------------------------------------------
/src/app/+issues/+list/list.component.html:
--------------------------------------------------------------------------------
1 |
2 | list works!
3 |
4 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/list.component.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | beforeEach,
3 | beforeEachProviders,
4 | describe,
5 | expect,
6 | it,
7 | inject,
8 | } from '@angular/core/testing';
9 | import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing';
10 | import { Component } from '@angular/core';
11 | import { By } from '@angular/platform-browser';
12 | import { ListComponent } from './list.component';
13 |
14 | describe('Component: List', () => {
15 | let builder: TestComponentBuilder;
16 |
17 | beforeEachProviders(() => [ListComponent]);
18 | beforeEach(inject([TestComponentBuilder], function (tcb: TestComponentBuilder) {
19 | builder = tcb;
20 | }));
21 |
22 | it('should inject the component', inject([ListComponent],
23 | (component: ListComponent) => {
24 | expect(component).toBeTruthy();
25 | }));
26 |
27 | it('should create the component', inject([], () => {
28 | return builder.createAsync(ListComponentTestController)
29 | .then((fixture: ComponentFixture) => {
30 | let query = fixture.debugElement.query(By.directive(ListComponent));
31 | expect(query).toBeTruthy();
32 | expect(query.componentInstance).toBeTruthy();
33 | });
34 | }));
35 | });
36 |
37 | @Component({
38 | selector: 'test',
39 | template: `
40 |
41 | `,
42 | directives: [ListComponent]
43 | })
44 | class ListComponentTestController {
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/list.component.ts:
--------------------------------------------------------------------------------
1 | import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core';
2 | import {ROUTER_DIRECTIVES, Router} from '@angular/router-deprecated';
3 | import {Observable} from 'rxjs/Observable';
4 | import {Subscription} from 'rxjs/Subscription';
5 | import {MD_LIST_DIRECTIVES} from '@angular2-material/list';
6 | import {Store} from '@ngrx/store';
7 |
8 | import {ToolbarComponent} from './toolbar/toolbar.component';
9 | import {IssueRowComponent} from './issue-row/issue-row.component';
10 | import { AppState, Issue, Repo } from '../../shared';
11 | import {GithubService} from '../../github.service';
12 | import {
13 | FilterStoreService,
14 | Filter,
15 | FilterObject,
16 | FilterMap,
17 | generateQuery
18 | } from '../../filter-store.service';
19 | import {RepoParamsService} from '../../repo-params.service';
20 | import {NotPendingRemoval} from './not-pending-removal.pipe';
21 |
22 | @Component({
23 | styles: [`
24 | md-list-item {
25 | background-color: rgb(245, 245, 245)
26 | }
27 | `],
28 | template: `
29 |
31 |
32 |
33 |
34 |
41 |
42 |
43 | `,
44 | providers: [GithubService, FilterStoreService, RepoParamsService],
45 | directives: [MD_LIST_DIRECTIVES, ToolbarComponent, IssueRowComponent, ROUTER_DIRECTIVES],
46 | pipes: [NotPendingRemoval],
47 | changeDetection: ChangeDetectionStrategy.OnPush
48 | })
49 | export class ListComponent implements OnInit {
50 | issues: Observable;
51 | repos: Observable;
52 | repoSelection: Observable;
53 | addIssueSubscription: Subscription;
54 | constructor(
55 | private gh: GithubService, private filterStore: FilterStoreService,
56 | private store: Store, private repoParams: RepoParamsService,
57 | private router: Router) {}
58 |
59 | ngOnInit() {
60 | var {repo, org} = this.repoParams.getRepo();
61 |
62 | /**
63 | * Get full repo object based on route params.
64 | */
65 | this.repoSelection = this.store.select('repos')
66 | .filter((r: Repo) => !!r)
67 | .map((repos: Repo[]) => repos.filter((repository: Repo) => {
68 | return repository.name === repo && repository.owner.login === org;
69 | })[0]);
70 |
71 | this.gh.getRepo(`${org}/${repo}`).subscribe((_repo: Repo) => {
72 | this.store.dispatch({type: 'AddRepo', payload: _repo});
73 | });
74 |
75 | /**
76 | * Fetch the issues for this repo.
77 | */
78 | this.addIssueSubscription =
79 | this.store.select('filters')
80 | .map((filters: FilterMap) => filters && filters[`${org}/${repo}`])
81 | .filter((filter: Filter) => !!filter)
82 | .flatMap((filter: Filter) => filter.changes)
83 | .map((filter: FilterObject) => generateQuery(filter))
84 | .switchMap((query: string) => this.gh.getIssues(query))
85 | .subscribe(
86 | (issues: Issue[]) => {this.store.dispatch({type: 'AddIssues', payload: issues});});
87 |
88 | this.store.dispatch({type: 'SetFilter', payload: this.filterStore.getFilter(`${org}/${repo}`)});
89 |
90 | this.issues = this.store.select('issues')
91 | .filter((i: Issue[]) => !!i)
92 | .map(
93 | (issues: Issue[]) => issues.filter(
94 | (issue: Issue) => {return issue.org === org && issue.repo === repo;}));
95 | }
96 |
97 | getSmallAvatar(repo: Repo): string { return repo ? `${repo.owner.avatar_url}&s=40` : ''; }
98 |
99 | ngOnDestroy() {
100 | if (this.addIssueSubscription) {
101 | this.addIssueSubscription.unsubscribe();
102 | }
103 | }
104 |
105 | closeIssue(issue: Issue): void {
106 | // Set the issue as pending removal
107 | this.store.dispatch({type: 'PendingRemoveIssue', payload: issue});
108 | this.gh.closeIssue(issue).take(1).subscribe(
109 | () => { this.store.dispatch({type: 'RemoveIssue', payload: issue}); });
110 | }
111 |
112 | triageIssue(issue: Issue) { this.router.navigate(['../Triage', {number: issue.number}]); }
113 | }
114 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/not-pending-removal.pipe.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | it,
3 | describe,
4 | expect,
5 | inject,
6 | beforeEachProviders
7 | } from '@angular/core/testing';
8 | import { NotPendingRemoval } from './not-pending-removal.pipe';
9 |
10 | describe('NotPendingRemoval Pipe', () => {
11 | beforeEachProviders(() => [NotPendingRemoval]);
12 |
13 | it('should transform the input', inject([NotPendingRemoval], (pipe: NotPendingRemoval) => {
14 | // expect(pipe.transform(true)).toBe(null);
15 | }));
16 | });
17 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/not-pending-removal.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { Issue } from '../../shared';
3 |
4 | @Pipe({
5 | name: 'notPendingRemoval'
6 | })
7 | export class NotPendingRemoval implements PipeTransform {
8 | transform (issues:Issue[]): Issue[] {
9 | if (!issues) return issues;
10 | return issues.filter((issue:Issue) => !issue.isPendingRemoval)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/shared/index.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/issue-zero/b5628226a783157630a2a2ed76137c9f3bf09d36/src/app/+issues/+list/shared/index.ts
--------------------------------------------------------------------------------
/src/app/+issues/+list/toolbar/index.ts:
--------------------------------------------------------------------------------
1 | export { ToolbarComponent } from './toolbar.component';
2 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/toolbar/toolbar.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/issue-zero/b5628226a783157630a2a2ed76137c9f3bf09d36/src/app/+issues/+list/toolbar/toolbar.component.css
--------------------------------------------------------------------------------
/src/app/+issues/+list/toolbar/toolbar.component.html:
--------------------------------------------------------------------------------
1 |
2 | toolbar works!
3 |
4 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/toolbar/toolbar.component.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | beforeEach,
3 | beforeEachProviders,
4 | describe,
5 | expect,
6 | it,
7 | inject,
8 | } from '@angular/core/testing';
9 | import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing';
10 | import { Component } from '@angular/core';
11 | import { By } from '@angular/platform-browser';
12 | import { ToolbarComponent } from './toolbar.component';
13 |
14 | describe('Component: Toolbar', () => {
15 | let builder: TestComponentBuilder;
16 |
17 | beforeEachProviders(() => [ToolbarComponent]);
18 | beforeEach(inject([TestComponentBuilder], function (tcb: TestComponentBuilder) {
19 | builder = tcb;
20 | }));
21 |
22 | it('should inject the component', inject([ToolbarComponent],
23 | (component: ToolbarComponent) => {
24 | expect(component).toBeTruthy();
25 | }));
26 |
27 | it('should create the component', inject([], () => {
28 | return builder.createAsync(ToolbarComponentTestController)
29 | .then((fixture: ComponentFixture) => {
30 | let query = fixture.debugElement.query(By.directive(ToolbarComponent));
31 | expect(query).toBeTruthy();
32 | expect(query.componentInstance).toBeTruthy();
33 | });
34 | }));
35 | });
36 |
37 | @Component({
38 | selector: 'test',
39 | template: `
40 |
41 | `,
42 | directives: [ToolbarComponent]
43 | })
44 | class ToolbarComponentTestController {
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/src/app/+issues/+list/toolbar/toolbar.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Component,
3 | EventEmitter,
4 | Input,
5 | Output
6 | } from '@angular/core';
7 | import { ROUTER_DIRECTIVES } from '@angular/router-deprecated';
8 | import { MdIcon } from '@angular2-material/icon';
9 | import {MdToolbar} from '@angular2-material/toolbar';
10 | import {MdButton} from '@angular2-material/button';
11 |
12 | @Component({
13 | selector: 'issue-list-toolbar',
14 | template: `
15 |
16 |
17 |
18 | {{repo.full_name}}
19 |
22 |
23 |
24 |
25 | filter
26 |
27 |
28 |
29 | `,
30 | styles: [`
31 | md-toolbar img {
32 | margin-right: 16px;
33 | }
34 | .fill-remaining-space {
35 | flex: 1 1 auto;
36 | }
37 | .change-repo {
38 | margin-left: 16px;
39 | }
40 | `],
41 | directives: [MdButton, MdIcon, MdToolbar, ROUTER_DIRECTIVES]
42 | })
43 | export class ToolbarComponent {
44 | @Input('repo') repo:any;
45 | }
46 |
--------------------------------------------------------------------------------
/src/app/+issues/+triage/index.ts:
--------------------------------------------------------------------------------
1 | export { TriageComponent } from './triage.component';
2 |
--------------------------------------------------------------------------------
/src/app/+issues/+triage/is-checked.pipe.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | it,
3 | describe,
4 | expect,
5 | inject,
6 | beforeEachProviders
7 | } from '@angular/core/testing';
8 | import { IsChecked } from './is-checked.pipe';
9 |
10 | describe('IsChecked Pipe', () => {
11 | beforeEachProviders(() => [IsChecked]);
12 |
13 | it('should transform the input', inject([IsChecked], (pipe: IsChecked) => {
14 | // expect(pipe.transform(true)).toBe(null);
15 | }));
16 | });
17 |
--------------------------------------------------------------------------------
/src/app/+issues/+triage/is-checked.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { Label, Issue } from '../../shared';
3 |
4 | @Pipe({
5 | name: 'isChecked'
6 | })
7 | export class IsChecked {
8 | transform (label: Label, [issue]: [Issue]): boolean {
9 | return issue ? issue.labels.filter(l => l.name === label.name).length === 1 : false;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/app/+issues/+triage/shared/index.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/issue-zero/b5628226a783157630a2a2ed76137c9f3bf09d36/src/app/+issues/+triage/shared/index.ts
--------------------------------------------------------------------------------
/src/app/+issues/+triage/to-date.pipe.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | it,
3 | describe,
4 | expect,
5 | inject,
6 | beforeEachProviders
7 | } from '@angular/core/testing';
8 | import { ToDate } from './to-date.pipe';
9 |
10 | describe('ToDate Pipe', () => {
11 | beforeEachProviders(() => [ToDate]);
12 |
13 | it('should transform the input', inject([ToDate], (pipe: ToDate) => {
14 | // expect(pipe.transform(true)).toBe(null);
15 | }));
16 | });
17 |
--------------------------------------------------------------------------------
/src/app/+issues/+triage/to-date.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 |
3 | @Pipe({
4 | name: 'toDate'
5 | })
6 | export class ToDate {
7 | transform(date:string): Date {
8 | return new Date(date);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/+issues/+triage/triage.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/issue-zero/b5628226a783157630a2a2ed76137c9f3bf09d36/src/app/+issues/+triage/triage.component.css
--------------------------------------------------------------------------------
/src/app/+issues/+triage/triage.component.html:
--------------------------------------------------------------------------------
1 |
2 | triage works!
3 |
4 |
--------------------------------------------------------------------------------
/src/app/+issues/+triage/triage.component.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | beforeEach,
3 | beforeEachProviders,
4 | describe,
5 | expect,
6 | it,
7 | inject,
8 | } from '@angular/core/testing';
9 | import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing';
10 | import { Component } from '@angular/core';
11 | import { By } from '@angular/platform-browser';
12 | import { TriageComponent } from './triage.component';
13 |
14 | describe('Component: Triage', () => {
15 | let builder: TestComponentBuilder;
16 |
17 | beforeEachProviders(() => [TriageComponent]);
18 | beforeEach(inject([TestComponentBuilder], function (tcb: TestComponentBuilder) {
19 | builder = tcb;
20 | }));
21 |
22 | it('should inject the component', inject([TriageComponent],
23 | (component: TriageComponent) => {
24 | expect(component).toBeTruthy();
25 | }));
26 |
27 | it('should create the component', inject([], () => {
28 | return builder.createAsync(TriageComponentTestController)
29 | .then((fixture: ComponentFixture) => {
30 | let query = fixture.debugElement.query(By.directive(TriageComponent));
31 | expect(query).toBeTruthy();
32 | expect(query.componentInstance).toBeTruthy();
33 | });
34 | }));
35 | });
36 |
37 | @Component({
38 | selector: 'test',
39 | template: `
40 |
41 | `,
42 | directives: [TriageComponent]
43 | })
44 | class TriageComponentTestController {
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/src/app/+issues/+triage/triage.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 | import {RouteParams, ROUTER_DIRECTIVES, Router} from '@angular/router-deprecated';
3 | import {MdButton} from '@angular2-material/button';
4 | import {MD_LIST_DIRECTIVES} from '@angular2-material/list';
5 | import {MdToolbar} from '@angular2-material/toolbar';
6 | import {MdCheckbox} from '@angular2-material/checkbox';
7 | import {MdInput} from '@angular2-material/input';
8 | import {MdCard} from '@angular2-material/card';
9 | import {Observable} from 'rxjs/Observable';
10 | import {Store} from '@ngrx/store';
11 |
12 | import {GithubService} from '../../github.service';
13 | import {RepoParamsService} from '../../repo-params.service';
14 | import { AppState, Issue, Label } from '../../shared';
15 | import { ToDate } from './to-date.pipe';
16 | import { IsChecked } from './is-checked.pipe';
17 |
18 | @Component({
19 | template: `
20 |
21 |
22 | {{issue?.title}}
23 |
24 | #{{issue?.number}}
25 |
26 |
27 |
28 | @{{issue.user.login}} on {{issue.created_at | toDate | date}}:
29 |
30 |
31 | {{issue?.body}}
32 |
33 |
34 |
35 |
36 | Triage
37 |
38 |
39 |
60 |
61 |
62 | `,
63 | styles: [`
64 | .description {
65 | font-size: 1.2em;
66 | }
67 | md-card {
68 | margin: 16px 16px 0;
69 | }
70 | .issue-number {
71 | color: rgba(0,0,0,0.54);
72 | }
73 | .user-and-date {
74 | color: rgba(0,0,0,0.54);
75 | }
76 | `],
77 | providers: [RepoParamsService],
78 | directives: [MD_LIST_DIRECTIVES, MdButton, MdCheckbox, ROUTER_DIRECTIVES, MdToolbar, MdInput, MdCard],
79 | pipes: [IsChecked, ToDate]
80 | })
81 | export class TriageComponent {
82 | comment: string;
83 | org: string;
84 | repo: string;
85 | labels: Observable