A few tweaks
This commit is contained in:
31
app.go
31
app.go
@@ -2,8 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"git.cems.dev/cdricms/bdooc/proto"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
@@ -52,13 +50,6 @@ func (a *App) GetEmployees(path string, limit, page uint, column, query *string)
|
||||
return a.employees.Employees[page*limit : page*limit+limit], nil
|
||||
}
|
||||
|
||||
func (a *App) SaveData(data []uint8, filename string) {
|
||||
err := proto.SaveToFile(data, filename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) GetProtoPath() string {
|
||||
return a.OpenPath([]runtime.FileFilter{{
|
||||
DisplayName: "Proto binary file",
|
||||
@@ -78,8 +69,22 @@ func (a *App) OpenPath(filters []runtime.FileFilter) string {
|
||||
return path
|
||||
}
|
||||
|
||||
func (a *App) IsPathValid(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
fmt.Println(path)
|
||||
return !os.IsNotExist(err)
|
||||
type FunctionAgg string
|
||||
|
||||
const (
|
||||
AVG = FunctionAgg("AVG")
|
||||
SUM = FunctionAgg("SUM")
|
||||
)
|
||||
|
||||
func (a *App) AggregateByColumn(groupBy proto.EmployeeField, on proto.EmployeeField, function FunctionAgg) map[string]float64 {
|
||||
return proto.AggregateByColumn(a.employees, proto.EmployeeField(proto.SnakeCaseToPascalCase(string(groupBy))), func(ep proto.EmployeePList) float64 {
|
||||
switch function {
|
||||
case AVG:
|
||||
return proto.Average(ep, proto.EmployeeField(proto.SnakeCaseToPascalCase(string(on))))
|
||||
case SUM:
|
||||
return proto.Sum(ep, proto.EmployeeField(proto.SnakeCaseToPascalCase(string(on))))
|
||||
}
|
||||
|
||||
return 0.0
|
||||
})
|
||||
}
|
||||
|
||||
109
frontend/src/Aggregation.svelte
Normal file
109
frontend/src/Aggregation.svelte
Normal file
@@ -0,0 +1,109 @@
|
||||
<script lang="ts">
|
||||
import Modal from "./Modal.svelte";
|
||||
import { AggregateByColumn } from "../wailsjs/go/main/App.js";
|
||||
export let isOpen: boolean;
|
||||
export let keys: string[];
|
||||
|
||||
let group: string | null = null;
|
||||
let onColumn: string | null = null;
|
||||
let func: string | null = null;
|
||||
|
||||
let promise: ReturnType<typeof AggregateByColumn>;
|
||||
|
||||
async function Aggregate() {
|
||||
if (!group || !onColumn || !func) return;
|
||||
try {
|
||||
const res = await AggregateByColumn(group, onColumn, func);
|
||||
return res;
|
||||
} catch (error) {
|
||||
throw error.message;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal
|
||||
{isOpen}
|
||||
onClose={() => {
|
||||
isOpen = false;
|
||||
}}
|
||||
>
|
||||
<section>
|
||||
<p>Aggregation</p>
|
||||
<div>
|
||||
<label for="group">Group by: </label>
|
||||
<select bind:value={group} name="group" id="">
|
||||
{#each keys as key}
|
||||
<option value={key}>{key}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="on-column">On: </label>
|
||||
<select bind:value={onColumn} name="on-column" id="">
|
||||
{#each keys as key}
|
||||
<option value={key}>{key}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<label for="function">Using: </label>
|
||||
<select bind:value={func} name="function" id="">
|
||||
<option value="AVG">Average</option>
|
||||
<option value="SUM">SUM</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="button" on:click={() => (promise = Aggregate())}
|
||||
>Aggregate</button
|
||||
>
|
||||
</section>
|
||||
{#if promise}
|
||||
<section>
|
||||
{#await promise}
|
||||
<p>Loading...</p>
|
||||
{:then res}
|
||||
<table class="agg-table">
|
||||
<tr>
|
||||
<th>{group}</th>
|
||||
<th>{func} of {onColumn}</th>
|
||||
</tr>
|
||||
{#each Object.entries(res) as [key, value]}
|
||||
<tr>
|
||||
<td>{key}</td>
|
||||
<td>{value}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</table>
|
||||
{:catch error}
|
||||
<p>{error}</p>
|
||||
{/await}
|
||||
</section>
|
||||
{/if}
|
||||
</Modal>
|
||||
|
||||
<style>
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #343434;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background-color: #110909;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
@@ -1,33 +1,44 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import * as rt from "../wailsjs/runtime/runtime"
|
||||
import * as rt from "../wailsjs/runtime/runtime";
|
||||
|
||||
import Table from "./Table.svelte";
|
||||
import { proto } from "../wailsjs/go/models";
|
||||
import Aggregation from "./Aggregation.svelte";
|
||||
|
||||
let path: string;
|
||||
let page = 0;
|
||||
|
||||
let isAggregate = false;
|
||||
|
||||
let limitReached: boolean;
|
||||
|
||||
$: console.log(limitReached)
|
||||
$: console.log(limitReached);
|
||||
|
||||
const keys: string[] = Object.keys(new proto.Employee());
|
||||
|
||||
onMount(async () => {
|
||||
rt.EventsOn("proto-opened", (_path: string) => {
|
||||
path = _path;
|
||||
})
|
||||
});
|
||||
|
||||
rt.EventsOn("csv-converted", (_path: string) => {
|
||||
console.log(_path)
|
||||
})
|
||||
console.log(_path);
|
||||
});
|
||||
|
||||
rt.EventsOn("aggregation", () => {
|
||||
isAggregate = true;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<main>
|
||||
{#if path}
|
||||
<Table {path} {page} bind:limitReached={limitReached} />
|
||||
<Table {path} bind:page bind:limitReached />
|
||||
<button disabled={page < 1} on:click={() => page--}>Prev</button>
|
||||
<span>{page+1}</span>
|
||||
<span>{page + 1}</span>
|
||||
<button disabled={limitReached} on:click={() => page++}>Next</button>
|
||||
<Aggregation bind:isOpen={isAggregate} {keys} />
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
|
||||
35
frontend/src/Modal.svelte
Normal file
35
frontend/src/Modal.svelte
Normal file
@@ -0,0 +1,35 @@
|
||||
<script lang="ts">
|
||||
export let isOpen: boolean;
|
||||
export let onClose: () => void;
|
||||
</script>
|
||||
|
||||
{#if isOpen}
|
||||
<dialog class="backdrop" open={isOpen}>
|
||||
<div class="dialog">
|
||||
<slot />
|
||||
<button on:click={() => onClose()}>Close</button>
|
||||
</div>
|
||||
</dialog>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
background-color: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { GetEmployees } from "../wailsjs/go/main/App.js";
|
||||
// import type { proto } from "../wailsjs/go/models";
|
||||
// let employees: proto.Employee[] = [];
|
||||
|
||||
export let path: string;
|
||||
export let page: number;
|
||||
let limit: number = 10;
|
||||
@@ -12,11 +11,17 @@
|
||||
let column: string | null = null;
|
||||
let query: string | null = null;
|
||||
|
||||
async function listEmployees(path: string, limit: number, page: number, column?: string, query?: string) {
|
||||
async function listEmployees(
|
||||
path: string,
|
||||
limit: number,
|
||||
page: number,
|
||||
column?: string,
|
||||
query?: string,
|
||||
) {
|
||||
try {
|
||||
const employees = await GetEmployees(path, limit, page, column, query);
|
||||
limitReached = employees.length < limit;
|
||||
return employees
|
||||
return employees;
|
||||
} catch (error) {
|
||||
throw error.message;
|
||||
}
|
||||
@@ -40,10 +45,16 @@
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => {
|
||||
page = 0;
|
||||
column = _column;
|
||||
query = _query;
|
||||
}}>Search</button
|
||||
>
|
||||
<button type="button" on:click={() => {
|
||||
query = ""
|
||||
column = null
|
||||
page = 0
|
||||
}}>Reset</button>
|
||||
</div>
|
||||
<table>
|
||||
<tr>
|
||||
|
||||
7
frontend/wailsjs/go/main/App.d.ts
vendored
7
frontend/wailsjs/go/main/App.d.ts
vendored
@@ -1,14 +1,13 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
import {proto} from '../models';
|
||||
import {main} from '../models';
|
||||
import {frontend} from '../models';
|
||||
|
||||
export function AggregateByColumn(arg1:proto.EmployeeField,arg2:proto.EmployeeField,arg3:main.FunctionAgg):Promise<{[key: string]: number}>;
|
||||
|
||||
export function GetEmployees(arg1:string,arg2:number,arg3:number,arg4:any,arg5:any):Promise<Array<proto.Employee>>;
|
||||
|
||||
export function GetProtoPath():Promise<string>;
|
||||
|
||||
export function IsPathValid(arg1:string):Promise<boolean>;
|
||||
|
||||
export function OpenPath(arg1:Array<frontend.FileFilter>):Promise<string>;
|
||||
|
||||
export function SaveData(arg1:Array<number>,arg2:string):Promise<void>;
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export function AggregateByColumn(arg1, arg2, arg3) {
|
||||
return window['go']['main']['App']['AggregateByColumn'](arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
export function GetEmployees(arg1, arg2, arg3, arg4, arg5) {
|
||||
return window['go']['main']['App']['GetEmployees'](arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
@@ -10,14 +14,6 @@ export function GetProtoPath() {
|
||||
return window['go']['main']['App']['GetProtoPath']();
|
||||
}
|
||||
|
||||
export function IsPathValid(arg1) {
|
||||
return window['go']['main']['App']['IsPathValid'](arg1);
|
||||
}
|
||||
|
||||
export function OpenPath(arg1) {
|
||||
return window['go']['main']['App']['OpenPath'](arg1);
|
||||
}
|
||||
|
||||
export function SaveData(arg1, arg2) {
|
||||
return window['go']['main']['App']['SaveData'](arg1, arg2);
|
||||
}
|
||||
|
||||
5
main.go
5
main.go
@@ -71,6 +71,11 @@ func main() {
|
||||
runtime.EventsEmit(app.ctx, "csv-converted", filePath)
|
||||
})
|
||||
|
||||
analysisMenu :=appMenu.AddSubmenu("Analysis")
|
||||
analysisMenu.AddText("Aggregation", keys.CmdOrCtrl("a"), func(_ *menu.CallbackData) {
|
||||
runtime.EventsEmit(app.ctx, "aggregation")
|
||||
})
|
||||
|
||||
// Create application with options
|
||||
err := wails.Run(&options.App{
|
||||
Title: "bdooc-t",
|
||||
|
||||
Reference in New Issue
Block a user