Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<table mat-table #sort="matSort" [dataSource]="dataSource" multiTemplateDataRows class="mat-elevation-z8" matSort>
<table mat-table [dataSource]="dataSource" multiTemplateDataRows class="mat-elevation-z8" matSort>

<!-- name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Budget Name </th>
<td mat-cell *matCellDef="let row">
{{row.name ? row.name : '-' }} <span *ngIf="row.childrenList?.length > 0" class="badge primary"
{{row.name ? row.name : '-' }} <span *ngIf="row?.childrenList?.length" class="badge primary"
(click)="openChildBudgetDialog(row)"> Linked Budgets ({{ row?.childrenList?.length }}) </span>
</td>
</ng-container>
Expand Down Expand Up @@ -74,4 +74,4 @@
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [pageSizeOptions]="[10, 25, 100]" aria-label="Select page of users"></mat-paginator>
<mat-paginator #paginator [pageSizeOptions]="[10, 25, 100]" aria-label="Select page of users"></mat-paginator>
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { Component, EventEmitter, inject, signal,effect,Input, Output, ViewChild } from '@angular/core';
import { MatTable, MatTableDataSource } from '@angular/material/table';
import { MatPaginator } from '@angular/material/paginator';
import { MatDialog } from '@angular/material/dialog';
import { MatSort } from '@angular/material/sort';
import { Router } from '@angular/router';

import { SubSink } from 'subsink';
import { Observable, tap } from 'rxjs';

import { Budget, BudgetRecord } from '@app/model/finance/planning/budgets';

import { ShareBudgetModalComponent } from '../share-budget-modal/share-budget-modal.component';
Expand All @@ -22,38 +19,48 @@ import { ChildBudgetsModalComponent } from '../../modals/child-budgets-modal/chi

export class BudgetTableComponent {

private _sbS = new SubSink();
// private _sbS = new SubSink();

@Input() budgets$: Observable<{overview: BudgetRecord[], budgets: any[]}>;
@Input() canPromote = false;
@Input({required:true }) budgets!: signal<{overview: BudgetRecord[], budgets: any[]}>;

@Output() doPromote: EventEmitter<void> = new EventEmitter();
@Output() doPromote = new EventEmitter();

dataSource = new MatTableDataSource();

displayedColumns: string[] = ['name', 'status', 'startYear', 'duration', 'actions'];

@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild('sort', { static: true }) sort: MatSort;
@ViewChild(MatPaginator) paginator!: MatPaginator;
@ViewChild('MatSort', { static: true }) sort: MatSort;

overviewBudgets: BudgetRecord[] = [];

constructor(private _router$$: Router,
private _dialog: MatDialog,
) { }

ngOnInit(): void {
this._sbS.sink = this.budgets$.pipe(tap((o) => {
this.overviewBudgets = o.overview;
this.dataSource.data = o.budgets;
})).subscribe();
// constructor(private _router$$: Router,
// private _dialog: MatDialog,
// ) { }

private _router = inject(Router);
private _dialog = inject(MatDialog);

constructor(){

effect(() =>{
const incomingBudgets = this.budgets();
this.overviewBudgets = incomingBudgets.overview;
this.dataSource.data = incomingBudgets.budgets;
if (this.paginator) {
this.dataSource.paginator = this.paginator;
}
if (this.sort) {
this.dataSource.sort = this.sort;
}
});
}
ngAfterViewInit(): void {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}

/**
* Checks whether the user has access to a certain feature.
*
* @TODO @IanOdhiambo9 - Please put proper access control architecture in place.
*/
access(requested:any)
{
switch (requested) {
Expand All @@ -66,10 +73,7 @@ export class BudgetTableComponent {
return false;
}

ngAfterViewInit(): void {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}


filterAccountRecords(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
Expand Down Expand Up @@ -106,8 +110,7 @@ export class BudgetTableComponent {

openChildBudgetDialog(parent : Budget): void
{
let children: any = this.overviewBudgets.find((budget) => budget.budget.id === parent.id)!?.children;
children = children?.map((child) => child.budget)
let children: any = this.overviewBudgets.find((budget) => budget.budget.id === parent.id)?.children?.map((child) => child.budget);
this._dialog.open(ChildBudgetsModalComponent, {
height: 'fit-content',
minWidth: '600px',
Expand All @@ -116,12 +119,10 @@ export class BudgetTableComponent {
}

goToDetail(budgetId: string, action: string) {
this._router$$.navigate(['budgets', budgetId, action]).then(() => this._dialog.closeAll());
this._router.navigate(['budgets', budgetId, action]).then(() => this._dialog.closeAll());
}

deleteBudget(budget: Budget) {

}
deleteBudget(budget: Budget) { }

translateStatus(status: number) {
switch (status) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</div>

<div class="table-container">
<app-budget-table [budgets$]="allBudgets$"></app-budget-table>
<app-budget-table [budgets$]="allBudgets()"></app-budget-table>
</div>
</div>
</app-page>
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { Component, inject,signal , computed, toSignal } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';

import { cloneDeep as ___cloneDeep, flatMap as __flatMap } from 'lodash';
import { Observable, combineLatest, map, tap } from 'rxjs';

import { Logger } from '@iote/bricks-angular';

import { Budget, BudgetRecord, BudgetStatus, OrgBudgetsOverview } from '@app/model/finance/planning/budgets';
import { Budget, BudgetRecord, BudgetStatus } from '@app/model/finance/planning/budgets';

import { BudgetsStore, OrgBudgetsStore } from '@app/state/finance/budgetting/budgets';

import { CreateBudgetModalComponent } from '../../components/create-budget-modal/create-budget-modal.component';


Expand All @@ -19,90 +15,67 @@ import { CreateBudgetModalComponent } from '../../components/create-budget-modal
styleUrls: ['./select-budget.component.scss',
'../../components/budget-view-styles.scss'],
})
/** List of all active budgets on the system. */
export class SelectBudgetPageComponent implements OnInit
{
/** Overview which contains all budgets of an organisation */
overview$!: Observable<OrgBudgetsOverview>;
sharedBudgets$: Observable<any[]>;

showFilter = false;

// budgetsLoaded: boolean = false;

allBudgets$: Observable<{overview: BudgetRecord[], budgets: any[]}>;

constructor(private _orgBudgets$$: OrgBudgetsStore,
private _budgets$$: BudgetsStore,
private _dialog: MatDialog,
private _logger: Logger)
{ }

ngOnInit() {
this.overview$ = this._orgBudgets$$.get();
this.sharedBudgets$ = this._budgets$$.get();

this.allBudgets$ = combineLatest([this.overview$, this._budgets$$.get()])
.pipe(map(([overview, budgets]) => {return {overview: __flatMap(overview), budgets: __flatMap(budgets)}}),
map((overview) => {
const trBudgets = overview.budgets.map((budget: any) => {budget['endYear'] = budget.startYear + budget.duration - 1; return budget;})
// this.budgetsLoaded = true;
return {overview: overview.overview, budgets: trBudgets}
}));
}

applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
// this.dataSource.filter = filterValue.trim().toLowerCase();
}
export class SelectBudgetPageComponent{

fieldsFilter(value: (Invoice) => boolean) {
// this.filter$$.next(value);
}
showFilter = signal(false);

toogleFilter(value) {
// this.showFilter = value
}
private _orgBudgets = inject(OrgBudgetsStore);
private _budgets$$ = inject(BudgetsStore);
private _dialog = inject(MatDialog);
private _logger = inject(Logger);

// Convert observables to signals
overview = toSignal(this._orgBudgets.get(), { initialValue: [] });
sharedBudgets = toSignal(this._budgets$$.get(), { initialValue: [] });

allBudgets = computed(() => {
const overview = __flatMap(this.overview());
const budgets = __flatMap(this.sharedBudgets()).map((budget: any) => {
budget['endYear'] = budget.startYear + budget.duration - 1;
return budget;
});
return {overview, budgets};
});

// constructor() { }

openDialog(parent : Budget | false): void
{
const dialog = this._dialog.open(CreateBudgetModalComponent, {
openDialog(parent: Budget | false): void {
this._dialog.open(CreateBudgetModalComponent, {
height: 'fit-content',
width: '600px',
data: parent != null ? parent : false
});

dialog.afterClosed().subscribe(() => {
// Dialog after action
})
}

/**
* @TODO - Review and fix
* Returns true if the budget can be activated */
canPromote(record: BudgetRecord) {
// Get's set on Budget Read from user privileges and budget status.
return (record.budget as any).canBeActivated;
}

/** Activate budget -> Promote to be used in */
setActive(record: BudgetRecord)
{
const toSave = ___cloneDeep(record.budget);
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
// this.dataSource.filter = filterValue.trim().toLowerCase();
}

fieldsFilter(value: (x: any) => boolean) {
// this.filter$$.next(value);
}

toogleFilter(value: boolean) {
this.showFilter.set(value);
}

// Clean up budget record values.
setActive(record: BudgetRecord) {
const toSave = ___cloneDeep(record.budget);
delete (toSave as any).canBeActivated;
delete (toSave as any).access;

// Set Active
toSave.status = BudgetStatus.InUse;

(<any> record).updating = true;
// Fire update
(record as any).updating = true;
this._budgets$$.update(toSave)
.subscribe(() => {
(<any> record).updating = false;
this._logger.log(() => `Updated Budget with id ${toSave.id}. Set as an active budget for this org.`)
(record as any).updating = false;
this._logger.log(() => `Updated Budget with id ${toSave.id}. Set as an active budget for this org.`);
});
}
}