initial commit

This commit is contained in:
Patrick Nagurny
2018-10-19 11:28:08 -04:00
commit 5ff09d328d
139 changed files with 23448 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
<h1>Dashboard</h1>
<p class="description">
<a href="/docs/getting-started" target="_blank">Click here</a> for help getting started.
</p>
<div class="section">
<!-- <div class="card getting-started">
<button type="button" class="close" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<div class="card-body">
<p><a href="/docs/getting-started" target="_blank">Click here</a> for help getting started.</p>
</div>
</div> -->
<div class="card budget">
<div class="card-body">
<div class="container-fluid" [ngClass]="{expanded: budgetExpanded}">
<div class="row">
<div class="col-8">
<h5>Current spending</h5>
</div>
<div class="col-4 amount">
<h5>{{expenseAmount | currencyFormat:org.precision}}</h5>
</div>
</div>
<div class="row" *ngFor="let expense of expenseAccounts" [routerLink]="'/accounts/'+expense.id+'/transactions'" [ngClass]="{hidden: hiddenExpenses[expense.id]}">
<div class="col-8 name">
{{expense.fullName | accountName:2}}
</div>
<div class="col-4 amount">
{{expense.nativeBalanceCost | currencyFormat:org.precision}}
</div>
</div>
<div class="row">
<div class="col-8">
<a [routerLink]="" (click)="toggleExpandedBudget()">
<span *ngIf="budgetExpanded">Less</span>
<span *ngIf="!budgetExpanded">More</span>
</a>
</div>
<div class="col-4 amount">
<a routerLink="/reports/income">See all expenses</a>
</div>
</div>
</div>
</div>
</div>
<div class="card recent">
<div class="card-body">
<div class="container-fluid" [ngClass]="{expanded: recentExpanded}">
<div class="row">
<div class="col-12">
<h5>Recent transactions</h5>
</div>
</div>
<div class="row" *ngFor="let recentTx of recentTxs" [routerLink]="'/accounts/'+recentTx.account.id+'/transactions'" [ngClass]="{hidden: recentTx.hidden}">
<div class="col-2 date">
{{recentTx.tx.date | date:"M/d"}}
</div>
<div class="col-6 description">
{{recentTx.tx.description}}
</div>
<div class="col-4 amount" [ngClass]="{'negative': recentTx.split.amount > 0}">
{{-recentTx.split.amount | currencyFormat:recentTx.account.precision}}
</div>
</div>
<div class="row">
<div class="col-12">
<a [routerLink]="" (click)="toggleExpandedRecent()">
<span *ngIf="recentExpanded">Less</span>
<span *ngIf="!recentExpanded">More</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from '../app-routing.module';
import { SharedModule } from '../shared/shared.module';
import { DashboardPage } from './dashboard';
@NgModule({
declarations: [
DashboardPage
],
imports: [
BrowserModule,
AppRoutingModule,
SharedModule
],
providers: []
})
export class DashboardModule { }

View File

@@ -0,0 +1,44 @@
@import '../../sass/variables';
.row {
cursor: pointer;
}
.getting-started {
position: relative;
.close {
position: absolute;
top: 0px;
right: 0px;
}
.card-body {
padding: 0
}
}
.budget {
.hidden {
display: none
}
.expanded .hidden {
display: flex
}
.amount {
text-align: right;
}
}
.recent {
.amount {
text-align: right;
}
.amount.negative {
color: $negative;
}
.hidden {
display: none
}
.expanded .hidden {
display: flex
}
}

View File

@@ -0,0 +1,129 @@
import { Component, OnInit } from '@angular/core';
import { Logger } from '../core/logger';
import { TransactionService } from '../core/transaction.service';
import { AccountService } from '../core/account.service';
import { OrgService } from '../core/org.service';
import { SessionService } from '../core/session.service';
import { Transaction, Split } from '../shared/transaction';
import { Org } from '../shared/org';
import { Account, AccountTree } from '../shared/account';
import { TxListPage } from '../transaction/list';
import { IncomeReport } from '../reports/income';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/take';
class RecentTx {
split: Split;
account: Account;
tx: Transaction;
hidden: boolean;
}
@Component({
selector: 'app-dashboard',
templateUrl: 'dashboard.html',
styleUrls: ['./dashboard.scss']
})
export class DashboardPage implements OnInit {
public org: Org;
public expenseAmount: number;
public budgetExpanded: boolean = false;
public recentExpanded: boolean = false;
public expenseAccounts: Account[] = [];
public hiddenExpenses: any = {};
public recentTxs: RecentTx[];
private numBudgetItems: number = 5;
private numSplits: number = 5;
constructor(
private log: Logger,
private txService: TransactionService,
private accountService: AccountService,
private orgService: OrgService,
private sessionService: SessionService) {
}
ngOnInit() {
this.sessionService.setLoading(true);
this.log.debug('dashboard init');
let periodStart = this.accountService.getPeriodStart();
this.org = this.orgService.getCurrentOrg();
this.log.debug('org', this.org);
let tree$ = this.accountService.getAccountTreeWithPeriodBalance(periodStart);
tree$.do(tree => {
let expenses = tree.getAccountByName('Expenses', 1);
this.expenseAmount = expenses.totalNativeBalanceCost;
this.expenseAccounts = tree.getFlattenedAccounts().filter(account => {
return tree.accountIsChildOf(account, expenses) && account.recentTxCount;
}).sort((a, b) => {
return b.recentTxCount - a.recentTxCount;
}).slice(0, this.numBudgetItems * 2);
this.hiddenExpenses = {};
this.expenseAccounts.forEach((account, index) => {
if(index >= this.numBudgetItems) {
this.hiddenExpenses[account.id] = true;
}
});
})
.switchMap(tree => {
let expenses = tree.getAccountByName('Expenses', 1);
let income = tree.getAccountByName('Income', 1);
return this.txService.getLastTransactions(this.numSplits * 4).take(1)
.map(txs => {
this.log.debug('lastTxs');
this.log.debug(txs);
return txs.map(tx => {
let splits = tx.splits.filter(split => {
let account = tree.accountMap[split.accountId];
if(!account || !split.amount) {
return false;
}
return tree.accountIsChildOf(account, expenses) || tree.accountIsChildOf(account, income);
});
return splits.map(split => {
let recentTx = new RecentTx();
recentTx.split = split;
recentTx.account = tree.accountMap[split.accountId];
recentTx.tx = tx;
return recentTx;
});
}).reduce((acc, recentTxs) => {
return acc.concat(recentTxs);
}, [])
}).map(recentTxs => {
return recentTxs.slice(0, this.numSplits * 2);
}).map(recentTxs => {
return recentTxs.map((recentTx, index) => {
if(index >= this.numSplits) {
recentTx.hidden = true;
}
return recentTx;
})
});
})
.subscribe(recentTxs => {
this.log.debug('recentTxs', recentTxs);
this.recentTxs = recentTxs;
this.sessionService.setLoading(false);
});
}
toggleExpandedBudget() {
this.budgetExpanded = !this.budgetExpanded;
}
toggleExpandedRecent() {
this.recentExpanded = !this.recentExpanded;
}
}