Skip to content

Commit

Permalink
Dashboards
Browse files Browse the repository at this point in the history
  • Loading branch information
akariv committed Jan 6, 2025
1 parent b7de120 commit 5a84b88
Show file tree
Hide file tree
Showing 31 changed files with 741 additions and 0 deletions.
1 change: 1 addition & 0 deletions projects/budgetkey/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const routes: Routes = [
{ path: 'about', loadChildren: () => import('./about/about.module').then(m => m.AboutModule) },
{ path: 'p', loadChildren: () => import('./profile/profile.module').then(m => m.ProfileModule) },
{ path: 'l', loadChildren: () => import('./list-page/list-page.module').then(m => m.ListPageModule) },
{ path: 'dashboards', loadChildren: () => import('./dashboards/dashboards.module').then(m => m.DashboardsModule) },
{ path: 'not-found', component: PageNotFoundComponent },
{ path: '**', pathMatch: 'full', component: PageNotFoundComponent },
];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
title: דו״ח היסטוריה ונהנים לתכנית תקציבית
doctype: budget
placeholder: חיפוש תכנית תקציבית (למשל ״20.67.01״ או ״העברות לרשויות״)
result_template: ":nice-code - :title"
filters:
depth__gt: 0
year: 2025
visualizations:
- title: היסטוריה תקציבית
kind: table
query: >
select
year as "שנה:str",
net_allocated as "תקציב מקורי:fig",
net_revised as "תקציב מאושר:fig",
(net_revised / (net_allocated + 0.0001) - 1) * 100 as "שינוי באחוזים:fig",
net_executed as "ביצוע:fig",
(net_executed / (net_revised + 0.0001) ) * 100 as "אחוז ביצוע תקציב:fig"
from raw_budget where code=':code'
order by year desc
- title: העברות בשנים האחרונות
kind: table
query: >
select
coalesce(to_char("date", 'YYYY/MM/DD'), 'טרם אושר') as "תאריך:str",
change_title as "סוג:str",
req_title as "כותרת:strw",
sum(net_expense_diff) as "נטו:fig",
sum(gross_expense_diff) as "ברוטו:fig",
sum(allocated_income_diff) as "הכנסה מיועדת:fig",
sum(commitment_limit_diff) as "הרשאה להתחייב:fig",
sum(personnel_max_diff) as "שיא כ״א:fig"
from raw_budget_changes where budget_code like ':code%%'
and year>=2015
group by 1,2,3,req_code,date
order by date desc
- title: סיכום העברות בשנה האחרונה
kind: table
query: >
SELECT change_title as "סוג העברה:str",
sum(net_expense_diff) as "סך שינוי נטו:fig"
FROM raw_budget_changes
WHERE budget_code LIKE ':code%%'
AND YEAR=2024
AND NOT pending
GROUP BY 1
- title: נתמכים עיקריים
kind: table
query: >
SELECT coalesce(entity_name, recipient) AS "מקבל התמיכה:str",
min(year_requested) as "משנת:str",
max(year_paid) as "עד שנת:str",
sum(amount_paid) as "סך שולם:fig",
sum(amount_total) as "סך אושר:fig"
FROM raw_supports
WHERE budget_code LIKE ':code%%'
GROUP BY 1
HAVING sum(amount_paid)>0
ORDER BY 4 DESC nulls LAST
LIMIT 20
- title: נושאי תמיכה עיקריים
kind: table
query: >
SELECT support_title AS "נושא התמיכה:str",
min(year_requested) as "משנת:str",
max(year_paid) as "עד שנת:str",
sum(amount_paid) as "סך שולם:fig",
sum(amount_total) as "סך אושר:fig"
FROM raw_supports
WHERE budget_code LIKE ':code%%'
GROUP BY 1
HAVING sum(amount_paid)>0
ORDER BY 4 DESC nulls LAST
LIMIT 20
- title: ספקים עיקריים
kind: table
query: >
SELECT coalesce(entity_name, supplier_name->>0) AS "ספק:str",
min(min_year) as "משנת:str",
max(max_year) as "עד שנת:str",
sum(executed) as "סך שולם:fig",
sum(volume) as "סך אושר:fig"
FROM contract_spending
WHERE budget_code LIKE ':code%%'
GROUP BY 1
ORDER BY 4 DESC nulls LAST
LIMIT 20
- title: התקשרויות מרכזיות
kind: table
query: >
SELECT coalesce(entity_name, supplier_name->>0) AS "ספק:strw",
purpose as "מטרה:strw",
budget_title as "מתקציב:strw",
purchasing_unit as "המזמין:str",
purchase_method as "אופן רכישה:strw",
min_year as "משנת:str",
executed as "סך שולם עד כה:fig",
volume as "היקף ההתקשרות:fig"
FROM contract_spending
WHERE budget_code LIKE ':code%%'
ORDER BY 7 DESC nulls LAST
LIMIT 20
49 changes: 49 additions & 0 deletions projects/budgetkey/src/app/dashboards/configurations/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export const config: any = {
"budget-transfers": {
"doctype": "budget",
"filters": {
"depth__gt": 0,
"year": 2025
},
"placeholder": "חיפוש תכנית תקציבית (למשל ״20.67.01״ או ״העברות לרשויות״)",
"result_template": ":nice-code - :title",
"title": "דו״ח היסטוריה ונהנים לתכנית תקציבית",
"visualizations": [
{
"kind": "table",
"query": "select year as \"שנה:str\", net_allocated as \"תקציב מקורי:fig\", net_revised as \"תקציב מאושר:fig\", (net_revised / (net_allocated + 0.0001) - 1) * 100 as \"שינוי באחוזים:fig\", net_executed as \"ביצוע:fig\", (net_executed / (net_revised + 0.0001) ) * 100 as \"אחוז ביצוע תקציב:fig\" from raw_budget where code=':code' order by year desc\n",
"title": "היסטוריה תקציבית"
},
{
"kind": "table",
"query": "select coalesce(to_char(\"date\", 'YYYY/MM/DD'), 'טרם אושר') as \"תאריך:str\", change_title as \"סוג:str\", req_title as \"כותרת:strw\", sum(net_expense_diff) as \"נטו:fig\", sum(gross_expense_diff) as \"ברוטו:fig\", sum(allocated_income_diff) as \"הכנסה מיועדת:fig\", sum(commitment_limit_diff) as \"הרשאה להתחייב:fig\", sum(personnel_max_diff) as \"שיא כ״א:fig\" from raw_budget_changes where budget_code like ':code%%' and year>=2015 group by 1,2,3,req_code,date order by date desc\n",
"title": "העברות בשנים האחרונות"
},
{
"kind": "table",
"query": "SELECT change_title as \"סוג העברה:str\",\n sum(net_expense_diff) as \"סך שינוי נטו:fig\"\nFROM raw_budget_changes WHERE budget_code LIKE ':code%%'\n AND YEAR=2024\n AND NOT pending\nGROUP BY 1\n",
"title": "סיכום העברות בשנה האחרונה"
},
{
"kind": "table",
"query": "SELECT coalesce(entity_name, recipient) AS \"מקבל התמיכה:str\",\n min(year_requested) as \"משנת:str\",\n max(year_paid) as \"עד שנת:str\",\n sum(amount_paid) as \"סך שולם:fig\",\n sum(amount_total) as \"סך אושר:fig\"\nFROM raw_supports WHERE budget_code LIKE ':code%%' GROUP BY 1 HAVING sum(amount_paid)>0 ORDER BY 4 DESC nulls LAST LIMIT 20\n",
"title": "נתמכים עיקריים"
},
{
"kind": "table",
"query": "SELECT support_title AS \"נושא התמיכה:str\",\n min(year_requested) as \"משנת:str\",\n max(year_paid) as \"עד שנת:str\",\n sum(amount_paid) as \"סך שולם:fig\",\n sum(amount_total) as \"סך אושר:fig\"\nFROM raw_supports WHERE budget_code LIKE ':code%%' GROUP BY 1 HAVING sum(amount_paid)>0 ORDER BY 4 DESC nulls LAST LIMIT 20\n",
"title": "נושאי תמיכה עיקריים"
},
{
"kind": "table",
"query": "SELECT coalesce(entity_name, supplier_name->>0) AS \"ספק:str\",\n min(min_year) as \"משנת:str\",\n max(max_year) as \"עד שנת:str\",\n sum(executed) as \"סך שולם:fig\",\n sum(volume) as \"סך אושר:fig\"\nFROM contract_spending WHERE budget_code LIKE ':code%%' GROUP BY 1 ORDER BY 4 DESC nulls LAST LIMIT 20\n",
"title": "ספקים עיקריים"
},
{
"kind": "table",
"query": "SELECT coalesce(entity_name, supplier_name->>0) AS \"ספק:strw\",\n purpose as \"מטרה:strw\",\n budget_title as \"מתקציב:strw\",\n purchasing_unit as \"המזמין:str\",\n purchase_method as \"אופן רכישה:strw\",\n min_year as \"משנת:str\",\n executed as \"סך שולם עד כה:fig\",\n volume as \"היקף ההתקשרות:fig\"\nFROM contract_spending WHERE budget_code LIKE ':code%%' ORDER BY 7 DESC nulls LAST LIMIT 20\n",
"title": "התקשרויות מרכזיות"
}
]
}
};
17 changes: 17 additions & 0 deletions projects/budgetkey/src/app/dashboards/configurations/convert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env python
import json
import yaml
import glob
import pathlib

ROOT = pathlib.Path(__file__).parent

# for f in glob.glob('src/app/configurations/*yaml'):
config = {}
for f in ROOT.glob('*.yaml'):
print(f)
config[f.stem] = yaml.load(f.open(), Loader=yaml.SafeLoader)
data = json.dumps(config, indent=2, ensure_ascii=False, sort_keys=True)
with (ROOT / 'config.ts').open('w') as out:
out.write('export const config: any = %s;' % data)

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<input type="text"
[placeholder]="api.config.placeholder"
(change)='doSearch($event)'
(keyup)='doSearch($event)'
>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
:host {
width: 100%;

input::placeholder {
color: #B9BCC3;
font-family: "Abraham TRIAL";
font-size: 16px;
line-height: 25px;
text-align: right;
}

input:focus::placeholder {
color: #B9BCC3;
font-family: "Abraham TRIAL";
font-size: 16px;
line-height: 25px;
text-align: right;
}

input {
appearance: none;
width: 100%;
background-color: #ffffff;

font-family: "Abraham TRIAL";
font-size: 16px;
line-height: 25px;
height: 44px;
border-radius: 25px;
box-shadow: none;
padding: 0 20px;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Component } from '@angular/core';
import { DashboardsApiService } from '../dashboards-api.service';

@Component({
selector: 'app-dashboard-search-bar',
standalone: true,
imports: [],
templateUrl: './dashboard-search-bar.component.html',
styleUrl: './dashboard-search-bar.component.less'
})
export class DashboardSearchBarComponent {

constructor(public api: DashboardsApiService) { }

doSearch(event: Event) {
const el = event.target as HTMLInputElement;
this.api.search(el.value)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@if (selected == null) {
<ul class="list-group">
@for (result of api.searchResults(); track result.doc_id) {
<li class="list-group-item"
[innerHtml]='render(result)'
(click)='selected=result'
>
</li>
}
</ul>
} @else {
<ul class="list-group">
<li class="list-group-item selected">
<a (click)='selected=null'><strong>&times;</strong></a>&nbsp;
<span [innerHtml]='render(selected)'></span>
</li>
</ul>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
:host {
width: 100%;
padding: 0 20px;
max-width: 400px;
font-family: "Abraham TRIAL";

li {
cursor: pointer;

&.selected {
font-weight: 700;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Component } from '@angular/core';
import { DashboardsApiService } from '../dashboards-api.service';
import { Router } from '@angular/router';

@Component({
selector: 'app-dashboard-search-results',
standalone: true,
imports: [],
templateUrl: './dashboard-search-results.component.html',
styleUrl: './dashboard-search-results.component.less'
})
export class DashboardSearchResultsComponent {
template: string;
title: string;

constructor(public api: DashboardsApiService, private router: Router) { }

ngOnInit() {
this.template = this.api.config.result_template;
this.title = this.api.config.title;
}

render(item: any) {
return this.template.replace(/:([a-z][-a-z0-9_.]*)/ig, (match, name) => {
return item[name];
});
}

set selected(item) {
console.log('config', this.api.baseRoute);
if (item) {
this.router.navigate([...this.api.baseRoute, item.doc_id.split('/').join('__')], {queryParamsHandling: 'preserve'});
} else {
this.router.navigate(this.api.baseRoute, {queryParamsHandling: 'preserve'});
}
}

get selected() {
return this.api.selectedItem();
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<h2>{{api.config.title}}</h2>
<app-dashboard-search-bar></app-dashboard-search-bar>
<app-dashboard-search-results></app-dashboard-search-results>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
:host {
width: 100%;
display: flex;
flex-flow: column;
align-content: flex-start;
gap: 2px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Component } from '@angular/core';
import { DashboardSearchBarComponent } from '../dashboard-search-bar/dashboard-search-bar.component';
import { DashboardSearchResultsComponent } from '../dashboard-search-results/dashboard-search-results.component';
import { DashboardsApiService } from '../dashboards-api.service';

@Component({
selector: 'app-dashboard-search',
standalone: true,
imports: [
DashboardSearchBarComponent,
DashboardSearchResultsComponent
],
templateUrl: './dashboard-search.component.html',
styleUrl: './dashboard-search.component.less'
})
export class DashboardSearchComponent {

constructor(public api: DashboardsApiService) { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<ul class="nav nav-tabs">
@for (vis of api.config.visualizations; track vis.title) {
<li class="nav-item"
[class.active]="vis.title === selectVis"
>
<a class="nav-link"
(click)='selectedVis(vis.title)'>
@if (loadingStatus[vis.title]) {
<i class='fa fa-spinner fa-spin'></i>
}
{{vis.title}}
</a>
</li>
}
</ul>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
a {
cursor: pointer;
}
Loading

0 comments on commit 5a84b88

Please sign in to comment.