| @@ -62,5 +62,47 @@ npm install --save-dev ts-node nodemon rimraf | |||
| * 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 | |||
| @@ -1,5 +1,5 @@ | |||
| { | |||
| "name": "demo", | |||
| "name": "graphql-pizza-demo", | |||
| "version": "1.0.0", | |||
| "lockfileVersion": 1, | |||
| "requires": true, | |||
| @@ -1,4 +1,4 @@ | |||
| import { ApolloServer } from "apollo-server"; | |||
| import { ApolloServer } from "apollo-server/dist"; | |||
| import { Resolvers } from "./generated/graphql"; | |||
| import { pizzaSchema } from "./schema/pizza"; | |||
| import { PizzaResolver } from "./resolver/pizza-resolver"; | |||
| @@ -7,7 +7,7 @@ | |||
| ] /* Specify library files to be included in the compilation. */, | |||
| "allowJs": true /* Allow javascript files to be compiled. */, | |||
| "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. */, | |||
| "skipLibCheck": true, | |||
| "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, | |||
| @@ -0,0 +1,18 @@ | |||
| # 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. | |||
| @@ -0,0 +1,16 @@ | |||
| # 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 | |||
| @@ -0,0 +1,46 @@ | |||
| # 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 | |||
| @@ -0,0 +1,27 @@ | |||
| # 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). | |||
| @@ -0,0 +1,129 @@ | |||
| { | |||
| "$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" | |||
| } | |||
| @@ -0,0 +1,9 @@ | |||
| overwrite: true | |||
| schema: "http://localhost:4000" | |||
| documents: "src/**/*.graphql" | |||
| generates: | |||
| src/generated/graphql.ts: | |||
| plugins: | |||
| - "typescript" | |||
| - "typescript-operations" | |||
| - "typescript-apollo-angular" | |||
| @@ -0,0 +1,36 @@ | |||
| // @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 | |||
| } | |||
| })); | |||
| } | |||
| }; | |||
| @@ -0,0 +1,23 @@ | |||
| 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)); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,11 @@ | |||
| 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>; | |||
| } | |||
| } | |||
| @@ -0,0 +1,14 @@ | |||
| /* 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" | |||
| ] | |||
| } | |||
| } | |||
| @@ -0,0 +1,32 @@ | |||
| // 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 | |||
| }); | |||
| }; | |||
| @@ -0,0 +1,60 @@ | |||
| { | |||
| "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" | |||
| } | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| <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> | |||
| @@ -0,0 +1,31 @@ | |||
| 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!'); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,10 @@ | |||
| import { Component } from '@angular/core'; | |||
| @Component({ | |||
| selector: 'app-root', | |||
| templateUrl: './app.component.html', | |||
| styleUrls: ['./app.component.scss'] | |||
| }) | |||
| export class AppComponent { | |||
| title = 'frontend2'; | |||
| } | |||
| @@ -0,0 +1,54 @@ | |||
| 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 { } | |||
| @@ -0,0 +1,34 @@ | |||
| <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> | |||
| @@ -0,0 +1,24 @@ | |||
| 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(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,39 @@ | |||
| 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(', '); | |||
| } | |||
| } | |||
| @@ -0,0 +1,9 @@ | |||
| query ListPizzaWithTopping { | |||
| listPizza { | |||
| id | |||
| name, | |||
| toppings { | |||
| name | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,27 @@ | |||
| <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> | |||
| @@ -0,0 +1,25 @@ | |||
| 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(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,32 @@ | |||
| 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 { | |||
| } | |||
| } | |||
| @@ -0,0 +1,6 @@ | |||
| query ListPizza { | |||
| listPizza { | |||
| id | |||
| name | |||
| } | |||
| } | |||
| @@ -0,0 +1,3 @@ | |||
| export const environment = { | |||
| production: true | |||
| }; | |||
| @@ -0,0 +1,16 @@ | |||
| // 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. | |||
| @@ -0,0 +1,128 @@ | |||
| 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; | |||
| } | |||
| @@ -0,0 +1,24 @@ | |||
| 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 {} | |||
| @@ -0,0 +1,15 @@ | |||
| <!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> | |||
| @@ -0,0 +1,12 @@ | |||
| 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)); | |||
| @@ -0,0 +1,63 @@ | |||
| /** | |||
| * 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 | |||
| */ | |||
| @@ -0,0 +1,320 @@ | |||
| /* 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%; | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| // 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); | |||
| @@ -0,0 +1,15 @@ | |||
| /* 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" | |||
| ] | |||
| } | |||
| @@ -0,0 +1,20 @@ | |||
| { | |||
| "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" | |||
| ] | |||
| } | |||
| } | |||
| @@ -0,0 +1,17 @@ | |||
| /* | |||
| 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" | |||
| } | |||
| ] | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| /* 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" | |||
| ] | |||
| } | |||
| @@ -0,0 +1,152 @@ | |||
| { | |||
| "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" | |||
| ] | |||
| } | |||