Added unit conversions and formula scaling
This commit is contained in:
		@@ -6,24 +6,28 @@
 | 
			
		||||
    <table class="table">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>Name</td>
 | 
			
		||||
            <td>Quantity</td>
 | 
			
		||||
            <td>Cost</td>
 | 
			
		||||
          <td>Name</td>
 | 
			
		||||
          <td>Quantity</td>
 | 
			
		||||
          <td>Cost</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </thead>
 | 
			
		||||
      <tbody>
 | 
			
		||||
          <tr *ngFor="let c of formula.components">
 | 
			
		||||
            <td>{{(c.component | async)?.name}}</td>
 | 
			
		||||
            <td>{{c.quantity | scale: formula.total : newTotal | convertFromG: unit}}</td>
 | 
			
		||||
            <td>{{(c.component | async)?.cost | currency}}</td>
 | 
			
		||||
        <tr *ngFor="let c of formula.components">
 | 
			
		||||
          <td>{{(c.component | async)?.name}}</td>
 | 
			
		||||
          <td>{{c.quantity | scale: formula.total : _newTotal | convertFromG: unit}} {{unit}}</td>
 | 
			
		||||
          <td>{{(c.component | async)?.cost | currency}}</td>
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
    <input type="number" [(ngModel)]="newTotal">
 | 
			
		||||
    <select [(ngModel)]="unit">
 | 
			
		||||
        <option>g</option>
 | 
			
		||||
        <option>oz</option>
 | 
			
		||||
        <option>kg</option>
 | 
			
		||||
        <option>lb</option>
 | 
			
		||||
    </select>
 | 
			
		||||
    <mat-form-field style="width: 75px">
 | 
			
		||||
      <input matInput type="number" placeholder="Yield" [(ngModel)]="newTotal">
 | 
			
		||||
    </mat-form-field>
 | 
			
		||||
    <mat-form-field style="width: 40px">
 | 
			
		||||
      <mat-select placeholder="Unit" [(ngModel)]="unit">
 | 
			
		||||
        <mat-option value="g">g</mat-option>
 | 
			
		||||
        <mat-option value="oz">oz</mat-option>
 | 
			
		||||
        <mat-option value="kg">kg</mat-option>
 | 
			
		||||
        <mat-option value="lb">lb</mat-option>
 | 
			
		||||
      </mat-select>
 | 
			
		||||
    </mat-form-field>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import { Component } from '@angular/core';
 | 
			
		||||
import { AngularFirestore } from 'angularfire2/firestore';
 | 
			
		||||
import {Component} from '@angular/core';
 | 
			
		||||
import {AngularFirestore} from 'angularfire2/firestore';
 | 
			
		||||
import {share} from 'rxjs/operators';
 | 
			
		||||
import {ConvertFromGPipe, ConvertToGPipe} from './units.pipe';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-root',
 | 
			
		||||
@@ -12,15 +13,28 @@ export class AppComponent {
 | 
			
		||||
  formula;
 | 
			
		||||
  components;
 | 
			
		||||
  unit = 'g';
 | 
			
		||||
  newTotal: number = 0;
 | 
			
		||||
 | 
			
		||||
  _newTotal: number = 0;
 | 
			
		||||
  get newTotal() {
 | 
			
		||||
    return new ConvertFromGPipe().transform(this._newTotal, this.unit);
 | 
			
		||||
  }
 | 
			
		||||
  set newTotal(total) {
 | 
			
		||||
    this._newTotal = new ConvertToGPipe().transform(total, this.unit);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  constructor(private db: AngularFirestore) {
 | 
			
		||||
    this.formulas = this.db.collection('formulas').valueChanges();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  displayFormula(formula) {
 | 
			
		||||
    formula.components.map(row => row.component = this.db.doc(`components/${row.component.id}`).valueChanges().pipe(share()));
 | 
			
		||||
    formula.total = formula.components.reduce((acc, row) => acc += row.quantity, 0);
 | 
			
		||||
    formula.components.map(
 | 
			
		||||
      row =>
 | 
			
		||||
        (row.component = this.db
 | 
			
		||||
          .doc(`components/${row.component.id}`)
 | 
			
		||||
          .valueChanges()
 | 
			
		||||
          .pipe(share()))
 | 
			
		||||
    );
 | 
			
		||||
    formula.total = formula.components.reduce((acc, row) => (acc += row.quantity), 0);
 | 
			
		||||
    this.newTotal = formula.total;
 | 
			
		||||
    this.formula = formula;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,27 @@
 | 
			
		||||
import { BrowserModule } from '@angular/platform-browser';
 | 
			
		||||
import {BrowserModule} from '@angular/platform-browser';
 | 
			
		||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
 | 
			
		||||
import {AngularFireModule} from 'angularfire2';
 | 
			
		||||
import {AngularFirestoreModule} from 'angularfire2/firestore';
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import {NgModule} from '@angular/core';
 | 
			
		||||
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
 | 
			
		||||
import { AppComponent } from './app.component';
 | 
			
		||||
import { environment } from '../environments/environment.prod';
 | 
			
		||||
import {AppComponent} from './app.component';
 | 
			
		||||
import {environment} from '../environments/environment.prod';
 | 
			
		||||
import {ConvertFromGPipe, ConvertToGPipe} from './units.pipe';
 | 
			
		||||
import { ScalePipe } from './scale.pipe';
 | 
			
		||||
import {ScalePipe} from './scale.pipe';
 | 
			
		||||
import {AngularMaterialModule} from './material.module';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  declarations: [
 | 
			
		||||
    AppComponent,
 | 
			
		||||
    ConvertFromGPipe,
 | 
			
		||||
    ConvertToGPipe,
 | 
			
		||||
    ScalePipe
 | 
			
		||||
  ],
 | 
			
		||||
  declarations: [AppComponent, ConvertFromGPipe, ConvertToGPipe, ScalePipe],
 | 
			
		||||
  imports: [
 | 
			
		||||
    AngularMaterialModule,
 | 
			
		||||
    AngularFireModule.initializeApp(environment.firebase),
 | 
			
		||||
    AngularFirestoreModule,
 | 
			
		||||
    BrowserAnimationsModule,
 | 
			
		||||
    BrowserModule,
 | 
			
		||||
    FormsModule,
 | 
			
		||||
    ReactiveFormsModule,
 | 
			
		||||
    ReactiveFormsModule
 | 
			
		||||
  ],
 | 
			
		||||
  providers: [],
 | 
			
		||||
  bootstrap: [AppComponent]
 | 
			
		||||
})
 | 
			
		||||
export class AppModule { }
 | 
			
		||||
export class AppModule {}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										107
									
								
								src/app/material.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/app/material.module.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
import {NgModule} from '@angular/core';
 | 
			
		||||
import {
 | 
			
		||||
  MatAutocompleteModule,
 | 
			
		||||
  MatButtonModule,
 | 
			
		||||
  MatButtonToggleModule,
 | 
			
		||||
  MatCardModule,
 | 
			
		||||
  MatCheckboxModule,
 | 
			
		||||
  MatChipsModule,
 | 
			
		||||
  MatDatepickerModule,
 | 
			
		||||
  MatDialogModule,
 | 
			
		||||
  MatDividerModule,
 | 
			
		||||
  MatExpansionModule,
 | 
			
		||||
  MatGridListModule,
 | 
			
		||||
  MatIconModule,
 | 
			
		||||
  MatInputModule,
 | 
			
		||||
  MatListModule,
 | 
			
		||||
  MatMenuModule,
 | 
			
		||||
  MatNativeDateModule,
 | 
			
		||||
  MatPaginatorModule,
 | 
			
		||||
  MatProgressBarModule,
 | 
			
		||||
  MatProgressSpinnerModule,
 | 
			
		||||
  MatRadioModule,
 | 
			
		||||
  MatRippleModule,
 | 
			
		||||
  MatSelectModule,
 | 
			
		||||
  MatSidenavModule,
 | 
			
		||||
  MatSliderModule,
 | 
			
		||||
  MatSlideToggleModule,
 | 
			
		||||
  MatSnackBarModule,
 | 
			
		||||
  MatSortModule,
 | 
			
		||||
  MatStepperModule,
 | 
			
		||||
  MatTableModule,
 | 
			
		||||
  MatTabsModule,
 | 
			
		||||
  MatToolbarModule,
 | 
			
		||||
  MatTooltipModule
 | 
			
		||||
} from '@angular/material';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  imports: [
 | 
			
		||||
    MatAutocompleteModule,
 | 
			
		||||
    MatButtonModule,
 | 
			
		||||
    MatButtonToggleModule,
 | 
			
		||||
    MatCardModule,
 | 
			
		||||
    MatCheckboxModule,
 | 
			
		||||
    MatChipsModule,
 | 
			
		||||
    MatDatepickerModule,
 | 
			
		||||
    MatDialogModule,
 | 
			
		||||
    MatDividerModule,
 | 
			
		||||
    MatExpansionModule,
 | 
			
		||||
    MatGridListModule,
 | 
			
		||||
    MatIconModule,
 | 
			
		||||
    MatInputModule,
 | 
			
		||||
    MatListModule,
 | 
			
		||||
    MatMenuModule,
 | 
			
		||||
    MatNativeDateModule,
 | 
			
		||||
    MatPaginatorModule,
 | 
			
		||||
    MatProgressBarModule,
 | 
			
		||||
    MatProgressSpinnerModule,
 | 
			
		||||
    MatRadioModule,
 | 
			
		||||
    MatRippleModule,
 | 
			
		||||
    MatSelectModule,
 | 
			
		||||
    MatSidenavModule,
 | 
			
		||||
    MatSliderModule,
 | 
			
		||||
    MatSlideToggleModule,
 | 
			
		||||
    MatSnackBarModule,
 | 
			
		||||
    MatSortModule,
 | 
			
		||||
    MatStepperModule,
 | 
			
		||||
    MatTableModule,
 | 
			
		||||
    MatTabsModule,
 | 
			
		||||
    MatToolbarModule,
 | 
			
		||||
    MatTooltipModule
 | 
			
		||||
  ],
 | 
			
		||||
  exports: [
 | 
			
		||||
    MatAutocompleteModule,
 | 
			
		||||
    MatButtonModule,
 | 
			
		||||
    MatButtonToggleModule,
 | 
			
		||||
    MatCardModule,
 | 
			
		||||
    MatCheckboxModule,
 | 
			
		||||
    MatChipsModule,
 | 
			
		||||
    MatDatepickerModule,
 | 
			
		||||
    MatDialogModule,
 | 
			
		||||
    MatDividerModule,
 | 
			
		||||
    MatExpansionModule,
 | 
			
		||||
    MatGridListModule,
 | 
			
		||||
    MatIconModule,
 | 
			
		||||
    MatInputModule,
 | 
			
		||||
    MatListModule,
 | 
			
		||||
    MatMenuModule,
 | 
			
		||||
    MatNativeDateModule,
 | 
			
		||||
    MatPaginatorModule,
 | 
			
		||||
    MatProgressBarModule,
 | 
			
		||||
    MatProgressSpinnerModule,
 | 
			
		||||
    MatRadioModule,
 | 
			
		||||
    MatRippleModule,
 | 
			
		||||
    MatSelectModule,
 | 
			
		||||
    MatSidenavModule,
 | 
			
		||||
    MatSliderModule,
 | 
			
		||||
    MatSlideToggleModule,
 | 
			
		||||
    MatSnackBarModule,
 | 
			
		||||
    MatSortModule,
 | 
			
		||||
    MatStepperModule,
 | 
			
		||||
    MatTableModule,
 | 
			
		||||
    MatTabsModule,
 | 
			
		||||
    MatToolbarModule,
 | 
			
		||||
    MatTooltipModule
 | 
			
		||||
  ]
 | 
			
		||||
})
 | 
			
		||||
export class AngularMaterialModule {}
 | 
			
		||||
@@ -1,37 +1,37 @@
 | 
			
		||||
import { Pipe, PipeTransform } from '@angular/core';
 | 
			
		||||
import {Pipe, PipeTransform} from '@angular/core';
 | 
			
		||||
 | 
			
		||||
@Pipe({
 | 
			
		||||
    name: 'convertFromG'
 | 
			
		||||
  })
 | 
			
		||||
  export class ConvertFromGPipe implements PipeTransform {
 | 
			
		||||
    transform(grams: number, to: string): string {
 | 
			
		||||
      switch(to) {
 | 
			
		||||
          case 'oz':
 | 
			
		||||
              return `${Math.round(grams / 28.34952)} oz`;
 | 
			
		||||
          case 'lb':
 | 
			
		||||
              return `${Math.round((grams * 0.0022) * 100) / 100} lb`;
 | 
			
		||||
          case 'kg':
 | 
			
		||||
              return `${Math.round((grams / 1000) * 100) / 100} kg`;
 | 
			
		||||
          default:
 | 
			
		||||
              return `${Math.round(grams)} g`;
 | 
			
		||||
      }
 | 
			
		||||
  name: 'convertFromG'
 | 
			
		||||
})
 | 
			
		||||
export class ConvertFromGPipe implements PipeTransform {
 | 
			
		||||
  transform(grams: number, to: string): number {
 | 
			
		||||
    switch (to) {
 | 
			
		||||
      case 'oz':
 | 
			
		||||
        return Math.round(grams / 28.34952);
 | 
			
		||||
      case 'lb':
 | 
			
		||||
        return Math.round(grams * 0.0022 * 100) / 100;
 | 
			
		||||
      case 'kg':
 | 
			
		||||
        return Math.round((grams / 1000) * 100) / 100;
 | 
			
		||||
      default:
 | 
			
		||||
        return Math.round(grams);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  @Pipe({
 | 
			
		||||
    name: 'convertToG'
 | 
			
		||||
  })
 | 
			
		||||
  export class ConvertToGPipe implements PipeTransform {
 | 
			
		||||
    transform(units: number, from: string): string {
 | 
			
		||||
      switch(from) {
 | 
			
		||||
          case 'oz':
 | 
			
		||||
              return `${Math.round(units * 28.34952)} oz`;
 | 
			
		||||
          case 'lb':
 | 
			
		||||
              return `${Math.round(units / 0.0022)} lb`;
 | 
			
		||||
          case 'kg':
 | 
			
		||||
              return `${Math.round(units * 1000)} kg`;
 | 
			
		||||
          default:
 | 
			
		||||
              return `${Math.round(units)} g`;
 | 
			
		||||
      }
 | 
			
		||||
@Pipe({
 | 
			
		||||
  name: 'convertToG'
 | 
			
		||||
})
 | 
			
		||||
export class ConvertToGPipe implements PipeTransform {
 | 
			
		||||
  transform(units: number, from: string): number {
 | 
			
		||||
    switch (from) {
 | 
			
		||||
      case 'oz':
 | 
			
		||||
        return Math.round(units * 28.34952);
 | 
			
		||||
      case 'lb':
 | 
			
		||||
        return Math.round(units / 0.0022);
 | 
			
		||||
      case 'kg':
 | 
			
		||||
        return Math.round(units * 1000);
 | 
			
		||||
      default:
 | 
			
		||||
        return Math.round(units);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
@import '~@angular/material/prebuilt-themes/indigo-pink.css';
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user