You've already forked reloading-manager
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
d1d6d24dbb
|
|||
|
6e908bad17
|
|||
|
f6ed88fd78
|
|||
|
b122fca494
|
|||
|
1cc6d5ece4
|
|||
|
74ea300f80
|
|||
|
f8958dfbef
|
|||
|
22e045730f
|
|||
|
a4edafdd2e
|
|||
|
f8974acab5
|
|||
|
ac3cd505bf
|
|||
|
03762a0be7
|
|||
|
0f915ccd82
|
|||
|
dd383b6fb3
|
|||
|
e484aa7e31
|
|||
|
3c60c1b012
|
|||
|
c5f1f32b44
|
|||
|
343abbb801
|
@@ -10,13 +10,6 @@ jobs:
|
|||||||
name: 🖼️ 🔨 Build Frontend
|
name: 🖼️ 🔨 Build Frontend
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: 🛡️ 🔒 Add Siteworx CA Certificates
|
|
||||||
run: |
|
|
||||||
apt update && apt install -yq ca-certificates curl
|
|
||||||
curl -Ls https://siteworxpro.com/hosted/Siteworx+Root+CA.pem -o /usr/local/share/ca-certificates/sw.crt
|
|
||||||
update-ca-certificates
|
|
||||||
|
|
||||||
- name: 📖 🔍 Checkout Repository Code
|
- name: 📖 🔍 Checkout Repository Code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
@@ -62,13 +55,6 @@ jobs:
|
|||||||
name: 🖥️ 🔨 Build Backend
|
name: 🖥️ 🔨 Build Backend
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: 🛡️🔒 Add Siteworx CA Certificates
|
|
||||||
run: |
|
|
||||||
apt update && apt install -yq ca-certificates curl
|
|
||||||
curl -Ls https://siteworxpro.com/hosted/Siteworx+Root+CA.pem -o /usr/local/share/ca-certificates/sw.crt
|
|
||||||
update-ca-certificates
|
|
||||||
|
|
||||||
- name: 📖🔍 Checkout Repository Code
|
- name: 📖🔍 Checkout Repository Code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
@@ -111,13 +97,6 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [BuildFrontend, BuildBackend]
|
needs: [BuildFrontend, BuildBackend]
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: 🛡️🔒 Add Siteworx CA Certificates
|
|
||||||
run: |
|
|
||||||
apt update && apt install -yq ca-certificates curl
|
|
||||||
curl -Ls https://siteworxpro.com/hosted/Siteworx+Root+CA.pem -o /usr/local/share/ca-certificates/sw.crt
|
|
||||||
update-ca-certificates
|
|
||||||
|
|
||||||
- name: 📖 🔍 Checkout Repository Code
|
- name: 📖 🔍 Checkout Repository Code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
@@ -127,18 +106,31 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "## Do not edit this file directly. It is auto-generated by the script." > argocd/deployment/deployment.yml
|
echo "## Do not edit this file directly. It is auto-generated by the script." > argocd/deployment/deployment.yml
|
||||||
sed "s|__TAG__|${{ gitea.ref_name }}|g" argocd/template/deployment.yml >> argocd/deployment/deployment.yml
|
sed "s|__TAG__|${{ gitea.ref_name }}|g" argocd/template/deployment.yml >> argocd/deployment/deployment.yml
|
||||||
#
|
|
||||||
# - name: 💾 ✅ Commit Updated Manifest
|
- name: 📤 📦 Recommit Build Artifacts
|
||||||
# uses: EndBug/add-and-commit@v9
|
uses: addnab/docker-run-action@v3
|
||||||
# with:
|
with:
|
||||||
# new_branch: release/${{ gitea.ref_name }}-deploy
|
image: alpine/git
|
||||||
# add: argocd/deployment/deployment.yml
|
options: --volumes-from ${{ env.JOB_CONTAINER_NAME }} -w ${{ gitea.workspace }}
|
||||||
# author_name: "GitHub Action 🤖"
|
run: |
|
||||||
# author_email: gitia@siteworxpro.com
|
mkdir -p ~/.ssh
|
||||||
# message: "📝 🔄 Update deployment manifest with new image tags"
|
chmod 700 ~/.ssh
|
||||||
|
ssh-keyscan -H gitea.siteworxpro.com >> ~/.ssh/known_hosts
|
||||||
|
echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
eval "$(ssh-agent -s)"
|
||||||
|
ssh-add ~/.ssh/id_rsa
|
||||||
|
git config --global user.email "gitea@siteworxpro.com"
|
||||||
|
git config --global user.name "Gitea-Runner via Gitea Actions"
|
||||||
|
git config --global push.autoSetupRemote true
|
||||||
|
git remote rm origin && git remote add origin "git@gitea.siteworxpro.com:siteworxpro/reloading-manager.git"
|
||||||
|
git add -f "argocd/deployment/*" || true
|
||||||
|
git checkout -b release/${{ gitea.ref_name }}-deploy || git checkout release/${{ gitea.ref_name }}-deploy
|
||||||
|
git commit -m "Build Auto Commit" || echo "No changes to commit"
|
||||||
|
git push origin HEAD:${{ gitea.ref_name }} -o ci.skip || echo "No changes to push"
|
||||||
|
|
||||||
- name: 🚀 ✨ Create Pull Request
|
- name: 🚀 ✨ Create Pull Request
|
||||||
uses: infinilbas/gitea-pr@v0
|
uses: peter-evans/create-pull-request@v7
|
||||||
env:
|
env:
|
||||||
NODE_TLS_REJECT_UNAUTHORIZED: 0
|
NODE_TLS_REJECT_UNAUTHORIZED: 0
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
default: 'true'
|
default: 'true'
|
||||||
push:
|
push:
|
||||||
|
paths-ignore:
|
||||||
|
- argocd/**/*
|
||||||
branches:
|
branches:
|
||||||
- "*"
|
- "*"
|
||||||
|
|
||||||
@@ -38,6 +40,29 @@ jobs:
|
|||||||
cd frontend
|
cd frontend
|
||||||
npm run build
|
npm run build
|
||||||
|
|
||||||
|
golangci-lint:
|
||||||
|
name: 🧪 🐹 GolangCI-Lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: 🛡️ 🔒 Add Siteworx CA Certificates
|
||||||
|
run: |
|
||||||
|
apt update && apt install -yq ca-certificates curl
|
||||||
|
curl -Ls https://siteworxpro.com/hosted/Siteworx+Root+CA.pem -o /usr/local/share/ca-certificates/sw.crt
|
||||||
|
update-ca-certificates
|
||||||
|
- name: 📖 🔍 Checkout Repository Code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
- name: ⚙️ 🐹 Set up Go Environment
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: '1.25.6'
|
||||||
|
cache: true
|
||||||
|
- name: ✅ 🧪 Run GolangCI-Lint
|
||||||
|
uses: golangci/golangci-lint-action@v8.0.0
|
||||||
|
with:
|
||||||
|
working-directory: backend
|
||||||
|
|
||||||
test-go:
|
test-go:
|
||||||
env:
|
env:
|
||||||
GOPRIVATE: 'git.siteworxpro.com'
|
GOPRIVATE: 'git.siteworxpro.com'
|
||||||
@@ -53,7 +78,7 @@ jobs:
|
|||||||
- name: ⚙️ 🐹 Set up Go Environment
|
- name: ⚙️ 🐹 Set up Go Environment
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: '1.24.3'
|
go-version: '1.25.6'
|
||||||
cache: true
|
cache: true
|
||||||
- name: 📖 🔍 Checkout Repository Code
|
- name: 📖 🔍 Checkout Repository Code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ kind: ConfigMap
|
|||||||
metadata:
|
metadata:
|
||||||
name: reloading-cm
|
name: reloading-cm
|
||||||
data:
|
data:
|
||||||
DB_HOST: "192.168.1.30"
|
DB_HOST: "postgres.postgres.svc.cluster.local"
|
||||||
DB_DATABASE: "loading"
|
DB_DATABASE: "loading"
|
||||||
DB_USER: "loading"
|
DB_USER: "loading"
|
||||||
DB_PASSWORD: "loading"
|
DB_PASSWORD: "loading"
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ spec:
|
|||||||
- name: siteworxpro
|
- name: siteworxpro
|
||||||
containers:
|
containers:
|
||||||
- name: frontend
|
- name: frontend
|
||||||
image: scr.siteworxpro.com/reloading-manager/frontend:v0.0.32
|
image: scr.siteworxpro.com/reloading-manager/frontend:v0.0.37
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 80
|
||||||
- name: backend
|
- name: backend
|
||||||
image: scr.siteworxpro.com/reloading-manager/backend:v0.0.32
|
image: scr.siteworxpro.com/reloading-manager/backend:v0.0.37
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
envFrom:
|
envFrom:
|
||||||
|
|||||||
17
backend/.golangci.yml
Normal file
17
backend/.golangci.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
version: "2"
|
||||||
|
linters:
|
||||||
|
default: standard
|
||||||
|
enable:
|
||||||
|
- whitespace
|
||||||
|
- tagalign
|
||||||
|
- reassign
|
||||||
|
- bodyclose
|
||||||
|
- contextcheck
|
||||||
|
- containedctx
|
||||||
|
- godot
|
||||||
|
- usestdlibvars
|
||||||
|
|
||||||
|
formatters:
|
||||||
|
settings:
|
||||||
|
gofmt:
|
||||||
|
simplify: true
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM siteworxpro/golang:1.24.3 AS build
|
FROM siteworxpro/golang:1.25.6 AS build
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ docker run -v $(pwd)/postgres:/var/lib/postgresql/data \
|
|||||||
-e POSTGRES_PASSWORD=password \
|
-e POSTGRES_PASSWORD=password \
|
||||||
--rm --name postgres \
|
--rm --name postgres \
|
||||||
-p 5432:5432 \
|
-p 5432:5432 \
|
||||||
-d scr.siteworxpro.com/library/postgres:17
|
-d postgres:17
|
||||||
```
|
```
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ package database
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.siteworxpro.com/packages/go/utilities/Env"
|
|
||||||
"git.siteworxpro.com/reloading-manager/backend/models/bullets"
|
"git.siteworxpro.com/reloading-manager/backend/models/bullets"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/models/loads"
|
"git.siteworxpro.com/reloading-manager/backend/models/loads"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/models/manufacturer"
|
"git.siteworxpro.com/reloading-manager/backend/models/manufacturer"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/models/powder"
|
"git.siteworxpro.com/reloading-manager/backend/models/powder"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/models/primers"
|
"git.siteworxpro.com/reloading-manager/backend/models/primers"
|
||||||
|
"gitea.siteworxpro.com/golang-packages/utilities/Env"
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
@@ -20,6 +20,10 @@ const (
|
|||||||
DbPassword Env.EnvironmentVariable = "DB_PASSWORD"
|
DbPassword Env.EnvironmentVariable = "DB_PASSWORD"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type contextKeyType string
|
||||||
|
|
||||||
|
const dbContextKey contextKeyType = "dbcontext"
|
||||||
|
|
||||||
type Database struct {
|
type Database struct {
|
||||||
Db *pgx.Conn
|
Db *pgx.Conn
|
||||||
connected bool
|
connected bool
|
||||||
@@ -50,6 +54,24 @@ func (*Database) DSN(hidePassword bool) string {
|
|||||||
return fmt.Sprintf("postgres://%s:%s@%s:5432/%s%s", dbUser, dbPassword, dbHost, dbDatabase, extraParams)
|
return fmt.Sprintf("postgres://%s:%s@%s:5432/%s%s", dbUser, dbPassword, dbHost, dbDatabase, extraParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewWithContext(ctx context.Context) context.Context {
|
||||||
|
db := GetNewDatabase()
|
||||||
|
|
||||||
|
return context.WithValue(ctx, dbContextKey, db)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFromContext(ctx context.Context) *Database {
|
||||||
|
if ok := ctx.Value(dbContextKey); ok != nil {
|
||||||
|
return ctx.Value(dbContextKey).(*Database)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithContext(ctx context.Context, database *Database) context.Context {
|
||||||
|
return context.WithValue(ctx, dbContextKey, database)
|
||||||
|
}
|
||||||
|
|
||||||
func GetNewDatabase() *Database {
|
func GetNewDatabase() *Database {
|
||||||
var dbSingleton Database
|
var dbSingleton Database
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import (
|
|||||||
|
|
||||||
func (db *Database) Migrate() {
|
func (db *Database) Migrate() {
|
||||||
sqlDB, err := sql.Open("postgres", db.DSN(false))
|
sqlDB, err := sql.Open("postgres", db.DSN(false))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
driver, err := postgres.WithInstance(sqlDB, &postgres.Config{
|
driver, err := postgres.WithInstance(sqlDB, &postgres.Config{
|
||||||
MigrationsTable: "schema_migrations",
|
MigrationsTable: "schema_migrations",
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
module git.siteworxpro.com/reloading-manager/backend
|
module git.siteworxpro.com/reloading-manager/backend
|
||||||
|
|
||||||
go 1.24.3
|
go 1.25.6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.siteworxpro.com/packages/go/utilities v1.3.0
|
gitea.siteworxpro.com/golang-packages/utilities v1.0.0
|
||||||
github.com/go-jet/jet/v2 v2.13.0
|
github.com/go-jet/jet/v2 v2.13.0
|
||||||
github.com/go-playground/validator v9.31.0+incompatible
|
github.com/go-playground/validator v9.31.0+incompatible
|
||||||
github.com/go-sql-driver/mysql v1.9.2
|
github.com/go-sql-driver/mysql v1.9.2
|
||||||
github.com/golang-migrate/migrate v3.5.4+incompatible
|
github.com/golang-migrate/migrate v3.5.4+incompatible
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/jackc/pgx/v5 v5.7.4
|
github.com/jackc/pgx/v5 v5.7.5
|
||||||
github.com/labstack/echo/v4 v4.13.3
|
github.com/labstack/echo/v4 v4.13.4
|
||||||
github.com/labstack/gommon v0.4.2
|
github.com/labstack/gommon v0.4.2
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -41,11 +41,11 @@ require (
|
|||||||
github.com/stretchr/testify v1.10.0 // indirect
|
github.com/stretchr/testify v1.10.0 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
golang.org/x/crypto v0.37.0 // indirect
|
golang.org/x/crypto v0.39.0 // indirect
|
||||||
golang.org/x/net v0.39.0 // indirect
|
golang.org/x/net v0.41.0 // indirect
|
||||||
golang.org/x/sys v0.32.0 // indirect
|
golang.org/x/sys v0.33.0 // indirect
|
||||||
golang.org/x/text v0.24.0 // indirect
|
golang.org/x/text v0.26.0 // indirect
|
||||||
golang.org/x/time v0.11.0 // indirect
|
golang.org/x/time v0.12.0 // indirect
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
git.siteworxpro.com/packages/go/utilities v1.3.0 h1:931q66COBJATgIQksPDSZlWMIwENJhhfC/GVf22ER5s=
|
gitea.siteworxpro.com/golang-packages/utilities v1.0.0 h1:f5JqAeZWBn/HBO9k5dzg0Wm91a69uwU5UC2P9ebQ9J0=
|
||||||
git.siteworxpro.com/packages/go/utilities v1.3.0/go.mod h1:iWhICNrMnB03PY9dM9eCNs9uQPEsPwae5pJDG+HHUPI=
|
gitea.siteworxpro.com/golang-packages/utilities v1.0.0/go.mod h1:QNqclnfv/BT2D5tbXgsGm7uhhe2Baovi5F6j0pVvMGc=
|
||||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
@@ -40,8 +40,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI
|
|||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
github.com/jackc/pgx/v5 v5.7.4 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg=
|
github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs=
|
||||||
github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
|
||||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
@@ -50,8 +50,8 @@ github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
|||||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
|
github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA=
|
||||||
github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
|
github.com/labstack/echo/v4 v4.13.4/go.mod h1:g63b33BZ5vZzcIUF8AtRH40DrTlXnx4UMC8rBdndmjQ=
|
||||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
@@ -86,41 +86,41 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
||||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
|
||||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
||||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||||
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=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
|
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
|
||||||
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
|
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|||||||
@@ -21,12 +21,15 @@ type BulletResponse struct {
|
|||||||
|
|
||||||
func Photo(c echo.Context) error {
|
func Photo(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
|
||||||
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid := handlers.ParseUuidOrBadRequest(c, id)
|
uid, err := handlers.ParseUuidOrBadRequest(c, id)
|
||||||
if uid == nil {
|
if err != nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID format")
|
||||||
}
|
}
|
||||||
|
|
||||||
byId, err := db.Bullets.GetBulletById(context.Background(), *uid)
|
byId, err := db.Bullets.GetBulletById(context.Background(), *uid)
|
||||||
@@ -48,15 +51,18 @@ func Photo(c echo.Context) error {
|
|||||||
|
|
||||||
func Delete(c echo.Context) error {
|
func Delete(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
|
||||||
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid := handlers.ParseUuidOrBadRequest(c, id)
|
uid, err := handlers.ParseUuidOrBadRequest(c, id)
|
||||||
if uid == nil {
|
if err != nil || uid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID format")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := db.Bullets.DeleteBullet(context.Background(), *uid)
|
err = db.Bullets.DeleteBullet(context.Background(), *uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -66,12 +72,14 @@ func Delete(c echo.Context) error {
|
|||||||
|
|
||||||
func Put(c echo.Context) error {
|
func Put(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid := handlers.ParseUuidOrBadRequest(c, id)
|
uid, err := handlers.ParseUuidOrBadRequest(c, id)
|
||||||
if uid == nil {
|
if err != nil || uid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID format")
|
||||||
}
|
}
|
||||||
|
|
||||||
byId, err := db.Bullets.GetBulletById(context.Background(), *uid)
|
byId, err := db.Bullets.GetBulletById(context.Background(), *uid)
|
||||||
@@ -101,9 +109,9 @@ func Put(c echo.Context) error {
|
|||||||
weight, _ := strconv.ParseInt(c.FormValue("weight"), 10, 32)
|
weight, _ := strconv.ParseInt(c.FormValue("weight"), 10, 32)
|
||||||
diameter, _ := strconv.ParseInt(c.FormValue("diameter"), 10, 32)
|
diameter, _ := strconv.ParseInt(c.FormValue("diameter"), 10, 32)
|
||||||
manufacturerId := c.FormValue("manufacturer_id")
|
manufacturerId := c.FormValue("manufacturer_id")
|
||||||
manufacturerUid := handlers.ParseUuidOrBadRequest(c, manufacturerId)
|
manufacturerUid, err := handlers.ParseUuidOrBadRequest(c, manufacturerId)
|
||||||
if manufacturerUid == nil {
|
if err == nil || manufacturerUid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID format")
|
||||||
}
|
}
|
||||||
|
|
||||||
name := c.FormValue("name")
|
name := c.FormValue("name")
|
||||||
@@ -147,13 +155,15 @@ func Put(c echo.Context) error {
|
|||||||
|
|
||||||
func Get(c echo.Context) error {
|
func Get(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
if c.Param("id") != "" {
|
if c.Param("id") != "" {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid := handlers.ParseUuidOrBadRequest(c, id)
|
uid, err := handlers.ParseUuidOrBadRequest(c, id)
|
||||||
if uid == nil {
|
if err != nil || uid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID format")
|
||||||
}
|
}
|
||||||
|
|
||||||
byId, err := db.Bullets.GetBulletById(context.Background(), *uid)
|
byId, err := db.Bullets.GetBulletById(context.Background(), *uid)
|
||||||
@@ -210,7 +220,6 @@ func Get(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Post(c echo.Context) error {
|
func Post(c echo.Context) error {
|
||||||
|
|
||||||
file, err := c.FormFile("photo")
|
file, err := c.FormFile("photo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger().Error(err)
|
c.Logger().Error(err)
|
||||||
@@ -245,11 +254,13 @@ func Post(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
manufacturerUid := handlers.ParseUuidOrBadRequest(c, manufacturerId)
|
manufacturerUid, err := handlers.ParseUuidOrBadRequest(c, manufacturerId)
|
||||||
if manufacturerUid == nil {
|
if err != nil || manufacturerUid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID format")
|
||||||
}
|
}
|
||||||
|
|
||||||
manufacturer, err := db.Manufacturer.GetById(context.Background(), *manufacturerUid)
|
manufacturer, err := db.Manufacturer.GetById(context.Background(), *manufacturerUid)
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ type postRequest struct {
|
|||||||
|
|
||||||
func Get(c echo.Context) error {
|
func Get(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
cartridges, err := db.Loads.GetCartridges(context.Background())
|
cartridges, err := db.Loads.GetCartridges(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -45,7 +47,9 @@ func Get(c echo.Context) error {
|
|||||||
|
|
||||||
func Post(c echo.Context) error {
|
func Post(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
req := postRequest{}
|
req := postRequest{}
|
||||||
|
|
||||||
@@ -79,14 +83,16 @@ func Post(c echo.Context) error {
|
|||||||
|
|
||||||
func Delete(c echo.Context) error {
|
func Delete(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
uid := handlers.ParseUuidOrBadRequest(c, c.Param("id"))
|
uid, err := handlers.ParseUuidOrBadRequest(c, c.Param("id"))
|
||||||
if uid == nil {
|
if err != nil || uid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "invalid id")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := db.Loads.DeleteCartridge(context.Background(), *uid)
|
err = db.Loads.DeleteCartridge(context.Background(), *uid)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -2,18 +2,12 @@ package handlers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func ReadFile(c echo.Context, formName string) ([]byte, error) {
|
func ReadFile(c echo.Context, formName string) ([]byte, error) {
|
||||||
file, err := c.FormFile(formName)
|
file, err := c.FormFile(formName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger().Error(err)
|
c.Logger().Error(err)
|
||||||
_ = c.JSON(http.StatusBadRequest, struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
}{
|
|
||||||
Message: "No file provided",
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package loads
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"git.siteworxpro.com/reloading-manager/backend/.gen/loading/public/table"
|
"git.siteworxpro.com/reloading-manager/backend/.gen/loading/public/table"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/database"
|
"git.siteworxpro.com/reloading-manager/backend/database"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/handlers"
|
"git.siteworxpro.com/reloading-manager/backend/handlers"
|
||||||
@@ -10,8 +9,10 @@ import (
|
|||||||
"git.siteworxpro.com/reloading-manager/backend/handlers/primers"
|
"git.siteworxpro.com/reloading-manager/backend/handlers/primers"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/models/loads"
|
"git.siteworxpro.com/reloading-manager/backend/models/loads"
|
||||||
"github.com/go-jet/jet/v2/postgres"
|
"github.com/go-jet/jet/v2/postgres"
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -43,13 +44,14 @@ type row struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type loadResponseResults struct {
|
type loadResponseResults struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
Cartridge string `json:"cartridge"`
|
Cartridge string `json:"cartridge"`
|
||||||
Col float32 `json:"col"`
|
CartridgeId string `json:"cartridge_id"`
|
||||||
Powder handlers.Powder `json:"powder"`
|
Col float32 `json:"col"`
|
||||||
PowderGr float32 `json:"powder_gr"`
|
Powder handlers.Powder `json:"powder"`
|
||||||
Primer primers.PrimerResponse `json:"primer"`
|
PowderGr float32 `json:"powder_gr"`
|
||||||
Bullet bullets.BulletResponse `json:"bullet"`
|
Primer primers.PrimerResponse `json:"primer"`
|
||||||
|
Bullet bullets.BulletResponse `json:"bullet"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type loadResponse struct {
|
type loadResponse struct {
|
||||||
@@ -63,8 +65,28 @@ type ResultChan[T any] struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Post(c echo.Context) error {
|
func Post(c echo.Context) error {
|
||||||
|
var exists *loads.GetLoadByIdRow
|
||||||
|
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
|
id := c.Param("id")
|
||||||
|
|
||||||
|
if id != "" {
|
||||||
|
uuid, err := handlers.ParseUuid(id)
|
||||||
|
if err != nil {
|
||||||
|
return handlers.BadRequest(c, "id is not a valid UUID")
|
||||||
|
}
|
||||||
|
|
||||||
|
gbi, err := db.Loads.GetLoadById(context.Background(), *uuid)
|
||||||
|
if err != nil || !gbi.ID.Valid {
|
||||||
|
return handlers.NotFound(c, "load not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
exists = &gbi
|
||||||
|
}
|
||||||
|
|
||||||
cartridgeID, err := handlers.ParseUuid(c.FormValue("cartridge_id"))
|
cartridgeID, err := handlers.ParseUuid(c.FormValue("cartridge_id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -87,8 +109,11 @@ func Post(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
file, err := handlers.ReadFile(c, "photo")
|
file, err := handlers.ReadFile(c, "photo")
|
||||||
if err != nil {
|
if err != nil && exists == nil {
|
||||||
return handlers.BadRequest(c, "photo is not valid")
|
return handlers.BadRequest(c, "photo is not valid")
|
||||||
|
} else if err != nil {
|
||||||
|
// If we are updating an existing load, we can ignore the error
|
||||||
|
file = exists.Photo
|
||||||
}
|
}
|
||||||
|
|
||||||
meta := c.FormValue("meta")
|
meta := c.FormValue("meta")
|
||||||
@@ -115,6 +140,26 @@ func Post(c echo.Context) error {
|
|||||||
return handlers.BadRequest(c, "col is not valid")
|
return handlers.BadRequest(c, "col is not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if exists != nil {
|
||||||
|
err = db.Loads.UpdateLoad(context.Background(), loads.UpdateLoadParams{
|
||||||
|
ID: exists.ID,
|
||||||
|
CartridgeID: *cartridgeID,
|
||||||
|
Col: colFl,
|
||||||
|
PowderID: *powderId,
|
||||||
|
PowderGr: powderGrFl,
|
||||||
|
PrimerID: *primerId,
|
||||||
|
BulletID: *bulletId,
|
||||||
|
Photo: file,
|
||||||
|
Meta: []byte(meta),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, handlers.Response[string]{Payload: exists.ID.String()})
|
||||||
|
}
|
||||||
|
|
||||||
uid, err := db.Loads.CreateLoad(context.Background(), loads.CreateLoadParams{
|
uid, err := db.Loads.CreateLoad(context.Background(), loads.CreateLoadParams{
|
||||||
CartridgeID: *cartridgeID,
|
CartridgeID: *cartridgeID,
|
||||||
Col: colFl,
|
Col: colFl,
|
||||||
@@ -133,16 +178,66 @@ func Post(c echo.Context) error {
|
|||||||
return c.JSON(http.StatusCreated, handlers.Response[string]{Payload: uid.String()})
|
return c.JSON(http.StatusCreated, handlers.Response[string]{Payload: uid.String()})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Photo(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
if id == "" {
|
||||||
|
return handlers.BadRequest(c, "id is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
uuid, err := handlers.ParseUuid(id)
|
||||||
|
if err != nil {
|
||||||
|
return handlers.BadRequest(c, "id is not a valid UUID")
|
||||||
|
}
|
||||||
|
|
||||||
|
db := c.(*database.CustomContext).Db
|
||||||
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
|
file, err := db.Loads.GetLoadById(context.Background(), *uuid)
|
||||||
|
if err != nil {
|
||||||
|
return handlers.NotFound(c, "load photo not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
mt, _, _ := mime.ParseMediaType(string(file.Photo))
|
||||||
|
|
||||||
|
return c.Blob(http.StatusOK, mt, file.Photo)
|
||||||
|
}
|
||||||
|
|
||||||
func Get(c echo.Context) error {
|
func Get(c echo.Context) error {
|
||||||
cTotal := make(chan ResultChan[int64])
|
id := c.Param("id")
|
||||||
cResults := make(chan ResultChan[[]loadResponseResults])
|
cResults := make(chan ResultChan[[]loadResponseResults])
|
||||||
|
|
||||||
|
if id != "" {
|
||||||
|
go execResultsQuery(cResults, c)
|
||||||
|
results := <-cResults
|
||||||
|
|
||||||
|
if results.Err != nil {
|
||||||
|
return results.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(results.Result) == 0 {
|
||||||
|
return handlers.NotFound(c, "load not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, handlers.Response[loadResponseResults]{Status: http.StatusText(http.StatusOK), Payload: results.Result[0]})
|
||||||
|
}
|
||||||
|
|
||||||
|
cTotal := make(chan ResultChan[int64])
|
||||||
|
|
||||||
go func(ch chan ResultChan[int64]) {
|
go func(ch chan ResultChan[int64]) {
|
||||||
db := database.GetNewDatabase()
|
db := database.GetNewDatabase()
|
||||||
|
|
||||||
defer db.Db.Close(context.Background())
|
defer func(Db *pgx.Conn, ctx context.Context) {
|
||||||
|
_ = Db.Close(ctx)
|
||||||
|
}(db.Db, context.Background())
|
||||||
|
|
||||||
q := getQuery(c, true)
|
q := getQuery(c, true)
|
||||||
|
if q == nil {
|
||||||
|
ch <- ResultChan[int64]{Result: 0}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
sql, params := q.Sql()
|
sql, params := q.Sql()
|
||||||
|
|
||||||
var total int64
|
var total int64
|
||||||
@@ -155,103 +250,8 @@ func Get(c echo.Context) error {
|
|||||||
} else {
|
} else {
|
||||||
ch <- ResultChan[int64]{Result: total}
|
ch <- ResultChan[int64]{Result: total}
|
||||||
}
|
}
|
||||||
|
|
||||||
}(cTotal)
|
}(cTotal)
|
||||||
|
go execResultsQuery(cResults, c)
|
||||||
go func(ch chan ResultChan[[]loadResponseResults]) {
|
|
||||||
db := database.GetNewDatabase()
|
|
||||||
|
|
||||||
defer db.Db.Close(context.Background())
|
|
||||||
|
|
||||||
q := getQuery(c, false)
|
|
||||||
|
|
||||||
fmt.Println(q.DebugSql())
|
|
||||||
|
|
||||||
sql, params := q.Sql()
|
|
||||||
rows, err := db.Db.Query(context.Background(), sql, params...)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
ch <- ResultChan[[]loadResponseResults]{Err: err}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
results := make([]loadResponseResults, 0)
|
|
||||||
for rows.Next() {
|
|
||||||
row := row{}
|
|
||||||
err = rows.Scan(
|
|
||||||
&row.ID,
|
|
||||||
&row.Col,
|
|
||||||
&row.PowderGr,
|
|
||||||
|
|
||||||
&row.CartridgeID,
|
|
||||||
&row.CartridgeName,
|
|
||||||
&row.CartridgeMeta,
|
|
||||||
|
|
||||||
&row.BulletID,
|
|
||||||
&row.BulletName,
|
|
||||||
&row.BulletDiameter,
|
|
||||||
&row.BulletWeight,
|
|
||||||
&row.BulletMeta,
|
|
||||||
&row.BulletManufacturerName,
|
|
||||||
&row.BulletManufacturerUrl,
|
|
||||||
|
|
||||||
&row.PrimerID,
|
|
||||||
&row.PrimerName,
|
|
||||||
&row.PrimerMeta,
|
|
||||||
&row.PrimerManufacturerName,
|
|
||||||
&row.PrimerManufacturerUrl,
|
|
||||||
|
|
||||||
&row.PowderID,
|
|
||||||
&row.PowderName,
|
|
||||||
&row.PowderMeta,
|
|
||||||
&row.PowderManufacturerName,
|
|
||||||
&row.PowderManufacturerUrl,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
ch <- ResultChan[[]loadResponseResults]{Err: err}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
results = append(results, loadResponseResults{
|
|
||||||
Id: row.ID.String(),
|
|
||||||
Cartridge: row.CartridgeName,
|
|
||||||
Col: row.Col,
|
|
||||||
Powder: handlers.Powder{
|
|
||||||
Id: row.PowderID.String(),
|
|
||||||
Name: row.PowderName,
|
|
||||||
Meta: string(row.PowderMeta),
|
|
||||||
Manufacturer: handlers.Manufacturer{
|
|
||||||
Name: row.PowderManufacturerName,
|
|
||||||
Url: row.PowderManufacturerUrl.String,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
PowderGr: row.PowderGr,
|
|
||||||
Primer: primers.PrimerResponse{
|
|
||||||
ID: row.PrimerID.String(),
|
|
||||||
Name: row.PrimerName,
|
|
||||||
Manufacturer: handlers.Manufacturer{
|
|
||||||
Name: row.PrimerManufacturerName,
|
|
||||||
Url: row.PrimerManufacturerUrl.String,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Bullet: bullets.BulletResponse{
|
|
||||||
Id: row.BulletID.String(),
|
|
||||||
Name: row.BulletName,
|
|
||||||
Diameter: row.BulletDiameter,
|
|
||||||
Weight: row.BulletWeight,
|
|
||||||
Manufacturer: handlers.Manufacturer{
|
|
||||||
Name: row.BulletManufacturerName,
|
|
||||||
Url: row.BulletManufacturerUrl.String,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
ch <- ResultChan[[]loadResponseResults]{Result: results}
|
|
||||||
}(cResults)
|
|
||||||
|
|
||||||
total := <-cTotal
|
total := <-cTotal
|
||||||
if total.Err != nil {
|
if total.Err != nil {
|
||||||
@@ -266,6 +266,106 @@ func Get(c echo.Context) error {
|
|||||||
return c.JSON(http.StatusOK, handlers.Response[loadResponse]{Status: http.StatusText(http.StatusOK), Payload: loadResponse{Total: int(total.Result), Results: results.Result}})
|
return c.JSON(http.StatusOK, handlers.Response[loadResponse]{Status: http.StatusText(http.StatusOK), Payload: loadResponse{Total: int(total.Result), Results: results.Result}})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func execResultsQuery(ch chan ResultChan[[]loadResponseResults], c echo.Context) {
|
||||||
|
db := database.GetNewDatabase()
|
||||||
|
|
||||||
|
defer func(Db *pgx.Conn, ctx context.Context) {
|
||||||
|
_ = Db.Close(ctx)
|
||||||
|
}(db.Db, context.Background())
|
||||||
|
|
||||||
|
q := getQuery(c, false)
|
||||||
|
|
||||||
|
if q == nil {
|
||||||
|
ch <- ResultChan[[]loadResponseResults]{Result: []loadResponseResults{}}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sql, params := q.Sql()
|
||||||
|
rows, err := db.Db.Query(context.Background(), sql, params...)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ch <- ResultChan[[]loadResponseResults]{Err: err}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results := make([]loadResponseResults, 0)
|
||||||
|
for rows.Next() {
|
||||||
|
row := row{}
|
||||||
|
err = rows.Scan(
|
||||||
|
&row.ID,
|
||||||
|
&row.Col,
|
||||||
|
&row.PowderGr,
|
||||||
|
|
||||||
|
&row.CartridgeID,
|
||||||
|
&row.CartridgeName,
|
||||||
|
&row.CartridgeMeta,
|
||||||
|
|
||||||
|
&row.BulletID,
|
||||||
|
&row.BulletName,
|
||||||
|
&row.BulletDiameter,
|
||||||
|
&row.BulletWeight,
|
||||||
|
&row.BulletMeta,
|
||||||
|
&row.BulletManufacturerName,
|
||||||
|
&row.BulletManufacturerUrl,
|
||||||
|
|
||||||
|
&row.PrimerID,
|
||||||
|
&row.PrimerName,
|
||||||
|
&row.PrimerMeta,
|
||||||
|
&row.PrimerManufacturerName,
|
||||||
|
&row.PrimerManufacturerUrl,
|
||||||
|
|
||||||
|
&row.PowderID,
|
||||||
|
&row.PowderName,
|
||||||
|
&row.PowderMeta,
|
||||||
|
&row.PowderManufacturerName,
|
||||||
|
&row.PowderManufacturerUrl,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ch <- ResultChan[[]loadResponseResults]{Err: err}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results = append(results, loadResponseResults{
|
||||||
|
Id: row.ID.String(),
|
||||||
|
Cartridge: row.CartridgeName,
|
||||||
|
CartridgeId: row.CartridgeID.String(),
|
||||||
|
Col: row.Col,
|
||||||
|
Powder: handlers.Powder{
|
||||||
|
Id: row.PowderID.String(),
|
||||||
|
Name: row.PowderName,
|
||||||
|
Meta: string(row.PowderMeta),
|
||||||
|
Manufacturer: handlers.Manufacturer{
|
||||||
|
Name: row.PowderManufacturerName,
|
||||||
|
Url: row.PowderManufacturerUrl.String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PowderGr: row.PowderGr,
|
||||||
|
Primer: primers.PrimerResponse{
|
||||||
|
ID: row.PrimerID.String(),
|
||||||
|
Name: row.PrimerName,
|
||||||
|
Manufacturer: handlers.Manufacturer{
|
||||||
|
Name: row.PrimerManufacturerName,
|
||||||
|
Url: row.PrimerManufacturerUrl.String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Bullet: bullets.BulletResponse{
|
||||||
|
Id: row.BulletID.String(),
|
||||||
|
Name: row.BulletName,
|
||||||
|
Diameter: row.BulletDiameter,
|
||||||
|
Weight: row.BulletWeight,
|
||||||
|
Manufacturer: handlers.Manufacturer{
|
||||||
|
Name: row.BulletManufacturerName,
|
||||||
|
Url: row.BulletManufacturerUrl.String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- ResultChan[[]loadResponseResults]{Result: results}
|
||||||
|
}
|
||||||
|
|
||||||
func getQuery(c echo.Context, countOnly bool) postgres.SelectStatement {
|
func getQuery(c echo.Context, countOnly bool) postgres.SelectStatement {
|
||||||
l := table.Loads.AS("l")
|
l := table.Loads.AS("l")
|
||||||
ctg := table.Cartridges.AS("c")
|
ctg := table.Cartridges.AS("c")
|
||||||
@@ -289,7 +389,6 @@ func getQuery(c echo.Context, countOnly bool) postgres.SelectStatement {
|
|||||||
if countOnly {
|
if countOnly {
|
||||||
q = tb.SELECT(postgres.COUNT(l.ID).AS("total"))
|
q = tb.SELECT(postgres.COUNT(l.ID).AS("total"))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
q = tb.SELECT(
|
q = tb.SELECT(
|
||||||
// Load
|
// Load
|
||||||
l.ID.AS("id"),
|
l.ID.AS("id"),
|
||||||
@@ -329,6 +428,17 @@ func getQuery(c echo.Context, countOnly bool) postgres.SelectStatement {
|
|||||||
// where expressions
|
// where expressions
|
||||||
expressions := make([]postgres.BoolExpression, 0)
|
expressions := make([]postgres.BoolExpression, 0)
|
||||||
|
|
||||||
|
if c.Param("id") != "" {
|
||||||
|
uuid, err := handlers.ParseUuid(c.Param("id"))
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
q = q.WHERE(l.ID.EQ(postgres.UUID(uuid)))
|
||||||
|
|
||||||
|
return q
|
||||||
|
}
|
||||||
|
|
||||||
if c.QueryParam("cartridge_id") != "" {
|
if c.QueryParam("cartridge_id") != "" {
|
||||||
ids := strings.Split(c.QueryParam("cartridge_id"), ",")
|
ids := strings.Split(c.QueryParam("cartridge_id"), ",")
|
||||||
if len(ids) > 0 {
|
if len(ids) > 0 {
|
||||||
@@ -438,17 +548,48 @@ func getQuery(c echo.Context, countOnly bool) postgres.SelectStatement {
|
|||||||
if limit == "" {
|
if limit == "" {
|
||||||
limit = "50"
|
limit = "50"
|
||||||
}
|
}
|
||||||
offset := c.QueryParam("offset")
|
|
||||||
if offset == "" {
|
pageInt := handlers.ParseInt64OrDefault(c.QueryParam("page"), 1)
|
||||||
offset = "0"
|
if pageInt < 1 {
|
||||||
|
pageInt = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
offset := (pageInt - 1) * handlers.ParseInt64OrDefault(limit, 50)
|
||||||
q = q.LIMIT(handlers.ParseInt64OrDefault(limit, 50)).
|
q = q.LIMIT(handlers.ParseInt64OrDefault(limit, 50)).
|
||||||
OFFSET(handlers.ParseInt64OrDefault(offset, 0))
|
OFFSET(offset)
|
||||||
|
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Delete(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
if id == "" {
|
||||||
|
return handlers.BadRequest(c, "id is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
uuid, err := handlers.ParseUuid(id)
|
||||||
|
if err != nil {
|
||||||
|
return handlers.BadRequest(c, "id is not a valid UUID")
|
||||||
|
}
|
||||||
|
|
||||||
|
db := c.(*database.CustomContext).Db
|
||||||
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
|
exists, err := db.Loads.GetLoadById(context.Background(), *uuid)
|
||||||
|
if err != nil || !exists.ID.Valid {
|
||||||
|
return handlers.NotFound(c, "load not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Loads.DeleteLoad(context.Background(), *uuid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.NoContent(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
func getUuidExpr(ids []string) []postgres.Expression {
|
func getUuidExpr(ids []string) []postgres.Expression {
|
||||||
expr := make([]postgres.Expression, 0)
|
expr := make([]postgres.Expression, 0)
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
|
|||||||
@@ -21,13 +21,15 @@ type manufacturerResponse struct {
|
|||||||
|
|
||||||
func Get(c echo.Context) error {
|
func Get(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
if c.Param("id") != "" {
|
if c.Param("id") != "" {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid := handlers.ParseUuidOrBadRequest(c, id)
|
uid, err := handlers.ParseUuidOrBadRequest(c, id)
|
||||||
if uid == nil {
|
if err != nil || uid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID format")
|
||||||
}
|
}
|
||||||
|
|
||||||
byId, err := db.Manufacturer.GetById(context.Background(), *uid)
|
byId, err := db.Manufacturer.GetById(context.Background(), *uid)
|
||||||
@@ -73,15 +75,17 @@ func Get(c echo.Context) error {
|
|||||||
|
|
||||||
func Delete(c echo.Context) error {
|
func Delete(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid := handlers.ParseUuidOrBadRequest(c, id)
|
uid, err := handlers.ParseUuidOrBadRequest(c, id)
|
||||||
if uid == nil {
|
if err != nil || uid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID format")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := db.Manufacturer.GetById(context.Background(), *uid)
|
_, err = db.Manufacturer.GetById(context.Background(), *uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return echo.NewHTTPError(http.StatusNotFound, "Not found")
|
return echo.NewHTTPError(http.StatusNotFound, "Not found")
|
||||||
}
|
}
|
||||||
@@ -97,16 +101,18 @@ func Delete(c echo.Context) error {
|
|||||||
|
|
||||||
func Post(c echo.Context) error {
|
func Post(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
if c.Param("id") != "" {
|
if c.Param("id") != "" {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid := handlers.ParseUuidOrBadRequest(c, id)
|
uid, err := handlers.ParseUuidOrBadRequest(c, id)
|
||||||
if uid == nil {
|
if err != nil || uid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID format")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := db.Manufacturer.GetById(context.Background(), *uid)
|
_, err = db.Manufacturer.GetById(context.Background(), *uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return echo.NewHTTPError(http.StatusNotFound, "Not found")
|
return echo.NewHTTPError(http.StatusNotFound, "Not found")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ import (
|
|||||||
|
|
||||||
func Photo(c echo.Context) error {
|
func Photo(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid, err := handlers.ParseUuid(id)
|
uid, err := handlers.ParseUuid(id)
|
||||||
@@ -41,7 +43,9 @@ func Photo(c echo.Context) error {
|
|||||||
func Delete(c echo.Context) error {
|
func Delete(c echo.Context) error {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
uid, err := handlers.ParseUuid(id)
|
uid, err := handlers.ParseUuid(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -58,7 +62,9 @@ func Delete(c echo.Context) error {
|
|||||||
|
|
||||||
func Post(c echo.Context) error {
|
func Post(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
if c.Param("id") != "" {
|
if c.Param("id") != "" {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
@@ -163,7 +169,9 @@ func Post(c echo.Context) error {
|
|||||||
|
|
||||||
func Get(c echo.Context) error {
|
func Get(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
if c.Param("id") != "" {
|
if c.Param("id") != "" {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package primers
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/database"
|
"git.siteworxpro.com/reloading-manager/backend/database"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/handlers"
|
"git.siteworxpro.com/reloading-manager/backend/handlers"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/models/primers"
|
"git.siteworxpro.com/reloading-manager/backend/models/primers"
|
||||||
@@ -19,7 +20,9 @@ type PrimerResponse struct {
|
|||||||
|
|
||||||
func Delete(c echo.Context) error {
|
func Delete(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid, err := handlers.ParseUuid(id)
|
uid, err := handlers.ParseUuid(id)
|
||||||
@@ -37,13 +40,15 @@ func Delete(c echo.Context) error {
|
|||||||
|
|
||||||
func Post(c echo.Context) error {
|
func Post(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
if c.Param("id") != "" {
|
if c.Param("id") != "" {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid := handlers.ParseUuidOrBadRequest(c, id)
|
uid, err := handlers.ParseUuidOrBadRequest(c, id)
|
||||||
if uid == nil {
|
if err != nil || uid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID.")
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := db.Primer.GetPrimerById(context.Background(), *uid)
|
p, err := db.Primer.GetPrimerById(context.Background(), *uid)
|
||||||
@@ -56,9 +61,9 @@ func Post(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if c.FormValue("manufacturer_id") != "" {
|
if c.FormValue("manufacturer_id") != "" {
|
||||||
mid := handlers.ParseUuidOrBadRequest(c, c.FormValue("manufacturer_id"))
|
mid, err := handlers.ParseUuidOrBadRequest(c, c.FormValue("manufacturer_id"))
|
||||||
if mid == nil {
|
if err != nil || mid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid Manufacturer ID.")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.ManufacturerID = *mid
|
p.ManufacturerID = *mid
|
||||||
@@ -112,13 +117,14 @@ func Post(c echo.Context) error {
|
|||||||
if metaString == "" {
|
if metaString == "" {
|
||||||
metaString = "{}"
|
metaString = "{}"
|
||||||
}
|
}
|
||||||
var meta json.RawMessage = []byte(metaString)
|
|
||||||
|
meta := []byte(metaString)
|
||||||
|
|
||||||
newUuid := uuid.New().String()
|
newUuid := uuid.New().String()
|
||||||
uid, _ := handlers.ParseUuid(newUuid)
|
uid, _ := handlers.ParseUuid(newUuid)
|
||||||
mid := handlers.ParseUuidOrBadRequest(c, manufacturerId)
|
mid, err := handlers.ParseUuidOrBadRequest(c, manufacturerId)
|
||||||
if mid == nil {
|
if err != nil || mid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid Manufacturer ID.")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.Primer.InsertPrimer(context.Background(), primers.InsertPrimerParams{
|
err = db.Primer.InsertPrimer(context.Background(), primers.InsertPrimerParams{
|
||||||
@@ -145,12 +151,14 @@ func Post(c echo.Context) error {
|
|||||||
|
|
||||||
func Photo(c echo.Context) error {
|
func Photo(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid := handlers.ParseUuidOrBadRequest(c, id)
|
uid, err := handlers.ParseUuidOrBadRequest(c, id)
|
||||||
if uid == nil {
|
if err != nil || uid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID.")
|
||||||
}
|
}
|
||||||
|
|
||||||
byId, err := db.Primer.GetPrimerById(context.Background(), *uid)
|
byId, err := db.Primer.GetPrimerById(context.Background(), *uid)
|
||||||
@@ -172,18 +180,20 @@ func Photo(c echo.Context) error {
|
|||||||
|
|
||||||
func Get(c echo.Context) error {
|
func Get(c echo.Context) error {
|
||||||
db := c.(*database.CustomContext).Db
|
db := c.(*database.CustomContext).Db
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
if c.Param("id") != "" {
|
if c.Param("id") != "" {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
uid := handlers.ParseUuidOrBadRequest(c, id)
|
uid, err := handlers.ParseUuidOrBadRequest(c, id)
|
||||||
if uid == nil {
|
if err != nil || uid == nil {
|
||||||
return nil
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid UUID.")
|
||||||
}
|
}
|
||||||
|
|
||||||
row, err := db.Primer.GetPrimerById(context.Background(), *uid)
|
row, err := db.Primer.GetPrimerById(context.Background(), *uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("primer not found: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, handlers.Response[PrimerResponse]{
|
return c.JSON(http.StatusOK, handlers.Response[PrimerResponse]{
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ type TestContext struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t TestContext) JSON(code int, i interface{}) error {
|
func (t TestContext) JSON(code int, i interface{}) error {
|
||||||
|
|
||||||
if code != 400 {
|
if code != 400 {
|
||||||
t.t.Fatal("expected 400")
|
t.t.Fatal("expected 400")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
@@ -23,7 +24,7 @@ func ParseUuidOrEmpty(s string) *pgtype.UUID {
|
|||||||
func ParseUuid(s string) (*pgtype.UUID, error) {
|
func ParseUuid(s string) (*pgtype.UUID, error) {
|
||||||
uid, err := uuid.Parse(s)
|
uid, err := uuid.Parse(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("invalid UUID format: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pgtype.UUID{
|
return &pgtype.UUID{
|
||||||
@@ -32,14 +33,11 @@ func ParseUuid(s string) (*pgtype.UUID, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseUuidOrBadRequest(c echo.Context, s string) *pgtype.UUID {
|
func ParseUuidOrBadRequest(c echo.Context, s string) (*pgtype.UUID, error) {
|
||||||
uid, err := ParseUuid(s)
|
uid, err := ParseUuid(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = BadRequest(c, "Invalid UUID.")
|
return nil, BadRequest(c, fmt.Sprintf("invalid UUID. %v", err))
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return uid
|
return uid, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.siteworxpro.com/packages/go/utilities/Env"
|
|
||||||
"git.siteworxpro.com/reloading-manager/backend/database"
|
"git.siteworxpro.com/reloading-manager/backend/database"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/handlers/bullets"
|
"git.siteworxpro.com/reloading-manager/backend/handlers/bullets"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/handlers/cartridge"
|
"git.siteworxpro.com/reloading-manager/backend/handlers/cartridge"
|
||||||
@@ -11,6 +10,7 @@ import (
|
|||||||
"git.siteworxpro.com/reloading-manager/backend/handlers/manufacturer"
|
"git.siteworxpro.com/reloading-manager/backend/handlers/manufacturer"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/handlers/powder"
|
"git.siteworxpro.com/reloading-manager/backend/handlers/powder"
|
||||||
"git.siteworxpro.com/reloading-manager/backend/handlers/primers"
|
"git.siteworxpro.com/reloading-manager/backend/handlers/primers"
|
||||||
|
"gitea.siteworxpro.com/golang-packages/utilities/Env"
|
||||||
"github.com/go-playground/validator"
|
"github.com/go-playground/validator"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
@@ -98,7 +98,11 @@ func main() {
|
|||||||
|
|
||||||
// loads
|
// loads
|
||||||
e.GET("/load", loads.Get)
|
e.GET("/load", loads.Get)
|
||||||
|
e.GET("/load/:id", loads.Get)
|
||||||
|
e.GET("/load/:id/photo", loads.Photo)
|
||||||
e.POST("/load", loads.Post)
|
e.POST("/load", loads.Post)
|
||||||
|
e.POST("/load/:id", loads.Post)
|
||||||
|
e.DELETE("/load/:id", loads.Delete)
|
||||||
|
|
||||||
addr := fmt.Sprintf("0.0.0.0:%s", Port.GetEnvString("8080"))
|
addr := fmt.Sprintf("0.0.0.0:%s", Port.GetEnvString("8080"))
|
||||||
|
|
||||||
@@ -113,7 +117,9 @@ func migrate(e *echo.Echo) {
|
|||||||
|
|
||||||
db := database.GetNewDatabase()
|
db := database.GetNewDatabase()
|
||||||
|
|
||||||
defer db.Db.Close(context.Background())
|
defer func() {
|
||||||
|
_ = db.Db.Close(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
db.Migrate()
|
db.Migrate()
|
||||||
e.Logger.Info("✅ Complete!")
|
e.Logger.Info("✅ Complete!")
|
||||||
|
|||||||
@@ -18,6 +18,22 @@ delete
|
|||||||
from cartridges
|
from cartridges
|
||||||
where id = $1;
|
where id = $1;
|
||||||
|
|
||||||
|
-- name: DeleteLoad :exec
|
||||||
|
delete from loads
|
||||||
|
where id = $1;
|
||||||
|
|
||||||
|
-- name: UpdateLoad :exec
|
||||||
|
update loads set
|
||||||
|
cartridge_id = $1,
|
||||||
|
col = $2,
|
||||||
|
powder_id = $3,
|
||||||
|
powder_gr = $4,
|
||||||
|
primer_id = $5,
|
||||||
|
bullet_id = $6,
|
||||||
|
photo = $7,
|
||||||
|
meta = $8
|
||||||
|
where id = $9;
|
||||||
|
|
||||||
-- name: CreateLoad :one
|
-- name: CreateLoad :one
|
||||||
insert into loads (cartridge_id, col, powder_id, powder_gr, primer_id, bullet_id, photo, meta)
|
insert into loads (cartridge_id, col, powder_id, powder_gr, primer_id, bullet_id, photo, meta)
|
||||||
values ($1, $2, $3, $4, $5, $6, $7, $8)
|
values ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||||
@@ -25,6 +41,7 @@ returning id;
|
|||||||
|
|
||||||
-- name: GetLoadById :one
|
-- name: GetLoadById :one
|
||||||
select l.id as id,
|
select l.id as id,
|
||||||
|
l.photo as photo,
|
||||||
c.id as cartridge_id,
|
c.id as cartridge_id,
|
||||||
c.name as cartridge_name,
|
c.name as cartridge_name,
|
||||||
c.meta as cartridge_meta,
|
c.meta as cartridge_meta,
|
||||||
|
|||||||
@@ -73,6 +73,16 @@ func (q *Queries) DeleteCartridge(ctx context.Context, id pgtype.UUID) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deleteLoad = `-- name: DeleteLoad :exec
|
||||||
|
delete from loads
|
||||||
|
where id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) DeleteLoad(ctx context.Context, id pgtype.UUID) error {
|
||||||
|
_, err := q.db.Exec(ctx, deleteLoad, id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
const getCartridgeById = `-- name: GetCartridgeById :one
|
const getCartridgeById = `-- name: GetCartridgeById :one
|
||||||
select c.id as id, c.name, c.meta
|
select c.id as id, c.name, c.meta
|
||||||
from cartridges c
|
from cartridges c
|
||||||
@@ -126,6 +136,7 @@ func (q *Queries) GetCartridges(ctx context.Context) ([]GetCartridgesRow, error)
|
|||||||
|
|
||||||
const getLoadById = `-- name: GetLoadById :one
|
const getLoadById = `-- name: GetLoadById :one
|
||||||
select l.id as id,
|
select l.id as id,
|
||||||
|
l.photo as photo,
|
||||||
c.id as cartridge_id,
|
c.id as cartridge_id,
|
||||||
c.name as cartridge_name,
|
c.name as cartridge_name,
|
||||||
c.meta as cartridge_meta,
|
c.meta as cartridge_meta,
|
||||||
@@ -147,6 +158,7 @@ where l.id = $1
|
|||||||
|
|
||||||
type GetLoadByIdRow struct {
|
type GetLoadByIdRow struct {
|
||||||
ID pgtype.UUID `json:"id"`
|
ID pgtype.UUID `json:"id"`
|
||||||
|
Photo []byte `json:"photo"`
|
||||||
CartridgeID pgtype.UUID `json:"cartridge_id"`
|
CartridgeID pgtype.UUID `json:"cartridge_id"`
|
||||||
CartridgeName string `json:"cartridge_name"`
|
CartridgeName string `json:"cartridge_name"`
|
||||||
CartridgeMeta []byte `json:"cartridge_meta"`
|
CartridgeMeta []byte `json:"cartridge_meta"`
|
||||||
@@ -165,6 +177,7 @@ func (q *Queries) GetLoadById(ctx context.Context, id pgtype.UUID) (GetLoadByIdR
|
|||||||
var i GetLoadByIdRow
|
var i GetLoadByIdRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
&i.Photo,
|
||||||
&i.CartridgeID,
|
&i.CartridgeID,
|
||||||
&i.CartridgeName,
|
&i.CartridgeName,
|
||||||
&i.CartridgeMeta,
|
&i.CartridgeMeta,
|
||||||
@@ -376,3 +389,43 @@ func (q *Queries) TotalLoads(ctx context.Context) (int64, error) {
|
|||||||
err := row.Scan(&count)
|
err := row.Scan(&count)
|
||||||
return count, err
|
return count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateLoad = `-- name: UpdateLoad :exec
|
||||||
|
update loads set
|
||||||
|
cartridge_id = $1,
|
||||||
|
col = $2,
|
||||||
|
powder_id = $3,
|
||||||
|
powder_gr = $4,
|
||||||
|
primer_id = $5,
|
||||||
|
bullet_id = $6,
|
||||||
|
photo = $7,
|
||||||
|
meta = $8
|
||||||
|
where id = $9
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateLoadParams struct {
|
||||||
|
CartridgeID pgtype.UUID `json:"cartridge_id"`
|
||||||
|
Col float32 `json:"col"`
|
||||||
|
PowderID pgtype.UUID `json:"powder_id"`
|
||||||
|
PowderGr float32 `json:"powder_gr"`
|
||||||
|
PrimerID pgtype.UUID `json:"primer_id"`
|
||||||
|
BulletID pgtype.UUID `json:"bullet_id"`
|
||||||
|
Photo []byte `json:"photo"`
|
||||||
|
Meta []byte `json:"meta"`
|
||||||
|
ID pgtype.UUID `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateLoad(ctx context.Context, arg UpdateLoadParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, updateLoad,
|
||||||
|
arg.CartridgeID,
|
||||||
|
arg.Col,
|
||||||
|
arg.PowderID,
|
||||||
|
arg.PowderGr,
|
||||||
|
arg.PrimerID,
|
||||||
|
arg.BulletID,
|
||||||
|
arg.Photo,
|
||||||
|
arg.Meta,
|
||||||
|
arg.ID,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v22.14.0
|
v25.4.0
|
||||||
106
frontend/package-lock.json
generated
106
frontend/package-lock.json
generated
@@ -1685,13 +1685,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.8.4",
|
"version": "1.13.4",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.4.tgz",
|
||||||
"integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
|
"integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.6",
|
"follow-redirects": "^1.15.6",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.4",
|
||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1703,9 +1703,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -2031,14 +2031,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/form-data": {
|
"node_modules/form-data": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
|
||||||
"integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
|
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"asynckit": "^0.4.0",
|
"asynckit": "^0.4.0",
|
||||||
"combined-stream": "^1.0.8",
|
"combined-stream": "^1.0.8",
|
||||||
"es-set-tostringtag": "^2.1.0",
|
"es-set-tostringtag": "^2.1.0",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
"mime-types": "^2.1.12"
|
"mime-types": "^2.1.12"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2758,6 +2759,51 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tinyglobby": {
|
||||||
|
"version": "0.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||||
|
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fdir": "^6.5.0",
|
||||||
|
"picomatch": "^4.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tinyglobby/node_modules/fdir": {
|
||||||
|
"version": "6.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||||
|
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"picomatch": "^3 || ^4"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"picomatch": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tinyglobby/node_modules/picomatch": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
@@ -2817,14 +2863,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "6.2.2",
|
"version": "6.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
|
||||||
"integrity": "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==",
|
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
|
"fdir": "^6.4.4",
|
||||||
|
"picomatch": "^4.0.2",
|
||||||
"postcss": "^8.5.3",
|
"postcss": "^8.5.3",
|
||||||
"rollup": "^4.30.1"
|
"rollup": "^4.34.9",
|
||||||
|
"tinyglobby": "^0.2.13"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"vite": "bin/vite.js"
|
"vite": "bin/vite.js"
|
||||||
@@ -2887,6 +2936,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vite/node_modules/fdir": {
|
||||||
|
"version": "6.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||||
|
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"picomatch": "^3 || ^4"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"picomatch": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vite/node_modules/picomatch": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vscode-uri": {
|
"node_modules/vscode-uri": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
|
||||||
|
|||||||
49
frontend/src/components/FullScreenLoader.vue
Normal file
49
frontend/src/components/FullScreenLoader.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div class="loader" v-if="loading">
|
||||||
|
<div class="flex flex-col justify-center items-center">
|
||||||
|
<ProgressSpinner :style="{ width: '50px', height: '50px' }" strokeWidth="5" />
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row justify-center items-center">
|
||||||
|
<span class="text-2xl">{{ message }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineAsyncComponent } from 'vue'
|
||||||
|
const ProgressSpinner = defineAsyncComponent(() => import('primevue/progressspinner'))
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
type: String,
|
||||||
|
default: 'Loading...'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(9, 5, 5, 0.56);
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.text-2xl {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -5,4 +5,5 @@ export const icons = {
|
|||||||
upload: 'fa-thin fa-sharp fa-upload',
|
upload: 'fa-thin fa-sharp fa-upload',
|
||||||
save: 'fa-thin fa-sharp fa-floppy-disk',
|
save: 'fa-thin fa-sharp fa-floppy-disk',
|
||||||
delete: 'fa-thin fa-sharp fa-trash',
|
delete: 'fa-thin fa-sharp fa-trash',
|
||||||
|
loading: 'fa-solid fa-sharp fa-cog fa-spin',
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<Card class="md:w-2/3 w-full">
|
<Card class="md:w-2/3 w-full">
|
||||||
<template #title>
|
<template #title>
|
||||||
Add New Load
|
<span v-if="route.params.id">Edit Load</span>
|
||||||
|
<span v-else>Add New Load</span>
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="grid grid-cols-1">
|
<div class="grid grid-cols-1">
|
||||||
@@ -66,7 +67,7 @@
|
|||||||
COL
|
COL
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full mt-3">
|
<div class="w-full mt-3">
|
||||||
<InputMask placeholder="0.000" v-model="load.col" mask="9.999" class="w-full" />
|
<InputMask :unmask="loading" :value="load.col" placeholder="0.000" v-model="load.col" mask="9.999" class="w-full" />
|
||||||
<Message v-if="v$.$dirty && v$.col.$invalid" :value="false" size="small" severity="error"
|
<Message v-if="v$.$dirty && v$.col.$invalid" :value="false" size="small" severity="error"
|
||||||
variant="simple">COL Required
|
variant="simple">COL Required
|
||||||
</Message>
|
</Message>
|
||||||
@@ -74,15 +75,20 @@
|
|||||||
|
|
||||||
<div class="w-full mt-5">
|
<div class="w-full mt-5">
|
||||||
<label>Picture</label>
|
<label>Picture</label>
|
||||||
<Message v-if="v$.$dirty && !file" :value="false" size="small" severity="error"
|
<Message v-if="v$.$dirty && (!route.params.id && !file)" :value="false" size="small" severity="error"
|
||||||
variant="simple">Picture Required
|
variant="simple">Picture Required
|
||||||
</Message>
|
</Message>
|
||||||
|
<div class="w-1/2">
|
||||||
|
<img v-if="pictureUrl && route.params.id && !loading" :src="pictureUrl" alt="picture" />
|
||||||
|
</div>
|
||||||
<FileUpload v-model="file" mode="basic" @select="fileSelected" customUpload />
|
<FileUpload v-model="file" mode="basic" @select="fileSelected" customUpload />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<Button label="Add" :icon="icons.add" @click="add" />
|
<Button v-if="!route.params.id" label="Add" :icon="icons.add" @click="add" />
|
||||||
|
<Button v-else label="Save" :icon="icons.edit" @click="add" />
|
||||||
|
<Button class="ml-3" severity="danger" v-if="route.params.id" label="Delete" :icon="icons.delete" @click="deleteLoad" />
|
||||||
</template>
|
</template>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
@@ -103,6 +109,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
|
<FullScreenLoader :loading="loading" />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
interface Select {
|
interface Select {
|
||||||
@@ -121,13 +128,16 @@ import { defineAsyncComponent, onMounted, ref } from 'vue'
|
|||||||
import { Primers } from '../../types/primers'
|
import { Primers } from '../../types/primers'
|
||||||
import { Powder } from '../../types/powder'
|
import { Powder } from '../../types/powder'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { Response } from '../../types/Response'
|
import { Load, Response } from '../../types/Response'
|
||||||
import { icons } from '../../lib/icons.ts'
|
import { icons } from '../../lib/icons.ts'
|
||||||
import { FileUploadSelectEvent } from 'primevue/fileupload'
|
import { FileUploadSelectEvent } from 'primevue/fileupload'
|
||||||
import useVuelidate from '@vuelidate/core'
|
import useVuelidate from '@vuelidate/core'
|
||||||
import { required } from '@vuelidate/validators'
|
import { required } from '@vuelidate/validators'
|
||||||
import { useToast } from 'primevue/usetoast'
|
import { useToast } from 'primevue/usetoast'
|
||||||
import router from '../../router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
const Card = defineAsyncComponent(() => import('primevue/card'))
|
const Card = defineAsyncComponent(() => import('primevue/card'))
|
||||||
const Select = defineAsyncComponent(() => import('primevue/select'))
|
const Select = defineAsyncComponent(() => import('primevue/select'))
|
||||||
@@ -138,6 +148,7 @@ const InputMask = defineAsyncComponent(() => import('primevue/inputmask'))
|
|||||||
const FileUpload = defineAsyncComponent(() => import('primevue/fileupload'))
|
const FileUpload = defineAsyncComponent(() => import('primevue/fileupload'))
|
||||||
const Dialog = defineAsyncComponent(() => import('primevue/dialog'))
|
const Dialog = defineAsyncComponent(() => import('primevue/dialog'))
|
||||||
const Message = defineAsyncComponent(() => import('primevue/message'))
|
const Message = defineAsyncComponent(() => import('primevue/message'))
|
||||||
|
const FullScreenLoader = defineAsyncComponent(() => import('../../components/FullScreenLoader.vue'))
|
||||||
|
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
@@ -145,6 +156,7 @@ const bullets = ref<Select[]>([])
|
|||||||
const primers = ref<Select[]>([])
|
const primers = ref<Select[]>([])
|
||||||
const powders = ref<Select[]>([])
|
const powders = ref<Select[]>([])
|
||||||
const cartridges = ref<Select[]>([])
|
const cartridges = ref<Select[]>([])
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
const cartridgeName = ref('')
|
const cartridgeName = ref('')
|
||||||
const addCartridgeDialog = ref(false)
|
const addCartridgeDialog = ref(false)
|
||||||
@@ -154,6 +166,12 @@ const fileSelected = (e: FileUploadSelectEvent) => {
|
|||||||
file.value = e.files[0]
|
file.value = e.files[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pictureUrl = ref<string | null>(null)
|
||||||
|
const calcUrl = () => {
|
||||||
|
const cache = new Date().getMilliseconds()
|
||||||
|
pictureUrl.value = import.meta.env.VITE_API + `/load/${route.params.id}/photo?cache=${cache}`
|
||||||
|
}
|
||||||
|
|
||||||
const load = ref({
|
const load = ref({
|
||||||
bullet: '',
|
bullet: '',
|
||||||
cartridge: '',
|
cartridge: '',
|
||||||
@@ -191,21 +209,18 @@ const fetchBullets = async () => {
|
|||||||
bullets.value.push({ label: `${bullet.manufacturer.name} ${bullet.weight}gr ${bullet.name}`, value: bullet.id })
|
bullets.value.push({ label: `${bullet.manufacturer.name} ${bullet.weight}gr ${bullet.name}`, value: bullet.id })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchPrimers = async () => {
|
const fetchPrimers = async () => {
|
||||||
const response = await axios.get<any, Response<Primers[]>>(`${import.meta.env.VITE_API}/primer`)
|
const response = await axios.get<any, Response<Primers[]>>(`${import.meta.env.VITE_API}/primer`)
|
||||||
response.data.payload.forEach((primer: Primers) => {
|
response.data.payload.forEach((primer: Primers) => {
|
||||||
primers.value.push({ label: `${primer.manufacturer.name} ${primer.name}`, value: primer.id })
|
primers.value.push({ label: `${primer.manufacturer.name} ${primer.name}`, value: primer.id })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchPowders = async () => {
|
const fetchPowders = async () => {
|
||||||
const response = await axios.get<any, Response<Powder[]>>(`${import.meta.env.VITE_API}/powder`)
|
const response = await axios.get<any, Response<Powder[]>>(`${import.meta.env.VITE_API}/powder`)
|
||||||
response.data.payload.forEach((powder: Powder) => {
|
response.data.payload.forEach((powder: Powder) => {
|
||||||
powders.value.push({ label: `${powder.manufacturer.name} ${powder.name}`, value: powder.id })
|
powders.value.push({ label: `${powder.manufacturer.name} ${powder.name}`, value: powder.id })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchCartridges = async () => {
|
const fetchCartridges = async () => {
|
||||||
cartridges.value = []
|
cartridges.value = []
|
||||||
|
|
||||||
@@ -214,7 +229,6 @@ const fetchCartridges = async () => {
|
|||||||
cartridges.value.push({ label: `${cartridge.name}`, value: cartridge.id })
|
cartridges.value.push({ label: `${cartridge.name}`, value: cartridge.id })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const addCartridgeName = async () => {
|
const addCartridgeName = async () => {
|
||||||
if (cartridgeName.value === '') {
|
if (cartridgeName.value === '') {
|
||||||
return
|
return
|
||||||
@@ -237,11 +251,10 @@ const addCartridgeName = async () => {
|
|||||||
cartridgeName.value = ''
|
cartridgeName.value = ''
|
||||||
addCartridgeDialog.value = false
|
addCartridgeDialog.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const add = async () => {
|
const add = async () => {
|
||||||
v$.value.$touch()
|
v$.value.$touch()
|
||||||
|
|
||||||
if (v$.value.$invalid || !file.value) {
|
if (v$.value.$invalid || (!route.params.id && !file.value)) {
|
||||||
toast.add({
|
toast.add({
|
||||||
severity: 'error',
|
severity: 'error',
|
||||||
summary: 'Error',
|
summary: 'Error',
|
||||||
@@ -252,6 +265,12 @@ const add = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let id = ""
|
||||||
|
|
||||||
|
if (route.params.id) {
|
||||||
|
id = "/" + route.params.id.toString()
|
||||||
|
}
|
||||||
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('bullet_id', load.value.bullet)
|
formData.append('bullet_id', load.value.bullet)
|
||||||
formData.append('cartridge_id', load.value.cartridge)
|
formData.append('cartridge_id', load.value.cartridge)
|
||||||
@@ -259,22 +278,43 @@ const add = async () => {
|
|||||||
formData.append('powder_gr', load.value.powderGrs.toString())
|
formData.append('powder_gr', load.value.powderGrs.toString())
|
||||||
formData.append('primer_id', load.value.primer)
|
formData.append('primer_id', load.value.primer)
|
||||||
formData.append('col', load.value.col)
|
formData.append('col', load.value.col)
|
||||||
formData.append('photo', file.value)
|
if (file.value) {
|
||||||
|
formData.append('photo', file.value)
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.post<any, Response<string>>(`${import.meta.env.VITE_API}/load`, formData, {
|
const response = await axios.post<any, Response<string>>(`${import.meta.env.VITE_API}/load${id}`, formData, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data',
|
'Content-Type': 'multipart/form-data',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const message = route.params.id ? 'Load updated' : 'Load added'
|
||||||
|
|
||||||
toast.add({
|
toast.add({
|
||||||
severity: 'success',
|
severity: 'success',
|
||||||
summary: 'Success',
|
summary: 'Success',
|
||||||
detail: 'Load added',
|
detail: message,
|
||||||
life: 3000,
|
life: 3000,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (route.params.id) {
|
||||||
|
load.value = {
|
||||||
|
bullet: '',
|
||||||
|
cartridge: '',
|
||||||
|
powder: '',
|
||||||
|
powderGrs: 0,
|
||||||
|
primer: '',
|
||||||
|
col: '',
|
||||||
|
}
|
||||||
|
file.value = null
|
||||||
|
|
||||||
|
v$.value.$reset()
|
||||||
|
await fetchLoad()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
await router.push(`/loads/edit/${response.data.payload}`)
|
await router.push(`/loads/edit/${response.data.payload}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.add({
|
toast.add({
|
||||||
@@ -284,14 +324,85 @@ const add = async () => {
|
|||||||
life: 3000,
|
life: 3000,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
const deleteLoad = async () => {
|
||||||
|
if (!route.params.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await axios.delete(`${import.meta.env.VITE_API}/load/${route.params.id}`)
|
||||||
|
|
||||||
|
toast.add({
|
||||||
|
severity: 'success',
|
||||||
|
summary: 'Success',
|
||||||
|
detail: 'Load deleted',
|
||||||
|
life: 3000,
|
||||||
|
})
|
||||||
|
|
||||||
|
await router.push('/loads/search')
|
||||||
|
} catch (error) {
|
||||||
|
toast.add({
|
||||||
|
severity: 'error',
|
||||||
|
summary: 'Error',
|
||||||
|
detail: 'Error deleting load',
|
||||||
|
life: 3000,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchLoad = async () => {
|
||||||
|
if (!route.params.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true
|
||||||
|
const response = await axios.get<any, Response<Load>>(`${import.meta.env.VITE_API}/load/${route.params.id}`)
|
||||||
|
|
||||||
|
if (response.data.payload) {
|
||||||
|
load.value.cartridge = response.data.payload.cartridge_id
|
||||||
|
load.value.bullet = response.data.payload.bullet.id
|
||||||
|
load.value.powder = response.data.payload.powder.id
|
||||||
|
load.value.powderGrs = response.data.payload.powder_gr
|
||||||
|
load.value.primer = response.data.payload.primer.id
|
||||||
|
load.value.col = response.data.payload.col.toString()
|
||||||
|
|
||||||
|
if (!load.value.col.includes('.')) {
|
||||||
|
load.value.col = `${load.value.col}.000`
|
||||||
|
} else {
|
||||||
|
const parts = load.value.col.split('.')
|
||||||
|
if (parts[1].length < 3) {
|
||||||
|
load.value.col = `${parts[0]}.${parts[1].padEnd(3, '0')}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
calcUrl()
|
||||||
|
} else {
|
||||||
|
toast.add({
|
||||||
|
severity: 'error',
|
||||||
|
summary: 'Error',
|
||||||
|
detail: 'Load not found',
|
||||||
|
life: 3000,
|
||||||
|
})
|
||||||
|
|
||||||
|
await router.push('/loads')
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchBullets()
|
fetchBullets()
|
||||||
fetchPrimers()
|
fetchPrimers()
|
||||||
fetchPowders()
|
fetchPowders()
|
||||||
fetchCartridges()
|
fetchCartridges()
|
||||||
|
|
||||||
|
if (route.params.id) {
|
||||||
|
setTimeout(() => {
|
||||||
|
fetchLoad()
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -8,13 +8,15 @@
|
|||||||
:value="loads"
|
:value="loads"
|
||||||
filterDisplay="row"
|
filterDisplay="row"
|
||||||
paginator
|
paginator
|
||||||
|
:rowsPerPageOptions="[5, 10, 20, 50]"
|
||||||
size="small"
|
size="small"
|
||||||
:sortField="sortField"
|
:sortField="sortField"
|
||||||
:sortOrder="sortOrder"
|
:sortOrder="sortOrder"
|
||||||
@update:sortField="(e: string) => {sortField = e; fetchLoads()}"
|
@update:sortField="(e: string) => {sortField = e; fetchLoads()}"
|
||||||
@update:sortOrder="(e: number | undefined) => {sortOrder = e; fetchLoads()}"
|
@update:sortOrder="(e: number | undefined) => {sortOrder = e; fetchLoads()}"
|
||||||
|
@page="updatePagination"
|
||||||
|
:rows="rowsPerPage"
|
||||||
lazy
|
lazy
|
||||||
:rows="50"
|
|
||||||
:totalRecords="total"
|
:totalRecords="total"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
>
|
>
|
||||||
@@ -42,7 +44,9 @@
|
|||||||
@change="fetchLoads" />
|
@change="fetchLoads" />
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ data }">
|
<template #body="{ data }">
|
||||||
{{ data.bullet.manufacturer.name }}
|
<a target="_blank" :href="data.bullet.manufacturer.url">
|
||||||
|
{{ data.bullet.manufacturer.name }}
|
||||||
|
</a>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="bullet_name" header="Bullet" :sortable="true" :showFilterMenu="false">
|
<Column field="bullet_name" header="Bullet" :sortable="true" :showFilterMenu="false">
|
||||||
@@ -63,7 +67,9 @@
|
|||||||
@change="fetchLoads" />
|
@change="fetchLoads" />
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ data }">
|
<template #body="{ data }">
|
||||||
{{ data.primer.manufacturer.name }}
|
<a target="_blank" :href="data.primer.manufacturer.url">
|
||||||
|
{{ data.primer.manufacturer.name }}
|
||||||
|
</a>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="primer_name" header="Primer" :sortable="true" :showFilterMenu="false">
|
<Column field="primer_name" header="Primer" :sortable="true" :showFilterMenu="false">
|
||||||
@@ -83,7 +89,9 @@
|
|||||||
@change="fetchLoads" />
|
@change="fetchLoads" />
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ data }">
|
<template #body="{ data }">
|
||||||
{{ data.powder.manufacturer.name }}
|
<a target="_blank" :href="data.powder.manufacturer.url">
|
||||||
|
{{ data.powder.manufacturer.name }}
|
||||||
|
</a>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
|
|
||||||
@@ -104,8 +112,13 @@
|
|||||||
</Column>
|
</Column>
|
||||||
|
|
||||||
<Column field="edit" header="Edit">
|
<Column field="edit" header="Edit">
|
||||||
<template #body>
|
<template #body="{ data }">
|
||||||
<Button size="small" text :icon="icons.edit" />
|
<Button
|
||||||
|
size="small"
|
||||||
|
text
|
||||||
|
:icon="icons.edit"
|
||||||
|
@click="router.push('/loads/edit/' + data.id)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
@@ -116,22 +129,13 @@
|
|||||||
import { Bullet } from '../../types/bullet'
|
import { Bullet } from '../../types/bullet'
|
||||||
import { Powder } from '../../types/powder'
|
import { Powder } from '../../types/powder'
|
||||||
import { Primers } from '../../types/primers'
|
import { Primers } from '../../types/primers'
|
||||||
|
import { Load } from '../../types/Response'
|
||||||
|
|
||||||
interface LoadResponse {
|
interface LoadResponse {
|
||||||
total: number
|
total: number
|
||||||
results: Load[]
|
results: Load[]
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Load {
|
|
||||||
id: string
|
|
||||||
bullet: Bullet
|
|
||||||
cartridge: string
|
|
||||||
powder: Powder
|
|
||||||
powder_gr: number
|
|
||||||
primer: Primers
|
|
||||||
col: number
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Option {
|
interface Option {
|
||||||
label: string
|
label: string
|
||||||
value: string
|
value: string
|
||||||
@@ -143,6 +147,7 @@ import { Response } from '../../types/Response'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import Column from 'primevue/column'
|
import Column from 'primevue/column'
|
||||||
import { icons } from '../../lib/icons.ts'
|
import { icons } from '../../lib/icons.ts'
|
||||||
|
import router from '../../router'
|
||||||
|
|
||||||
const DataTable = defineAsyncComponent(() => import('primevue/datatable'))
|
const DataTable = defineAsyncComponent(() => import('primevue/datatable'))
|
||||||
const Card = defineAsyncComponent(() => import('primevue/card'))
|
const Card = defineAsyncComponent(() => import('primevue/card'))
|
||||||
@@ -151,6 +156,8 @@ const MultiSelect = defineAsyncComponent(() => import('primevue/multiselect'))
|
|||||||
|
|
||||||
const loads = ref<Load[]>([])
|
const loads = ref<Load[]>([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
|
const rowsPerPage = ref(50)
|
||||||
|
const page = ref(1)
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
|
|
||||||
// use local storage to store the selected filters
|
// use local storage to store the selected filters
|
||||||
@@ -181,6 +188,14 @@ const powderManufacturerSelected = ref<string[]>(localStorageFilters.powderManuf
|
|||||||
const powderOptions = ref<Option[]>([])
|
const powderOptions = ref<Option[]>([])
|
||||||
const powderSelected = ref<string[]>(localStorageFilters.powderSelected ?? [])
|
const powderSelected = ref<string[]>(localStorageFilters.powderSelected ?? [])
|
||||||
|
|
||||||
|
const updatePagination = (e: { page: number, rows: number }) => {
|
||||||
|
console.log(e)
|
||||||
|
|
||||||
|
page.value = e.page + 1
|
||||||
|
rowsPerPage.value = e.rows
|
||||||
|
fetchLoads()
|
||||||
|
}
|
||||||
|
|
||||||
const fetchLoads = async () => {
|
const fetchLoads = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
@@ -220,6 +235,9 @@ const fetchLoads = async () => {
|
|||||||
searchParams.unshift(`powder_id=${powderSelected.value.join(',')}`)
|
searchParams.unshift(`powder_id=${powderSelected.value.join(',')}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
searchParams.unshift(`limit=${rowsPerPage.value}`)
|
||||||
|
searchParams.unshift(`page=${page.value}`)
|
||||||
|
|
||||||
localStorage.setItem(localStorageKey, JSON.stringify({
|
localStorage.setItem(localStorageKey, JSON.stringify({
|
||||||
cartridgeSelected: cartridgeSelected.value,
|
cartridgeSelected: cartridgeSelected.value,
|
||||||
bulletManufacturerSelected: bulletManufacturerSelected.value,
|
bulletManufacturerSelected: bulletManufacturerSelected.value,
|
||||||
@@ -257,6 +275,11 @@ onMounted(() => {
|
|||||||
value: bullet.manufacturer.id,
|
value: bullet.manufacturer.id,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// dedupe the bullet Manufacturer options
|
||||||
|
bulletManufacturerOptions.value = bulletManufacturerOptions.value.filter((option, index, self) =>
|
||||||
|
index === self.findIndex((o) => o.value === option.value)
|
||||||
|
)
|
||||||
|
|
||||||
bulletOptions.value = resp.data.payload.map((bullet) => ({
|
bulletOptions.value = resp.data.payload.map((bullet) => ({
|
||||||
label: `${bullet.name} ${bullet.weight}gr .${bullet.diameter}`,
|
label: `${bullet.name} ${bullet.weight}gr .${bullet.diameter}`,
|
||||||
value: bullet.id,
|
value: bullet.id,
|
||||||
@@ -269,6 +292,11 @@ onMounted(() => {
|
|||||||
value: primer.manufacturer.id,
|
value: primer.manufacturer.id,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// dedupe the primer Manufacturer options
|
||||||
|
primerManufacturerOptions.value = primerManufacturerOptions.value.filter((option, index, self) =>
|
||||||
|
index === self.findIndex((o) => o.value === option.value)
|
||||||
|
)
|
||||||
|
|
||||||
primerOptions.value = resp.data.payload.map((primer) => ({
|
primerOptions.value = resp.data.payload.map((primer) => ({
|
||||||
label: primer.name,
|
label: primer.name,
|
||||||
value: primer.id,
|
value: primer.id,
|
||||||
@@ -281,6 +309,11 @@ onMounted(() => {
|
|||||||
value: powder.manufacturer.id,
|
value: powder.manufacturer.id,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// dedupe the powder Manufacturer options
|
||||||
|
powderManufacturerOptions.value = powderManufacturerOptions.value.filter((option, index, self) =>
|
||||||
|
index === self.findIndex((o) => o.value === option.value)
|
||||||
|
)
|
||||||
|
|
||||||
powderOptions.value = resp.data.payload.map((powder) => ({
|
powderOptions.value = resp.data.payload.map((powder) => ({
|
||||||
label: powder.name,
|
label: powder.name,
|
||||||
value: powder.id,
|
value: powder.id,
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ const routes = [
|
|||||||
path: '/loads/search',
|
path: '/loads/search',
|
||||||
component: () => import('../pages/loads/Search.vue'),
|
component: () => import('../pages/loads/Search.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/loads/edit/:id',
|
||||||
|
component: () => import('../pages/loads/Add.vue'),
|
||||||
|
},
|
||||||
] as RouteRecordRaw[]
|
] as RouteRecordRaw[]
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|||||||
14
frontend/src/types/Response.d.ts
vendored
14
frontend/src/types/Response.d.ts
vendored
@@ -1,4 +1,18 @@
|
|||||||
import {AxiosResponse} from "axios";
|
import {AxiosResponse} from "axios";
|
||||||
|
import { Bullet } from './bullet'
|
||||||
|
import { Powder } from './powder'
|
||||||
|
import { Primers } from './primers'
|
||||||
|
|
||||||
|
interface Load {
|
||||||
|
id: string
|
||||||
|
bullet: Bullet
|
||||||
|
cartridge: string
|
||||||
|
cartridge_id: string
|
||||||
|
powder: Powder
|
||||||
|
powder_gr: number
|
||||||
|
primer: Primers
|
||||||
|
col: number
|
||||||
|
}
|
||||||
|
|
||||||
export interface Response<T> extends AxiosResponse {
|
export interface Response<T> extends AxiosResponse {
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
Reference in New Issue
Block a user