New formula manager

This commit is contained in:
Zakary Timson 2018-11-04 17:30:43 -05:00
parent b57e3cc2cc
commit 80a59878f1
12 changed files with 243 additions and 226 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "fhsons", "name": "fhsons",
"version": "0.0.0", "version": "1.0.0",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",

View File

@ -1,3 +1,4 @@
<div class="container-fluid bg-white">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-12 py-4"> <div class="col-12 py-4">
@ -11,7 +12,8 @@
</div> </div>
</div> </div>
</div> </div>
<div style="background-color: #53709f;"> </div>
<div style="background: #53709f;">
<div class="container"> <div class="container">
<div class="row pt-4"> <div class="row pt-4">
<div class="col-12"> <div class="col-12">

View File

@ -1,5 +1,4 @@
<!-- Nav -->
<div class="wrapper">
<nav class="navbar navbar-expand-lg fixed-top navbar-light bg-light"> <nav class="navbar navbar-expand-lg fixed-top navbar-light bg-light">
<div class="container"> <div class="container">
<a class="navbar-brand roboto" [routerLink]="['/']"> <a class="navbar-brand roboto" [routerLink]="['/']">
@ -42,15 +41,14 @@
</div> </div>
</nav> </nav>
<!-- Push content down from under nav-->
<div style="height: 56px"></div>
<!-- Content --> <!-- Content -->
<div> <div>
<div style="height: 56px"></div>
<router-outlet></router-outlet> <router-outlet></router-outlet>
</div> </div>
<div class="push"></div>
</div>
<!-- Footer --> <!-- Footer -->
<footer> <footer>
<div class="container-fluid"> <div class="container-fluid">

View File

@ -26,10 +26,10 @@ import { ProductsComponent } from './store/products/products.component';
import { CartComponent } from './store/cart/cart.component'; import { CartComponent } from './store/cart/cart.component';
import { ViewComponents } from './formulaManager/viewComponents/viewComponents.component'; import { ViewComponents } from './formulaManager/viewComponents/viewComponents.component';
import { NewComponentComponent } from './formulaManager/newComponent/newComponent.component'; import { NewComponentComponent } from './formulaManager/newComponent/newComponent.component';
import { HttpModule } from '@angular/http';
import { NewFormulaComponent } from './formulaManager/newFormula/newFormula.component'; import { NewFormulaComponent } from './formulaManager/newFormula/newFormula.component';
import { AppStore } from './app.store'; import { AppStore } from './app.store';
import { SlideshowModule } from 'ng-simple-slideshow'; import { SlideshowModule } from 'ng-simple-slideshow';
import {HttpClientModule} from '@angular/common/http';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -60,7 +60,7 @@ import { SlideshowModule } from 'ng-simple-slideshow';
BrowserAnimationsModule, BrowserAnimationsModule,
BrowserModule, BrowserModule,
FormsModule, FormsModule,
HttpModule, HttpClientModule,
NgxElectronModule, NgxElectronModule,
ReactiveFormsModule, ReactiveFormsModule,
RouterModule.forRoot([ RouterModule.forRoot([

View File

@ -1,45 +1,12 @@
<div class="container"> <mat-drawer-container class="flex-grow-1">
<div *ngIf="!electron.isElectronApp" class="row mt-3 d-none d-lg-block"> <mat-drawer #drawer [mode]="mobile ? 'over' : 'side'" [opened]="!mobile" [disableClose]="!mobile" [autoFocus]="false">
<div class="col-12"> <mat-form-field appearance="outline" class="mx-3 mt-3 pb-0">
<div class="jumbotron text-white" style=" <mat-label>Search</mat-label>
background-color: #000; <input #search matInput>
background-image: url('../../assets/img/formula.jpg');
background-size: cover;
">
<h1 class="display-4">Standalone</h1>
<p class="lead text-white-50">Download Formula Manager 2.0</p>
<hr class="my-4">
<p>Tired of using your browser? Try downloading Formula Manager 2.0!</p>
<a class="btn btn-primary btn-lg mb-3 mr-3" href="#" download>
<i class="fab fa-windows"></i> Windows</a>
<a class="btn btn-primary btn-lg mb-3 mr-3" href="#" download>
<i class="fab fa-apple"></i> MacOS</a>
<a class="btn btn-primary btn-lg mb-3 mr-3" href="#" download>
<i class="fab fa-linux"></i> Linux</a>
<button *ngIf="installPrompt" class="btn btn-primary btn-lg mb-3" (click)="prompt()">
<i class="fas fa-mobile-alt"></i> Mobile</button>
</div>
</div>
</div>
<div *ngIf="store.user" class="row mt-3">
<div class="col-12">
<div class="float-right">
<button mat-raised-button class="mr-3" (click)="openComponents()">
<mat-icon>list</mat-icon> Components
</button>
<button mat-raised-button (click)="newFormula()">
<mat-icon>add</mat-icon> Formula
</button>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-12 col-lg-3 mb-5">
<mat-form-field class="w-100">
<input #search matInput placeholder="Search">
<mat-icon matSuffix>search</mat-icon> <mat-icon matSuffix>search</mat-icon>
</mat-form-field> </mat-form-field>
<mat-list style="max-height: 500px; overflow-y: scroll"> <mat-divider></mat-divider>
<mat-list>
<ng-container *ngFor="let f of formulas | async; let i = index"> <ng-container *ngFor="let f of formulas | async; let i = index">
<mat-divider *ngIf="f.name.toLowerCase().indexOf(search.value.toLowerCase()) != -1 && i > 0"></mat-divider> <mat-divider *ngIf="f.name.toLowerCase().indexOf(search.value.toLowerCase()) != -1 && i > 0"></mat-divider>
<mat-list-item *ngIf="f.name.toLowerCase().indexOf(search.value.toLowerCase()) != -1" (click)="displayFormula(f)" [ngClass]="{'active': f.id == formula?.id}"> <mat-list-item *ngIf="f.name.toLowerCase().indexOf(search.value.toLowerCase()) != -1" (click)="displayFormula(f)" [ngClass]="{'active': f.id == formula?.id}">
@ -48,44 +15,61 @@
</mat-list-item> </mat-list-item>
</ng-container> </ng-container>
</mat-list> </mat-list>
<div *ngIf="store.user" class="fixed-bottom w-100">
<mat-divider></mat-divider>
<button mat-button class="m-1 float-right" (click)="newFormula()">
<mat-icon>add</mat-icon> New
</button>
</div> </div>
<div *ngIf="!formula" class="d-none d-lg-block col-lg-9"> </mat-drawer>
<div class="w-100"> <mat-drawer-content class="p-3 bg-white" style="min-height: 450px; background: url('assets/img/splatter.jpg') center; background-size: cover;">
<div class="col-12 p-5"> <div>
<mat-card class="mx-auto text-center"> <button *ngIf="mobile" mat-raised-button (click)="drawer.open()">
<mat-icon>opacity</mat-icon> Formulas
</button>
</div>
<div *ngIf="(electron.isElectronApp || mobile) && !formula">
<img src="assets/img/starthere.png" class="m-4">
</div>
<mat-card *ngIf="!electron.isElectronApp && !mobile && !formula" class="mx-auto" style="max-width: 600px">
<mat-card-header>
<div class="d-flex align-items-center" style="color: #53709f">
<mat-icon style="transform: scale(2.5)">opacity</mat-icon>
<h1 class="ml-3 display-4">Formula Manager</h1>
</div>
</mat-card-header>
<mat-card-content> <mat-card-content>
Pick a formula from the left hand side to see its components! <p class="lead text-white-50">Tired of using your browser? Download the standalone version of the Formula Manager.</p>
<button mat-button class="button-fix"><i class="fab fa-windows mr-1 mb-1"></i> Windows</button>
<button mat-button class="button-fix"><i class="fab fa-apple mr-1 mb-1"></i> MacOS</button>
<button mat-button class="button-fix"><i class="fab fa-linux mr-1 mb-1"></i> Linux</button>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
</div> <mat-card *ngIf="formula" class="my-4 mx-auto" style="max-width: 600px">
</div> <mat-card-header>
</div> <mat-card-title class="mb-0"><h4>{{formula.name}}</h4></mat-card-title>
<div *ngIf="formula" class="col-12 col-lg-9 mb-5"> <mat-card-subtitle>{{formula.created | date}}</mat-card-subtitle>
<div> <div *ngIf="store.user" class="ml-auto">
<div class="float-left"> <h4>Approved:
<h3 class="mb-0">{{formula.name}}</h3>
<span class="text-muted">Created: {{formula.created | date}}</span>
</div>
<div *ngIf="store.user" class="float-right">
<h5>Approved:
<mat-icon *ngIf="formula.approved" class="text-success" style="transform: translateY(20%)">check_circle</mat-icon> <mat-icon *ngIf="formula.approved" class="text-success" style="transform: translateY(20%)">check_circle</mat-icon>
<mat-icon *ngIf="!formula.approved" class="text-danger" style="transform: translateY(20%)">remove_circle</mat-icon> <mat-icon *ngIf="!formula.approved" class="text-danger" style="transform: translateY(20%)">remove_circle</mat-icon>
</h5> </h4>
</div>
</div> </div>
</mat-card-header>
<mat-card-content>
<table class="w-100 mt-4 table"> <table class="w-100 mt-4 table">
<thead> <thead>
<tr> <tr>
<th style="width: 80%">Name</th> <th style="width: 80%">Name</th>
<th style="width: 10%">Quantity</th> <th class="text-right" style="width: 10%">Quantity</th>
<th style="width: 10%">Cost</th> <th class="text-right" style="width: 10%">Cost</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr *ngFor="let c of formula.components"> <tr *ngFor="let c of formula.components">
<td style="width: 80%">{{c.component?.name}}</td> <td style="width: 80%">{{c.component?.name}}</td>
<td style="width: 10%">{{c.quantity | scale: formula.total : _newTotal | convertFromG: unit}} {{unit}}</td> <td class="text-right" style="width: 10%">{{c.quantity | scale: formula.total : _newTotal | convertFromG: unit}} {{unit}}</td>
<td style="width: 10%">{{c.quantity | scale: formula.total : _newTotal / 1000 * c.component.cost | currency}}</td> <td class="text-right" style="width: 10%">{{c.quantity | scale: formula.total : _newTotal / 1000 * c.component.cost | currency}}</td>
</tbody> </tbody>
</table> </table>
<div class="col-12 d-lg-block mb-3" style="height: 4px; background:black; width: 100%;"></div> <div class="col-12 d-lg-block mb-3" style="height: 4px; background:black; width: 100%;"></div>
@ -111,19 +95,21 @@
</div> </div>
</div> </div>
</div> </div>
<div *ngIf="store.user" class="w-100 mt-4"> </mat-card-content>
<div class="float-right"> <mat-card-actions *ngIf="store.user" style="overflow: hidden">
<button *ngIf="!formula.approved" mat-raised-button class="mr-3" (click)="approve(formula)"> <mat-divider></mat-divider>
<button *ngIf="!formula.approved" mat-button class="m-1 mt-2" (click)="approve(formula)">
<mat-icon>check</mat-icon>Approve <mat-icon>check</mat-icon>Approve
</button> </button>
<button mat-raised-button class="mr-3" (click)="edit(formula)"> <div class="float-right m-1 mt-2">
<button mat-button class="mr-3" (click)="edit(formula)">
<mat-icon>edit</mat-icon>Edit <mat-icon>edit</mat-icon>Edit
</button> </button>
<button mat-raised-button (click)="delete(formula)"> <button mat-button (click)="delete(formula)">
<mat-icon>delete</mat-icon>Delete <mat-icon>delete</mat-icon>Delete
</button> </button>
</div> </div>
</div> </mat-card-actions>
</div> </mat-card>
</div> </mat-drawer-content>
</div> </mat-drawer-container>

View File

@ -1,4 +1,4 @@
import {Component, ElementRef, ViewChildren, HostListener} from '@angular/core'; import {Component} from '@angular/core';
import {ConvertFromGPipe, ConvertToGPipe} from './units.pipe'; import {ConvertFromGPipe, ConvertToGPipe} from './units.pipe';
import {ElectronService} from 'ngx-electron'; import {ElectronService} from 'ngx-electron';
import {LocalStorage} from 'webstorage-decorators'; import {LocalStorage} from 'webstorage-decorators';
@ -8,6 +8,7 @@ import {NewFormulaComponent} from './newFormula/newFormula.component';
import {AppStore} from '../app.store'; import {AppStore} from '../app.store';
import {map} from 'rxjs/operators'; import {map} from 'rxjs/operators';
import {DeleteComponent} from '../delete/delete.component'; import {DeleteComponent} from '../delete/delete.component';
import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout';
@Component({ @Component({
selector: 'formula-manager', selector: 'formula-manager',
@ -25,17 +26,22 @@ export class FormulaManagerComponent {
formulas; formulas;
@LocalStorage({defaultValue: 'g'}) @LocalStorage({defaultValue: 'g'})
unit; unit;
mobile = false;
_newTotal: number = 0; _newTotal: number = 0;
get newTotal() { get newTotal() {
return new ConvertFromGPipe().transform(this._newTotal, this.unit); return new ConvertFromGPipe().transform(this._newTotal, this.unit);
} }
set newTotal(total) { set newTotal(total) {
this._newTotal = new ConvertToGPipe().transform(total, this.unit); this._newTotal = new ConvertToGPipe().transform(total, this.unit);
} }
constructor(public electron: ElectronService, private dialog: MatDialog, public store: AppStore) { constructor(public electron: ElectronService, private dialog: MatDialog, private $breakpoint: BreakpointObserver, public store: AppStore) {
this.formulas = this.store.formulas.pipe(map(rows => rows.filter(row => this.store.user || row.approved))); this.formulas = this.store.formulas.pipe(map(rows => rows.filter(row => this.store.user || row.approved)));
// Handle switching between mobile and desktop
this.$breakpoint.observe(Breakpoints.Handset).subscribe(e => this.mobile = e.matches);
} }
approve(formula) { approve(formula) {

View File

@ -36,7 +36,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="container-fluid pb-5"> <div class="container-fluid bg-white pb-5">
<div class="row"> <div class="row">
<div class="col d-none d-md-inline p-0" style="position: relative"> <div class="col d-none d-md-inline p-0" style="position: relative">
<div class="d-inline-block" style="position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%)"> <div class="d-inline-block" style="position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%)">

View File

@ -1,8 +1,21 @@
@import '~@angular/material/prebuilt-themes/indigo-pink.css'; @import '~@angular/material/prebuilt-themes/indigo-pink.css';
@import url('https://use.fontawesome.com/releases/v5.1.0/css/all.css'); @import url('https://use.fontawesome.com/releases/v5.1.0/css/all.css');
@import url('https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css'); @import url('https://fonts.googleapis.com/css?family=Material+Icons|Roboto+Condensed');
@import url('https://fonts.googleapis.com/css?family=Roboto+Condensed');
@import url('https://fonts.googleapis.com/icon?family=Material+Icons'); ::-webkit-scrollbar-track {
border-radius: 10px;
background-color: rgba(255, 255, 255, 0);
}
::-webkit-scrollbar {
width: 8px;
background-color: #F5F5F5;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: #555;
}
html, html,
body { body {
@ -10,6 +23,11 @@ body {
width: 100%; width: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;
background-color: #292929;
}
.button-fix {
font-size: 1.2rem;
} }
a, a,

7
src/assets/css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

BIN
src/assets/img/splatter.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -16,7 +16,7 @@
<link rel="icon" type="image/png" href="assets/img/logo.png"> <link rel="icon" type="image/png" href="assets/img/logo.png">
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.1/css/all.css"> <link rel="stylesheet" href="assets/css/bootstrap.min.css">
<script src="https://www.paypalobjects.com/api/checkout.js"></script> <script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>