* init new Angular project | * init new Angular project | ||||
``` | ``` | ||||
ng new graphql-demo | |||||
``` | |||||
ng new frontend | |||||
``` | |||||
``` | |||||
npm i | |||||
npm add apollo-angular | |||||
ng add apollo-angular | |||||
npm add graphql | |||||
npm add --save-dev @graphql-codegen/cli | |||||
npm i | |||||
``` | |||||
* init codegen | |||||
``` | |||||
npx graphql-codegen init | |||||
npm i | |||||
``` | |||||
* check angular | |||||
* use url "http://localhost:400" | |||||
* fragment path default | |||||
* plugin default | |||||
* output default | |||||
* set uri in graphql module | |||||
* move | |||||
* graphql.module | |||||
## Pizza component | |||||
``` | |||||
ng add @angular/material | |||||
(style - default) | |||||
``` | |||||
``` | |||||
ng g c pizza-list | |||||
``` | |||||
* copy | |||||
* app.module.ts | |||||
* app.component.ts | |||||
* styles.css |
{ | { | ||||
"name": "demo", | |||||
"name": "graphql-pizza-demo", | |||||
"version": "1.0.0", | "version": "1.0.0", | ||||
"lockfileVersion": 1, | "lockfileVersion": 1, | ||||
"requires": true, | "requires": true, |
import { ApolloServer } from "apollo-server"; | |||||
import { ApolloServer } from "apollo-server/dist"; | |||||
import { Resolvers } from "./generated/graphql"; | import { Resolvers } from "./generated/graphql"; | ||||
import { pizzaSchema } from "./schema/pizza"; | import { pizzaSchema } from "./schema/pizza"; | ||||
import { PizzaResolver } from "./resolver/pizza-resolver"; | import { PizzaResolver } from "./resolver/pizza-resolver"; |
] /* Specify library files to be included in the compilation. */, | ] /* Specify library files to be included in the compilation. */, | ||||
"allowJs": true /* Allow javascript files to be compiled. */, | "allowJs": true /* Allow javascript files to be compiled. */, | ||||
"outDir": "build" /* Redirect output structure to the directory. */, | "outDir": "build" /* Redirect output structure to the directory. */, | ||||
"rootDir": "src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, | |||||
"rootDir": "../srceal.js/assets/src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, | |||||
"strict": true /* Enable all strict type-checking options. */, | "strict": true /* Enable all strict type-checking options. */, | ||||
"skipLibCheck": true, | "skipLibCheck": true, | ||||
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, | "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, |
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. | |||||
# For additional information regarding the format and rule options, please see: | |||||
# https://github.com/browserslist/browserslist#queries | |||||
# For the full list of supported browsers by the Angular framework, please see: | |||||
# https://angular.io/guide/browser-support | |||||
# You can see what browsers were selected by your queries by running: | |||||
# npx browserslist | |||||
last 1 Chrome version | |||||
last 1 Firefox version | |||||
last 2 Edge major versions | |||||
last 2 Safari major versions | |||||
last 2 iOS major versions | |||||
Firefox ESR | |||||
not IE 9-10 # Angular support for IE 9-10 has been deprecated and will be removed as of Angular v11. To opt-in, remove the 'not' prefix on this line. | |||||
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. |
# Editor configuration, see https://editorconfig.org | |||||
root = true | |||||
[*] | |||||
charset = utf-8 | |||||
indent_style = space | |||||
indent_size = 2 | |||||
insert_final_newline = true | |||||
trim_trailing_whitespace = true | |||||
[*.ts] | |||||
quote_type = single | |||||
[*.md] | |||||
max_line_length = off | |||||
trim_trailing_whitespace = false |
# See http://help.github.com/ignore-files/ for more about ignoring files. | |||||
# compiled output | |||||
/dist | |||||
/tmp | |||||
/out-tsc | |||||
# Only exists if Bazel was run | |||||
/bazel-out | |||||
# dependencies | |||||
/node_modules | |||||
# profiling files | |||||
chrome-profiler-events*.json | |||||
speed-measure-plugin*.json | |||||
# IDEs and editors | |||||
/.idea | |||||
.project | |||||
.classpath | |||||
.c9/ | |||||
*.launch | |||||
.settings/ | |||||
*.sublime-workspace | |||||
# IDE - VSCode | |||||
.vscode/* | |||||
!.vscode/settings.json | |||||
!.vscode/tasks.json | |||||
!.vscode/launch.json | |||||
!.vscode/extensions.json | |||||
.history/* | |||||
# misc | |||||
/.sass-cache | |||||
/connect.lock | |||||
/coverage | |||||
/libpeerconnection.log | |||||
npm-debug.log | |||||
yarn-error.log | |||||
testem.log | |||||
/typings | |||||
# System Files | |||||
.DS_Store | |||||
Thumbs.db |
# Frontend2 | |||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.0.3. | |||||
## Development server | |||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. | |||||
## Code scaffolding | |||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. | |||||
## Build | |||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. | |||||
## Running unit tests | |||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). | |||||
## Running end-to-end tests | |||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). | |||||
## Further help | |||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). |
{ | |||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json", | |||||
"version": 1, | |||||
"newProjectRoot": "projects", | |||||
"projects": { | |||||
"frontend2": { | |||||
"projectType": "application", | |||||
"schematics": { | |||||
"@schematics/angular:component": { | |||||
"style": "scss" | |||||
} | |||||
}, | |||||
"root": "", | |||||
"sourceRoot": "src", | |||||
"prefix": "app", | |||||
"architect": { | |||||
"build": { | |||||
"builder": "@angular-devkit/build-angular:browser", | |||||
"options": { | |||||
"outputPath": "dist/frontend2", | |||||
"index": "src/index.html", | |||||
"main": "src/main.ts", | |||||
"polyfills": "src/polyfills.ts", | |||||
"tsConfig": "tsconfig.app.json", | |||||
"aot": true, | |||||
"assets": [ | |||||
"src/favicon.ico", | |||||
"src/assets" | |||||
], | |||||
"styles": [ | |||||
"src/styles.scss" | |||||
], | |||||
"scripts": [] | |||||
}, | |||||
"configurations": { | |||||
"production": { | |||||
"fileReplacements": [ | |||||
{ | |||||
"replace": "src/environments/environment.ts", | |||||
"with": "src/environments/environment.prod.ts" | |||||
} | |||||
], | |||||
"optimization": true, | |||||
"outputHashing": "all", | |||||
"sourceMap": false, | |||||
"extractCss": true, | |||||
"namedChunks": false, | |||||
"extractLicenses": true, | |||||
"vendorChunk": false, | |||||
"buildOptimizer": true, | |||||
"budgets": [ | |||||
{ | |||||
"type": "initial", | |||||
"maximumWarning": "2mb", | |||||
"maximumError": "5mb" | |||||
}, | |||||
{ | |||||
"type": "anyComponentStyle", | |||||
"maximumWarning": "6kb", | |||||
"maximumError": "10kb" | |||||
} | |||||
] | |||||
} | |||||
} | |||||
}, | |||||
"serve": { | |||||
"builder": "@angular-devkit/build-angular:dev-server", | |||||
"options": { | |||||
"browserTarget": "frontend2:build" | |||||
}, | |||||
"configurations": { | |||||
"production": { | |||||
"browserTarget": "frontend2:build:production" | |||||
} | |||||
} | |||||
}, | |||||
"extract-i18n": { | |||||
"builder": "@angular-devkit/build-angular:extract-i18n", | |||||
"options": { | |||||
"browserTarget": "frontend2:build" | |||||
} | |||||
}, | |||||
"test": { | |||||
"builder": "@angular-devkit/build-angular:karma", | |||||
"options": { | |||||
"main": "src/test.ts", | |||||
"polyfills": "src/polyfills.ts", | |||||
"tsConfig": "tsconfig.spec.json", | |||||
"karmaConfig": "karma.conf.js", | |||||
"assets": [ | |||||
"src/favicon.ico", | |||||
"src/assets" | |||||
], | |||||
"styles": [ | |||||
"src/styles.scss" | |||||
], | |||||
"scripts": [] | |||||
} | |||||
}, | |||||
"lint": { | |||||
"builder": "@angular-devkit/build-angular:tslint", | |||||
"options": { | |||||
"tsConfig": [ | |||||
"tsconfig.app.json", | |||||
"tsconfig.spec.json", | |||||
"e2e/tsconfig.json" | |||||
], | |||||
"exclude": [ | |||||
"**/node_modules/**" | |||||
] | |||||
} | |||||
}, | |||||
"e2e": { | |||||
"builder": "@angular-devkit/build-angular:protractor", | |||||
"options": { | |||||
"protractorConfig": "e2e/protractor.conf.js", | |||||
"devServerTarget": "frontend2:serve" | |||||
}, | |||||
"configurations": { | |||||
"production": { | |||||
"devServerTarget": "frontend2:serve:production" | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
}, | |||||
"defaultProject": "frontend2" | |||||
} |
overwrite: true | |||||
schema: "http://localhost:4000" | |||||
documents: "src/**/*.graphql" | |||||
generates: | |||||
src/generated/graphql.ts: | |||||
plugins: | |||||
- "typescript" | |||||
- "typescript-operations" | |||||
- "typescript-apollo-angular" |
// @ts-check | |||||
// Protractor configuration file, see link for more information | |||||
// https://github.com/angular/protractor/blob/master/lib/config.ts | |||||
const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); | |||||
/** | |||||
* @type { import("protractor").Config } | |||||
*/ | |||||
exports.config = { | |||||
allScriptsTimeout: 11000, | |||||
specs: [ | |||||
'./src/**/*.e2e-spec.ts' | |||||
], | |||||
capabilities: { | |||||
browserName: 'chrome' | |||||
}, | |||||
directConnect: true, | |||||
baseUrl: 'http://localhost:4200/', | |||||
framework: 'jasmine', | |||||
jasmineNodeOpts: { | |||||
showColors: true, | |||||
defaultTimeoutInterval: 30000, | |||||
print: function() {} | |||||
}, | |||||
onPrepare() { | |||||
require('ts-node').register({ | |||||
project: require('path').join(__dirname, './tsconfig.json') | |||||
}); | |||||
jasmine.getEnv().addReporter(new SpecReporter({ | |||||
spec: { | |||||
displayStacktrace: StacktraceOption.PRETTY | |||||
} | |||||
})); | |||||
} | |||||
}; |
import { AppPage } from './app.po'; | |||||
import { browser, logging } from 'protractor'; | |||||
describe('workspace-project App', () => { | |||||
let page: AppPage; | |||||
beforeEach(() => { | |||||
page = new AppPage(); | |||||
}); | |||||
it('should display welcome message', () => { | |||||
page.navigateTo(); | |||||
expect(page.getTitleText()).toEqual('frontend2 app is running!'); | |||||
}); | |||||
afterEach(async () => { | |||||
// Assert that there are no errors emitted from the browser | |||||
const logs = await browser.manage().logs().get(logging.Type.BROWSER); | |||||
expect(logs).not.toContain(jasmine.objectContaining({ | |||||
level: logging.Level.SEVERE, | |||||
} as logging.Entry)); | |||||
}); | |||||
}); |
import { browser, by, element } from 'protractor'; | |||||
export class AppPage { | |||||
navigateTo(): Promise<unknown> { | |||||
return browser.get(browser.baseUrl) as Promise<unknown>; | |||||
} | |||||
getTitleText(): Promise<string> { | |||||
return element(by.css('app-root .content span')).getText() as Promise<string>; | |||||
} | |||||
} |
/* To learn more about this file see: https://angular.io/config/tsconfig. */ | |||||
{ | |||||
"extends": "../tsconfig.base.json", | |||||
"compilerOptions": { | |||||
"outDir": "../out-tsc/e2e", | |||||
"module": "commonjs", | |||||
"target": "es2018", | |||||
"types": [ | |||||
"jasmine", | |||||
"jasminewd2", | |||||
"node" | |||||
] | |||||
} | |||||
} |
// Karma configuration file, see link for more information | |||||
// https://karma-runner.github.io/1.0/config/configuration-file.html | |||||
module.exports = function (config) { | |||||
config.set({ | |||||
basePath: '', | |||||
frameworks: ['jasmine', '@angular-devkit/build-angular'], | |||||
plugins: [ | |||||
require('karma-jasmine'), | |||||
require('karma-chrome-launcher'), | |||||
require('karma-jasmine-html-reporter'), | |||||
require('karma-coverage-istanbul-reporter'), | |||||
require('@angular-devkit/build-angular/plugins/karma') | |||||
], | |||||
client: { | |||||
clearContext: false // leave Jasmine Spec Runner output visible in browser | |||||
}, | |||||
coverageIstanbulReporter: { | |||||
dir: require('path').join(__dirname, './coverage/frontend2'), | |||||
reports: ['html', 'lcovonly', 'text-summary'], | |||||
fixWebpackSourcePaths: true | |||||
}, | |||||
reporters: ['progress', 'kjhtml'], | |||||
port: 9876, | |||||
colors: true, | |||||
logLevel: config.LOG_INFO, | |||||
autoWatch: true, | |||||
browsers: ['Chrome'], | |||||
singleRun: false, | |||||
restartOnFileChange: true | |||||
}); | |||||
}; |
{ | |||||
"name": "frontend2", | |||||
"version": "0.0.0", | |||||
"scripts": { | |||||
"ng": "ng", | |||||
"start": "ng serve", | |||||
"build": "ng build", | |||||
"test": "ng test", | |||||
"lint": "ng lint", | |||||
"e2e": "ng e2e", | |||||
"gen": "graphql-codegen --config codegen.yml" | |||||
}, | |||||
"private": true, | |||||
"dependencies": { | |||||
"@angular/animations": "~10.0.4", | |||||
"@angular/cdk": "^10.0.2", | |||||
"@angular/common": "~10.0.4", | |||||
"@angular/compiler": "~10.0.4", | |||||
"@angular/core": "~10.0.4", | |||||
"@angular/forms": "~10.0.4", | |||||
"@angular/material": "^10.0.2", | |||||
"@angular/platform-browser": "~10.0.4", | |||||
"@angular/platform-browser-dynamic": "~10.0.4", | |||||
"@angular/router": "~10.0.4", | |||||
"apollo-angular": "^1.10.0", | |||||
"apollo-angular-link-http": "^1.11.0", | |||||
"apollo-cache-inmemory": "^1.6.0", | |||||
"apollo-client": "^2.6.0", | |||||
"apollo-link": "^1.2.11", | |||||
"graphql": "^15.3.0", | |||||
"graphql-tag": "^2.10.0", | |||||
"rxjs": "~6.5.5", | |||||
"tslib": "^2.0.0", | |||||
"zone.js": "~0.10.3" | |||||
}, | |||||
"devDependencies": { | |||||
"@angular-devkit/build-angular": "~0.1000.3", | |||||
"@angular/cli": "~10.0.3", | |||||
"@angular/compiler-cli": "~10.0.4", | |||||
"@graphql-codegen/cli": "1.17.0", | |||||
"@types/jasmine": "~3.5.0", | |||||
"@types/jasminewd2": "~2.0.3", | |||||
"@types/node": "^12.11.1", | |||||
"codelyzer": "^6.0.0", | |||||
"jasmine-core": "~3.5.0", | |||||
"jasmine-spec-reporter": "~5.0.0", | |||||
"karma": "~5.0.0", | |||||
"karma-chrome-launcher": "~3.1.0", | |||||
"karma-coverage-istanbul-reporter": "~3.0.2", | |||||
"karma-jasmine": "~3.3.0", | |||||
"karma-jasmine-html-reporter": "^1.5.0", | |||||
"protractor": "~7.0.0", | |||||
"ts-node": "~8.3.0", | |||||
"tslint": "~6.1.0", | |||||
"typescript": "~3.9.5", | |||||
"@graphql-codegen/typescript": "1.17.0", | |||||
"@graphql-codegen/typescript-operations": "1.17.0", | |||||
"@graphql-codegen/typescript-apollo-angular": "1.17.0" | |||||
} | |||||
} |
<div | |||||
class="main-container" | |||||
autosize | |||||
> | |||||
<mat-toolbar color="primary" class="main-toolbar"> | |||||
<mat-toolbar-row> | |||||
<h1 class="main-app-name">Pizza Tool</h1> | |||||
</mat-toolbar-row> | |||||
</mat-toolbar> | |||||
<mat-sidenav-container | |||||
[hasBackdrop]="true" | |||||
class="main-sidenav-container" | |||||
> | |||||
<mat-sidenav-content> | |||||
<app-pizza-list></app-pizza-list> | |||||
<app-pizza-list-with-topping></app-pizza-list-with-topping> | |||||
<mat-toolbar class="footer"></mat-toolbar> | |||||
</mat-sidenav-content> | |||||
</mat-sidenav-container> | |||||
</div> |
import { TestBed, async } from '@angular/core/testing'; | |||||
import { AppComponent } from './app.component'; | |||||
describe('AppComponent', () => { | |||||
beforeEach(async(() => { | |||||
TestBed.configureTestingModule({ | |||||
declarations: [ | |||||
AppComponent | |||||
], | |||||
}).compileComponents(); | |||||
})); | |||||
it('should create the app', () => { | |||||
const fixture = TestBed.createComponent(AppComponent); | |||||
const app = fixture.componentInstance; | |||||
expect(app).toBeTruthy(); | |||||
}); | |||||
it(`should have as title 'frontend2'`, () => { | |||||
const fixture = TestBed.createComponent(AppComponent); | |||||
const app = fixture.componentInstance; | |||||
expect(app.title).toEqual('frontend2'); | |||||
}); | |||||
it('should render title', () => { | |||||
const fixture = TestBed.createComponent(AppComponent); | |||||
fixture.detectChanges(); | |||||
const compiled = fixture.nativeElement; | |||||
expect(compiled.querySelector('.content span').textContent).toContain('frontend2 app is running!'); | |||||
}); | |||||
}); |
import { Component } from '@angular/core'; | |||||
@Component({ | |||||
selector: 'app-root', | |||||
templateUrl: './app.component.html', | |||||
styleUrls: ['./app.component.scss'] | |||||
}) | |||||
export class AppComponent { | |||||
title = 'frontend2'; | |||||
} |
import { BrowserModule } from '@angular/platform-browser'; | |||||
import { NgModule } from '@angular/core'; | |||||
import { MatCardModule } from '@angular/material/card'; | |||||
import { MatCheckboxModule } from '@angular/material/checkbox'; | |||||
import { MatIconModule } from '@angular/material/icon'; | |||||
import { MatInputModule } from '@angular/material/input'; | |||||
import { MatListModule } from '@angular/material/list'; | |||||
import { MatMenuModule } from '@angular/material/menu'; | |||||
import { MatSidenavModule } from '@angular/material/sidenav'; | |||||
import { MatTableModule } from '@angular/material/table'; | |||||
import { MatTabsModule } from '@angular/material/tabs'; | |||||
import { MatToolbarModule } from '@angular/material/toolbar'; | |||||
import { MatButtonModule } from '@angular/material/button'; | |||||
import { AppComponent } from './app.component'; | |||||
import { GraphQLModule } from '../graphql.module'; | |||||
import { HttpClientModule } from '@angular/common/http'; | |||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; | |||||
import { PizzaListComponent } from './pizza-list/pizza-list.component'; | |||||
import { PizzaListWithToppingComponent } from './pizza-list-with-topping/pizza-list-with-topping.component'; | |||||
import { CommonModule } from '@angular/common'; | |||||
import { FormsModule } from '@angular/forms'; | |||||
@NgModule({ | |||||
declarations: [ | |||||
AppComponent, | |||||
PizzaListComponent, | |||||
PizzaListWithToppingComponent, | |||||
], | |||||
imports: [ | |||||
MatCheckboxModule, | |||||
MatCardModule, | |||||
MatInputModule, | |||||
MatListModule, | |||||
MatToolbarModule, | |||||
MatMenuModule, | |||||
MatIconModule, | |||||
MatTabsModule, | |||||
MatTableModule, | |||||
MatSidenavModule, | |||||
MatButtonModule, | |||||
BrowserModule, | |||||
HttpClientModule, | |||||
CommonModule, | |||||
FormsModule, | |||||
GraphQLModule, | |||||
BrowserModule, | |||||
GraphQLModule, | |||||
HttpClientModule, | |||||
BrowserAnimationsModule | |||||
], | |||||
providers: [], | |||||
bootstrap: [AppComponent] | |||||
}) | |||||
export class AppModule { } |
<mat-toolbar> | |||||
<mat-toolbar-row> | |||||
<h1>Pizzas With topping</h1> | |||||
</mat-toolbar-row> | |||||
</mat-toolbar> | |||||
<table mat-table [dataSource]="pizzas"> | |||||
<ng-container matColumnDef="id"> | |||||
<th class="id" mat-header-cell *matHeaderCellDef>ID</th> | |||||
<td class="id" mat-cell *matCellDef="let pizza; let i = index"> | |||||
{{ pizza.id }} | |||||
</td> | |||||
</ng-container> | |||||
<ng-container matColumnDef="name"> | |||||
<th class="name" mat-header-cell *matHeaderCellDef>Name</th> | |||||
<td class="name" mat-cell *matCellDef="let pizza; let i = index"> | |||||
{{ pizza.name }} | |||||
</td> | |||||
</ng-container> | |||||
<ng-container matColumnDef="toppings"> | |||||
<th class="toppings" mat-header-cell *matHeaderCellDef>Name</th> | |||||
<td class="toppings" mat-cell *matCellDef="let pizza; let i = index"> | |||||
{{ getToppingListString(pizza.toppings) }} | |||||
</td> | |||||
</ng-container> | |||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> | |||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr> | |||||
</table> | |||||
<ng-template #nopizzaSelected> | |||||
no pizza selected, please select a pizza to see events! | |||||
</ng-template> |
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
describe('PizzaListWithToppingComponent', () => { | |||||
let component: PizzaListWithToppingComponent; | |||||
let fixture: ComponentFixture<PizzaListWithToppingComponent>; | |||||
beforeEach(async(() => { | |||||
TestBed.configureTestingModule({ | |||||
declarations: [ PizzaListWithToppingComponent ] | |||||
}) | |||||
.compileComponents(); | |||||
})); | |||||
beforeEach(() => { | |||||
fixture = TestBed.createComponent(PizzaListWithToppingComponent); | |||||
component = fixture.componentInstance; | |||||
fixture.detectChanges(); | |||||
}); | |||||
it('should create', () => { | |||||
expect(component).toBeTruthy(); | |||||
}); | |||||
}); |
import { Component, OnInit } from '@angular/core'; | |||||
import { Pizza, ListPizzaGQL, ListPizzaWithToppingGQL, Topping } from 'src/generated/graphql'; | |||||
import { Observable } from 'rxjs'; | |||||
import { map } from 'rxjs/operators'; | |||||
@Component({ | |||||
selector: 'app-pizza-list-with-topping', | |||||
templateUrl: './pizza-list-with-topping.component.html', | |||||
styleUrls: ['./pizza-list-with-topping.component.scss'] | |||||
}) | |||||
export class PizzaListWithToppingComponent implements OnInit { | |||||
displayedColumns: string[] = [ | |||||
'id', | |||||
'name', | |||||
'toppings' | |||||
]; | |||||
pizzas: Observable<Pizza[]>; | |||||
constructor(listPizzaWithToppings: ListPizzaWithToppingGQL) { | |||||
this.pizzas = listPizzaWithToppings | |||||
.watch() | |||||
.valueChanges | |||||
.pipe(map(result => result.data.listPizza as Pizza[])); | |||||
} | |||||
ngOnInit(): void { | |||||
} | |||||
getToppingListString(toppings: Topping[]): string { | |||||
return toppings.map(topping => topping.name).join(', '); | |||||
} | |||||
} |
query ListPizzaWithTopping { | |||||
listPizza { | |||||
id | |||||
name, | |||||
toppings { | |||||
name | |||||
} | |||||
} | |||||
} |
<mat-toolbar> | |||||
<mat-toolbar-row> | |||||
<h1>Pizza</h1> | |||||
</mat-toolbar-row> | |||||
</mat-toolbar> | |||||
<table mat-table [dataSource]="pizzas"> | |||||
<ng-container matColumnDef="id"> | |||||
<th class="id" mat-header-cell *matHeaderCellDef>ID</th> | |||||
<td class="id" mat-cell *matCellDef="let pizza; let i = index"> | |||||
{{ pizza.id }} | |||||
</td> | |||||
</ng-container> | |||||
<ng-container matColumnDef="name"> | |||||
<th class="name" mat-header-cell *matHeaderCellDef>Name</th> | |||||
<td class="name" mat-cell *matCellDef="let pizza; let i = index"> | |||||
{{ pizza.name }} | |||||
</td> | |||||
</ng-container> | |||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> | |||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr> | |||||
</table> | |||||
<ng-template #nopizzaSelected> | |||||
no pizza selected, please select a pizza to see events! | |||||
</ng-template> |
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
import { PizzaListComponent } from './pizza-list.component'; | |||||
describe('PizzaListComponent', () => { | |||||
let component: PizzaListComponent; | |||||
let fixture: ComponentFixture<PizzaListComponent>; | |||||
beforeEach(async(() => { | |||||
TestBed.configureTestingModule({ | |||||
declarations: [ PizzaListComponent ] | |||||
}) | |||||
.compileComponents(); | |||||
})); | |||||
beforeEach(() => { | |||||
fixture = TestBed.createComponent(PizzaListComponent); | |||||
component = fixture.componentInstance; | |||||
fixture.detectChanges(); | |||||
}); | |||||
it('should create', () => { | |||||
expect(component).toBeTruthy(); | |||||
}); | |||||
}); |
import { Component, OnInit } from '@angular/core'; | |||||
import { Pizza, ListPizzaGQL } from 'src/generated/graphql'; | |||||
import { Observable } from 'rxjs'; | |||||
import { map } from 'rxjs/operators'; | |||||
@Component({ | |||||
selector: 'app-pizza-list', | |||||
templateUrl: './pizza-list.component.html', | |||||
styleUrls: ['./pizza-list.component.scss'] | |||||
}) | |||||
export class PizzaListComponent implements OnInit { | |||||
displayedColumns: string[] = [ | |||||
'id', | |||||
'name', | |||||
]; | |||||
pizzas: Observable<Pizza[]>; | |||||
constructor(listPizza: ListPizzaGQL) { | |||||
this.pizzas = listPizza | |||||
.watch() | |||||
.valueChanges | |||||
.pipe(map(result => result.data.listPizza as Pizza[])); | |||||
} | |||||
ngOnInit(): void { | |||||
} | |||||
} |
query ListPizza { | |||||
listPizza { | |||||
id | |||||
name | |||||
} | |||||
} |
export const environment = { | |||||
production: true | |||||
}; |
// This file can be replaced during build by using the `fileReplacements` array. | |||||
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. | |||||
// The list of file replacements can be found in `angular.json`. | |||||
export const environment = { | |||||
production: false | |||||
}; | |||||
/* | |||||
* For easier debugging in development mode, you can import the following file | |||||
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. | |||||
* | |||||
* This import should be commented out in production mode because it will have a negative impact | |||||
* on performance if an error is thrown. | |||||
*/ | |||||
// import 'zone.js/dist/zone-error'; // Included with Angular CLI. |
import gql from 'graphql-tag'; | |||||
import { Injectable } from '@angular/core'; | |||||
import * as Apollo from 'apollo-angular'; | |||||
export type Maybe<T> = T | null; | |||||
export type Exact<T extends { [key: string]: any }> = { [K in keyof T]: T[K] }; | |||||
/** All built-in and custom scalars, mapped to their actual values */ | |||||
export type Scalars = { | |||||
ID: string; | |||||
String: string; | |||||
Boolean: boolean; | |||||
Int: number; | |||||
Float: number; | |||||
/** The `Upload` scalar type represents a file upload. */ | |||||
Upload: any; | |||||
}; | |||||
export type Pizza = { | |||||
__typename?: 'Pizza'; | |||||
id: Scalars['ID']; | |||||
name: Scalars['String']; | |||||
toppings: Array<Topping>; | |||||
}; | |||||
export type Topping = { | |||||
__typename?: 'Topping'; | |||||
id: Scalars['ID']; | |||||
name: Scalars['String']; | |||||
}; | |||||
export type Query = { | |||||
__typename?: 'Query'; | |||||
getPizzaById: Pizza; | |||||
getToppingById: Topping; | |||||
getPizzaByName: Pizza; | |||||
getToppingByName: Topping; | |||||
listPizza: Array<Maybe<Pizza>>; | |||||
listTopping: Array<Maybe<Topping>>; | |||||
}; | |||||
export type QueryGetPizzaByIdArgs = { | |||||
pizzaId: Scalars['ID']; | |||||
}; | |||||
export type QueryGetToppingByIdArgs = { | |||||
toppingId: Scalars['ID']; | |||||
}; | |||||
export type QueryGetPizzaByNameArgs = { | |||||
pizzaName: Scalars['ID']; | |||||
}; | |||||
export type QueryGetToppingByNameArgs = { | |||||
toppingName: Scalars['ID']; | |||||
}; | |||||
export enum CacheControlScope { | |||||
Public = 'PUBLIC', | |||||
Private = 'PRIVATE' | |||||
} | |||||
export type ListPizzaWithToppingQueryVariables = Exact<{ [key: string]: never; }>; | |||||
export type ListPizzaWithToppingQuery = ( | |||||
{ __typename?: 'Query' } | |||||
& { listPizza: Array<Maybe<( | |||||
{ __typename?: 'Pizza' } | |||||
& Pick<Pizza, 'id' | 'name'> | |||||
& { toppings: Array<( | |||||
{ __typename?: 'Topping' } | |||||
& Pick<Topping, 'name'> | |||||
)> } | |||||
)>> } | |||||
); | |||||
export type ListPizzaQueryVariables = Exact<{ [key: string]: never; }>; | |||||
export type ListPizzaQuery = ( | |||||
{ __typename?: 'Query' } | |||||
& { listPizza: Array<Maybe<( | |||||
{ __typename?: 'Pizza' } | |||||
& Pick<Pizza, 'id' | 'name'> | |||||
)>> } | |||||
); | |||||
export const ListPizzaWithToppingDocument = gql` | |||||
query ListPizzaWithTopping { | |||||
listPizza { | |||||
id | |||||
name | |||||
toppings { | |||||
name | |||||
} | |||||
} | |||||
} | |||||
`; | |||||
@Injectable({ | |||||
providedIn: 'root' | |||||
}) | |||||
export class ListPizzaWithToppingGQL extends Apollo.Query<ListPizzaWithToppingQuery, ListPizzaWithToppingQueryVariables> { | |||||
document = ListPizzaWithToppingDocument; | |||||
} | |||||
export const ListPizzaDocument = gql` | |||||
query ListPizza { | |||||
listPizza { | |||||
id | |||||
name | |||||
} | |||||
} | |||||
`; | |||||
@Injectable({ | |||||
providedIn: 'root' | |||||
}) | |||||
export class ListPizzaGQL extends Apollo.Query<ListPizzaQuery, ListPizzaQueryVariables> { | |||||
document = ListPizzaDocument; | |||||
} |
import {NgModule} from '@angular/core'; | |||||
import {ApolloModule, APOLLO_OPTIONS} from 'apollo-angular'; | |||||
import {HttpLinkModule, HttpLink} from 'apollo-angular-link-http'; | |||||
import {InMemoryCache} from 'apollo-cache-inmemory'; | |||||
const uri = 'http://localhost:4000'; // <-- add the URL of the GraphQL server here | |||||
export function createApollo(httpLink: HttpLink) { | |||||
return { | |||||
link: httpLink.create({uri}), | |||||
cache: new InMemoryCache(), | |||||
}; | |||||
} | |||||
@NgModule({ | |||||
exports: [ApolloModule, HttpLinkModule], | |||||
providers: [ | |||||
{ | |||||
provide: APOLLO_OPTIONS, | |||||
useFactory: createApollo, | |||||
deps: [HttpLink], | |||||
}, | |||||
], | |||||
}) | |||||
export class GraphQLModule {} |
<!doctype html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="utf-8"> | |||||
<title>Frontend2</title> | |||||
<base href="/"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1"> | |||||
<link rel="icon" type="image/x-icon" href="favicon.ico"> | |||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap" rel="stylesheet"> | |||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> | |||||
</head> | |||||
<body> | |||||
<app-root></app-root> | |||||
</body> | |||||
</html> |
import { enableProdMode } from '@angular/core'; | |||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; | |||||
import { AppModule } from './app/app.module'; | |||||
import { environment } from './environments/environment'; | |||||
if (environment.production) { | |||||
enableProdMode(); | |||||
} | |||||
platformBrowserDynamic().bootstrapModule(AppModule) | |||||
.catch(err => console.error(err)); |
/** | |||||
* This file includes polyfills needed by Angular and is loaded before the app. | |||||
* You can add your own extra polyfills to this file. | |||||
* | |||||
* This file is divided into 2 sections: | |||||
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. | |||||
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main | |||||
* file. | |||||
* | |||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that | |||||
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), | |||||
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. | |||||
* | |||||
* Learn more in https://angular.io/guide/browser-support | |||||
*/ | |||||
/*************************************************************************************************** | |||||
* BROWSER POLYFILLS | |||||
*/ | |||||
/** IE10 and IE11 requires the following for NgClass support on SVG elements */ | |||||
// import 'classlist.js'; // Run `npm install --save classlist.js`. | |||||
/** | |||||
* Web Animations `@angular/platform-browser/animations` | |||||
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. | |||||
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). | |||||
*/ | |||||
// import 'web-animations-js'; // Run `npm install --save web-animations-js`. | |||||
/** | |||||
* By default, zone.js will patch all possible macroTask and DomEvents | |||||
* user can disable parts of macroTask/DomEvents patch by setting following flags | |||||
* because those flags need to be set before `zone.js` being loaded, and webpack | |||||
* will put import in the top of bundle, so user need to create a separate file | |||||
* in this directory (for example: zone-flags.ts), and put the following flags | |||||
* into that file, and then add the following code before importing zone.js. | |||||
* import './zone-flags'; | |||||
* | |||||
* The flags allowed in zone-flags.ts are listed here. | |||||
* | |||||
* The following flags will work for all browsers. | |||||
* | |||||
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame | |||||
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick | |||||
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames | |||||
* | |||||
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js | |||||
* with the following flag, it will bypass `zone.js` patch for IE/Edge | |||||
* | |||||
* (window as any).__Zone_enable_cross_context_check = true; | |||||
* | |||||
*/ | |||||
/*************************************************************************************************** | |||||
* Zone JS is required by default for Angular itself. | |||||
*/ | |||||
import 'zone.js/dist/zone'; // Included with Angular CLI. | |||||
/*************************************************************************************************** | |||||
* APPLICATION IMPORTS | |||||
*/ |
/* You can add global styles to this file, and also import other style files */ | |||||
html, | |||||
body { | |||||
height: 100%; | |||||
} | |||||
body { | |||||
margin: 0; | |||||
font-family: Roboto, "Helvetica Neue", sans-serif; | |||||
} | |||||
/** | |||||
* Generated theme by Material Theme Generator | |||||
* https://materialtheme.arcsine.dev | |||||
*/ | |||||
@import "~@angular/material/theming"; | |||||
// Include the common styles for Angular Material. We include this here so that you only | |||||
// have to load a single css file for Angular Material in your app. | |||||
// Fonts | |||||
@import "https://fonts.googleapis.com/css?family=Material+Icons"; | |||||
@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,500"); | |||||
$fontConfig: ( | |||||
display-4: mat-typography-level(112px, 112px, 300, "Roboto", -0.0134em), | |||||
display-3: mat-typography-level(56px, 56px, 400, "Roboto", -0.0089em), | |||||
display-2: mat-typography-level(45px, 48px, 400, "Roboto", 0em), | |||||
display-1: mat-typography-level(34px, 40px, 400, "Roboto", 0.0074em), | |||||
headline: mat-typography-level(24px, 32px, 400, "Roboto", 0em), | |||||
title: mat-typography-level(20px, 32px, 500, "Roboto", 0.0075em), | |||||
subheading-2: mat-typography-level(16px, 28px, 400, "Roboto", 0.0094em), | |||||
subheading-1: mat-typography-level(15px, 24px, 500, "Roboto", 0.0067em), | |||||
body-2: mat-typography-level(14px, 24px, 500, "Roboto", 0.0179em), | |||||
body-1: mat-typography-level(14px, 20px, 400, "Roboto", 0.0179em), | |||||
button: mat-typography-level(14px, 14px, 500, "Roboto", 0.0893em), | |||||
caption: mat-typography-level(12px, 20px, 400, "Roboto", 0.0333em), | |||||
input: mat-typography-level(inherit, 1.125, 400, "Roboto", 1.5px), | |||||
); | |||||
// Foreground Elements | |||||
// Light Theme Text | |||||
$dark-text: #000000; | |||||
$dark-primary-text: rgba($dark-text, 0.87); | |||||
$dark-accent-text: rgba($dark-primary-text, 0.54); | |||||
$dark-disabled-text: rgba($dark-primary-text, 0.38); | |||||
$dark-dividers: rgba($dark-primary-text, 0.12); | |||||
$dark-focused: rgba($dark-primary-text, 0.12); | |||||
$mat-light-theme-foreground: ( | |||||
base: black, | |||||
divider: $dark-dividers, | |||||
dividers: $dark-dividers, | |||||
disabled: $dark-disabled-text, | |||||
disabled-button: rgba($dark-text, 0.26), | |||||
disabled-text: $dark-disabled-text, | |||||
elevation: black, | |||||
secondary-text: $dark-accent-text, | |||||
hint-text: $dark-disabled-text, | |||||
accent-text: $dark-accent-text, | |||||
icon: $dark-accent-text, | |||||
icons: $dark-accent-text, | |||||
text: $dark-primary-text, | |||||
slider-min: $dark-primary-text, | |||||
slider-off: rgba($dark-text, 0.26), | |||||
slider-off-active: $dark-disabled-text, | |||||
); | |||||
// Dark Theme text | |||||
$light-text: #ffffff; | |||||
$light-primary-text: $light-text; | |||||
$light-accent-text: rgba($light-primary-text, 0.7); | |||||
$light-disabled-text: rgba($light-primary-text, 0.5); | |||||
$light-dividers: rgba($light-primary-text, 0.12); | |||||
$light-focused: rgba($light-primary-text, 0.12); | |||||
$mat-dark-theme-foreground: ( | |||||
base: $light-text, | |||||
divider: $light-dividers, | |||||
dividers: $light-dividers, | |||||
disabled: $light-disabled-text, | |||||
disabled-button: rgba($light-text, 0.3), | |||||
disabled-text: $light-disabled-text, | |||||
elevation: black, | |||||
hint-text: $light-disabled-text, | |||||
secondary-text: $light-accent-text, | |||||
accent-text: $light-accent-text, | |||||
icon: $light-text, | |||||
icons: $light-text, | |||||
text: $light-text, | |||||
slider-min: $light-text, | |||||
slider-off: rgba($light-text, 0.3), | |||||
slider-off-active: rgba($light-text, 0.3), | |||||
); | |||||
// Background config | |||||
// Light bg | |||||
$light-background: #fafafa; | |||||
$light-bg-darker-5: darken($light-background, 5%); | |||||
$light-bg-darker-10: darken($light-background, 10%); | |||||
$light-bg-darker-20: darken($light-background, 20%); | |||||
$light-bg-darker-30: darken($light-background, 30%); | |||||
$light-bg-lighter-5: lighten($light-background, 5%); | |||||
$dark-bg-tooltip: lighten(#2c2c2c, 20%); | |||||
$dark-bg-alpha-4: rgba(#2c2c2c, 0.04); | |||||
$dark-bg-alpha-12: rgba(#2c2c2c, 0.12); | |||||
$mat-light-theme-background: ( | |||||
background: $light-background, | |||||
status-bar: $light-bg-darker-20, | |||||
app-bar: $light-bg-darker-5, | |||||
hover: $dark-bg-alpha-4, | |||||
card: $light-bg-lighter-5, | |||||
dialog: $light-bg-lighter-5, | |||||
tooltip: $dark-bg-tooltip, | |||||
disabled-button: $dark-bg-alpha-12, | |||||
raised-button: $light-bg-lighter-5, | |||||
focused-button: $dark-focused, | |||||
selected-button: $light-bg-darker-20, | |||||
selected-disabled-button: $light-bg-darker-30, | |||||
disabled-button-toggle: $light-bg-darker-10, | |||||
unselected-chip: $light-bg-darker-10, | |||||
disabled-list-option: $light-bg-darker-10, | |||||
); | |||||
// Dark bg | |||||
$dark-background: #2c2c2c; | |||||
$dark-bg-lighter-5: lighten($dark-background, 5%); | |||||
$dark-bg-lighter-10: lighten($dark-background, 10%); | |||||
$dark-bg-lighter-20: lighten($dark-background, 20%); | |||||
$dark-bg-lighter-30: lighten($dark-background, 30%); | |||||
$light-bg-alpha-4: rgba(#fafafa, 0.04); | |||||
$light-bg-alpha-12: rgba(#fafafa, 0.12); | |||||
// Background palette for dark themes. | |||||
$mat-dark-theme-background: ( | |||||
background: $dark-background, | |||||
status-bar: $dark-bg-lighter-20, | |||||
app-bar: $dark-bg-lighter-5, | |||||
hover: $light-bg-alpha-4, | |||||
card: $dark-bg-lighter-5, | |||||
dialog: $dark-bg-lighter-5, | |||||
tooltip: $dark-bg-lighter-20, | |||||
disabled-button: $light-bg-alpha-12, | |||||
raised-button: $dark-bg-lighter-5, | |||||
focused-button: $light-focused, | |||||
selected-button: $dark-bg-lighter-20, | |||||
selected-disabled-button: $dark-bg-lighter-30, | |||||
disabled-button-toggle: $dark-bg-lighter-10, | |||||
unselected-chip: $dark-bg-lighter-20, | |||||
disabled-list-option: $dark-bg-lighter-10, | |||||
); | |||||
// Compute font config | |||||
@include mat-core($fontConfig); | |||||
// Theme Config | |||||
body { | |||||
--primary-color: #cc33ca; | |||||
--primary-lighter-color: #f0c2ef; | |||||
--primary-darker-color: #b920b7; | |||||
--text-primary-color: #{$light-primary-text}; | |||||
--text-primary-lighter-color: #{$dark-primary-text}; | |||||
--text-primary-darker-color: #{$light-primary-text}; | |||||
} | |||||
$mat-primary: ( | |||||
main: #cc33ca, | |||||
lighter: #f0c2ef, | |||||
darker: #b920b7, | |||||
200: #cc33ca, | |||||
// For slide toggle, | |||||
contrast: | |||||
( | |||||
main: $light-primary-text, | |||||
lighter: $dark-primary-text, | |||||
darker: $light-primary-text, | |||||
), | |||||
); | |||||
$theme-primary: mat-palette($mat-primary, main, lighter, darker); | |||||
body { | |||||
--accent-color: #797979; | |||||
--accent-lighter-color: #d7d7d7; | |||||
--accent-darker-color: #5c5c5c; | |||||
--text-accent-color: #{$light-primary-text}; | |||||
--text-accent-lighter-color: #{$dark-primary-text}; | |||||
--text-accent-darker-color: #{$light-primary-text}; | |||||
} | |||||
$mat-accent: ( | |||||
main: #797979, | |||||
lighter: #d7d7d7, | |||||
darker: #5c5c5c, | |||||
200: #797979, | |||||
// For slide toggle, | |||||
contrast: | |||||
( | |||||
main: $light-primary-text, | |||||
lighter: $dark-primary-text, | |||||
darker: $light-primary-text, | |||||
), | |||||
); | |||||
$theme-accent: mat-palette($mat-accent, main, lighter, darker); | |||||
body { | |||||
--warn-color: #ff0000; | |||||
--warn-lighter-color: #ffb3b3; | |||||
--warn-darker-color: #ff0000; | |||||
--text-warn-color: #{$light-primary-text}; | |||||
--text-warn-lighter-color: #{$dark-primary-text}; | |||||
--text-warn-darker-color: #{$light-primary-text}; | |||||
} | |||||
$mat-warn: ( | |||||
main: #ff0000, | |||||
lighter: #ffb3b3, | |||||
darker: #ff0000, | |||||
200: #ff0000, | |||||
// For slide toggle, | |||||
contrast: | |||||
( | |||||
main: $light-primary-text, | |||||
lighter: $dark-primary-text, | |||||
darker: $light-primary-text, | |||||
), | |||||
); | |||||
$theme-warn: mat-palette($mat-warn, main, lighter, darker); | |||||
$theme: mat-dark-theme($theme-primary, $theme-accent, $theme-warn); | |||||
$altTheme: mat-light-theme($theme-primary, $theme-accent, $theme-warn); | |||||
// Theme Init | |||||
@include angular-material-theme($theme); | |||||
.theme-alternate { | |||||
@include angular-material-theme($altTheme); | |||||
} | |||||
// Specific component overrides, pieces that are not in line with the general theming | |||||
// Handle buttons appropriately, with respect to line-height | |||||
.mat-raised-button, | |||||
.mat-stroked-button, | |||||
.mat-flat-button { | |||||
padding: 0 1.15em; | |||||
margin: 0 0.65em; | |||||
min-width: 3em; | |||||
line-height: 36.4px; | |||||
} | |||||
.mat-standard-chip { | |||||
padding: 0.5em 0.85em; | |||||
min-height: 2.5em; | |||||
} | |||||
.material-icons { | |||||
font-size: 24px; | |||||
font-family: "Material Icons", "Material Icons"; | |||||
.mat-badge-content { | |||||
font-family: "Roboto"; | |||||
} | |||||
} | |||||
.footer { | |||||
flex-shrink: 0; | |||||
} | |||||
a[href], | |||||
input[type="submit"], | |||||
input[type="image"], | |||||
label[for], | |||||
select, | |||||
button, | |||||
.pointer { | |||||
cursor: pointer; | |||||
} | |||||
.spacer { | |||||
flex: 1 1 auto; | |||||
} | |||||
.main-container { | |||||
display: flex; | |||||
flex-direction: column; | |||||
position: absolute; | |||||
top: 0; | |||||
bottom: 0; | |||||
left: 0; | |||||
right: 0; | |||||
} | |||||
.main-is-mobile .main-toolbar { | |||||
position: fixed; | |||||
/* Make sure the toolbar will stay on top of the content as it scrolls past. */ | |||||
z-index: 2; | |||||
} | |||||
h1.main-app-name { | |||||
margin-left: 8px; | |||||
} | |||||
.main-sidenav-container { | |||||
/* When the sidenav is not fixed, stretch the sidenav container to fill the available space. This | |||||
causes `<mat-sidenav-content>` to act as our scrolling element for desktop layouts. */ | |||||
flex: 1; | |||||
} | |||||
.main-is-mobile .main-sidenav-container { | |||||
/* When the sidenav is fixed, don't constrain the height of the sidenav container. This allows the | |||||
`<body>` to be our scrolling element for mobile layouts. */ | |||||
flex: 1 0 auto; | |||||
} | |||||
table { | |||||
width: 100%; | |||||
} |
// This file is required by karma.conf.js and loads recursively all the .spec and framework files | |||||
import 'zone.js/dist/zone-testing'; | |||||
import { getTestBed } from '@angular/core/testing'; | |||||
import { | |||||
BrowserDynamicTestingModule, | |||||
platformBrowserDynamicTesting | |||||
} from '@angular/platform-browser-dynamic/testing'; | |||||
declare const require: { | |||||
context(path: string, deep?: boolean, filter?: RegExp): { | |||||
keys(): string[]; | |||||
<T>(id: string): T; | |||||
}; | |||||
}; | |||||
// First, initialize the Angular testing environment. | |||||
getTestBed().initTestEnvironment( | |||||
BrowserDynamicTestingModule, | |||||
platformBrowserDynamicTesting() | |||||
); | |||||
// Then we find all the tests. | |||||
const context = require.context('./', true, /\.spec\.ts$/); | |||||
// And load the modules. | |||||
context.keys().map(context); |
/* To learn more about this file see: https://angular.io/config/tsconfig. */ | |||||
{ | |||||
"extends": "./tsconfig.base.json", | |||||
"compilerOptions": { | |||||
"outDir": "./out-tsc/app", | |||||
"types": [] | |||||
}, | |||||
"files": [ | |||||
"src/main.ts", | |||||
"src/polyfills.ts" | |||||
], | |||||
"include": [ | |||||
"src/**/*.d.ts" | |||||
] | |||||
} |
{ | |||||
"compileOnSave": false, | |||||
"compilerOptions": { | |||||
"baseUrl": "./", | |||||
"outDir": "./dist/out-tsc", | |||||
"sourceMap": true, | |||||
"declaration": false, | |||||
"downlevelIteration": true, | |||||
"experimentalDecorators": true, | |||||
"moduleResolution": "node", | |||||
"importHelpers": true, | |||||
"target": "es2015", | |||||
"module": "es2020", | |||||
"lib": [ | |||||
"es2018", | |||||
"dom", | |||||
"esnext.asynciterable" | |||||
] | |||||
} | |||||
} |
/* | |||||
This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScript’s language server to improve development experience. | |||||
It is not intended to be used to perform a compilation. | |||||
To learn more about this file see: https://angular.io/config/solution-tsconfig. | |||||
*/ | |||||
{ | |||||
"files": [], | |||||
"references": [ | |||||
{ | |||||
"path": "./tsconfig.app.json" | |||||
}, | |||||
{ | |||||
"path": "./tsconfig.spec.json" | |||||
} | |||||
] | |||||
} |
/* To learn more about this file see: https://angular.io/config/tsconfig. */ | |||||
{ | |||||
"extends": "./tsconfig.base.json", | |||||
"compilerOptions": { | |||||
"outDir": "./out-tsc/spec", | |||||
"types": [ | |||||
"jasmine" | |||||
] | |||||
}, | |||||
"files": [ | |||||
"src/test.ts", | |||||
"src/polyfills.ts" | |||||
], | |||||
"include": [ | |||||
"src/**/*.spec.ts", | |||||
"src/**/*.d.ts" | |||||
] | |||||
} |
{ | |||||
"extends": "tslint:recommended", | |||||
"rules": { | |||||
"align": { | |||||
"options": [ | |||||
"parameters", | |||||
"statements" | |||||
] | |||||
}, | |||||
"array-type": false, | |||||
"arrow-return-shorthand": true, | |||||
"curly": true, | |||||
"deprecation": { | |||||
"severity": "warning" | |||||
}, | |||||
"component-class-suffix": true, | |||||
"contextual-lifecycle": true, | |||||
"directive-class-suffix": true, | |||||
"directive-selector": [ | |||||
true, | |||||
"attribute", | |||||
"app", | |||||
"camelCase" | |||||
], | |||||
"component-selector": [ | |||||
true, | |||||
"element", | |||||
"app", | |||||
"kebab-case" | |||||
], | |||||
"eofline": true, | |||||
"import-blacklist": [ | |||||
true, | |||||
"rxjs/Rx" | |||||
], | |||||
"import-spacing": true, | |||||
"indent": { | |||||
"options": [ | |||||
"spaces" | |||||
] | |||||
}, | |||||
"max-classes-per-file": false, | |||||
"max-line-length": [ | |||||
true, | |||||
140 | |||||
], | |||||
"member-ordering": [ | |||||
true, | |||||
{ | |||||
"order": [ | |||||
"static-field", | |||||
"instance-field", | |||||
"static-method", | |||||
"instance-method" | |||||
] | |||||
} | |||||
], | |||||
"no-console": [ | |||||
true, | |||||
"debug", | |||||
"info", | |||||
"time", | |||||
"timeEnd", | |||||
"trace" | |||||
], | |||||
"no-empty": false, | |||||
"no-inferrable-types": [ | |||||
true, | |||||
"ignore-params" | |||||
], | |||||
"no-non-null-assertion": true, | |||||
"no-redundant-jsdoc": true, | |||||
"no-switch-case-fall-through": true, | |||||
"no-var-requires": false, | |||||
"object-literal-key-quotes": [ | |||||
true, | |||||
"as-needed" | |||||
], | |||||
"quotemark": [ | |||||
true, | |||||
"single" | |||||
], | |||||
"semicolon": { | |||||
"options": [ | |||||
"always" | |||||
] | |||||
}, | |||||
"space-before-function-paren": { | |||||
"options": { | |||||
"anonymous": "never", | |||||
"asyncArrow": "always", | |||||
"constructor": "never", | |||||
"method": "never", | |||||
"named": "never" | |||||
} | |||||
}, | |||||
"typedef": [ | |||||
true, | |||||
"call-signature" | |||||
], | |||||
"typedef-whitespace": { | |||||
"options": [ | |||||
{ | |||||
"call-signature": "nospace", | |||||
"index-signature": "nospace", | |||||
"parameter": "nospace", | |||||
"property-declaration": "nospace", | |||||
"variable-declaration": "nospace" | |||||
}, | |||||
{ | |||||
"call-signature": "onespace", | |||||
"index-signature": "onespace", | |||||
"parameter": "onespace", | |||||
"property-declaration": "onespace", | |||||
"variable-declaration": "onespace" | |||||
} | |||||
] | |||||
}, | |||||
"variable-name": { | |||||
"options": [ | |||||
"ban-keywords", | |||||
"check-format", | |||||
"allow-pascal-case" | |||||
] | |||||
}, | |||||
"whitespace": { | |||||
"options": [ | |||||
"check-branch", | |||||
"check-decl", | |||||
"check-operator", | |||||
"check-separator", | |||||
"check-type", | |||||
"check-typecast" | |||||
] | |||||
}, | |||||
"no-conflicting-lifecycle": true, | |||||
"no-host-metadata-property": true, | |||||
"no-input-rename": true, | |||||
"no-inputs-metadata-property": true, | |||||
"no-output-native": true, | |||||
"no-output-on-prefix": true, | |||||
"no-output-rename": true, | |||||
"no-outputs-metadata-property": true, | |||||
"template-banana-in-box": true, | |||||
"template-no-negated-async": true, | |||||
"use-lifecycle-interface": true, | |||||
"use-pipe-transform-interface": true | |||||
}, | |||||
"rulesDirectory": [ | |||||
"codelyzer" | |||||
] | |||||
} |