Compare commits

...

12 Commits

Author SHA1 Message Date
bc99e35c79 add github pipeline folder
All checks were successful
build / build (push) Successful in 3m1s
2025-03-11 10:09:54 +01:00
58de81e47c mae pipeline go brr
All checks were successful
build / build (push) Successful in 3m24s
2025-03-11 09:54:47 +01:00
b3bc1c4965 add db to struct
All checks were successful
build / windows (push) Successful in 2m22s
build / linux (push) Successful in 1m54s
2025-03-11 09:49:13 +01:00
d2164622c4 clip x overflow
All checks were successful
build / windows (push) Successful in 2m25s
build / linux (push) Successful in 4m19s
2025-03-10 09:12:27 +01:00
7bae1918c4 Revert "bump upload artifact to v4"
Some checks failed
build / windows (push) Has been cancelled
build / linux (push) Has been cancelled
This reverts commit e55904f8f2.
2025-03-07 15:53:32 +01:00
e55904f8f2 bump upload artifact to v4
Some checks failed
build / windows (push) Successful in 6m23s
build / linux (push) Failing after 4m3s
2025-03-07 15:36:00 +01:00
2b13e5c03a remove sub things and add view
All checks were successful
build / windows (push) Successful in 2m22s
build / linux (push) Successful in 2m3s
2025-03-07 15:23:33 +01:00
feb248e991 add a route 2025-03-07 15:22:44 +01:00
42e8605945 fix scroll issue
All checks were successful
build / windows (push) Successful in 2m32s
build / linux (push) Successful in 1m57s
2025-03-07 14:43:36 +01:00
bd3b0a3377 fix app title
All checks were successful
build / windows (push) Successful in 2m20s
build / linux (push) Successful in 1m54s
2025-03-03 13:52:58 +01:00
1a82a75aaf update readme
Some checks are pending
build / windows (push) Waiting to run
build / linux (push) Waiting to run
2025-03-03 13:51:34 +01:00
0f710b8d9f added workflow
All checks were successful
build / windows (push) Successful in 2m32s
build / linux (push) Successful in 1m52s
Reviewed-on: #1
2025-03-03 13:30:39 +01:00
19 changed files with 192 additions and 117 deletions

View File

@ -0,0 +1,36 @@
name: build
on:
push:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: https://github.com/actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: 1.24
- name: install apt dependencies
run: apt-get update && apt-get install -y mingw-w64 nsis nodejs libgtk-3-dev libwebkit2gtk-4.1-dev
- name: install pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: install wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: build for windows
run: env GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ CGO_CXXFLAGS="-IC:\msys64\mingw64\include" wails build -ldflags '-extldflags "-static"' -skipbindings -nsis
- name: Archive win bins
uses: actions/upload-artifact@v3
with:
name: windows-bins
path: build/bin
- name: build for linux
run: wails build -tags webkit2_41
- name: Archive linux bins
uses: actions/upload-artifact@v3
with:
name: linux-bins
path: build/bin

36
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: build
on:
push:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: https://github.com/actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: 1.24
- name: install apt dependencies
run: apt-get update && apt-get install -y mingw-w64 nsis nodejs libgtk-3-dev libwebkit2gtk-4.1-dev
- name: install pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: install wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: build for windows
run: env GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ CGO_CXXFLAGS="-IC:\msys64\mingw64\include" wails build -ldflags '-extldflags "-static"' -skipbindings -nsis
- name: Archive win bins
uses: actions/upload-artifact@v3
with:
name: windows-bins
path: build/bin
- name: build for linux
run: wails build -tags webkit2_41
- name: Archive linux bins
uses: actions/upload-artifact@v3
with:
name: linux-bins
path: build/bin

View File

@ -1,5 +1,12 @@
# wails template
This is my wails-template i am using for the *ICT-Regiomeisterschaften 2025*.
It uses vanilla svelte with vite in the Frontend. For styling i use Flowbyte and TailwindCSS. I have setup a pipeline to build windows and linux binaries. For windows i have a working installer.
Feel free to use this template on your own. To set it up just run ```setup.sh```. If you're not using gitea you will have to rename the ```.gitea``` folder to ```.github```, to use the pipelines.
Enjoy :)
# README
## Links

6
app.go
View File

@ -5,17 +5,19 @@ import (
"fmt"
"github.com/gen2brain/beeep"
"gorm.io/gorm"
)
// App struct
type App struct {
ctx context.Context
db *gorm.DB
}
// NewApp creates a new App application struct
func NewApp() *App {
func NewApp(db *gorm.DB) *App {
return &App{}
return &App{db: db}
}
// startup is called when the app starts. The context is saved

View File

@ -1,12 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
<title>wails-svelte-tailwind-ts</title>
</head>
<body>
<div id="app"></div>
<script src="./src/main.ts" type="module"></script>
</body>
</html>

View File

@ -1,14 +1,20 @@
<script lang="ts">
import "./app.css";
import { Router, Route, Link, navigate } from "svelte-routing";
import Home from "./routes/Home.svelte";
import Things from "./routes/Things.svelte";
import "./app.css";
import { Navbar, DarkMode, Heading } from "flowbite-svelte";
import { Navbar, DarkMode } from "flowbite-svelte";
import { HomeOutline } from "flowbite-svelte-icons";
import Thing from "./routes/Thing.svelte";
let url: string = $state("/");
$effect(() => {
console.log(url);
});
</script>
<main class="flex-col h-screen items-center bg-gray-50 dark:bg-gray-900">
<div
class="flex flex-col h-screen w-screen items-center bg-gray-50 dark:bg-gray-900 overflow-clip"
>
<Router bind:url>
<Navbar class="border-b">
<button
@ -20,6 +26,13 @@
</button>
<DarkMode />
</Navbar>
<Route path="/"><Home /></Route>
</Router>
<main
class="size-full max-h-full max-w-full overflow-y-scroll overflow-x-clip"
>
<Route path="/"><Things /></Route>
<Route path="/things/:id" let:params>
<Thing thingID={parseInt(params.id)} />
</Route>
</main>
</Router>
</div>

View File

@ -0,0 +1,26 @@
<script lang="ts">
import { GetThings } from "../../wailsjs/go/things/Service";
import { model } from "../../wailsjs/go/models";
import { onMount } from "svelte";
import { Heading } from "flowbite-svelte";
let { thingID }: { thingID: number } = $props();
let thing: model.Thing = $state(new model.Thing());
function update() {
GetThings().then((ts) => {
ts.forEach((t) => {
if (t.ID === thingID) {
thing = t;
}
});
});
}
onMount(update);
</script>
<div class="m-5">
<Heading>
{thing.Name}
</Heading>
</div>

View File

@ -17,6 +17,7 @@
TableBodyRow,
TableBodyCell,
} from "flowbite-svelte";
import { navigate } from "svelte-routing";
let name: string = $state();
let thingsList: model.Thing[] = $state([]);
@ -33,10 +34,6 @@
name = "";
}
function deleteEvent(id: number) {
DeleteThing(id).then(update);
}
onMount(update);
</script>
@ -53,6 +50,7 @@
<TableHead>
<TableHeadCell>ID</TableHeadCell>
<TableHeadCell>Name</TableHeadCell>
<TableHeadCell>View</TableHeadCell>
<TableHeadCell>Delete</TableHeadCell>
</TableHead>
<TableBody>
@ -65,8 +63,13 @@
<TableBodyCell>
{t.Name}
</TableBodyCell>
<TableBodyCell>
<Button on:click={(_) => deleteEvent(t.ID)}>Delete</Button>
<Button onclick={() => navigate(`/things/${t.ID}`)}>View</Button>
</TableBodyCell>
<TableBodyCell>
<Button onclick={() => DeleteThing(t.ID).then(update)}>Delete</Button>
</TableBodyCell>
</TableBodyRow>
{/each}

View File

@ -14,7 +14,24 @@
*/
"allowJs": true,
"checkJs": true,
"isolatedModules": true
"isolatedModules": true,
"paths": {
"@/*": [
"src/*"
],
"@assets/*": [
"src/assets/*"
],
"@components/*": [
"src/components/*"
],
"@routes/*": [
"src/routes/*"
],
"@wails/*": [
"src/wailsjs/*"
]
}
},
"include": [
"src/**/*.d.ts",

View File

@ -1,7 +1,17 @@
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import path from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [svelte()]
plugins: [svelte()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@assets': path.resolve(__dirname, './src/assets'),
'@components': path.resolve(__dirname, './src/components'),
'@routes': path.resolve(__dirname, './src/routes'),
'@wails': path.resolve(__dirname, './src/wailsjs'),
},
},
})

View File

@ -1,25 +1,8 @@
export namespace model {
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 {
ID: number;
Name: string;
Subthings: SubThing[];
static createFrom(source: any = {}) {
return new Thing(source);
@ -29,25 +12,6 @@ export namespace model {
if ('string' === typeof source) source = JSON.parse(source);
this.ID = source["ID"];
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,14 +2,8 @@
// This file is automatically generated. DO NOT EDIT
import {model} 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 GetSubThings(arg1:number):Promise<Array<model.SubThing>>;
export function GetThings():Promise<Array<model.Thing>>;
export function NewThing(arg1:string):Promise<void>;

View File

@ -2,22 +2,10 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// 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) {
return window['go']['things']['Service']['DeleteThing'](arg1);
}
export function GetSubThings(arg1) {
return window['go']['things']['Service']['GetSubThings'](arg1);
}
export function GetThings() {
return window['go']['things']['Service']['GetThings']();
}

6
go.mod
View File

@ -1,8 +1,6 @@
module wails-template
go 1.23.0
toolchain go1.24.0
go 1.24.0
require (
github.com/gen2brain/beeep v0.0.0-20240516210008-9c006672e7f4
@ -40,7 +38,7 @@ require (
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/wailsapp/go-webview2 v1.0.19 // indirect
github.com/wailsapp/mimetype v1.4.1 // indirect
golang.org/x/crypto v0.34.0 // indirect
golang.org/x/crypto v0.35.0 // indirect
golang.org/x/net v0.35.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.22.0 // indirect

4
go.sum
View File

@ -70,8 +70,8 @@ github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhw
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
github.com/wailsapp/wails/v2 v2.10.1 h1:QWHvWMXII2nI/nXz77gpPG8P3ehl6zKe+u4su5BWIns=
github.com/wailsapp/wails/v2 v2.10.1/go.mod h1:zrebnFV6MQf9kx8HI4iAv63vsR5v67oS7GTEZ7Pz1TY=
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
golang.org/x/crypto v0.34.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=

View File

@ -15,13 +15,13 @@ var assets embed.FS
func main() {
// Create an instance of the app structure
app := NewApp()
db := model.InitDB()
app := NewApp(db)
things := &things.Service{DB: db}
// Create application with options
err := wails.Run(&options.App{
Title: "wails-svelte-tailwind-ts",
Title: "wails-template",
Width: 1024,
Height: 768,
AssetServer: &assetserver.Options{

View File

@ -2,6 +2,8 @@ package model
import (
"log"
"os"
"path"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
@ -10,20 +12,17 @@ import (
type Thing struct {
ID int
Name string
Subthings []SubThing
}
type SubThing struct {
ID int
ThingID int
Name string
}
func InitDB() *gorm.DB {
db, err := gorm.Open(sqlite.Open("things.db"))
home, err := os.UserHomeDir()
if err != nil {
panic(err)
}
db, err := gorm.Open(sqlite.Open(path.Join(home, "things.db")))
if err != nil {
log.Panic(err)
}
db.AutoMigrate(&Thing{}, &SubThing{})
db.AutoMigrate(&Thing{})
return db
}

View File

@ -4,7 +4,7 @@
CURRENT_DIR_NAME=$(basename "$PWD")
# Define the files to be updated
FILES=("main.go" "go.mod" "wails.json")
FILES=("main.go" "go.mod" "wails.json" "things/resource.go")
# String to be replaced
OLD_STRING="wails-template"

View File

@ -31,24 +31,3 @@ func (s *Service) DeleteThing(id int) {
log.Fatal(err)
}
}
func (s *Service) GetSubThings(thingID int) (subthings []model.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(&model.SubThing{
ThingID: thingID,
Name: name,
}).Error; err != nil {
log.Fatal(err)
}
}
func (s *Service) DeleteSubThing(id int) {
if err := s.DB.Delete(model.SubThing{}, id).Error; err != nil {
log.Fatal(err)
}
}