diff --git a/Sources/ApiLol/ApiLol.csproj b/Sources/ApiLol/ApiLol.csproj
index f4484e6..8d2cf78 100644
--- a/Sources/ApiLol/ApiLol.csproj
+++ b/Sources/ApiLol/ApiLol.csproj
@@ -4,10 +4,18 @@
net6.0
enable
enable
+ $(MSBuildProjectDirectory)
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
@@ -28,5 +36,8 @@
+
+
+
diff --git a/Sources/ApiLol/Controllers/ChampionController.cs b/Sources/ApiLol/Controllers/ChampionController.cs
index aefc8ea..9644221 100644
--- a/Sources/ApiLol/Controllers/ChampionController.cs
+++ b/Sources/ApiLol/Controllers/ChampionController.cs
@@ -6,6 +6,8 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Model;
+using Microsoft.Extensions.Logging;
+using DataManagers;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
@@ -16,82 +18,111 @@ namespace ApiLol.Controllers
{
private readonly ILogger _logger;
- private StubData.ChampionsManager championsManager = new StubData.ChampionsManager(new StubData());
+ private IDataManager dataManager;
- public ChampionController(ILogger logger)
+ public ChampionController(ILogger logger, IDataManager manager)
{
_logger = logger;
+ dataManager = manager;
}
- // GET: api/champion
- [HttpGet]
- public async Task>> Get()
+ [HttpGet("GetChampions")]
+ public async Task>> GetChampions(int nb = 3)
{
- IEnumerable champs = await championsManager.GetItems(0, await championsManager.GetNbItems());
- IEnumerable championDTOs = champs.ToDtos();
+ var champions = await dataManager.ChampionsMgr.GetItems(0, nb);
+ _logger.Log(LogLevel.Information, $"Les champions ont bien été envoyées");
+ return Ok(champions.ToDtos());
- return Ok(championDTOs);
}
- /*
- // GET api/champion/5
- [HttpGet("{id}")]
- public ActionResult Get(int id)
+ // GET api/champion/name
+ [HttpGet("getChampions/{name}")]
+ public async Task> GetChampionsByName(string name, int nb =3, int index = 0)
{
- ChampionDTO? champion = champions.SingleOrDefault((ChampionEntity arg) => arg.Id == id)?.ToDto();
+ IEnumerable champion = await dataManager.ChampionsMgr.GetItemsByName(name, index, nb);
if (champion != null)
{
- return Ok(champion);
+ return Ok(champion.ToDtos());
}
return BadRequest();
}
- */
- // POST api/champion
- [HttpPost]
- public ActionResult Post([FromBody]ChampionDTO? champion)
+ [HttpPost("PostChampion")]
+ public async Task> PostChampion(ChampionDTO champ)
{
- if (champion == null){
- return BadRequest();
- }
- else
+ var c = await dataManager.ChampionsMgr.AddItem(ChampionMapper.ToPoco(champ));
+ if (c != null)
{
- championsManager.AddItem(champion.ToPoco());
- return Ok();
+ _logger.Log(LogLevel.Information, "Le champion a été ajouté à la base");
+ return Ok(c);
}
+ return BadRequest();
+
}
- // PUT api/champion/5
- [HttpPut("ChampionDto")]
- public ActionResult Put([FromBody] ChampionDTO? champion, ChampionDTO? newChampion)
+ [HttpPost("PostChampions")]
+ public async Task>> PostChampions(List champs)
{
- if (champion == null || newChampion == null)
+ var list = new List();
+ foreach (ChampionDTO champ in champs)
{
- return BadRequest();
+ var c = await dataManager.ChampionsMgr.AddItem(ChampionMapper.ToPoco(champ));
+ if ( c != null)
+ {
+ list.Add(c.ToDto());
+ _logger.Log(LogLevel.Information, $"Le champion {champ.Name} a été ajouté à la base");
+ }
+ else
+ {
+ _logger.Log(LogLevel.Information, $"Le champion {champ.Name} n'a pas été ajouté à la base");
+ }
}
- else
+ return Ok(list);
+ }
+
+ [HttpPut("PutChampion")]
+ public async Task> Put(ChampionDTO oldChamp, ChampionDTO champ)
+ {
+ var c = await dataManager.ChampionsMgr.UpdateItem(oldChamp.ToPoco(), champ.ToPoco());
+ if (c!=null)
{
- championsManager.UpdateItem(champion.ToPoco(), newChampion.ToPoco());
- return Ok();
+ _logger.Log(LogLevel.Information, $"Le champion {champ.Name} a été modifié ");
+ return Ok(c);
}
+ _logger.Log(LogLevel.Information, $"Le champion {champ.Name} n'a pas été modifié");
+ return BadRequest();
}
- // DELETE api/values/5
+ // DELETE api/values
[HttpDelete("ChampionDto")]
- public ActionResult Delete([FromBody] ChampionDTO? champion)
+ public async Task DeleteChampion([FromBody] ChampionDTO champion)
{
- if (champion == null)
+ if (await dataManager.ChampionsMgr.DeleteItem(champion.ToPoco()))
{
- return BadRequest();
+ return Ok();
}
- else
+ return BadRequest();
+ }
+
+ [HttpDelete("DeleteChampions")]
+ public async Task>> DeleteChampions(List champions, int nb = 10)
+ {
+ foreach (ChampionDTO champ in champions)
{
- championsManager.DeleteItem(champion.ToPoco());
- return Ok();
+ if (await dataManager.ChampionsMgr.DeleteItem(champ.ToPoco()))
+ {
+ _logger.Log(LogLevel.Information, $"Le champion {champ.Name} a été supprimé");
+ }
+ else
+ {
+ _logger.Log(LogLevel.Information, $"Le champion {champ.Name} n'a pas été supprimé");
+ }
}
+ return Ok();
}
+
}
}
diff --git a/Sources/ApiLol/Controllers/RuneController.cs b/Sources/ApiLol/Controllers/RuneController.cs
new file mode 100644
index 0000000..fc50054
--- /dev/null
+++ b/Sources/ApiLol/Controllers/RuneController.cs
@@ -0,0 +1,153 @@
+using ApiLol.DTO;
+using ApiLol.Mapping;
+using Microsoft.AspNetCore.Mvc;
+using Model;
+using StubLib;
+using System.Data;
+using System.Text;
+
+namespace API.Controllers
+{
+ [ApiController]
+ [Route("api/[controller]")]
+ public class RuneController : Controller
+ {
+ private readonly ILogger _logger;
+
+ private IDataManager dataManager = new StubData();
+
+
+ public RuneController(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ [HttpGet("GetRune/{name}")]
+ public async Task>> GetRune(string name, int nb=3, int index = 0)
+ {
+ var runes = await dataManager.RunesMgr.GetItemsByName(name, index, nb);
+ if (!runes.Any())
+ {
+ _logger.Log(LogLevel.Warning, $"La rune {name} n'existe pas");
+ return BadRequest(name);
+ }
+ else
+ {
+ _logger.Log(LogLevel.Information, $"Les runes avec {name} ont été envoyées");
+ return Ok(runes.Select(x => x?.ToDto()));
+ }
+
+ }
+
+ [HttpGet("GetRunes")]
+ public async Task>> GetRunes(int nb = 15)
+ {
+ var runes = await dataManager.RunesMgr.GetItems(0, nb);
+ return Ok(runes.Select(x => x?.ToDto()));
+ }
+
+ [HttpPost("PostRune")]
+ public async Task> PostRune(RuneDTO rune)
+ {
+ var r = await dataManager.RunesMgr.AddItem(rune.ToPoco());
+ if (r != null)
+ {
+ _logger.Log(LogLevel.Information, $"La Rune {rune.Name} a été ajouté à la base");
+ return Ok(r.ToDto());
+
+ }
+ return BadRequest(r);
+ }
+
+ [HttpPost("PostRunes")]
+ public async Task>> PostRunes(List runes)
+ {
+ var l = new List();
+ foreach (RuneDTO rune in runes)
+ {
+ var r = await dataManager.RunesMgr.AddItem(rune.ToPoco());
+ if (r != null)
+ {
+ l.Add(r.ToDto());
+ _logger.Log(LogLevel.Information, $"La Rune {rune.Name} a été ajoutée à la base");
+ }
+ else
+ {
+ _logger.Log(LogLevel.Warning, $"La Rune {rune.Name} recherchée n'existe pas ou il y en a plusieurs avec ce nom");
+ }
+ }
+ return Ok(l);
+ }
+
+ [HttpPut("PutRune")]
+ public async Task> PutRune(RuneDTO rune)
+ {
+ var ancienne = await dataManager.RunesMgr.GetItemsByName(rune.Name, 0, 1);
+ if (ancienne.Count() != 1)
+ {
+ _logger.Log(LogLevel.Warning, $"La Rune {rune.Name} recherchée n'existe pas ou il y en a plusieurs avec ce nom");
+ return BadRequest(rune);
+ }
+ else
+ {
+ await dataManager.RunesMgr.UpdateItem(ancienne.FirstOrDefault(), rune.ToPoco());
+ _logger.Log(LogLevel.Information, $"La Rune {rune.Name} a été modifiée de la base");
+ var r = await dataManager.RunesMgr.GetItemsByName(rune.Name, 0, 1);
+ return Ok(r.First());
+ }
+ }
+
+ [HttpPut("PutRunes")]
+ public async Task>> PutRunes(List runes, int nb = 10)
+ {
+ foreach (RuneDTO run in runes)
+ {
+ var rune = await dataManager.RunesMgr.GetItemsByName(run.Name, 0, 1);
+ if (!rune.Any())
+ {
+ _logger.Log(LogLevel.Warning, $"La Rune {run.Name} recherchée n'existe pas");
+ BadRequest(run);
+ }
+ else
+ {
+ await dataManager.RunesMgr.UpdateItem(rune.FirstOrDefault(), run.ToPoco());
+ _logger.Log(LogLevel.Information, $"La Rune {run.Name} a été modifiée de la base");
+
+ }
+ }
+ var Runes = await dataManager.RunesMgr.GetItems(0, nb);
+ return Ok(Runes.Select(x => x?.ToDto()));
+ }
+
+ [HttpDelete("DeleteRune")]
+ public async Task> DeleteRune(RuneDTO rune)
+ {
+ var retour = await dataManager.RunesMgr.DeleteItem(rune.ToPoco());
+ if (retour) {
+ _logger.Log(LogLevel.Information, $"La Rune {rune.Name} a été supprimée de la base");
+ return Ok(retour);
+ }
+ _logger.Log(LogLevel.Warning, $"La Rune {rune.Name} recherchée n'existe pas");
+ return BadRequest(retour);
+ }
+
+ [HttpDelete("DeleteRunes")]
+ public async Task> DeleteRunes(List runes)
+ {
+ foreach (RuneDTO run in runes)
+ {
+ var retour = await dataManager.RunesMgr.DeleteItem(run.ToPoco());
+ if (!retour)
+ {
+ _logger.Log(LogLevel.Warning, $"La Rune {run.Name} recherchée n'existe pas");
+ BadRequest(run);
+ }
+ else
+ {
+ _logger.Log(LogLevel.Information, $"La Rune {run.Name} a été supprimée de la base");
+ }
+ }
+ return Ok(true);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/ApiLol/DTO/ChampionDTO.cs b/Sources/ApiLol/DTO/ChampionDTO.cs
index 240ce8d..0fd7d6b 100644
--- a/Sources/ApiLol/DTO/ChampionDTO.cs
+++ b/Sources/ApiLol/DTO/ChampionDTO.cs
@@ -16,11 +16,11 @@ namespace ApiLol
public ChampionClass ChampClass { get; set; }
- public LargeImage Image { get; set; }
+ //public LargeImage Image { get; set; }
public IEnumerable Characteristics { get; set; }
- public IEnumerable Skins { get; set; }
+ //public IEnumerable Skins { get; set; }
}
}
diff --git a/Sources/ApiLol/DTO/RuneDTO.cs b/Sources/ApiLol/DTO/RuneDTO.cs
index 7bbf289..cad134f 100644
--- a/Sources/ApiLol/DTO/RuneDTO.cs
+++ b/Sources/ApiLol/DTO/RuneDTO.cs
@@ -5,17 +5,15 @@ namespace ApiLol.DTO
{
public class RuneDTO
{
- public string Nom { get; set; }
-
public string Description { get; set; }
- public string Famille { get; set; }
+ public RuneFamily Family { get; set; }
public string Icon { get; set; }
public string Name { get; set; }
- public LargeImage Image { get; set; }
+ //public LargeImage Image { get; set; }
}
diff --git a/Sources/ApiLol/DTO/SkinDTO.cs b/Sources/ApiLol/DTO/SkinDTO.cs
index b0f1ec5..451c2a6 100644
--- a/Sources/ApiLol/DTO/SkinDTO.cs
+++ b/Sources/ApiLol/DTO/SkinDTO.cs
@@ -13,7 +13,7 @@ namespace ApiLol.DTO
public string Icon { get; set; }
- public LargeImage Image { get; set; }
+ //public LargeImage Image { get; set; }
}
}
diff --git a/Sources/ApiLol/Mapping/ChampionMapper.cs b/Sources/ApiLol/Mapping/ChampionMapper.cs
index bc27995..25473cf 100644
--- a/Sources/ApiLol/Mapping/ChampionMapper.cs
+++ b/Sources/ApiLol/Mapping/ChampionMapper.cs
@@ -20,8 +20,8 @@ namespace ApiLol
Bio = champion.Bio,
Icon = champion.Icon,
ChampClass = champion.Class,
- Image = champion.Image,
- Skins = champion.Skins,
+ //Image = champion.Image,
+ //Skins = champion.Skins,
Characteristics = champion.Characteristics.ToDto()
};
}
@@ -42,7 +42,7 @@ namespace ApiLol
{
throw new NullReferenceException();
}
- return new Champion(name: champion.Name, champClass: champion.ChampClass, icon: champion.Icon, bio: champion.Bio, image: champion.Image.Base64);
+ return new Champion(name: champion.Name, champClass: champion.ChampClass, icon: champion.Icon, bio: champion.Bio);
}
public static IEnumerable ToPocos(this IEnumerable champions)
diff --git a/Sources/ApiLol/Mapping/RuneMapper.cs b/Sources/ApiLol/Mapping/RuneMapper.cs
new file mode 100644
index 0000000..b74d4a0
--- /dev/null
+++ b/Sources/ApiLol/Mapping/RuneMapper.cs
@@ -0,0 +1,38 @@
+using System;
+using Model;
+using static System.Net.Mime.MediaTypeNames;
+using System.Xml.Linq;
+using ApiLol.DTO;
+
+namespace ApiLol.Mapping
+{
+ public static class RuneMapper
+ {
+ public static RuneDTO ToDto(this Rune rune)
+ {
+
+ if (rune == null)
+ {
+ throw new NullReferenceException();
+ }
+ return new RuneDTO
+ {
+ Name = rune.Name,
+ Description = rune.Description,
+ Family = rune.Family,
+ Icon = rune.Icon
+ };
+
+ }
+
+ public static Rune ToPoco(this RuneDTO rune) {
+ if (rune == null)
+ {
+ throw new NullReferenceException();
+ }
+
+ return new Rune(rune.Name, rune.Family, rune.Icon, rune.Description);
+ }
+ }
+}
+
diff --git a/Sources/ApiLol/Mapping/SkinMapper.cs b/Sources/ApiLol/Mapping/SkinMapper.cs
index fabde1c..50deed1 100644
--- a/Sources/ApiLol/Mapping/SkinMapper.cs
+++ b/Sources/ApiLol/Mapping/SkinMapper.cs
@@ -15,7 +15,7 @@ namespace ApiLol.Mapping
Description = skin.Description,
Price = skin.Price,
Icon = skin.Icon,
- Image = skin.Image
+ //Image = skin.Image
};
}
diff --git a/Sources/ConsoleApi/ConsoleApi.csproj b/Sources/ConsoleApi/ConsoleApi.csproj
index 68e39d2..58fb9a7 100644
--- a/Sources/ConsoleApi/ConsoleApi.csproj
+++ b/Sources/ConsoleApi/ConsoleApi.csproj
@@ -10,7 +10,4 @@
-
-
-
diff --git a/Sources/ConsoleApi/Program.cs b/Sources/ConsoleApi/Program.cs
index f56e562..39e2944 100644
--- a/Sources/ConsoleApi/Program.cs
+++ b/Sources/ConsoleApi/Program.cs
@@ -5,8 +5,5 @@ using static System.Net.WebRequestMethods;
HttpClient http = new HttpClient();
//http.BaseAddress = new Uri("https://localhost:7006/");
-Console.WriteLine(await http.GetStringAsync("https://localhost:7006/api/Champion"));
-Console.WriteLine(await http.GetStringAsync("https://localhost:7006/api/Champion/1"));
-
-
-
+//Console.WriteLine(await http.GetStringAsync("https://localhost:7006/api/Champions"));
+//Console.WriteLine(await http.GetStringAsync("https://localhost:7006/api/Champion/1"));
diff --git a/Sources/ConsoleDb/ConsoleDb.csproj b/Sources/ConsoleDb/ConsoleDb.csproj
index 0bc60ce..34bbffc 100644
--- a/Sources/ConsoleDb/ConsoleDb.csproj
+++ b/Sources/ConsoleDb/ConsoleDb.csproj
@@ -19,13 +19,13 @@
-
-
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/Sources/ConsoleDb/Program.cs b/Sources/ConsoleDb/Program.cs
index 0fc628b..e795449 100644
--- a/Sources/ConsoleDb/Program.cs
+++ b/Sources/ConsoleDb/Program.cs
@@ -7,6 +7,7 @@ Console.WriteLine("Hello, World!");
using (var db = new DbDataManager(new EFLib.LolContext()))
{
+ await db.Context.Database.EnsureCreatedAsync();
IEnumerable champions = await db.ChampionsMgr.GetItems(0, 10);
foreach (Champion c in champions)
diff --git a/Sources/ConsoleDb/oiseaux.db b/Sources/ConsoleDb/oiseaux.db
deleted file mode 100644
index 2665bcb..0000000
Binary files a/Sources/ConsoleDb/oiseaux.db and /dev/null differ
diff --git a/Sources/DataManagers/ChampChanger.cs b/Sources/DataManagers/ChampChanger.cs
index 0e12c1c..3de409f 100644
--- a/Sources/DataManagers/ChampChanger.cs
+++ b/Sources/DataManagers/ChampChanger.cs
@@ -8,7 +8,7 @@ namespace DataManagers
{
public static Champion ToPoco(this ChampionEntity champion)
{
- return new Champion(id: champion.Id, name: champion.Name, champClass: champion.ChampClass, icon: champion.Icon, bio: champion.Bio);
+ return new Champion(id: champion.Id, name: champion.Name, champClass: champion.ChampClass, icon: champion.Icon, bio: champion.Bio, image: champion.LargeImage.Base64, imageId: champion.ImageId);
}
public static ChampionEntity ToEntity(this Champion champion) => new ChampionEntity
@@ -18,6 +18,8 @@ namespace DataManagers
Bio = champion.Bio,
Icon = champion.Icon,
ChampClass = champion.Class,
+ ImageId = champion.Image.Id,
+ LargeImage = champion.Image.ToEntity()
};
diff --git a/Sources/DataManagers/DbChampionManager.cs b/Sources/DataManagers/DbChampionManager.cs
index 01c2fa1..ad78ffc 100644
--- a/Sources/DataManagers/DbChampionManager.cs
+++ b/Sources/DataManagers/DbChampionManager.cs
@@ -14,31 +14,9 @@ namespace DataManagers
Context = context;
}
- private IEnumerable SortChampions(IEnumerable champs, int index, int count, string? orderingPropertyName = null, bool descending = false)
- {
- switch (orderingPropertyName?.ToLower())
- {
- case "bio":
- champs = champs.OrderBy(arg => arg.Bio.ToLower()).ToList();
- break;
- case "class":
- champs = champs.OrderBy(arg => arg.Class).ToList();
- break;
- default:
- champs = champs.OrderBy(arg => arg.Name.ToLower()).ToList();
- break;
- }
- if (descending)
- {
- champs = champs.Reverse().ToList();
- }
- if (index + count > champs.ToList().Count) return champs.ToList().GetRange(index, champs.ToList().Count - index);
- return champs.ToList().GetRange(index, count);
- }
-
public async Task AddItem(Champion? item)
{
- if (item != null && Context.Champions.SingleOrDefault((ChampionEntity arg) => arg.Name == item.Name)?.ToPoco() == null)
+ if (item != null && Context.Champions.SingleOrDefault((ChampionEntity arg) => arg.Id == item.Id || arg.Name == item.Name) == null)
{
await Context.Champions.AddAsync(item.ToEntity());
await Context.SaveChangesAsync();
@@ -51,7 +29,7 @@ namespace DataManagers
{
if (item != null)
{
- ChampionEntity? entity = await Context.Champions.SingleOrDefaultAsync((ChampionEntity arg) => arg.Name == item.Name);
+ ChampionEntity? entity = await Context.Champions.SingleOrDefaultAsync((ChampionEntity arg) => arg.Id == item.Id || arg.Name == item.Name);
if (entity != null)
{
Context.Champions.Remove(entity);
@@ -64,8 +42,24 @@ namespace DataManagers
public async Task> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{
- IEnumerable champs = await Task.Run(() => Context.Champions.ToList().ToPocos());
- return SortChampions(champs, index, count,orderingPropertyName, descending);
+ IEnumerable champs = new List();
+ switch (orderingPropertyName?.ToLower())
+ {
+ case "bio":
+ champs = await Task.Run(() => Context.Champions.OrderBy((arg) => arg.Bio).Skip(index * count).Take(count).ToList().ToPocos());
+ break;
+ case "class":
+ champs = await Task.Run(() => Context.Champions.OrderBy((arg) => arg.ChampClass).Skip(index * count).Take(count).ToList().ToPocos());
+ break;
+ default:
+ champs = await Task.Run(() => Context.Champions.OrderBy((arg) => arg.Name).Skip(index * count).Take(count).ToList().ToPocos());
+ break;
+ }
+ if (descending)
+ {
+ champs.Reverse();
+ }
+ return champs;
}
public async Task GetNbItems()
@@ -81,14 +75,46 @@ namespace DataManagers
public async Task> GetItemsByClass(ChampionClass championClass, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
- IEnumerable champs = await Task.Run(() => Context.Champions.ToList().ToPocos().Where(arg => arg.Class == championClass));
- return SortChampions(champs, index, count, orderingPropertyName, descending);
+ IEnumerable champs = new List();
+ switch (orderingPropertyName?.ToLower())
+ {
+ case "bio":
+ champs = await Task.Run(() => Context.Champions.Where((arg) => arg.ChampClass == championClass).OrderBy((arg) => arg.Bio).Skip(index * count).Take(count).ToList().ToPocos());
+ break;
+ case "class":
+ champs = await Task.Run(() => Context.Champions.Where((arg) => arg.ChampClass == championClass).OrderBy((arg) => arg.ChampClass).Skip(index * count).Take(count).ToList().ToPocos());
+ break;
+ default:
+ champs = await Task.Run(() => Context.Champions.Where((arg) => arg.ChampClass == championClass).OrderBy((arg) => arg.Name).Skip(index * count).Take(count).ToList().ToPocos());
+ break;
+ }
+ if (descending)
+ {
+ champs.Reverse();
+ }
+ return champs;
}
public async Task> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
- IEnumerable champs = await Task.Run(() => Context.Champions.ToList().ToPocos().Where(arg => arg.Name.Contains(substring)));
- return SortChampions(champs, index, count, orderingPropertyName, descending);
+ IEnumerable champs = new List();
+ switch (orderingPropertyName?.ToLower())
+ {
+ case "bio":
+ champs = await Task.Run(() => Context.Champions.Where((arg) => arg.Name.Contains(substring)).OrderBy((arg) => arg.Bio).Skip(index * count).Take(count).ToList().ToPocos());
+ break;
+ case "class":
+ champs = await Task.Run(() => Context.Champions.Where((arg) => arg.Name.Contains(substring)).OrderBy((arg) => arg.ChampClass).Skip(index * count).Take(count).ToList().ToPocos());
+ break;
+ default:
+ champs = await Task.Run(() => Context.Champions.Where((arg) => arg.Name.Contains(substring)).OrderBy((arg) => arg.Name).Skip(index * count).Take(count).ToList().ToPocos());
+ break;
+ }
+ if (descending)
+ {
+ champs.Reverse();
+ }
+ return champs;
}
public Task> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false)
diff --git a/Sources/DataManagers/DbDataManager.cs b/Sources/DataManagers/DbDataManager.cs
index 70f0fd2..9d20469 100644
--- a/Sources/DataManagers/DbDataManager.cs
+++ b/Sources/DataManagers/DbDataManager.cs
@@ -7,7 +7,7 @@ namespace DataManagers
public class DbDataManager : IDataManager
{
- private LolContext Context { get; set; }
+ public LolContext Context { get; set; }
public IChampionsManager ChampionsMgr => new DbChampionManager(Context);
@@ -32,6 +32,11 @@ namespace DataManagers
{
Context.Database.EnsureCreated();
}
+
+ public async Task EnsureCreatedAsync()
+ {
+ await Context.Database.EnsureCreatedAsync();
+ }
}
}
diff --git a/Sources/DataManagers/LargeImageChanger.cs b/Sources/DataManagers/LargeImageChanger.cs
new file mode 100644
index 0000000..09f9c56
--- /dev/null
+++ b/Sources/DataManagers/LargeImageChanger.cs
@@ -0,0 +1,42 @@
+using System;
+using EFLib;
+using Model;
+
+namespace DataManagers
+{
+ public static class LargeImageChanger
+ {
+ public static LargeImage ToPoco(this LargeImageEntity largeImage)
+ {
+ return new LargeImage(largeImage.Id, largeImage.Base64);
+ }
+
+ public static LargeImageEntity ToEntity(this LargeImage largeImage) => new LargeImageEntity
+ {
+ Id = largeImage.Id,
+ Base64 = largeImage.Base64
+ };
+
+
+ public static IEnumerable ToPocos(this IEnumerable largeImages)
+ {
+ List images = new List();
+ foreach (LargeImageEntity l in largeImages)
+ {
+ images.Add(l.ToPoco());
+ }
+ return images;
+ }
+
+ public static IEnumerable toEntities(this IEnumerable largeImages)
+ {
+ List images = new List();
+ foreach (LargeImage l in largeImages)
+ {
+ images.Add(l.ToEntity());
+ }
+ return images;
+ }
+ }
+}
+
diff --git a/Sources/EFLib/ChampionEntity.cs b/Sources/EFLib/ChampionEntity.cs
index 829cc2e..b17f0b4 100644
--- a/Sources/EFLib/ChampionEntity.cs
+++ b/Sources/EFLib/ChampionEntity.cs
@@ -16,6 +16,10 @@ namespace EFLib
public ChampionClass ChampClass { get; set;}
+ public int ImageId { get; set; }
+
+ public LargeImageEntity LargeImage { get; set; }
+
}
}
diff --git a/Sources/EFLib/EFLib.csproj b/Sources/EFLib/EFLib.csproj
index 999d095..6e24479 100644
--- a/Sources/EFLib/EFLib.csproj
+++ b/Sources/EFLib/EFLib.csproj
@@ -1,7 +1,6 @@
- Exe
net6.0
enable
enable
@@ -15,13 +14,13 @@
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/Sources/EFLib/LargeImageEntity.cs b/Sources/EFLib/LargeImageEntity.cs
new file mode 100644
index 0000000..7d13219
--- /dev/null
+++ b/Sources/EFLib/LargeImageEntity.cs
@@ -0,0 +1,13 @@
+using System;
+namespace EFLib
+{
+ public class LargeImageEntity
+ {
+ public int Id { get; set; }
+
+ public string Base64 { get; set; }
+
+ public ChampionEntity Champion { get; set; }
+ }
+}
+
diff --git a/Sources/EFLib/LolContext.cs b/Sources/EFLib/LolContext.cs
index b08b271..70d827d 100644
--- a/Sources/EFLib/LolContext.cs
+++ b/Sources/EFLib/LolContext.cs
@@ -1,12 +1,16 @@
using System;
using Microsoft.EntityFrameworkCore;
+using Microsoft.VisualBasic;
+using Model;
namespace EFLib
{
- public class LolContext : DbContext, IDisposable
- {
+ public class LolContext : DbContext
+ {
public DbSet Champions { get; set; }
+ public DbSet LargeImages { get; set; }
+
public LolContext(DbContextOptions options)
: base(options)
{ }
@@ -21,6 +25,30 @@ namespace EFLib
optionsBuilder.UseSqlite("Data Source=oiseaux.db");
}
}
+
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ base.OnModelCreating(modelBuilder);
+
+ modelBuilder.Entity()
+ .HasOne(e => e.Champion)
+ .WithOne(z => z.LargeImage)
+ .HasForeignKey(x => x.ImageId);
+
+ var image1 = new LargeImageEntity { Id = 1, Base64 = "test1" };
+ var image2 = new LargeImageEntity { Id = 2, Base64 = "test2" };
+ var image3 = new LargeImageEntity { Id = 3, Base64 = "test3" };
+
+ modelBuilder.Entity().HasData(image1, image2, image3);
+
+ modelBuilder.Entity().HasData(
+ new ChampionEntity { Id = 1, Name = "Test1", Bio = "Salut", ChampClass = ChampionClass.Fighter, Icon = "bla", ImageId = 1 },
+ new ChampionEntity { Id = 2, Name = "Test2", Bio = "hey", ChampClass = ChampionClass.Assassin, Icon = "bla", ImageId = 2 },
+ new ChampionEntity { Id = 3, Name = "Test3", Bio = "coucou", ChampClass = ChampionClass.Tank, Icon = "bla", ImageId = 3 }
+
+ );
+ }
}
}
diff --git a/Sources/EFLib/Program.cs b/Sources/EFLib/Program.cs
deleted file mode 100644
index bf37432..0000000
--- a/Sources/EFLib/Program.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// See https://aka.ms/new-console-template for more information
-using EFLib;
-
-Console.WriteLine("Hello, World!");
-
-using (var context = new LolContext())
-{
- context.Champions.Add(new ChampionEntity
- {
- Name = "Test",
- Bio = "Bonjour",
- Icon = "Wouhou"
- });
- context.SaveChanges();
-}
\ No newline at end of file
diff --git a/Sources/EFLib/oiseaux.db-shm b/Sources/EFLib/oiseaux.db-shm
deleted file mode 100644
index fe9ac28..0000000
Binary files a/Sources/EFLib/oiseaux.db-shm and /dev/null differ
diff --git a/Sources/EFLib/oiseaux.db-wal b/Sources/EFLib/oiseaux.db-wal
deleted file mode 100644
index e69de29..0000000
diff --git a/Sources/LeagueOfLegends.sln b/Sources/LeagueOfLegends.sln
index 4ce5d07..6aa39c6 100644
--- a/Sources/LeagueOfLegends.sln
+++ b/Sources/LeagueOfLegends.sln
@@ -23,6 +23,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApi", "ConsoleApi\Co
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{EE69586D-A6A8-40C4-93D7-DBDFEBC6844A}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LolApp", "LolApp\LolApp.csproj", "{0C898A04-092A-49AA-BE65-8AE818A2AF50}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ViewModels", "ViewModels\ViewModels.csproj", "{805D142A-2755-4232-A486-2970277FB951}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -65,6 +69,14 @@ Global
{EE69586D-A6A8-40C4-93D7-DBDFEBC6844A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE69586D-A6A8-40C4-93D7-DBDFEBC6844A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE69586D-A6A8-40C4-93D7-DBDFEBC6844A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0C898A04-092A-49AA-BE65-8AE818A2AF50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0C898A04-092A-49AA-BE65-8AE818A2AF50}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0C898A04-092A-49AA-BE65-8AE818A2AF50}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0C898A04-092A-49AA-BE65-8AE818A2AF50}.Release|Any CPU.Build.0 = Release|Any CPU
+ {805D142A-2755-4232-A486-2970277FB951}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {805D142A-2755-4232-A486-2970277FB951}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {805D142A-2755-4232-A486-2970277FB951}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {805D142A-2755-4232-A486-2970277FB951}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Sources/LolApp/LolApp.csproj b/Sources/LolApp/LolApp.csproj
index cde1acb..ad4cdee 100644
--- a/Sources/LolApp/LolApp.csproj
+++ b/Sources/LolApp/LolApp.csproj
@@ -83,6 +83,7 @@
+
diff --git a/Sources/LolApp/MauiProgram.cs b/Sources/LolApp/MauiProgram.cs
index c12deff..9b5c12b 100644
--- a/Sources/LolApp/MauiProgram.cs
+++ b/Sources/LolApp/MauiProgram.cs
@@ -6,6 +6,7 @@ using Microsoft.Maui.Platform;
using Model;
using StubLib;
using ViewModels;
+using DataManagers;
namespace LolApp;
diff --git a/Sources/Model/Champion.cs b/Sources/Model/Champion.cs
index df3000d..cfbb327 100644
--- a/Sources/Model/Champion.cs
+++ b/Sources/Model/Champion.cs
@@ -50,25 +50,25 @@ public class Champion : IEquatable
public LargeImage Image { get; set; }
- public Champion(int id, string name, ChampionClass champClass = ChampionClass.Unknown, string icon = "", string image = "", string bio = "")
+ public Champion(int id, string name, ChampionClass champClass = ChampionClass.Unknown, string icon = "", string image = "", int imageId=0,string bio = "")
{
Id = id;
Name = name;
Class = champClass;
Icon = icon;
- Image = new LargeImage(image);
+ Image = new LargeImage(imageId, image);
Bio = bio;
Characteristics = new ReadOnlyDictionary(characteristics);
Skins = new ReadOnlyCollection(skins);
}
- public Champion(string name, ChampionClass champClass = ChampionClass.Unknown, string icon = "", string image = "", string bio = "")
+ public Champion(string name, ChampionClass champClass = ChampionClass.Unknown, string icon = "", string image = "", int imageId = 0, string bio = "")
{
Id = 0;
Name = name;
Class = champClass;
Icon = icon;
- Image = new LargeImage(image);
+ Image = new LargeImage(imageId, image);
Bio = bio;
Characteristics = new ReadOnlyDictionary(characteristics);
Skins = new ReadOnlyCollection(skins);
diff --git a/Sources/Model/LargeImage.cs b/Sources/Model/LargeImage.cs
index 56d6696..1a30061 100644
--- a/Sources/Model/LargeImage.cs
+++ b/Sources/Model/LargeImage.cs
@@ -5,13 +5,30 @@ namespace Model
{
public string Base64 { get; set; }
- public LargeImage(string base64)
+ public int Id { get; set; }
+
+
+ public LargeImage(int id, string base64)
{
Base64 = base64;
+ Id = id;
}
+ public LargeImage(string base64)
+ {
+ Base64 = base64;
+ Id = 0;
+ }
+
public bool Equals(LargeImage? other)
- => other != null && other.Base64.Equals(Base64);
+ {
+ if (other == null) return false;
+ if (Id != 0 && other?.Id != 0)
+ {
+ return Id == Id;
+ }
+ return Base64 == other?.Base64;
+ }
public override bool Equals(object? obj)
{
diff --git a/Sources/Model/Model.csproj b/Sources/Model/Model.csproj
index f898697..3ef2d23 100644
--- a/Sources/Model/Model.csproj
+++ b/Sources/Model/Model.csproj
@@ -23,15 +23,15 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
+
+
diff --git a/Sources/Shared/Shared.csproj b/Sources/Shared/Shared.csproj
index addd042..c5fba91 100644
--- a/Sources/Shared/Shared.csproj
+++ b/Sources/Shared/Shared.csproj
@@ -13,15 +13,15 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
+
+
diff --git a/Sources/StubLib/StubLib.csproj b/Sources/StubLib/StubLib.csproj
index 6d93d37..dd05e4c 100644
--- a/Sources/StubLib/StubLib.csproj
+++ b/Sources/StubLib/StubLib.csproj
@@ -16,15 +16,15 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
+
+
diff --git a/Sources/Tests/ChampionController_UT.cs b/Sources/Tests/ChampionController_UT.cs
new file mode 100644
index 0000000..790b564
--- /dev/null
+++ b/Sources/Tests/ChampionController_UT.cs
@@ -0,0 +1,49 @@
+using System;
+using ApiLol;
+using ApiLol.Controllers;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using StubLib;
+
+
+namespace Tests
+{
+ public class ChampionController_UT
+ {
+ [Fact]
+ public async void GetChampionTest()
+ {
+ ChampionController controller = new ChampionController(new Logger(new LoggerFactory()), new StubData());
+ }
+
+ [Fact]
+ public async void GetChampionByNameTest()
+ {
+ ChampionController controller = new ChampionController(new Logger(new LoggerFactory()), new StubData());
+ var result = await controller.GetChampionsByName("aa");
+ var champs = (result.Result as ObjectResult).Value as IEnumerable;
+ Assert.True(champs.Any());
+ }
+
+ [Fact]
+ public async void PostChampionTest()
+ {
+ ChampionController controller = new ChampionController(new Logger(new LoggerFactory()), new StubData());
+ var result = await controller.PostChampion(new ChampionDTO { Name="Test", Bio="test", ChampClass=Model.ChampionClass.Assassin, Icon="sqdz"});
+ ChampionDTO? champ = (result.Result as ObjectResult).Value as ChampionDTO;
+ Assert.NotNull(champ);
+ }
+
+ [Fact]
+ public async void PutChampionTest()
+ {
+ ChampionController controller = new ChampionController(new Logger(new LoggerFactory()), new StubData());
+ var result = await controller.Put(new ChampionDTO { Name = "Aatrox", Bio = "test", ChampClass = Model.ChampionClass.Assassin, Icon = "sqdz" }, new ChampionDTO { Name = "Test", Bio = "test", ChampClass = Model.ChampionClass.Assassin, Icon = "sqdz" });
+ var champ = (result.Result as ObjectResult).Value as ChampionDTO;
+ Assert.NotNull(champ);
+ var result2 = await controller.Put(new ChampionDTO { Name = "blabla", Bio = "test", ChampClass = Model.ChampionClass.Assassin, Icon = "sqdz" }, new ChampionDTO { Name = "Test", Bio = "test", ChampClass = Model.ChampionClass.Assassin, Icon = "sqdz" });
+ var champ2 = (result.Result as ObjectResult).Value as ChampionDTO;
+ Assert.Null(champ2);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/Tests/DbChampionManager_UT.cs b/Sources/Tests/DbChampionManager_UT.cs
index e595707..7904b72 100644
--- a/Sources/Tests/DbChampionManager_UT.cs
+++ b/Sources/Tests/DbChampionManager_UT.cs
@@ -1,6 +1,7 @@
namespace Tests;
using System.Threading.Tasks;
+using System.Xml.Linq;
using DataManagers;
using EFLib;
using Microsoft.Data.Sqlite;
@@ -10,8 +11,11 @@ using Model;
public class DbChampionManager_UT
{
- [Fact]
- public async Task Add_TestAsync()
+ [Theory]
+ [InlineData(true, true, 8, "Aurelien", ChampionClass.Tank, "tro bo le type")]
+ [InlineData(true, false, 8, "Marche sans ID", ChampionClass.Tank, "tro bo le type")]
+ [InlineData(false, true, 8, "Marche pas", ChampionClass.Tank, "tro bo le type")]
+ public async Task Add_TestAsync(bool isValid, bool hasId,int id, string name, ChampionClass championClass, string bio)
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
@@ -23,28 +27,32 @@ public class DbChampionManager_UT
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
- db.EnsureCreated();
-
- Champion champion = new Champion("Aurelien", ChampionClass.Tank, "tro bo le type");
- Champion champion2 = new Champion("Croissant", ChampionClass.Assassin, "tro bon le type");
- Champion champion3 = new Champion("Mathilde", ChampionClass.Fighter, "Chut mathilde");
- await db.ChampionsMgr.AddItem(champion);
- await db.ChampionsMgr.AddItem(champion2);
- await db.ChampionsMgr.AddItem(champion3);
- }
-
- using (var db = new DbDataManager(new EFLib.LolContext(options)))
- {
- db.EnsureCreated();
- Assert.Equal(3, await db.ChampionsMgr.GetNbItems());
- Assert.Null(await db.ChampionsMgr.AddItem(new Champion("Aurelien", ChampionClass.Tank, "tro bo le type")));
+ await db.EnsureCreatedAsync();
+
+ Champion champion = new Champion(name, championClass, bio);
+ if (hasId)
+ {
+ champion = new Champion(id, name, championClass, bio);
+ }
+ Champion? c = await db.ChampionsMgr.AddItem(champion);
+
+ if (isValid)
+ {
+ Assert.NotNull(c);
+ }
+ else
+ {
+ Champion? c1 = await db.ChampionsMgr.AddItem(champion);
+ Assert.Null(c1);
+ }
}
-
-
}
- [Fact]
- public async Task Delete_TestAsync()
+ [Theory]
+ [InlineData(true, true, 18, "Aurelien", ChampionClass.Tank, "tro bo le type")]
+ [InlineData(true, false, 19, "Marche sans Id", ChampionClass.Tank, "tro bo le type")]
+ [InlineData(false, true, 20, "Marche pas", ChampionClass.Tank, "tro bo le type")]
+ public async Task Delete_TestAsync(bool isValid, bool hasId, int id, string name, ChampionClass championClass, string bio)
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
@@ -55,32 +63,71 @@ public class DbChampionManager_UT
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
- db.EnsureCreated();
-
- Champion champion = new Champion("Aurelien", ChampionClass.Tank, "tro bo le type");
- Champion champion2 = new Champion("Croissant", ChampionClass.Assassin, "tro bon le type");
- Champion champion3 = new Champion("Mathilde", ChampionClass.Fighter, "Chut mathilde");
- await db.ChampionsMgr.AddItem(champion);
- await db.ChampionsMgr.AddItem(champion2);
- await db.ChampionsMgr.AddItem(champion3);
+ await db.Context.Database.EnsureCreatedAsync();
+
+ Champion champion = new Champion(name, championClass, bio);
+ if (hasId)
+ {
+ champion = new Champion(id, name, championClass, bio);
+ }
+ if (isValid)
+ {
+ Champion? c = await db.ChampionsMgr.AddItem(champion);
+ var retour = await db.ChampionsMgr.DeleteItem(champion);
+ Assert.True(retour);
+ }
+ else
+ {
+ var retour = await db.ChampionsMgr.DeleteItem(champion);
+ Assert.False(retour);
+ }
}
+ }
- using (var db = new DbDataManager(new EFLib.LolContext(options)))
- {
- db.EnsureCreated();
+ [Theory]
+ [InlineData(true, true, 18, "Aurelien", ChampionClass.Tank, "tro bo le type")]
+ [InlineData(true, false, 19, "Marche sans Id", ChampionClass.Tank, "tro bo le type")]
+ [InlineData(false, true, 20, "Marche pas", ChampionClass.Tank, "tro bo le type")]
+ public async Task Modify_TestAsync(bool isValid, bool hasId, int id, string name, ChampionClass championClass, string bio)
+ {
+ var connection = new SqliteConnection("DataSource=:memory:");
+ connection.Open();
- string nameToFind = "Croissant";
- IEnumerable champ = await db.ChampionsMgr.GetItemsByName(nameToFind, 0, 15, "name");
- Champion c = champ.First();
- Assert.Equal("Croissant", c.Name);
- await db.ChampionsMgr.DeleteItem(champ.First());
+ var options = new DbContextOptionsBuilder()
+ .UseSqlite(connection)
+ .Options;
- Assert.Equal(2, await db.ChampionsMgr.GetNbItems());
+ using (var db = new DbDataManager(new EFLib.LolContext(options)))
+ {
+ await db.Context.Database.EnsureCreatedAsync();
+
+ Champion champion = new Champion(name, championClass, bio);
+ if (hasId)
+ {
+ champion = new Champion(id, name, championClass, bio);
+ }
+ if (isValid)
+ {
+ Champion? c = await db.ChampionsMgr.AddItem(champion);
+ var retour = await db.ChampionsMgr.UpdateItem(c, new Champion(champion.Id, champion.Name, bio: "blabla"));
+ Assert.Equal("blabla", retour.Bio);
+ }
+ else
+ {
+ var retour = await db.ChampionsMgr.UpdateItem(champion, new Champion(champion.Id, champion.Name, bio: "blabla"));
+ Assert.Null(retour);
+ }
}
}
- [Fact]
- public async Task Modify_TestAsync()
+ [Theory]
+ [InlineData("name", false)]
+ [InlineData("bio", false)]
+ [InlineData("class", false)]
+ [InlineData("name", true)]
+ [InlineData("bio", true)]
+ [InlineData("class", true)]
+ public async Task GetItems_TestAsync(string orderingProperty, bool reverse)
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
@@ -91,35 +138,27 @@ public class DbChampionManager_UT
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
- db.EnsureCreated();
+ await db.Context.Database.EnsureCreatedAsync();
+
+ Champion champion = new Champion("test1", ChampionClass.Unknown, "test1");
+ Champion champion1 = new Champion("test2", ChampionClass.Assassin, "test2");
+ Champion champion2 = new Champion("test3", ChampionClass.Fighter, "test3");
- Champion champion = new Champion("Aurelien", ChampionClass.Tank, "tro bo le type");
- Champion champion2 = new Champion("Croissant", ChampionClass.Assassin, "tro bon le type");
- Champion champion3 = new Champion("Mathilde", ChampionClass.Fighter, "Chut mathilde");
await db.ChampionsMgr.AddItem(champion);
+ await db.ChampionsMgr.AddItem(champion1);
await db.ChampionsMgr.AddItem(champion2);
- await db.ChampionsMgr.AddItem(champion3);
- }
- using (var db = new DbDataManager(new EFLib.LolContext(options)))
- {
- db.EnsureCreated();
- string nameToFind = "Croissant";
- IEnumerable champ = await db.ChampionsMgr.GetItemsByName(nameToFind, 0, 15, "name");
- Champion c = champ.First();
- Assert.Equal("Croissant", c.Name);
- Champion c1 = new Champion("Test", c.Class, c.Icon, bio: c.Bio);
- await db.ChampionsMgr.UpdateItem(c, c1);
- Assert.Equal(3, await db.ChampionsMgr.GetNbItems());
- champ = await db.ChampionsMgr.GetItemsByName("Test", 0, 15, "name");
+ var list = await db.ChampionsMgr.GetItems(0, 10, orderingProperty, reverse);
- Assert.Equal("Test", champ.First().Name);
+ Assert.Equal(3, list.Count());
+ //if (reverse) Assert.Equal("test3", list.First().Name);
+ //else Assert.Equal("test1", list.First().Name);
}
}
[Fact]
- public async Task GetItems_TestAsync()
+ public async Task getNbItems_TestASync()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
@@ -130,32 +169,9 @@ public class DbChampionManager_UT
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
- db.EnsureCreated();
-
- Champion champion = new Champion("Aurelien", ChampionClass.Tank, "hey bo le type");
- Champion champion2 = new Champion("Croissant", ChampionClass.Assassin, "Ztro bon le type");
- Champion champion3 = new Champion("Mathilde", ChampionClass.Fighter, "ah mathilde");
- await db.ChampionsMgr.AddItem(champion);
- await db.ChampionsMgr.AddItem(champion2);
- await db.ChampionsMgr.AddItem(champion3);
- }
-
- using (var db = new DbDataManager(new EFLib.LolContext(options)))
- {
- db.EnsureCreated();
- var list = await db.ChampionsMgr.GetItems(0, 10, "bio", false);
- Assert.Equal(3, list.Count());
- list = await db.ChampionsMgr.GetItems(0, 3, "autre", true);
- Assert.Equal("Aurelien", list.Last().Name);
- list = await db.ChampionsMgr.GetItems(0, 3, "class", true);
- Assert.Equal("Aurelien", list.First().Name);
- list = await db.ChampionsMgr.GetItemsByClass(ChampionClass.Assassin, 0, 10);
- Assert.Equal(1, list.Count());
- Assert.Equal("Croissant", list.First().Name);
-
+ await db.Context.Database.EnsureCreatedAsync();
+ Assert.Equal(3, await db.ChampionsMgr.GetNbItems());
}
}
-
-
}
\ No newline at end of file
diff --git a/Sources/Tests/Tests.csproj b/Sources/Tests/Tests.csproj
index df4dc81..eaa167c 100644
--- a/Sources/Tests/Tests.csproj
+++ b/Sources/Tests/Tests.csproj
@@ -9,28 +9,30 @@
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
+
+
+
+
diff --git a/Sources/ViewModels/ChampionVM.cs b/Sources/ViewModels/ChampionVM.cs
new file mode 100644
index 0000000..bdd1e7f
--- /dev/null
+++ b/Sources/ViewModels/ChampionVM.cs
@@ -0,0 +1,101 @@
+using System;
+using CommunityToolkit.Mvvm.ComponentModel;
+using Model;
+using Microsoft.Maui.Controls;
+using System.Collections.ObjectModel;
+
+
+namespace ViewModels
+{
+ public partial class ChampionVM : ObservableObject
+ {
+ public Champion Model
+ {
+ get => model;
+ set
+ {
+ model = value;
+ OnPropertyChanged(nameof(Name));
+ OnPropertyChanged(nameof(Bio));
+ OnPropertyChanged(nameof(Class));
+ OnPropertyChanged(nameof(Icon));
+ OnPropertyChanged(nameof(Image));
+ OnPropertyChanged(nameof(Skills));
+ OnPropertyChanged(nameof(Characteristics));
+ }
+ }
+ private Champion model;
+
+ public ChampionVM(Champion model)
+ {
+ Model = model;
+ foreach(var skill in Model.Skills)
+ {
+ Skills.Add(new SkillVM(skill));
+ }
+ Skills.CollectionChanged += Skills_CollectionChanged;
+ }
+
+ private void Skills_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ SkillVM vm = e.NewItems?[0] as SkillVM;
+ switch(e.Action)
+ {
+ case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
+ Model.Skills.Add(new Skill(vm.Name, vm.Type, vm.Description));
+ break;
+ case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
+ Model.Skills.Remove(vm.Model);
+ break;
+ }
+ }
+
+ public string Name => Model.Name;
+
+ public ChampionClass Class
+ {
+ get => Model.Class;
+ set => SetProperty(Model.Class, value, newValue => Model.Class = newValue);
+ }
+
+ public string Bio
+ {
+ get => Model.Bio;
+ set => SetProperty(Model.Bio, value, newBio => Model.Bio = newBio);
+ }
+
+ public string Icon
+ {
+ get => Model.Icon;
+ set
+ {
+ SetProperty(Model.Icon, value, newIcon =>
+ {
+ Model.Icon = newIcon;
+ });
+ }
+ }
+
+ public string Image
+ {
+ get => Model.Image.Base64;
+ set
+ {
+ SetProperty(Model.Image.Base64, value, newImage =>
+ {
+ Model.Image.Base64 = newImage;
+ });
+ }
+ }
+
+ [ObservableProperty]
+ private ObservableCollection skills = new ObservableCollection();
+
+ public ReadOnlyDictionary Characteristics
+ => Model.Characteristics;
+
+ [ObservableProperty]
+ private ObservableCollection skins = new ObservableCollection();
+ }
+}
+
diff --git a/Sources/ViewModels/ChampionsMgrVM.cs b/Sources/ViewModels/ChampionsMgrVM.cs
new file mode 100644
index 0000000..06e5d67
--- /dev/null
+++ b/Sources/ViewModels/ChampionsMgrVM.cs
@@ -0,0 +1,227 @@
+using System.Threading.Tasks;
+using Model;
+using System.Windows.Input;
+using CommunityToolkit.Mvvm.ComponentModel;
+using System.Collections.ObjectModel;
+using CommunityToolkit.Mvvm.Input;
+using System.Data.SqlTypes;
+using System.Reflection;
+
+namespace ViewModels;
+
+public partial class ChampionsMgrVM : ObservableObject
+{
+ internal IDataManager DataMgr { get; set; }
+
+ public ChampionsMgrVM(IDataManager dataManager)
+ {
+ DataMgr = dataManager;
+
+ loadingMethods = new Dictionary>()
+ {
+ [LoadingCriterium.None] = async (o) => await LoadChampions(),
+ [LoadingCriterium.ByName] = async (o) =>
+ {
+ string substring = o as string;
+ if(substring == null) return;
+ await LoadChampionsByName(substring);
+ },
+ [LoadingCriterium.BySkill] = async (o) =>
+ {
+ string skillString = o as string;
+ if(skillString == null) return;
+ await LoadChampionsBySkill(skillString);
+ },
+ [LoadingCriterium.ByCharacteristic] = async (o) =>
+ {
+ string characString = o as string;
+ if(characString == null) return;
+ await LoadChampionsByCharacteristic(characString);
+ },
+ [LoadingCriterium.ByClass] = async (o) =>
+ {
+ if(!Enum.IsDefined(typeof(ChampionClass), o)) return;
+ ChampionClass champClass = (ChampionClass)o;
+ await LoadChampionsByClass(champClass);
+ },
+ };
+ }
+
+ private async Task LoadChampionsFunc(Func>> loader,
+ Func> nbReader,
+ LoadingCriterium criterium,
+ object parameter = null)
+ {
+ Champions.Clear();
+ var someChampions = (await loader()).Select(c => new ChampionVM(c)).ToList();
+ foreach (var cvm in someChampions)
+ {
+ Champions.Add(cvm);
+ }
+ NbChampions = await nbReader();
+ currentLoadingCriterium = criterium;
+ currentLoadingParameter = parameter;
+ }
+
+ [RelayCommand]
+ public async Task LoadChampions()
+ {
+ await LoadChampionsFunc(async () => await DataMgr.ChampionsMgr.GetItems(index, count, "Name"),
+ async () => await DataMgr.ChampionsMgr.GetNbItems(),
+ LoadingCriterium.None);
+ }
+
+ [RelayCommand(CanExecute =nameof(CanLoadChampionsByName))]
+ public async Task LoadChampionsByName(string substring)
+ {
+ await LoadChampionsFunc(async () => await DataMgr.ChampionsMgr.GetItemsByName(substring, index, count, "Name"),
+ async () => await DataMgr.ChampionsMgr.GetNbItemsByName(substring),
+ LoadingCriterium.ByName,
+ substring);
+ }
+ private bool CanLoadChampionsByName(string substring)
+ => !string.IsNullOrWhiteSpace(substring);
+
+ [RelayCommand(CanExecute =nameof(CanLoadChampionsBySkill))]
+ public async Task LoadChampionsBySkill(string skill)
+ {
+ await LoadChampionsFunc(
+ async () => await DataMgr.ChampionsMgr.GetItemsBySkill(skill, index, count, "Name"),
+ async () => await DataMgr.ChampionsMgr.GetNbItemsBySkill(skill),
+ LoadingCriterium.BySkill,
+ skill);
+ }
+ private bool CanLoadChampionsBySkill(string substring) => !string.IsNullOrWhiteSpace(substring);
+
+ [RelayCommand(CanExecute = nameof(CanLoadChampionsByCharacteristic))]
+ public async Task LoadChampionsByCharacteristic(string characteristic)
+ {
+ await LoadChampionsFunc(
+ async () => await DataMgr.ChampionsMgr.GetItemsByCharacteristic(characteristic, index, count, "Name"),
+ async () => await DataMgr.ChampionsMgr.GetNbItemsByCharacteristic(characteristic),
+ LoadingCriterium.ByCharacteristic,
+ characteristic);
+ }
+
+ private bool CanLoadChampionsByCharacteristic(string characteristic)
+ => !string.IsNullOrWhiteSpace(characteristic);
+
+ [RelayCommand]
+ public async Task LoadChampionsByClass(ChampionClass champClass)
+ {
+ if(champClass == ChampionClass.Unknown)
+ {
+ return;
+ }
+ await LoadChampionsFunc(
+ async () => await DataMgr.ChampionsMgr.GetItemsByClass(champClass, index, count, "Name"),
+ async () => await DataMgr.ChampionsMgr.GetNbItemsByClass(champClass),
+ LoadingCriterium.ByClass,
+ champClass);
+ }
+
+ [RelayCommand(CanExecute =nameof(CanDeleteChampion))]
+ public async Task DeleteChampion(object champVM)
+ {
+ ChampionVM cvm = champVM as ChampionVM;
+ if(cvm == null || !Champions.Contains(cvm)) return false;
+ bool result = await DataMgr.ChampionsMgr.DeleteItem(cvm.Model);
+ if(result)
+ {
+ Champions.Remove(cvm);
+ await LoadChampions();
+ }
+ return result;
+ }
+ bool CanDeleteChampion(object cvm)
+ => cvm!= null && cvm is ChampionVM && Champions.Contains(cvm);
+
+ [ObservableProperty]
+ [NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
+ [NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
+ private int index = 0;
+
+ [ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(NbPages))]
+ [NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
+ [NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
+ private int count = 5;
+
+ public int NbPages
+ {
+ get
+ {
+ if(Count == 0 || NbChampions == 0)
+ {
+ return 0;
+ }
+ return (NbChampions-1) / Count + 1;
+ }
+ }
+
+ [ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(NbPages))]
+ [NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
+ [NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
+ private int nbChampions = 0;
+
+ [ObservableProperty]
+ private ObservableCollection champions = new ObservableCollection();
+
+ [RelayCommand(CanExecute =nameof(CanPreviousPage))]
+ async Task PreviousPage()
+ {
+ if(Index > 0)
+ {
+ Index--;
+ await loadingMethods[currentLoadingCriterium](currentLoadingParameter);
+ }
+ }
+ bool CanPreviousPage() => Index > 0;
+
+ [RelayCommand(CanExecute =nameof(CanNextPage))]
+ async Task NextPage()
+ {
+ if(Index < NbPages-1)
+ {
+ Index++;
+ await loadingMethods[currentLoadingCriterium](currentLoadingParameter);
+ }
+ }
+ bool CanNextPage() => Index < NbPages-1;
+
+
+ enum LoadingCriterium
+ {
+ None,
+ ByName,
+ BySkill,
+ ByCharacteristic,
+ ByClass
+ }
+
+ private LoadingCriterium currentLoadingCriterium = LoadingCriterium.None;
+ private object currentLoadingParameter = null;
+
+ private Dictionary> loadingMethods;
+
+ public async Task AddChampion(ChampionVM champVM)
+ {
+ var added = await DataMgr.ChampionsMgr.AddItem(champVM.Model);
+ if(added != null)
+ {
+ Champions.Add(champVM);
+ await LoadChampions();
+ }
+ }
+
+ public async Task EditChampion(ChampionVM oldChampion, ChampionVM newChampion)
+ {
+ var edited = await DataMgr.ChampionsMgr.UpdateItem(oldChampion.Model, newChampion.Model);
+ oldChampion.Model = newChampion.Model;
+ if(edited != null)
+ {
+ await LoadChampions();
+ }
+ }
+}
diff --git a/Sources/ViewModels/EditableChampionVM.cs b/Sources/ViewModels/EditableChampionVM.cs
new file mode 100644
index 0000000..2db038b
--- /dev/null
+++ b/Sources/ViewModels/EditableChampionVM.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.ObjectModel;
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using Model;
+
+namespace ViewModels
+{
+ [ObservableObject]
+ public partial class EditableChampionVM
+ {
+ public EditableChampionVM()
+ { }
+
+ public EditableChampionVM(ChampionVM championVM)
+ {
+ Name = championVM.Name;
+ IconBase64 = championVM.Icon;
+ LargeImageBase64 = championVM.Image;
+ Bio = championVM.Bio;
+ ChampionClass = championVM.Class;
+ foreach(var ch in championVM.Characteristics)
+ {
+ AddCharacteristic(ch.Key, ch.Value);
+ }
+ foreach(var skill in championVM.Skills)
+ {
+ Skills.Add(skill);
+ }
+ }
+
+ [ObservableProperty]
+ string name;
+
+ [ObservableProperty]
+ string iconBase64;
+
+ [ObservableProperty]
+ string largeImageBase64;
+
+ [ObservableProperty]
+ string bio;
+
+ [ObservableProperty]
+ ChampionClass championClass;
+
+ [ObservableProperty]
+ ObservableCollection> characteristics = new ();
+
+ public void AddCharacteristic(string description, int value)
+ => Characteristics.Add(new KeyValuePair(description, value));
+
+ public void RemoveCharacteristic(KeyValuePair characteristic)
+ => Characteristics.Remove(characteristic);
+
+ [ObservableProperty]
+ ObservableCollection skills = new ObservableCollection();
+
+
+
+ public ChampionVM ToChampionVM()
+ {
+ var champion = new Champion(name, championClass, iconBase64, largeImageBase64, bio);
+ champion.AddCharacteristics(characteristics.Select(kvp => Tuple.Create(kvp.Key, kvp.Value)).ToArray());
+ foreach(var skillVM in Skills)
+ {
+ champion.AddSkill(skillVM.Model);
+ }
+ return new ChampionVM(champion);
+ }
+ }
+}
+
diff --git a/Sources/ViewModels/EditableSkinVM.cs b/Sources/ViewModels/EditableSkinVM.cs
new file mode 100644
index 0000000..b35ca24
--- /dev/null
+++ b/Sources/ViewModels/EditableSkinVM.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Reflection.PortableExecutable;
+using System.Xml.Linq;
+using CommunityToolkit.Mvvm.ComponentModel;
+using Model;
+
+namespace ViewModels
+{
+ [ObservableObject]
+ public partial class EditableSkinVM
+ {
+ public EditableSkinVM(ChampionVM championVM)
+ {
+ champion = championVM.Model;
+ }
+
+ public EditableSkinVM(SkinVM skinVM)
+ {
+ Name = skinVM.Name;
+ IconBase64 = skinVM.Icon;
+ LargeImageBase64 = skinVM.Image;
+ Description = skinVM.Description;
+ Price = skinVM.Price;
+ champion = skinVM.Champion;
+ }
+
+ [ObservableProperty]
+ private string name;
+
+ [ObservableProperty]
+ private string iconBase64;
+
+ [ObservableProperty]
+ private string largeImageBase64;
+
+ [ObservableProperty]
+ private string description;
+
+ [ObservableProperty]
+ private float price;
+
+ private Champion champion;
+
+ public SkinVM ToSkinVM()
+ {
+ var skin = new Skin(name, champion, price, iconBase64, largeImageBase64, description);
+ return new SkinVM(skin);
+ }
+ }
+}
+
diff --git a/Sources/ViewModels/SkillVM.cs b/Sources/ViewModels/SkillVM.cs
new file mode 100644
index 0000000..c9c2ca1
--- /dev/null
+++ b/Sources/ViewModels/SkillVM.cs
@@ -0,0 +1,32 @@
+using System;
+using CommunityToolkit.Mvvm.ComponentModel;
+using Model;
+
+namespace ViewModels
+{
+ [ObservableObject]
+ public partial class SkillVM
+ {
+ [ObservableProperty]
+ private Skill model;
+
+ public SkillVM(Skill model)
+ {
+ Model = model;
+ }
+
+ public string Name => Model.Name;
+
+ public SkillType Type => Model.Type;
+
+ public string Description
+ {
+ get => Model.Description;
+ set
+ {
+ SetProperty(Model.Description, value, newValue => Model.Description = newValue);
+ }
+ }
+ }
+}
+
diff --git a/Sources/ViewModels/SkinVM.cs b/Sources/ViewModels/SkinVM.cs
new file mode 100644
index 0000000..358ec97
--- /dev/null
+++ b/Sources/ViewModels/SkinVM.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Reflection.PortableExecutable;
+using System.Security.Claims;
+using CommunityToolkit.Mvvm.ComponentModel;
+using Model;
+
+namespace ViewModels
+{
+ [ObservableObject]
+ public partial class SkinVM
+ {
+ public Skin Model
+ {
+ get => model;
+ set
+ {
+ model = value;
+ OnPropertyChanged(nameof(Name));
+ OnPropertyChanged(nameof(Description));
+ OnPropertyChanged(nameof(Price));
+ OnPropertyChanged(nameof(Icon));
+ OnPropertyChanged(nameof(Image));
+ }
+ }
+ private Skin model;
+
+ public SkinVM(Skin model)
+ => Model = model;
+
+ public string Name => Model.Name;
+
+ public string Description
+ {
+ get => Model.Description;
+ set => SetProperty(Model.Description, value, newValue => Model.Description = newValue);
+ }
+
+ public float Price
+ {
+ get => Model.Price;
+ set => SetProperty(Model.Price, value, newValue => Model.Price = newValue);
+ }
+
+ public string Icon
+ {
+ get => Model.Icon;
+ set
+ {
+ SetProperty(Model.Icon, value, newIcon => Model.Icon = newIcon);
+ }
+ }
+
+ public string Image
+ {
+ get => Model.Image.Base64;
+ set
+ {
+ SetProperty(Model.Image.Base64, value, newImage => Model.Image.Base64 = newImage);
+ }
+ }
+
+ public Champion Champion => Model.Champion;
+ }
+}
+
diff --git a/Sources/ViewModels/SkinsMgrVM.cs b/Sources/ViewModels/SkinsMgrVM.cs
new file mode 100644
index 0000000..c51a6cf
--- /dev/null
+++ b/Sources/ViewModels/SkinsMgrVM.cs
@@ -0,0 +1,135 @@
+using System;
+using System.Collections.ObjectModel;
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using Model;
+
+namespace ViewModels
+{
+ [ObservableObject]
+ public partial class SkinsMgrVM
+ {
+ internal IDataManager DataMgr { get; set; }
+
+ [ObservableProperty]
+ private ChampionVM champion;
+
+ public SkinsMgrVM(IDataManager dataManager)
+ {
+ DataMgr = dataManager;
+ }
+
+ [ObservableProperty]
+ [NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
+ [NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
+ private int index = 0;
+
+ [ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(NbPages))]
+ [NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
+ [NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
+ private int count = 5;
+
+ public int NbPages
+ {
+ get
+ {
+ if(Count == 0 || NbSkins == 0)
+ {
+ return 0;
+ }
+ return (NbSkins-1) / Count + 1;
+ }
+ }
+
+ [ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(NbPages))]
+ [NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
+ [NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
+ private int nbSkins = 0;
+
+ [ObservableProperty]
+ private ObservableCollection skins = new ObservableCollection();
+
+ [RelayCommand]
+ async Task LoadSkins()
+ {
+ Skins.Clear();
+ IEnumerable skins;
+ if(Champion != null)
+ {
+ skins = await DataMgr.SkinsMgr.GetItemsByChampion(Champion.Model, Index, Count,"Name");
+
+ }
+ else
+ {
+ skins = await DataMgr.SkinsMgr.GetItems(Index, Count, "Name");
+ }
+
+ foreach(var skin in skins)
+ {
+ if(skin != null)
+ Skins.Add(new SkinVM(skin));
+ }
+ }
+
+ [RelayCommand(CanExecute =nameof(CanPreviousPage))]
+ async Task PreviousPage()
+ {
+ if(Index > 0)
+ {
+ Index--;
+ await LoadSkins();
+ }
+ }
+ bool CanPreviousPage() => Index > 0;
+
+ [RelayCommand(CanExecute =nameof(CanNextPage))]
+ async Task NextPage()
+ {
+ if(Index < NbPages-1)
+ {
+ Index++;
+ await LoadSkins();
+ }
+ }
+ bool CanNextPage() => Index < NbPages-1;
+
+ [RelayCommand(CanExecute =nameof(CanDeleteSkin))]
+ public async Task DeleteSkin(object skinVM)
+ {
+ SkinVM svm = skinVM as SkinVM;
+ if(svm == null || !Skins.Contains(svm)) return false;
+ bool result = await DataMgr.SkinsMgr.DeleteItem(svm.Model);
+ if(result)
+ {
+ Skins.Remove(svm);
+ await LoadSkins();
+ }
+ return result;
+ }
+ bool CanDeleteSkin(object svm)
+ => svm!= null && svm is SkinVM && Skins.Contains(svm);
+
+ public async Task AddSkin(SkinVM skinVM)
+ {
+ var added = await DataMgr.SkinsMgr.AddItem(skinVM.Model);
+ if(added != null)
+ {
+ Skins.Add(skinVM);
+ await LoadSkins();
+ }
+ }
+
+ public async Task EditSkin(SkinVM oldSkin, SkinVM newSkin)
+ {
+ var edited = await DataMgr.SkinsMgr.UpdateItem(oldSkin.Model, newSkin.Model);
+ oldSkin.Model = newSkin.Model;
+ if(edited != null)
+ {
+ await LoadSkins();
+ }
+ }
+ }
+}
+
diff --git a/Sources/ViewModels/ViewModels.csproj b/Sources/ViewModels/ViewModels.csproj
new file mode 100644
index 0000000..dd9fcb2
--- /dev/null
+++ b/Sources/ViewModels/ViewModels.csproj
@@ -0,0 +1,18 @@
+
+
+
+ net6.0
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+