Simplified some permissions

Renamed Accounts Audit to Audit
Renamed Machines to Devices as it made sense
Sections and Tables are now under Sections Permission
Guest Book is now under Customers Permission
Renamed Beer Consumption Report to Beer Sale Report
Fix: Move Kot and Table to check what the final effect is
This commit is contained in:
2020-11-15 12:26:24 +05:30
parent aead1f1b36
commit 163b40e9e5
44 changed files with 310 additions and 253 deletions

View File

@ -0,0 +1,16 @@
import { DataSource } from '@angular/cdk/collections';
import { Observable, of as observableOf } from 'rxjs';
import { BeerSaleReportItem } from './beer-sale-report-item';
export class BeerSaleReportDataSource extends DataSource<BeerSaleReportItem> {
constructor(public data: BeerSaleReportItem[]) {
super();
}
connect(): Observable<BeerSaleReportItem[]> {
return observableOf(this.data);
}
disconnect() {}
}

View File

@ -0,0 +1,5 @@
export class BeerSaleReportItem {
date: string;
name: string;
quantity: number;
}

View File

@ -0,0 +1,15 @@
import { inject, TestBed } from '@angular/core/testing';
import { BeerSaleReportResolver } from './beer-sale-report-resolver.service';
describe('BeerSaleReportResolver', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [BeerSaleReportResolver],
});
});
it('should be created', inject([BeerSaleReportResolver], (service: BeerSaleReportResolver) => {
expect(service).toBeTruthy();
}));
});

View File

@ -0,0 +1,19 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve } from '@angular/router';
import { Observable } from 'rxjs/internal/Observable';
import { BeerSaleReport } from './beer-sale-report';
import { BeerSaleReportService } from './beer-sale-report.service';
@Injectable({
providedIn: 'root',
})
export class BeerSaleReportResolver implements Resolve<BeerSaleReport> {
constructor(private ser: BeerSaleReportService) {}
resolve(route: ActivatedRouteSnapshot): Observable<BeerSaleReport> {
const startDate = route.queryParamMap.get('startDate') || null;
const finishDate = route.queryParamMap.get('finishDate') || null;
return this.ser.get(startDate, finishDate);
}
}

View File

@ -0,0 +1,13 @@
import { BeerSaleReportRoutingModule } from './beer-sale-report-routing.module';
describe('BeerSaleReportRoutingModule', () => {
let beerSaleReportRoutingModule: BeerSaleReportRoutingModule;
beforeEach(() => {
beerSaleReportRoutingModule = new BeerSaleReportRoutingModule();
});
it('should create an instance', () => {
expect(beerSaleReportRoutingModule).toBeTruthy();
});
});

View File

@ -0,0 +1,30 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from '../auth/auth-guard.service';
import { BeerSaleReportResolver } from './beer-sale-report-resolver.service';
import { BeerSaleReportComponent } from './beer-sale-report.component';
const beerSaleReportRoutes: Routes = [
{
path: '',
component: BeerSaleReportComponent,
canActivate: [AuthGuard],
data: {
permission: 'Beer Sale Report',
},
resolve: {
info: BeerSaleReportResolver,
},
runGuardsAndResolvers: 'always',
},
];
@NgModule({
imports: [CommonModule, RouterModule.forChild(beerSaleReportRoutes)],
exports: [RouterModule],
providers: [BeerSaleReportResolver],
})
export class BeerSaleReportRoutingModule {}

View File

@ -0,0 +1,4 @@
.right {
display: flex;
justify-content: flex-end;
}

View File

@ -0,0 +1,73 @@
<mat-card>
<mat-card-title-group>
<mat-card-title>Beer Sale Report</mat-card-title>
<button mat-button mat-icon-button (click)="exportCsv()">
<mat-icon>save_alt</mat-icon>
</button>
</mat-card-title-group>
<mat-card-content>
<form [formGroup]="form" fxLayout="column">
<div
fxLayout="row"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
fxLayoutAlign="space-around start"
>
<mat-form-field fxFlex="40">
<input
matInput
[matDatepicker]="startDate"
(focus)="startDate.open()"
placeholder="Start Date"
formControlName="startDate"
autocomplete="off"
/>
<mat-datepicker-toggle matSuffix [for]="startDate"></mat-datepicker-toggle>
<mat-datepicker #startDate></mat-datepicker>
</mat-form-field>
<mat-form-field fxFlex="40">
<input
matInput
[matDatepicker]="finishDate"
(focus)="finishDate.open()"
placeholder="Finish Date"
formControlName="finishDate"
autocomplete="off"
/>
<mat-datepicker-toggle matSuffix [for]="finishDate"></mat-datepicker-toggle>
<mat-datepicker #finishDate></mat-datepicker>
</mat-form-field>
<button fxFlex="20" mat-raised-button color="primary" (click)="show()">Show</button>
</div>
</form>
<mat-table #table [dataSource]="dataSource" aria-label="Elements">
<!-- Date Column -->
<ng-container matColumnDef="date">
<mat-header-cell *matHeaderCellDef>Time</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.date }}</mat-cell>
</ng-container>
<!-- Name Column -->
<ng-container *ngFor="let col of info.headers" matColumnDef="{{ col }}">
<mat-header-cell *matHeaderCellDef class="right">{{ col }}</mat-header-cell>
<mat-cell *matCellDef="let row" class="right">{{ row[col] }}</mat-cell>
</ng-container>
<!-- &lt;!&ndash; Name Column &ndash;&gt;-->
<!-- <ng-container matColumnDef="name">-->
<!-- <mat-header-cell *matHeaderCellDef class="right">Name</mat-header-cell>-->
<!-- <mat-cell *matCellDef="let row" class="right">{{row.name}}</mat-cell>-->
<!-- </ng-container>-->
<!-- &lt;!&ndash; Quantity Column &ndash;&gt;-->
<!-- <ng-container matColumnDef="quantity">-->
<!-- <mat-header-cell *matHeaderCellDef class="right">Quantity</mat-header-cell>-->
<!-- <mat-cell *matCellDef="let row" class="right">{{row.quantity | number:'1.2-2'}}</mat-cell>-->
<!-- </ng-container>-->
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
</mat-table>
</mat-card-content>
</mat-card>

View File

@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BeerSaleReportComponent } from './beer-sale-report.component';
describe('BeerSaleReportComponent', () => {
let component: BeerSaleReportComponent;
let fixture: ComponentFixture<BeerSaleReportComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [BeerSaleReportComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BeerSaleReportComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,91 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import * as moment from 'moment';
import { ToCsvService } from '../shared/to-csv.service';
import { BeerSaleReport } from './beer-sale-report';
import { BeerSaleReportDataSource } from './beer-sale-report-datasource';
@Component({
selector: 'app-beer-sale-report',
templateUrl: './beer-sale-report.component.html',
styleUrls: ['./beer-sale-report.component.css'],
})
export class BeerSaleReportComponent implements OnInit {
dataSource: BeerSaleReportDataSource;
form: FormGroup;
info: BeerSaleReport;
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns: string[] = ['date'];
constructor(
private route: ActivatedRoute,
private router: Router,
private fb: FormBuilder,
private toCsv: ToCsvService,
) {
this.createForm();
}
ngOnInit() {
this.route.data.subscribe((data: { info: BeerSaleReport }) => {
this.info = data.info;
this.displayedColumns = ['date'].concat(this.info.headers);
this.form.setValue({
startDate: moment(this.info.startDate, 'DD-MMM-YYYY').toDate(),
finishDate: moment(this.info.finishDate, 'DD-MMM-YYYY').toDate(),
});
this.dataSource = new BeerSaleReportDataSource(this.info.data);
});
}
show() {
const info = this.getInfo();
this.router.navigate(['beer-sale-report'], {
queryParams: {
startDate: info.startDate,
finishDate: info.finishDate,
},
});
}
createForm() {
this.form = this.fb.group({
startDate: '',
finishDate: '',
});
}
getInfo(): BeerSaleReport {
const formModel = this.form.value;
return {
startDate: moment(formModel.startDate).format('DD-MMM-YYYY'),
finishDate: moment(formModel.finishDate).format('DD-MMM-YYYY'),
};
}
exportCsv() {
const headers = this.info.headers.reduce(
(a, c) => {
a[c] = c;
return a;
},
{
Date: 'date',
},
);
const csvData = new Blob([this.toCsv.toCsv(headers, this.info.data)], {
type: 'text/csv;charset=utf-8;',
});
const link = document.createElement('a');
link.href = window.URL.createObjectURL(csvData);
link.setAttribute('download', 'beer-sale-report.csv');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}

View File

@ -0,0 +1,13 @@
import { BeerSaleReportModule } from './beer-sale-report.module';
describe('BeerSaleReportModule', () => {
let beerSaleReportModule: BeerSaleReportModule;
beforeEach(() => {
beerSaleReportModule = new BeerSaleReportModule();
});
it('should create an instance', () => {
expect(beerSaleReportModule).toBeTruthy();
});
});

View File

@ -0,0 +1,65 @@
import { A11yModule } from '@angular/cdk/a11y';
import { CdkTableModule } from '@angular/cdk/table';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FlexLayoutModule } from '@angular/flex-layout';
import { ReactiveFormsModule } from '@angular/forms';
import { MomentDateAdapter } from '@angular/material-moment-adapter';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import {
DateAdapter,
MAT_DATE_FORMATS,
MAT_DATE_LOCALE,
MatNativeDateModule,
} from '@angular/material/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatTableModule } from '@angular/material/table';
import { SharedModule } from '../shared/shared.module';
import { BeerSaleReportRoutingModule } from './beer-sale-report-routing.module';
import { BeerSaleReportComponent } from './beer-sale-report.component';
export const MY_FORMATS = {
parse: {
dateInput: 'DD-MMM-YYYY',
},
display: {
dateInput: 'DD-MMM-YYYY',
monthYearLabel: 'MMM YYYY',
dateA11yLabel: 'DD-MMM-YYYY',
monthYearA11yLabel: 'MMM YYYY',
},
};
@NgModule({
imports: [
A11yModule,
CommonModule,
CdkTableModule,
FlexLayoutModule,
MatAutocompleteModule,
MatButtonModule,
MatCardModule,
MatDatepickerModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
MatNativeDateModule,
MatTableModule,
ReactiveFormsModule,
SharedModule,
BeerSaleReportRoutingModule,
],
declarations: [BeerSaleReportComponent],
providers: [
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
{ provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
],
})
export class BeerSaleReportModule {}

View File

@ -0,0 +1,15 @@
import { inject, TestBed } from '@angular/core/testing';
import { BeerSaleReportService } from './beer-sale-report.service';
describe('BeerSaleReportService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [BeerSaleReportService],
});
});
it('should be created', inject([BeerSaleReportService], (service: BeerSaleReportService) => {
expect(service).toBeTruthy();
}));
});

View File

@ -0,0 +1,33 @@
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { catchError } from 'rxjs/operators';
import { ErrorLoggerService } from '../core/error-logger.service';
import { BeerSaleReport } from './beer-sale-report';
const url = '/api/beer-sale-report';
const serviceName = 'BeerSaleReportService';
@Injectable({
providedIn: 'root',
})
export class BeerSaleReportService {
constructor(private http: HttpClient, private log: ErrorLoggerService) {}
get(startDate: string, finishDate): Observable<BeerSaleReport> {
const options = { params: new HttpParams() };
if (startDate !== null) {
options.params = options.params.set('s', startDate);
}
if (finishDate !== null) {
options.params = options.params.set('f', finishDate);
}
return <Observable<BeerSaleReport>>(
this.http
.get<BeerSaleReport>(url, options)
.pipe(catchError(this.log.handleError(serviceName, 'get')))
);
}
}

View File

@ -0,0 +1,8 @@
import { BeerSaleReportItem } from './beer-sale-report-item';
export class BeerSaleReport {
startDate: string;
finishDate: string;
headers?: string[];
data?: BeerSaleReportItem[];
}