You've already forked reloading-manager
tagging release w.t.f.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ 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"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -45,6 +46,7 @@ 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"`
|
||||||
|
CartridgeId string `json:"cartridge_id"`
|
||||||
Col float32 `json:"col"`
|
Col float32 `json:"col"`
|
||||||
Powder handlers.Powder `json:"powder"`
|
Powder handlers.Powder `json:"powder"`
|
||||||
PowderGr float32 `json:"powder_gr"`
|
PowderGr float32 `json:"powder_gr"`
|
||||||
@@ -134,15 +136,40 @@ func Post(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
@@ -157,14 +184,35 @@ func Get(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}(cTotal)
|
}(cTotal)
|
||||||
|
go execResultsQuery(cResults, c)
|
||||||
|
|
||||||
go func(ch chan ResultChan[[]loadResponseResults]) {
|
total := <-cTotal
|
||||||
|
if total.Err != nil {
|
||||||
|
return total.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
results := <-cResults
|
||||||
|
if results.Err != nil {
|
||||||
|
return results.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
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, false)
|
q := getQuery(c, false)
|
||||||
|
|
||||||
|
if q == nil {
|
||||||
|
ch <- ResultChan[[]loadResponseResults]{Result: []loadResponseResults{}}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println(q.DebugSql())
|
fmt.Println(q.DebugSql())
|
||||||
|
|
||||||
sql, params := q.Sql()
|
sql, params := q.Sql()
|
||||||
@@ -172,7 +220,6 @@ func Get(c echo.Context) error {
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ch <- ResultChan[[]loadResponseResults]{Err: err}
|
ch <- ResultChan[[]loadResponseResults]{Err: err}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,6 +265,7 @@ func Get(c echo.Context) error {
|
|||||||
results = append(results, loadResponseResults{
|
results = append(results, loadResponseResults{
|
||||||
Id: row.ID.String(),
|
Id: row.ID.String(),
|
||||||
Cartridge: row.CartridgeName,
|
Cartridge: row.CartridgeName,
|
||||||
|
CartridgeId: row.CartridgeID.String(),
|
||||||
Col: row.Col,
|
Col: row.Col,
|
||||||
Powder: handlers.Powder{
|
Powder: handlers.Powder{
|
||||||
Id: row.PowderID.String(),
|
Id: row.PowderID.String(),
|
||||||
@@ -251,19 +299,6 @@ func Get(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ch <- ResultChan[[]loadResponseResults]{Result: results}
|
ch <- ResultChan[[]loadResponseResults]{Result: results}
|
||||||
}(cResults)
|
|
||||||
|
|
||||||
total := <-cTotal
|
|
||||||
if total.Err != nil {
|
|
||||||
return total.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
results := <-cResults
|
|
||||||
if results.Err != nil {
|
|
||||||
return results.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, handlers.Response[loadResponse]{Status: http.StatusText(http.StatusOK), Payload: loadResponse{Total: int(total.Result), Results: results.Result}})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getQuery(c echo.Context, countOnly bool) postgres.SelectStatement {
|
func getQuery(c echo.Context, countOnly bool) postgres.SelectStatement {
|
||||||
@@ -289,7 +324,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 +363,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,13 +483,15 @@ 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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ func main() {
|
|||||||
|
|
||||||
// loads
|
// loads
|
||||||
e.GET("/load", loads.Get)
|
e.GET("/load", loads.Get)
|
||||||
|
e.GET("/load/:id", loads.Get)
|
||||||
e.POST("/load", loads.Post)
|
e.POST("/load", loads.Post)
|
||||||
|
|
||||||
addr := fmt.Sprintf("0.0.0.0:%s", Port.GetEnvString("8080"))
|
addr := fmt.Sprintf("0.0.0.0:%s", Port.GetEnvString("8080"))
|
||||||
|
|||||||
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">
|
||||||
@@ -103,6 +104,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
|
<FullScreenLoader :loading="loading" />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
interface Select {
|
interface Select {
|
||||||
@@ -121,13 +123,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 +143,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 +151,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)
|
||||||
@@ -191,21 +198,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 +218,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,7 +240,6 @@ 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()
|
||||||
|
|
||||||
@@ -284,14 +286,46 @@ const add = async () => {
|
|||||||
life: 3000,
|
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
|
||||||
|
} 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) {
|
||||||
|
fetchLoad()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
</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 }">
|
||||||
|
<a target="_blank" :href="data.bullet.manufacturer.url">
|
||||||
{{ data.bullet.manufacturer.name }}
|
{{ 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 }">
|
||||||
|
<a target="_blank" :href="data.primer.manufacturer.url">
|
||||||
{{ data.primer.manufacturer.name }}
|
{{ 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 }">
|
||||||
|
<a target="_blank" :href="data.powder.manufacturer.url">
|
||||||
{{ data.powder.manufacturer.name }}
|
{{ 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,
|
||||||
@@ -269,6 +287,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 +304,12 @@ 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