Events-WebAPI fix and tweak

This commit is contained in:
Boris Milašinović
2026-05-12 17:23:45 +02:00
parent b66d05c298
commit 3f2e199ec4
12 changed files with 209 additions and 10 deletions

1
.gitignore vendored
View File

@@ -501,6 +501,7 @@ typings/
#bower and libman wwwroot/lib #bower and libman wwwroot/lib
**/wwwroot/lib **/wwwroot/lib
**/logs/internal-nlog.txt **/logs/internal-nlog.txt
Events-WebApi/Events.FilesAPI/GeneratedFiles/
# some needed exceptions # some needed exceptions
/DataGenerator/.dotnet/.dotnet /DataGenerator/.dotnet/.dotnet

View File

@@ -1488,9 +1488,9 @@
} }
}, },
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.5.8", "version": "8.5.14",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz",
"integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@@ -1630,9 +1630,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "6.4.1", "version": "6.4.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz",
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View File

@@ -254,9 +254,13 @@ watch(eventsCatalogVersion, () => {
filterDisplay="menu" filterDisplay="menu"
lazy lazy
paginator paginator
paginatorTemplate="CurrentPageReport FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
showCurrentPageReport
:rows="pageSize" :rows="pageSize"
:rowsPerPageOptions="[10, 25, 50, 100]"
:first="(page - 1) * pageSize" :first="(page - 1) * pageSize"
:total-records="totalRecords" :total-records="totalRecords"
currentPageReportTemplate="{first} to {last} of {totalRecords}"
:sort-field="sort" :sort-field="sort"
:sort-order="sortOrder" :sort-order="sortOrder"
@filter="onFilter" @filter="onFilter"

View File

@@ -327,9 +327,13 @@ onMounted(async () => {
filterDisplay="menu" filterDisplay="menu"
lazy lazy
paginator paginator
paginatorTemplate="CurrentPageReport FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
showCurrentPageReport
:rows="pageSize" :rows="pageSize"
:rowsPerPageOptions="[10, 25, 50, 100]"
:first="(page - 1) * pageSize" :first="(page - 1) * pageSize"
:total-records="totalRecords" :total-records="totalRecords"
currentPageReportTemplate="{first} to {last} of {totalRecords}"
:sort-field="sort" :sort-field="sort"
:sort-order="sortOrder" :sort-order="sortOrder"
@filter="onFilter" @filter="onFilter"

View File

@@ -405,9 +405,13 @@ onMounted(async () => {
filterDisplay="menu" filterDisplay="menu"
lazy lazy
paginator paginator
paginatorTemplate="CurrentPageReport FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
showCurrentPageReport
:rows="pageSize" :rows="pageSize"
:rowsPerPageOptions="[10, 25, 50, 100]"
:first="(page - 1) * pageSize" :first="(page - 1) * pageSize"
:total-records="totalRecords" :total-records="totalRecords"
currentPageReportTemplate="{first} to {last} of {totalRecords}"
:sort-field="sort" :sort-field="sort"
:sort-order="sortOrder" :sort-order="sortOrder"
@filter="onFilter" @filter="onFilter"
@@ -500,8 +504,8 @@ onMounted(async () => {
optionLabel="name" optionLabel="name"
:minLength="1" :minLength="1"
completeOnFocus completeOnFocus
dropdown fluid
dropdownMode="current" showClear
force-selection force-selection
@complete="completePeopleLookup" @complete="completePeopleLookup"
> >

View File

@@ -188,9 +188,13 @@ onMounted(() => {
filterDisplay="menu" filterDisplay="menu"
lazy lazy
paginator paginator
paginatorTemplate="CurrentPageReport FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
showCurrentPageReport
:rows="pageSize" :rows="pageSize"
:rowsPerPageOptions="[10, 25, 50, 100]"
:first="(page - 1) * pageSize" :first="(page - 1) * pageSize"
:total-records="totalRecords" :total-records="totalRecords"
currentPageReportTemplate="{first} to {last} of {totalRecords}"
:sort-field="sort" :sort-field="sort"
:sort-order="sortOrder" :sort-order="sortOrder"
@filter="onFilter" @filter="onFilter"

View File

@@ -42,6 +42,28 @@ body {
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 8px 24px rgba(15, 35, 56, 0.06); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 8px 24px rgba(15, 35, 56, 0.06);
} }
.panel-card .p-paginator {
position: relative;
justify-content: center;
}
.panel-card .p-paginator-current {
position: absolute;
left: 0;
}
@media (max-width: 768px) {
.panel-card .p-paginator {
justify-content: flex-start;
row-gap: 0.5rem;
padding-top: 2rem;
}
.panel-card .p-paginator-current {
top: 0.25rem;
}
}
.tabs-header-bar { .tabs-header-bar {
display: grid; display: grid;
grid-template-columns: 1fr auto 1fr; grid-template-columns: 1fr auto 1fr;

View File

@@ -1,4 +1,8 @@
using Events.Auth; using Events.Auth;
using Events.FilesAPI.Features.Certificates.Download;
using Events.FilesAPI.Features.Certificates.Synchronize;
using Events.FilesAPI.Features.RegistrationsExcel.Download;
using Events.FilesAPI.Features.RegistrationsExcel.Synchronize;
using Events.FilesAPI.Infrastructure.Messaging; using Events.FilesAPI.Infrastructure.Messaging;
using Events.FilesAPI.Infrastructure.Options; using Events.FilesAPI.Infrastructure.Options;
using Events.WebAPI.Handlers.EF.Data.Postgres; using Events.WebAPI.Handlers.EF.Data.Postgres;
@@ -19,6 +23,11 @@ builder.Services.AddOptions<GeneratedFilesOptions>()
"GeneratedFilesOptions:OutputPath must be configured.") "GeneratedFilesOptions:OutputPath must be configured.")
.ValidateOnStart(); .ValidateOnStart();
builder.Services.AddTransient<CertificateFileGenerator>();
builder.Services.AddTransient<CertificateFileLocator>();
builder.Services.AddTransient<RegistrationsExcelFileGenerator>();
builder.Services.AddTransient<RegistrationsExcelFileLocator>();
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly)); builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));
builder.Services.SetupMassTransit(builder.Configuration); builder.Services.SetupMassTransit(builder.Configuration);

View File

@@ -12,7 +12,7 @@
"Password": "guest" "Password": "guest"
}, },
"Paths": { "Paths": {
"OutputPath": "./Certificates" "OutputPath": "./GeneratedFiles"
}, },
"ConnectionStrings": { "ConnectionStrings": {
"EventsPostgres": "Host=localhost;Port=5432;Database=events;Username=sport;Password=go and look in the secrets file;Persist Security Info=True;" "EventsPostgres": "Host=localhost;Port=5432;Database=events;Username=sport;Password=go and look in the secrets file;Persist Security Info=True;"

View File

@@ -159,6 +159,35 @@ Once the APIs are running:
- most `WebAPI` endpoints require a bearer token - most `WebAPI` endpoints require a bearer token
- `FilesAPI` download endpoints are also protected and require the `events:read` scope - `FilesAPI` download endpoints are also protected and require the `events:read` scope
## Running Everything Without VS Code
From the `Events-WebApi` directory, you can start all three processes together with:
```bash
./start-all.sh
```
This starts:
- `Events.WebAPI` on `https://localhost:7295`
- `Events.FilesAPI` on `https://localhost:7296`
- `Events.ClientApp` on `http://localhost:5173`
The script keeps all processes attached to the terminal and stops them together when you press `Ctrl+C`.
If you want to stop the stack from another terminal, use:
```bash
./stop-all.sh
```
Before the first run, make sure the client dependencies are installed:
```bash
cd Events.ClientApp
npm install
```
## Running The Client App ## Running The Client App
See [Events.ClientApp/README.md](/C:/GitRepos/FPMOZ-PI/predavanja/Events-WebApi/Events.ClientApp/README.md:1) for more details. See [Events.ClientApp/README.md](/C:/GitRepos/FPMOZ-PI/predavanja/Events-WebApi/Events.ClientApp/README.md:1) for more details.
@@ -180,7 +209,7 @@ npm run dev
According to the current `appsettings.json`, the default is: According to the current `appsettings.json`, the default is:
```text ```text
./Certificates ./GeneratedFiles
``` ```
## Troubleshooting ## Troubleshooting

86
Events-WebApi/start-all.sh Executable file
View File

@@ -0,0 +1,86 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WEBAPI_PROJECT="$ROOT_DIR/Events.WebAPI/Events.WebAPI.csproj"
FILESAPI_PROJECT="$ROOT_DIR/Events.FilesAPI/Events.FilesAPI.csproj"
CLIENTAPP_DIR="$ROOT_DIR/Events.ClientApp"
pids=()
start_process() {
if command -v setsid >/dev/null 2>&1; then
setsid "$@" &
else
"$@" &
fi
pids+=($!)
}
stop_process() {
local signal="$1"
local pid="$2"
kill "-$signal" -- "-$pid" 2>/dev/null || kill "-$signal" "$pid" 2>/dev/null || true
}
cleanup() {
local exit_code=$?
trap - INT TERM EXIT
if ((${#pids[@]} > 0)); then
echo
echo "Stopping Events stack..."
for pid in "${pids[@]}"; do
stop_process INT "$pid"
done
sleep 1
for pid in "${pids[@]}"; do
stop_process TERM "$pid"
done
sleep 1
for pid in "${pids[@]}"; do
stop_process KILL "$pid"
done
wait "${pids[@]}" 2>/dev/null || true
fi
exit "$exit_code"
}
trap cleanup INT TERM EXIT
if [[ ! -d "$CLIENTAPP_DIR/node_modules" ]]; then
echo "Missing node_modules in Events.ClientApp."
echo "Run: cd \"$CLIENTAPP_DIR\" && npm install"
exit 1
fi
"$ROOT_DIR/stop-all.sh" >/dev/null 2>&1 || true
echo "Starting Events.WebAPI on https://localhost:7295"
start_process dotnet run --launch-profile https --project "$WEBAPI_PROJECT"
echo "Starting Events.FilesAPI on https://localhost:7296"
start_process dotnet run --launch-profile https --project "$FILESAPI_PROJECT"
echo "Starting Events.ClientApp on http://localhost:5173"
start_process env CLIENTAPP_DIR="$CLIENTAPP_DIR" bash -c 'cd "$CLIENTAPP_DIR" && npm run dev'
echo
echo "Events stack is starting."
echo "WebAPI: https://localhost:7295"
echo "FilesAPI: https://localhost:7296"
echo "ClientApp: http://localhost:5173"
echo
echo "Press Ctrl+C to stop all processes."
wait

36
Events-WebApi/stop-all.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -euo pipefail
kill_port() {
local port="$1"
local pids
pids="$(lsof -tiTCP:"$port" -sTCP:LISTEN 2>/dev/null || true)"
if [[ -z "$pids" ]]; then
return 0
fi
kill $pids 2>/dev/null || true
sleep 1
pids="$(lsof -tiTCP:"$port" -sTCP:LISTEN 2>/dev/null || true)"
if [[ -n "$pids" ]]; then
kill -9 $pids 2>/dev/null || true
fi
}
echo "Stopping Events.WebAPI..."
kill_port 7295
pkill -f "/Events.WebAPI/bin/.*/Events.WebAPI" || true
echo "Stopping Events.FilesAPI..."
kill_port 7296
pkill -f "/Events.FilesAPI/bin/.*/Events.FilesAPI" || true
echo "Stopping Events.ClientApp..."
kill_port 5173
pkill -f "Events.ClientApp.*node_modules/.bin/vite" || true
pkill -f "vite" || true
echo "Events stack stopped."