add save button and remove asp.net SPA proxy

using the docker compose nginx proxy instead
This commit is contained in:
2023-12-20 12:53:30 +01:00
parent f619cc850a
commit bc158279d8
10 changed files with 100 additions and 103 deletions
@@ -24,12 +24,12 @@ public class CharacterDbModelToDtoService : ICharacterDbModelToDtoService
Osztaly = entity.Osztaly.Convert(),
Tulajdonsagok = new KarakterTulajdonsagokDto
{
T_Ero = entity.Ero,
T_Ugy = entity.Ugyesseg,
T_Egs = entity.Egeszseg,
T_Int = entity.Intelligencia,
T_Bol = entity.Bolcsesseg,
T_Kar = entity.Karizma,
Ero = entity.Ero,
Ugy = entity.Ugyesseg,
Egs = entity.Egeszseg,
Int = entity.Intelligencia,
Bol = entity.Bolcsesseg,
Kar = entity.Karizma,
},
Kepzettsegek = entity.KarakterKepzettsegek.Where(x => !x.IsTolvajKepzettseg).Select(x => x.Kepzettseg.Convert()).ToList(),
Tolvajkepzettsegek = entity.KarakterKepzettsegek.Where(x => x.IsTolvajKepzettseg).Select(x => x.Kepzettseg.Convert()).ToList(),
@@ -23,12 +23,12 @@ public class CharacterDtoToDbModelService : ICharacterDtoToDbModelService
Isten = dto.Isten,
Faj = FajExtensions.Convert(dto.Faj),
Osztaly = OsztalyExtensions.Convert(dto.Osztaly),
Ero = dto.Tulajdonsagok.T_Ero,
Ugyesseg = dto.Tulajdonsagok.T_Ugy,
Egeszseg = dto.Tulajdonsagok.T_Egs,
Intelligencia = dto.Tulajdonsagok.T_Int,
Bolcsesseg = dto.Tulajdonsagok.T_Bol,
Karizma = dto.Tulajdonsagok.T_Kar,
Ero = dto.Tulajdonsagok.Ero,
Ugyesseg = dto.Tulajdonsagok.Ugy,
Egeszseg = dto.Tulajdonsagok.Egs,
Intelligencia = dto.Tulajdonsagok.Int,
Bolcsesseg = dto.Tulajdonsagok.Bol,
Karizma = dto.Tulajdonsagok.Kar,
Szint = dto.Szint,
};
karakter.KarakterKepzettsegek = ConvertKepzettsegek(dto, karakter);
@@ -1,11 +1,19 @@
using System.Text.Json.Serialization;
namespace Kemkas.Web.ViewModels;
public struct KarakterTulajdonsagokDto
{
public byte T_Ero { get; set; }
public byte T_Ugy { get; set; }
public byte T_Egs { get; set; }
public byte T_Int { get; set; }
public byte T_Bol { get; set; }
public byte T_Kar { get; set; }
[JsonPropertyName("t_ero")]
public byte Ero { get; set; }
[JsonPropertyName("t_ugy")]
public byte Ugy { get; set; }
[JsonPropertyName("t_egs")]
public byte Egs { get; set; }
[JsonPropertyName("t_int")]
public byte Int { get; set; }
[JsonPropertyName("t_bol")]
public byte Bol { get; set; }
[JsonPropertyName("t_kar")]
public byte Kar { get; set; }
}
+5
View File
@@ -10,6 +10,11 @@ function App(props: {faro?: Faro}) {
path: "/",
element: <CreateCharacter faro={props.faro} />,
},
{
path: "/:id",
element: <CreateCharacter faro={props.faro} />,
loader: args => fetch(`/Character/${args.params.id}`)
}
]);
return (
@@ -0,0 +1,8 @@
import {Tooltip} from "react-bootstrap";
import React from "react";
const SaveOverlayTooltip = <Tooltip id="save-tooltip">
A mentéssel egyedi URL-en elérhető lesz a karakter bárkinek, azonban módosítani már nem lehet, csak újat menteni.
</Tooltip>
export default SaveOverlayTooltip
@@ -17,23 +17,29 @@ import {
SetDefaultTolvajKepzettsegek,
} from "../domain-models/kepzettsegek";
import {CreatePDF} from "../pdf/character.pdf";
import {KarakterDefaults} from "../domain-models/karakter";
import {KarakterDefaults, KarakterInputs} from "../domain-models/karakter";
import {CalculateMasodlagosErtekek} from "../domain-models/masodlagos_ertekek";
import {KarakterInputToPdfView} from "../pdf/karakter_pdf_view";
import JellemSelector from "../components/JellemSelector";
import {CanLevelUp, LevelDown, LevelUp} from "../domain-models/level";
import {Card} from "react-bootstrap";
import {Card, OverlayTrigger} from "react-bootstrap";
import LevelUps from "../components/LevelUps";
import HarcosFegyverSpecializacio from "../components/HarcosFegyverSpecializacio";
import Felszereles from '../components/Felszereles';
import { KarakterFelszereles } from '../domain-models/felszereles';
import {Faro} from "@grafana/faro-web-sdk";
import {StoreNewCharacter} from "../api/character.api";
import {useLoaderData} from "react-router-dom";
import saveOverlayTooltip from "../components/SaveOverlayTooltip";
function CreateCharacterPage(props: {faro?: Faro}) {
function CreateCharacterPage(props: {
faro?: Faro,
}) {
const {faro} = props
let [karakter, changeKarakter] = useState(KarakterDefaults)
const initialKarakterInputs = useLoaderData() as KarakterInputs;
let [karakter, changeKarakter] = useState(initialKarakterInputs ?? KarakterDefaults)
const tulajdonsagokFajjal = TulajdonsagokFajjal(karakter.tulajdonsagok, karakter.faj)
@@ -50,7 +56,6 @@ function CreateCharacterPage(props: {faro?: Faro}) {
const canLevelUp = CanLevelUp(karakter)
return (
<div>
<div className='container-fluid p-5 bg-black text-white text-center'>
@@ -167,19 +172,37 @@ function CreateCharacterPage(props: {faro?: Faro}) {
<Felszereles osztaly={karakter.osztaly} felszereles={karakter.felszereles}
changeFelszereles={setFelszereles} harcosSpec={karakter.harcosSpecializaciok}/>
<div className='d-grid gap-2 m-5'>
<button className='btn btn-danger btn-lg' type='button' onClick={async () => {
await StoreNewCharacter(karakter)
}}>Mentés
</button>
<button className='btn btn-danger btn-lg' type='button' onClick={async () => {
faro?.api.pushEvent('character_created', {
osztaly: karakter.osztaly,
szint: karakter.szint.toString()
})
await CreatePDF(KarakterInputToPdfView(karakter))
}}>PDF
</button>
<div className="row">
<div className="col-6">
<div className='d-grid gap-2 m-5'>
<OverlayTrigger placement='top' overlay={saveOverlayTooltip} delay={0} defaultShow={false} flip={false}>
<button className='btn btn-danger btn-lg' type='button' onClick={async () => {
faro?.api.pushEvent('public_character_stored', {
osztaly: karakter.osztaly,
szint: karakter.szint.toString()
})
let newId = await StoreNewCharacter(karakter)
const win = window.open(`/${newId}`, '_blank');
if (win != null) {
win.focus();
}
}}>Mentés
</button>
</OverlayTrigger>
</div>
</div>
<div className="col-6">
<div className='d-grid gap-2 m-5'>
<button className='btn btn-danger btn-lg' type='button' onClick={async () => {
faro?.api.pushEvent('character_created', {
osztaly: karakter.osztaly,
szint: karakter.szint.toString()
})
await CreatePDF(KarakterInputToPdfView(karakter))
}}>PDF
</button>
</div>
</div>
</div>
</form>
</div>
-36
View File
@@ -1,36 +0,0 @@
const { createProxyMiddleware } = require('http-proxy-middleware');
const { env } = require('process');
const target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :
env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:40870';
const context = [
"/weatherforecast",
"/_configuration",
"/.well-known",
"/Identity",
"/connect",
"/ApplyDatabaseMigrations",
"/_framework"
];
const onError = (err, req, resp, target) => {
console.error(`${err.message}`);
}
module.exports = function (app) {
const appProxy = createProxyMiddleware(context, {
target: target,
// Handle errors to prevent the proxy middleware from crashing when
// the ASP NET Core webserver is unavailable
onError: onError,
secure: false,
// Uncomment this line to add support for proxying websockets
//ws: true,
headers: {
Connection: 'Keep-Alive'
}
});
app.use(appProxy);
};
-31
View File
@@ -1,31 +0,0 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';
const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
removeItem: jest.fn(),
clear: jest.fn(),
length: 0,
key: jest.fn()
};
global.localStorage = localStorageMock;
// Mock the request issued by the react app to get the client configuration parameters.
window.fetch = () => {
return Promise.resolve(
{
ok: true,
json: () => Promise.resolve({
"authority": "https://localhost:7251",
"client_id": "Kemkas.Web",
"redirect_uri": "https://localhost:7251/authentication/login-callback",
"post_logout_redirect_uri": "https://localhost:7251/authentication/logout-callback",
"response_type": "id_token token",
"scope": "Kemkas.WebAPI openid profile"
})
});
};
+11
View File
@@ -2,6 +2,17 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kemkas.Web", "Kemkas.Web\Kemkas.Web.csproj", "{ABAEE4DC-1A07-40AE-A2B6-4D3755A6C1E8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "General", "General", "{5D06CE1E-DD86-41C0-A1BF-53162BD027AA}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
TODO.md = TODO.md
.gitignore = .gitignore
.dockerignore = .dockerignore
.tool-versions = .tool-versions
.github\dependabot.yml = .github\dependabot.yml
.github\workflows\ci.yml = .github\workflows\ci.yml
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+9
View File
@@ -8,5 +8,14 @@ Kard és Mágia karakter alkotó segédlet (https://app.kemkas.hu)
## Coding readmes
To start development, spin up the docker-compose.yaml file and use the launchSettings.json to start the backend and frontend dev servers.
For the first time setup:
1. start the DB from the docker compose (required for the backend)
2. launch the project with the launchSettings file (will generate SSL certs)
3. spin up the proxy from docker compose (needs the SSL certs)
Later start the docker compose first and the project launch settings after the DB is up and running.
[Frontend README](./frontend/README.md)