associations

This commit is contained in:
schreifuchs 2025-02-05 09:29:18 +01:00
parent 9d8db9efdc
commit 69e496506c
9 changed files with 231 additions and 23 deletions

View File

@ -20,11 +20,18 @@
TableBody, TableBody,
TableBodyRow, TableBodyRow,
TableBodyCell, TableBodyCell,
Modal,
} from "flowbite-svelte"; } from "flowbite-svelte";
import SubThings from "./lib/SubThings.svelte";
let name: string; let name: string;
let thingsList: things.Thing[] = []; let thingsList: things.Thing[] = [];
let thingID: number;
let subthingOpened: boolean = false;
$: console.log(subthingOpened);
function update() { function update() {
GetThings().then((ts) => { GetThings().then((ts) => {
thingsList = ts; thingsList = ts;
@ -37,7 +44,7 @@
name = ""; name = "";
} }
function deleteEvent(id: number) { function deleteThing(id: number) {
DeleteThing(id).then(update); DeleteThing(id).then(update);
} }
@ -79,10 +86,24 @@
{t.Name} {t.Name}
</TableBodyCell> </TableBodyCell>
<TableBodyCell> <TableBodyCell>
<Button on:click={(_) => deleteEvent(t.ID)}>Delete</Button> <Button on:click={(_) => deleteThing(t.ID)}>Delete</Button>
<Button
on:click={(_) => {
thingID = t.ID;
subthingOpened = true;
}}>Edit</Button
>
</TableBodyCell> </TableBodyCell>
</TableBodyRow> </TableBodyRow>
{/each} {/each}
</TableBody> </TableBody>
</Table> </Table>
<Modal bind:open={subthingOpened} size="xl">
<SubThings bind:thingID />
<Button
on:click={(_) => {
subthingOpened = false;
}}>Close</Button
>
</Modal>
</main> </main>

View File

@ -0,0 +1,82 @@
<script lang="ts">
import {
Button,
Input,
Label,
Table,
TableBody,
TableBodyCell,
TableBodyRow,
TableHead,
TableHeadCell,
} from "flowbite-svelte";
import { things } from "../../wailsjs/go/models";
import {
AddSubThing,
DeleteSubThing,
GetSubThings,
} from "../../wailsjs/go/things/Service";
export let thingID: null | number = null;
let subThings: things.SubThing[] = [];
function update() {
if (thingID) {
GetSubThings(thingID).then((ts) => {
subThings = ts;
});
}
}
$: {
thingID = thingID;
update();
}
let name: string;
function submit(e: Event) {
e.preventDefault();
AddSubThing(thingID, name).then(update);
name = "";
}
function deleteSubThing(id: number) {
DeleteSubThing(id).then(update);
}
</script>
<form class="max-w-96 m-5 grid-cols-1 gap-10" on:submit={submit}>
<div class="m-5">
<Label for="first_name" class="mb-2">First name</Label>
<Input type="text" placeholder="John" bind:value={name} required />
</div>
<div class="m-5">
<Button type="submit">Submit</Button>
</div>
</form>
<Table class="m-5">
<TableHead>
<TableHeadCell>ID</TableHeadCell>
<TableHeadCell>Name</TableHeadCell>
<TableHeadCell>Delete</TableHeadCell>
</TableHead>
<TableBody>
{#each subThings as t}
<TableBodyRow>
<TableBodyCell>
{t.ID}
</TableBodyCell>
<TableBodyCell>
{t.Name}
</TableBodyCell>
<TableBodyCell>
<Button on:click={(_) => deleteSubThing(t.ID)}>Delete</Button>
</TableBodyCell>
</TableBodyRow>
{/each}
</TableBody>
</Table>

View File

@ -1,8 +1,25 @@
export namespace things { export namespace things {
export class SubThing {
ID: number;
ThingID: number;
Name: string;
static createFrom(source: any = {}) {
return new SubThing(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.ID = source["ID"];
this.ThingID = source["ThingID"];
this.Name = source["Name"];
}
}
export class Thing { export class Thing {
ID: number; ID: number;
Name: string; Name: string;
Subthings: SubThing[];
static createFrom(source: any = {}) { static createFrom(source: any = {}) {
return new Thing(source); return new Thing(source);
@ -12,6 +29,25 @@ export namespace things {
if ('string' === typeof source) source = JSON.parse(source); if ('string' === typeof source) source = JSON.parse(source);
this.ID = source["ID"]; this.ID = source["ID"];
this.Name = source["Name"]; this.Name = source["Name"];
this.Subthings = this.convertValues(source["Subthings"], SubThing);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
} }
} }

View File

@ -2,8 +2,14 @@
// This file is automatically generated. DO NOT EDIT // This file is automatically generated. DO NOT EDIT
import {things} from '../models'; import {things} from '../models';
export function AddSubThing(arg1:number,arg2:string):Promise<void>;
export function DeleteSubThing(arg1:number):Promise<void>;
export function DeleteThing(arg1:number):Promise<void>; export function DeleteThing(arg1:number):Promise<void>;
export function GetSubThings(arg1:number):Promise<Array<things.SubThing>>;
export function GetThings():Promise<Array<things.Thing>>; export function GetThings():Promise<Array<things.Thing>>;
export function NewThing(arg1:string):Promise<void>; export function NewThing(arg1:string):Promise<void>;

View File

@ -2,10 +2,22 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT // This file is automatically generated. DO NOT EDIT
export function AddSubThing(arg1, arg2) {
return window['go']['things']['Service']['AddSubThing'](arg1, arg2);
}
export function DeleteSubThing(arg1) {
return window['go']['things']['Service']['DeleteSubThing'](arg1);
}
export function DeleteThing(arg1) { export function DeleteThing(arg1) {
return window['go']['things']['Service']['DeleteThing'](arg1); return window['go']['things']['Service']['DeleteThing'](arg1);
} }
export function GetSubThings(arg1) {
return window['go']['things']['Service']['GetSubThings'](arg1);
}
export function GetThings() { export function GetThings() {
return window['go']['things']['Service']['GetThings'](); return window['go']['things']['Service']['GetThings']();
} }

11
go.mod
View File

@ -2,7 +2,11 @@ module wails-svelte-tailwind-ts
go 1.23 go 1.23
require github.com/wailsapp/wails/v2 v2.9.2 require (
github.com/wailsapp/wails/v2 v2.9.2
gorm.io/driver/sqlite v1.5.7
gorm.io/gorm v1.25.12
)
require ( require (
github.com/bep/debounce v1.2.1 // indirect github.com/bep/debounce v1.2.1 // indirect
@ -10,6 +14,8 @@ require (
github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/labstack/echo/v4 v4.10.2 // indirect github.com/labstack/echo/v4 v4.10.2 // indirect
github.com/labstack/gommon v0.4.0 // indirect github.com/labstack/gommon v0.4.0 // indirect
github.com/leaanthony/go-ansi-parser v1.6.0 // indirect github.com/leaanthony/go-ansi-parser v1.6.0 // indirect
@ -18,6 +24,7 @@ require (
github.com/leaanthony/u v1.1.0 // indirect github.com/leaanthony/u v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-sqlite3 v1.14.24 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.4.4 // indirect github.com/rivo/uniseg v0.4.4 // indirect
@ -31,7 +38,7 @@ require (
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
golang.org/x/net v0.25.0 // indirect golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect golang.org/x/text v0.22.0 // indirect
) )
// replace github.com/wailsapp/wails/v2 v2.9.2 => /Users/u80864958/go/pkg/mod // replace github.com/wailsapp/wails/v2 v2.9.2 => /Users/u80864958/go/pkg/mod

14
go.sum
View File

@ -11,6 +11,10 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck= github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs= github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k= github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
@ -35,6 +39,8 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -84,11 +90,15 @@ golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=

BIN
things.db Normal file

Binary file not shown.

View File

@ -1,43 +1,77 @@
package things package things
import "slices" import (
"log"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type Thing struct { type Thing struct {
ID int ID int
Name string Name string
Subthings []SubThing
}
type SubThing struct {
ID int
ThingID int
Name string
} }
type Service struct { type Service struct {
things map[int]Thing db *gorm.DB
maxID int
} }
func NewThingsService() *Service { func NewThingsService() *Service {
db, err := gorm.Open(sqlite.Open("things.db"))
if err != nil {
log.Panic(err)
}
db.AutoMigrate(&Thing{}, &SubThing{})
return &Service{ return &Service{
things: make(map[int]Thing), db: db,
} }
} }
func (s *Service) NewThing(name string) { func (s *Service) NewThing(name string) {
s.maxID++ if err := s.db.Save(&Thing{Name: name}).Error; err != nil {
s.things[s.maxID] = Thing{ log.Fatal(err)
Name: name,
ID: s.maxID,
} }
print(name) print(name)
} }
func (s *Service) GetThings() []Thing { func (s *Service) GetThings() (things []Thing) {
things := make([]Thing, 0, len(s.things)) if err := s.db.Find(&things).Error; err != nil {
for _, t := range s.things { log.Fatal(err)
things = append(things, t)
} }
slices.SortFunc(things, func(a, b Thing) int { return a.ID - b.ID })
return things return things
} }
func (s *Service) DeleteThing(id int) { func (s *Service) DeleteThing(id int) {
delete(s.things, id) if err := s.db.Delete(Thing{}, id).Error; err != nil {
log.Fatal(err)
}
}
func (s *Service) GetSubThings(thingID int) (subthings []SubThing) {
if err := s.db.Where("thing_id = ?", thingID).Find(&subthings).Error; err != nil {
log.Fatal(err)
}
return
}
func (s *Service) AddSubThing(thingID int, name string) {
if err := s.db.Save(&SubThing{
ThingID: thingID,
Name: name,
}).Error; err != nil {
log.Fatal(err)
}
}
func (s *Service) DeleteSubThing(id int) {
if err := s.db.Delete(SubThing{}, id).Error; err != nil {
log.Fatal(err)
}
} }