feat 2e save to DB

not fully tested, but seems to work overall
This commit is contained in:
2024-02-20 14:55:08 +01:00
parent 41e894cd42
commit 636dcb92b3
16 changed files with 372 additions and 47 deletions
@@ -12,14 +12,14 @@ namespace Kemkas.Web.Controllers;
/// </summary>
/// <param name="validationService"></param>
/// <param name="dtoToDbModelService"></param>
/// <param name="dbModelToDtoService"></param>
/// <param name="dbModelToDto1EService"></param>
/// <param name="persistenceService"></param>
[ApiController]
[Route("[controller]")]
public class Character1EController(
ICharacterValidationService validationService,
ICharacter1EDtoToDbModelService dtoToDbModelService,
ICharacterDbModelToDtoService dbModelToDtoService,
ICharacterDbModelToDto1EService dbModelToDto1EService,
ICharacterPersistenceService persistenceService)
: ControllerBase
{
@@ -58,7 +58,7 @@ public class Character1EController(
return NotFound();
}
return dbModelToDtoService.Convert(entity);
return dbModelToDto1EService.Convert(entity);
}
[HttpPost("{id:guid}")]
@@ -11,7 +11,8 @@ namespace Kemkas.Web.Controllers;
[Route("[controller]")]
public class Character2EController(
ICharacter2EDtoToDbModelService dtoToDbModelService,
ICharacterPersistenceService persistenceService
ICharacterPersistenceService persistenceService,
ICharacterDbModelToDto2EService dbModelToDtoService
) : ControllerBase
{
[HttpPost]
@@ -39,5 +40,50 @@ public class Character2EController(
var id = await persistenceService.StoreNewCharacter2E(model, isPublic);
return id;
}
[HttpGet("{id:guid}")]
public async Task<ActionResult<Character2eDto>> GetCharacterById([FromRoute] Guid id)
{
var entity = await persistenceService.GetCharacter2EById(id);
if (entity is null)
{
return NotFound();
}
return dbModelToDtoService.Convert(entity);
}
[HttpPost("{id:guid}")]
public async Task<ActionResult<Guid>> UpdateCharacter([FromRoute] Guid id, [FromBody] Character2eDto dto, [FromQuery]bool isPublic = true)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// var errors = validationService.Validate(dto);
// if (errors != null)
// {
// return BadRequest(errors);
// }
var original = await persistenceService.GetCharacter2EById(id, tracking: true);
if (original is null)
{
return NotFound();
}
try
{
dtoToDbModelService.Update(original, dto);
}
catch (ValidationException ex)
{
return BadRequest(ex.Message);
}
await persistenceService.UpdateCharacter2E(original, isPublic);
return id;
}
}
+1 -1
View File
@@ -20,7 +20,7 @@ public enum Osztaly2E
Harcos = 1,
Ijasz = 2,
Amazon = 3,
Kaloz = 4,
Tengeresz = 4,
Barbar = 5,
Pap = 6,
Tolvaj = 7,
+2 -2
View File
@@ -28,7 +28,7 @@ public static class OsztalyExtensions
"o_2e_harcos" => Osztaly2E.Harcos,
"o_2e_ijasz" => Osztaly2E.Ijasz,
"o_2e_amazon" => Osztaly2E.Amazon,
"o_2e_kaloz" => Osztaly2E.Kaloz,
"o_2e_tengeresz" => Osztaly2E.Tengeresz,
"o_2e_barbar" => Osztaly2E.Barbar,
"o_2e_pap" => Osztaly2E.Pap,
"o_2e_tolvaj" => Osztaly2E.Tolvaj,
@@ -65,7 +65,7 @@ public static class OsztalyExtensions
Osztaly2E.Harcos => "o_2e_harcos",
Osztaly2E.Ijasz => "o_2e_ijasz",
Osztaly2E.Amazon => "o_2e_amazon",
Osztaly2E.Kaloz => "o_2e_kaloz",
Osztaly2E.Tengeresz => "o_2e_tengeresz",
Osztaly2E.Barbar => "o_2e_barbar",
Osztaly2E.Pap => "o_2e_pap",
Osztaly2E.Tolvaj => "o_2e_tolvaj",
+3 -1
View File
@@ -8,6 +8,7 @@ using Kemkas.Web.Db;
using Kemkas.Web.Db.Models;
using Kemkas.Web.Services.FirstEdition.Character;
using Kemkas.Web.Services.Identity;
using Kemkas.Web.Services.SecondEdition.Character;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Identity.UI.Services;
@@ -51,7 +52,8 @@ builder.AddOpenTelemetry();
builder.Services.AddHealthChecks();
builder.Services.AddCharacterServices();
builder.Services.AddCharacter1EServices();
builder.Services.AddCharacter2EServices();
var app = builder.Build();
app.UsePathBase("/api");
@@ -4,12 +4,12 @@ using Kemkas.Web.ViewModels;
namespace Kemkas.Web.Services.FirstEdition.Character;
public interface ICharacterDbModelToDtoService
public interface ICharacterDbModelToDto1EService
{
public Character1eDto Convert(V1Karakter entity);
}
public class CharacterDbModelToDtoService : ICharacterDbModelToDtoService
public class CharacterDbModelToDto1EService : ICharacterDbModelToDto1EService
{
public Character1eDto Convert(V1Karakter entity)
{
@@ -5,13 +5,13 @@ namespace Kemkas.Web.Services.FirstEdition.Character;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddCharacterServices(this IServiceCollection serviceCollection)
public static IServiceCollection AddCharacter1EServices(this IServiceCollection serviceCollection)
{
serviceCollection.AddScoped<ICurrentUserService, CurrentUserService>();
serviceCollection.AddTransient<ICharacterValidationService, CharacterValidationService>();
serviceCollection.AddTransient<ICharacter1EDtoToDbModelService, Character1EDtoToDbModelService>();
serviceCollection.AddTransient<ICharacterDbModelToDtoService, CharacterDbModelToDtoService>();
serviceCollection.AddTransient<ICharacterDbModelToDto1EService, CharacterDbModelToDto1EService>();
serviceCollection.AddScoped<ICharacterPersistenceService, CharacterPersistenceService>();
return serviceCollection;
}
@@ -11,7 +11,7 @@ public interface ICharacter2EDtoToDbModelService
public void Update(V2Karakter original, Character2eDto dto);
}
public class Character1EDtoToDbModelService : ICharacter2EDtoToDbModelService
public class Character2EDtoToDbModelService : ICharacter2EDtoToDbModelService
{
public V2Karakter Convert(Character2eDto dto)
{
@@ -57,7 +57,38 @@ public class Character1EDtoToDbModelService : ICharacter2EDtoToDbModelService
public void Update(V2Karakter original, Character2eDto dto)
{
throw new NotImplementedException();
original.Nev = dto.Nev;
original.Nem = dto.Nem;
original.Kor = dto.Kor;
original.Isten = dto.Isten;
original.Jellem = JellemExtensions.Convert(dto.Jellem);
original.Faj = FajExtensions.Convert2E(dto.Faj);
original.Ero = dto.Tulajdonsagok.Ero;
original.Ugyesseg = dto.Tulajdonsagok.Ugy;
original.Egeszseg = dto.Tulajdonsagok.Egs;
original.Intelligencia = dto.Tulajdonsagok.Int;
original.Bolcsesseg = dto.Tulajdonsagok.Bol;
original.Karizma = dto.Tulajdonsagok.Kar;
original.Szint = dto.Szint;
original.Pajzs = dto.Felszereles.PajzsId;
original.Pancel = dto.Felszereles.PancelId;
original.KarakterKepzettsegek = ConvertKarakterKepzettsegek(dto, original);
original.Felszereles = dto.Felszereles.FegyverIds.Select(x => new V2Felszereles
{
Karakter = original,
IsFegyver = true,
TargyId = x,
}).ToList();
original.Szintlepesek = dto.Szintlepesek.Select((x, i) => new V2Szintlepes
{
Karakter = original,
Osztaly = OsztalyExtensions.Convert2E(x.Osztaly),
KarakterSzint = (byte)(i + 1),
HpRoll = x.HProll,
FegyverSpecializacio = x.HarcosFegyver ?? x.KalozKritikus,
TulajdonsagNoveles = x.TulajdonsagNoveles == null ? null : TulajdonsagExtensions.Convert(x.TulajdonsagNoveles),
TolvajExtraKepzettseg = x.TolvajExtraKepzettseg == null ? null : KepzettsegExtensions.Convert2E(x.TolvajExtraKepzettseg),
}).ToList();
}
private static List<V2KarakterKepzettseg> ConvertKarakterKepzettsegek(Character2eDto dto, V2Karakter karakter)
@@ -0,0 +1,54 @@
using Kemkas.Web.Db.Enums;
using Kemkas.Web.Db.Models;
using Kemkas.Web.ViewModels;
namespace Kemkas.Web.Services.SecondEdition.Character;
public interface ICharacterDbModelToDto2EService
{
public Character2eDto Convert(V2Karakter entity);
}
public class CharacterDbModelToDto2EService : ICharacterDbModelToDto2EService
{
public Character2eDto Convert(V2Karakter entity)
{
return new Character2eDto
{
Nev = entity.Nev,
Nem = entity.Nem,
Kor = entity.Kor,
Jellem = entity.Jellem.Convert(),
Isten = entity.Isten,
Faj = entity.Faj.Convert(),
Tulajdonsagok = new KarakterTulajdonsagokDto
{
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(),
Szint = entity.Szint,
Felszereles = new KarakterFelszerelesDto
{
PajzsId = entity.Pajzs,
PancelId = entity.Pancel,
FegyverIds = entity.Felszereles.Where(x => x.IsFegyver).Select(x => x.TargyId).ToList(),
},
IsPublic = entity.IsPublic,
Szintlepesek = entity.Szintlepesek.OrderBy(x => x.KarakterSzint).Select(sz => new Szintlepes
{
Osztaly = sz.Osztaly.Convert(),
KalozKritikus = sz.Osztaly == Osztaly2E.Tengeresz ? sz.FegyverSpecializacio : null,
HarcosFegyver = sz.Osztaly == Osztaly2E.Harcos ? sz.FegyverSpecializacio : null,
TulajdonsagNoveles = sz.TulajdonsagNoveles?.Convert(),
HProll = sz.HpRoll,
TolvajExtraKepzettseg = sz.TolvajExtraKepzettseg?.Convert()
}).ToList()
};
}
}
@@ -0,0 +1,11 @@
namespace Kemkas.Web.Services.SecondEdition.Character;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddCharacter2EServices(this IServiceCollection serviceCollection)
{
serviceCollection.AddTransient<ICharacter2EDtoToDbModelService, Character2EDtoToDbModelService>();
serviceCollection.AddTransient<ICharacterDbModelToDto2EService, CharacterDbModelToDto2EService>();
return serviceCollection;
}
}
@@ -54,13 +54,13 @@ public class CharacterPersistenceService(
public async Task<V1Karakter?> GetCharacter1EById(Guid id, bool tracking = false)
{
IQueryable<V1Karakter> queriable = dbContext.Karakterek.Include(x => x.KarakterKepzettsegek)
IQueryable<V1Karakter> queryable = dbContext.Karakterek.Include(x => x.KarakterKepzettsegek)
.Include(x => x.Szintlepesek)
.Include(x => x.Felszereles);
queriable = tracking ? queriable.AsTracking() : queriable.AsNoTracking();
queryable = tracking ? queryable.AsTracking() : queryable.AsNoTracking();
var entity = await queriable
var entity = await queryable
.FirstOrDefaultAsync(x => x.Id == id);
if (entity?.OwnerUserId is null || entity.IsPublic)
@@ -74,13 +74,13 @@ public class CharacterPersistenceService(
public async Task<V2Karakter?> GetCharacter2EById(Guid id, bool tracking = false)
{
IQueryable<V2Karakter> queriable = dbContext.Karakterek2E.Include(x => x.KarakterKepzettsegek)
IQueryable<V2Karakter> queryable = dbContext.Karakterek2E.Include(x => x.KarakterKepzettsegek)
.Include(x => x.Szintlepesek)
.Include(x => x.Felszereles);
queriable = tracking ? queriable.AsTracking() : queriable.AsNoTracking();
queryable = tracking ? queryable.AsTracking() : queryable.AsNoTracking();
var entity = await queriable
var entity = await queryable
.FirstOrDefaultAsync(x => x.Id == id);
if (entity?.OwnerUserId is null || entity.IsPublic)
@@ -113,19 +113,28 @@ public class CharacterPersistenceService(
})
.ToListAsync();
var characters2E = await dbContext.Karakterek2E
var characters2ERaw = await dbContext.Karakterek2E.Include(k => k.Szintlepesek)
.Where(k => k.OwnerUserId == currentUser.Id)
.Select(k => new CharacterListItemDto
.Select(k => new
{
Id = k.Id,
Name = k.Nev,
Szint = k.Szint,
Faj = k.Faj.Convert(),
Osztaly = "TODO!", // TODO: support for multiclass characters
Edition = "2e"
k.Id,
k.Nev,
k.Szint,
k.Faj,
Osztalyok = k.Szintlepesek.Select(x => x.Osztaly).ToList(),
})
.ToListAsync();
var characters2E = characters2ERaw.Select(k => new CharacterListItemDto
{
Id = k.Id,
Name = k.Nev,
Szint = k.Szint,
Faj = k.Faj.Convert(),
Osztaly = string.Join('/', k.Osztalyok.Select(o => o.Convert())),
Edition = "2e"
});
characters.AddRange(characters2E);
return characters;
+2 -2
View File
@@ -71,12 +71,12 @@ function App(props: {faro?: Faro}) {
},
{
path: "/2e/karakter",
element: <CreateCharacter2E />,
element: <CreateCharacter2E faro={props.faro}/>,
ErrorBoundary: ErrorBoundary,
},
{
path: "/2e/karakter/:id",
element: <CreateCharacter faro={props.faro}/>,
element: <CreateCharacter2E faro={props.faro}/>,
loader: args => fetch(`${window.location.origin}/api/Character2E/${args.params.id}`),
ErrorBoundary: ErrorBoundary,
},
@@ -30,4 +30,3 @@ export async function UpdateCharacter(id: string, karakter: KarakterInputs, isPu
throw Error(response.statusText)
}
}
@@ -0,0 +1,32 @@
import axios from "axios";
import {Karakter2E} from "../domain-models/karakter2E";
export async function StoreNewCharacter2E(karakter: Karakter2E, isPublic: boolean = false) {
let response = await axios.post(`${window.location.origin}/api/Character2E/`, karakter, {
withCredentials: true,
params: {
isPublic,
}
})
if (response.status < 300){
return response.data as string
}
else {
throw Error(response.statusText)
}
}
export async function UpdateCharacter2E(id: string, karakter: Karakter2E, isPublic: boolean = false) {
let response = await axios.post(`${window.location.origin}/api/Character2E/${id}`, karakter, {
withCredentials: true,
params: {
isPublic,
}
})
if (response.status < 300){
return response.data as string
}
else {
throw Error(response.statusText)
}
}
@@ -1,7 +1,7 @@
import React, {useState} from 'react'
import {useParams} from "react-router-dom";
import {Toast, ToastContainer} from "react-bootstrap";
import {ChangeLvl1Osztaly, DefaultKarakter} from "../domain-models/karakter2E";
import React, {useContext, useState} from 'react'
import {useLoaderData, useNavigate, useParams} from "react-router-dom";
import {Button, InputGroup, Modal, OverlayTrigger, Toast, ToastContainer, Tooltip} from "react-bootstrap";
import {ChangeLvl1Osztaly, DefaultKarakter, Karakter2E} from "../domain-models/karakter2E";
import {KarakterTulajdonsagok} from "../domain-models/tulajdonsag2E";
import FajSelector2E from "../components/FajSelector2E";
import Tulajdonsagok2E from "../components/Tulajdonsagok2E";
@@ -24,12 +24,31 @@ import LevelUps from "../components/LevelUps";
import {LevelDown, LevelUp} from "../domain-models/szintlepes";
import HarcosFegyverSpecializacio from "../components/HarcosFegyverSpec";
import {arraySetN} from "../../util";
import saveOverlayTooltip from "../../first-edition/components/SaveOverlayTooltip";
import {UserContext} from "../../shared/contexts/UserContext";
import {
StoreNewCharacter2E,
UpdateCharacter2E
} from "../api/character.api";
import {Faro} from "@grafana/faro-web-sdk";
import Form from "react-bootstrap/Form";
function CreateCharacter2E(props: {}) {
function CreateCharacter2E(props: {
faro?: Faro
}) {
const {faro} = props
const { id } = useParams();
const fetchedUser = useContext(UserContext);
const loaderData = useLoaderData() as Karakter2E & { isPublic: boolean } | undefined;
let initialKarakterInputs = DefaultKarakter;
if (loaderData != null) {
const { isPublic: t1, ...t2 } = loaderData;
initialKarakterInputs = t2
}
const initialIsPublic = loaderData?.isPublic ?? fetchedUser?.data == null;
const navigate = useNavigate();
const [karakter, setKarakter] = useState(DefaultKarakter)
const [karakter, setKarakter] = useState(initialKarakterInputs)
const tulajdonsagokFajjal = TulajdonsagokFajjal(karakter.tulajdonsagok, karakter.faj)
const changeKepzettseg = (k: KepzettsegId[]) => setKarakter({...karakter, kepzettsegek: k})
const changeTolvajKepzettseg = (tk?: KepzettsegId[]) => setKarakter({...karakter, tolvajKepzettsegek: tk})
@@ -37,9 +56,44 @@ function CreateCharacter2E(props: {}) {
SetDefaultKepzettsegek({...karakter, tulajdonsagok: tulajdonsagokFajjal}, changeKepzettseg)
const changeFelszereles = (f: KarakterFelszereles) => setKarakter({...karakter, felszereles: f})
let [showSaveModal, setShowSaveModal] = useState(false);
let [newId, setNewId] = useState(null as string | null)
let [showSaved, setShowSaved] = useState(false);
let [isPublic, setIsPublic] = useState(initialIsPublic);
const newCharacterUrl = () => `${window.location.origin}/2e/karakter/${newId}`
const handleSaveModalCopyAndClose = async () => {
await navigator.clipboard.writeText(newCharacterUrl());
handleSaveModalClose()
}
const handleSaveModalClose = () => {
setShowSaveModal(false);
navigate(`/2e/karakter/${newId}`)
}
const hideSaved = () => setShowSaved(false);
const onSaveClicked = async () => {
faro?.api.pushEvent('character_stored', {
osztaly: karakter.szintlepesek[0].osztaly.toString(),
szint: karakter.szint.toString(),
faj: karakter.faj.toString(),
is_public: isPublic.toString(),
edition: "2e",
})
if (id == null) {
let recievedId = await StoreNewCharacter2E(karakter, isPublic);
setNewId(recievedId)
setShowSaveModal(true);
} else {
await UpdateCharacter2E(id, karakter, isPublic);
setShowSaved(true);
setTimeout(() => {
hideSaved();
}, 5000)
}
}
return <div>
<div className='container-fluid p-5 bg-black text-white text-center'>
@@ -50,6 +104,28 @@ function CreateCharacter2E(props: {}) {
<Toast.Header><strong>Karakter mentve!</strong></Toast.Header>
</Toast>
</ToastContainer>
<Modal show={showSaveModal} onHide={handleSaveModalClose}>
<Modal.Header closeButton>
<Modal.Title>Karakter mentve!</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>Karaktered az alábbi {isPublic ? 'publikus' : 'privát'} URLen érhető el.</p>
<p><a href={newCharacterUrl()}>{newCharacterUrl()}</a></p>
<InputGroup className="mb-3">
<Form.Control id="input" value={newCharacterUrl()} />
<Button variant={"outline-dark"} onClick={() => {
let copyText = document.querySelector("#input") as any;
copyText?.select()
document.execCommand("copy");
}}>Másolás</Button>
</InputGroup>
</Modal.Body>
<Modal.Footer>
<Button variant="danger" onClick={handleSaveModalCopyAndClose}>
Másolás és bezárás
</Button>
</Modal.Footer>
</Modal>
<div className='p-3'>
<form onSubmit={async (event) => event.preventDefault()}>
<div className='row'>
@@ -107,10 +183,15 @@ function CreateCharacter2E(props: {}) {
changeOsztaly={o => setKarakter(ChangeLvl1Osztaly(karakter, o))}
/>
{karakter.szintlepesek[0].osztaly === Osztaly2E.Harcos &&
<HarcosFegyverSpecializacio
<HarcosFegyverSpecializacio
specialization={karakter.szintlepesek[0].harcosFegyver || 'kard_hosszu'}
szint={1}
changeSpecialization={(spec) => setKarakter({...karakter, szintlepesek: arraySetN(karakter.szintlepesek, 0, {...karakter.szintlepesek[0], harcosFegyver: spec})})}
changeSpecialization={(spec) => setKarakter({...karakter,
szintlepesek: arraySetN(karakter.szintlepesek, 0, {
...karakter.szintlepesek[0],
harcosFegyver: spec
})
})}
existingSpecializations={karakter.szintlepesek.map(x => x.harcosFegyver)}
/>}
<KarakterKepzettsegek
@@ -121,23 +202,25 @@ function CreateCharacter2E(props: {}) {
tolvajKepzettsegek={karakter.tolvajKepzettsegek || []}
changeTolvajKepzettsegek={changeTolvajKepzettseg}
/>
<hr />
<hr/>
{/* 1. szinten */}
<MasodlagosErtekek {...CalculateMasodlagosErtekek({
...karakter,
tulajdonsagok: tulajdonsagokFajjal,
szint: 1,
szintlepesek: karakter.szintlepesek.slice(0,1)
szintlepesek: karakter.szintlepesek.slice(0, 1)
})} />
<hr />
<hr/>
<LevelUps karakter={karakter} changeKarakter={setKarakter}/>
{karakter.szint > 1 && <hr/>}
<div className='d-grid gap-2 m-5'>
{karakter.szint < 12 &&
<button className='btn btn-dark btn-lg' type='button' onClick={() => LevelUp(karakter, setKarakter)}>Szintlépés!
<button className='btn btn-dark btn-lg' type='button'
onClick={() => LevelUp(karakter, setKarakter)}>Szintlépés!
</button>}
{karakter.szint > 1 &&
<button className='btn btn-dark btn-lg' type='button' onClick={() => LevelDown(karakter, setKarakter)}>Visszalépés!
<button className='btn btn-dark btn-lg' type='button'
onClick={() => LevelDown(karakter, setKarakter)}>Visszalépés!
</button>}
</div>
<hr/>
@@ -145,9 +228,66 @@ function CreateCharacter2E(props: {}) {
changeFelszereles={changeFelszereles}/>
<hr/>
<div className='row'>
<h5 className='col align-self-center'>Véglegesítés</h5>
</div>
{fetchedUser.data != null &&
<div className='row m-2'>
<label className='col-md-2 col-sm-3 col-form-label'>Publikus karakterlap?</label>
<select className="col form-select" value={isPublic.toString()}
onChange={(event) => setIsPublic(event.target.value === "true")}>
<option value="true">Igen</option>
<option value="false">Nem</option>
</select>
</div>
}
<div className="row">
<div className="col-6">
<div className='d-grid gap-2 m-5'>
{fetchedUser.data == null
? <OverlayTrigger
placement='top'
overlay={saveOverlayTooltip}
delay={0}
defaultShow={false}
flip={false}
>
<button
className='btn btn-danger btn-lg'
type='button'
onClick={onSaveClicked}
>
Mentés
</button>
</OverlayTrigger>
: <button
className='btn btn-danger btn-lg'
type='button'
onClick={onSaveClicked}
>
Mentés
</button>
}
</div>
</div>
<div className="col-6">
<OverlayTrigger
placement='top'
overlay={<Tooltip id="pdf-btn-tooltip">Hamarosan!</Tooltip>}
delay={0}
defaultShow={false}
flip={false}
trigger={"hover"}
>
<div className='d-grid gap-2 m-5'>
<button className='btn btn-secondary btn-lg' disabled={true} type='button'>PDF</button>
</div>
</OverlayTrigger>
</div>
</div>
</form>
</div>
<hr/>
</div>
}
+1
View File
@@ -1,2 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=karakter/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kemkas/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>