From 4322be00532c28538cab7916c2e4b7619f5a6ec5 Mon Sep 17 00:00:00 2001 From: Jonathan McCaffrey Date: Sun, 10 Apr 2022 17:32:22 -0400 Subject: [PATCH] feat(Toasts) Adding toasts --- Components/Components.csproj | 1 + Components/Feedback/AlertComponent.razor | 30 ++--- Components/Feedback/SeverityType.cs | 8 -- Components/Feedback/ToastComponent.razor | 114 ++++++++++++++++++ Components/Inputs/CodeLinkComponent.razor | 28 +++++ Components/_Imports.razor | 8 +- IGP/App.razor | 11 +- IGP/Database.db | Bin 278528 -> 278528 bytes IGP/IGP.csproj | 38 ++++-- IGP/Index.razor | 11 ++ IGP/Localizations.Designer.cs | 54 +++++++++ IGP/Localizations.properties | 0 IGP/Localizations.resx | 24 ++++ IGP/Pages/AboutPage.razor | 1 - IGP/Pages/Agile/AgilePage.razor | 12 +- .../BuildCalculator/BuildCalculatorPage.razor | 2 +- IGP/Pages/HarassCalculatorPage.razor | 56 +-------- IGP/Pages/MakingOf/MakingOfPage.razor | 2 +- .../MakingOf/Parts/MakingOfFeedback.razor | 8 +- IGP/Portals/ToastPortal.razor | 42 +++++++ IGP/Program.cs | 9 ++ IGP/_Imports.razor | 2 + IGP/wwwroot/css/app.css | 13 +- IGP/wwwroot/generated/AgileTaskModels.json | 2 +- IGP/wwwroot/index.html | 9 +- Model/Feedback/SeverityType.cs | 9 ++ Model/Feedback/ToastModel.cs | 8 ++ Services/IServices.cs | 12 ++ Services/Website/ToastService.cs | 64 ++++++++++ 29 files changed, 478 insertions(+), 100 deletions(-) delete mode 100644 Components/Feedback/SeverityType.cs create mode 100644 Components/Feedback/ToastComponent.razor create mode 100644 Components/Inputs/CodeLinkComponent.razor create mode 100644 IGP/Localizations.Designer.cs create mode 100644 IGP/Localizations.properties create mode 100644 IGP/Localizations.resx create mode 100644 IGP/Portals/ToastPortal.razor create mode 100644 Model/Feedback/SeverityType.cs create mode 100644 Model/Feedback/ToastModel.cs create mode 100644 Services/Website/ToastService.cs diff --git a/Components/Components.csproj b/Components/Components.csproj index b068a9d..083b3df 100644 --- a/Components/Components.csproj +++ b/Components/Components.csproj @@ -21,6 +21,7 @@ + diff --git a/Components/Feedback/AlertComponent.razor b/Components/Feedback/AlertComponent.razor index 9fc2e61..a8797d2 100644 --- a/Components/Feedback/AlertComponent.razor +++ b/Components/Feedback/AlertComponent.razor @@ -1,4 +1,5 @@ -
+@using Model.Feedback +
@if (Title != null) {
@Title @@ -21,24 +22,25 @@ width: 100%; } - .alertContainer.@SeverityType.Warning.ToString().ToLower() { - border-color: #2a2000; - background-color: #ffbf0029; + + .alertContainer.@SeverityType.Warning.ToLower() { + background-color: var(--severity-warning-color); + border-color: var(--severity-warning-border-color); } - .alertContainer.@SeverityType.Error.ToString().ToLower() { - border-color: #290102; - background-color: #4C2C33; + .alertContainer.@SeverityType.Error.ToLower() { + background-color: var(--severity-error-color); + border-color: var(--severity-error-border-color); } - .alertContainer.@SeverityType.Information.ToString().ToLower() { - border-color: #030129; - background-color: #2c3a4c; + .alertContainer.@SeverityType.Information.ToLower() { + background-color: var(--severity-information-color); + border-color: var(--severity-information-border-color); } - .alertContainer.@SeverityType.Success.ToString().ToLower() { - border-color: #042901; - background-color: #2E4C2C; + .alertContainer.@SeverityType.Success.ToLower() { + background-color: var(--severity-success-color); + border-color: var(--severity-success-border-color); } .alertTitle { @@ -56,6 +58,6 @@ public RenderFragment? Message { get; set; } [Parameter] - public SeverityType Type { get; set; } = SeverityType.Warning; + public string Type { get; set; } = SeverityType.Warning; } \ No newline at end of file diff --git a/Components/Feedback/SeverityType.cs b/Components/Feedback/SeverityType.cs deleted file mode 100644 index 8efbea4..0000000 --- a/Components/Feedback/SeverityType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Components.Feedback; - -public enum SeverityType { - Warning, - Information, - Error, - Success -} \ No newline at end of file diff --git a/Components/Feedback/ToastComponent.razor b/Components/Feedback/ToastComponent.razor new file mode 100644 index 0000000..d90ce3a --- /dev/null +++ b/Components/Feedback/ToastComponent.razor @@ -0,0 +1,114 @@ +@using Services +@inject IToastService toastService + +@implements IDisposable + +@if (Toast == null) +{ +
Add toast object...
+} +else +{ +
+
+ @Toast.Title +
+
+ @Toast.Message +
+
+} + + + +@code { + [Parameter] + public ToastModel? Toast { get; set; } = default!; + + private bool isFadingOut = false; + + private string FadeoutStyle => isFadingOut ? "fadeout" : ""; + + private int removalTime = 150000; + private int fadeoutTime = 4000; + + //private int fade + + private Timer removalTimer = null!; + private Timer fadeoutTimer = null!; + + protected override void OnInitialized() + { +#if DEBUG + removalTime = 5000; +#endif + + removalTimer = new Timer(removalTime); + removalTimer.Elapsed += OnRemoval!; + removalTimer.Enabled = true; + + fadeoutTimer = new Timer(removalTime - fadeoutTime); + fadeoutTimer.Elapsed += OnFadeout!; + fadeoutTimer.Enabled = true; + } + + void OnFadeout(object source, ElapsedEventArgs eventArgs) + { + isFadingOut = true; + + StateHasChanged(); + } + + void OnRemoval(object source, ElapsedEventArgs eventArgs) + { + toastService.RemoveToast(Toast!); + } + + public void Dispose() + { + removalTimer.Dispose(); + fadeoutTimer.Dispose(); + } +} \ No newline at end of file diff --git a/Components/Inputs/CodeLinkComponent.razor b/Components/Inputs/CodeLinkComponent.razor new file mode 100644 index 0000000..f3a6947 --- /dev/null +++ b/Components/Inputs/CodeLinkComponent.razor @@ -0,0 +1,28 @@ + + View on GitHub + + + + +@code { + + [Parameter] + public string Href { get; set; } = ""; +} \ No newline at end of file diff --git a/Components/_Imports.razor b/Components/_Imports.razor index aec752a..941bb27 100644 --- a/Components/_Imports.razor +++ b/Components/_Imports.razor @@ -7,4 +7,10 @@ @using Microsoft.JSInterop @using System.Text @using System.Text.Json -@using YamlDotNet.Serialization \ No newline at end of file +@using YamlDotNet.Serialization +@using Model.Feedback + +@using System; +@using System.Threading.Tasks; +@using System.Timers; + diff --git a/IGP/App.razor b/IGP/App.razor index 212285e..31d0d76 100644 --- a/IGP/App.razor +++ b/IGP/App.razor @@ -14,6 +14,7 @@ + + + +@code { + + protected override void OnInitialized() + { + toastService.Subscribe(OnUpdate); + } + + public void Dispose() + { + toastService.Unsubscribe(OnUpdate); + } + + void OnUpdate() + { + StateHasChanged(); + } + +} \ No newline at end of file diff --git a/IGP/Program.cs b/IGP/Program.cs index c88cc30..f1b71d1 100644 --- a/IGP/Program.cs +++ b/IGP/Program.cs @@ -4,6 +4,7 @@ using Services; using Services.Development; using Services.Immortal; using Services.Website; +using System.Globalization; #if NO_SQL #else @@ -11,6 +12,11 @@ using Contexts; using Microsoft.EntityFrameworkCore; #endif +CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); +CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US"); + + + var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.Logging.SetMinimumLevel(LogLevel.Warning); @@ -19,6 +25,8 @@ builder.RootComponents.Add("head::after"); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); +builder.Services.AddLocalization(); + builder.Services.AddSingleton(); builder.Services.AddSingleton(); @@ -40,6 +48,7 @@ builder.Services.AddSingleton(new HttpClient builder.Services.AddSingleton(); +builder.Services.AddSingleton(); #if NO_SQL diff --git a/IGP/_Imports.razor b/IGP/_Imports.razor index bd9720c..6d70f71 100644 --- a/IGP/_Imports.razor +++ b/IGP/_Imports.razor @@ -7,6 +7,7 @@ @using Components.Navigation @using Components.Shared @using Components.Utils +@using System.Globalization @using IGP.Dialog @using IGP.Pages @using IGP.Pages.Agile.Parts @@ -27,6 +28,7 @@ @using IGP.Pages.Notes.Parts @using IGP.Portals @using Markdig +@using Model.Feedback @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web diff --git a/IGP/wwwroot/css/app.css b/IGP/wwwroot/css/app.css index 975b4d5..5d65f2c 100644 --- a/IGP/wwwroot/css/app.css +++ b/IGP/wwwroot/css/app.css @@ -4,6 +4,15 @@ @import "components/table.css"; :root { + --severity-warning-color: #2a2000; + --severity-warning-border-color: #755c13; + --severity-error-color: #290102; + --severity-error-border-color: #4C2C33; + --severity-information-color: #030129; + --severity-information-border-color: #2c3a4c; + --severity-success-color: #042901; + --severity-success-border-color: #2E4C2C; + --accent: #432462; --primary: #4308a3; --primary-border: #2c0b62; @@ -22,12 +31,14 @@ --info: #451376; --info-border: #210b36; + --info-hover: #451376; + --info-border-hover: #210b36; + --dialog-border-color: black; --dialog-border-width: 2px; --dialog-radius: 6px; } - html { box-sizing: border-box; } diff --git a/IGP/wwwroot/generated/AgileTaskModels.json b/IGP/wwwroot/generated/AgileTaskModels.json index 14d8018..32aa758 100644 --- a/IGP/wwwroot/generated/AgileTaskModels.json +++ b/IGP/wwwroot/generated/AgileTaskModels.json @@ -1 +1 @@ -[{"Id":1,"AgileSprintModelId":null,"Name":"Support Safari","Description":"Consider other web browsers.","Notes":"Added","Status":"Todo","Priority":"Low","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":2,"AgileSprintModelId":2,"Name":"Filter Patch Notes","Description":"You should be showing people what they really want to see in the patch notes.","Notes":"Added","Status":"Done","Priority":"Blocker","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":3,"AgileSprintModelId":null,"Name":"Consider Pyre","Description":"Add Pyre Income. Make it so you can take Pyre Camps and Pyre Miners","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":4,"AgileSprintModelId":null,"Name":"Optimizations","Description":"Build Calculator should be usable.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":5,"AgileSprintModelId":null,"Name":"Change Attack Timing Interval","Description":"Be able to sett attack timing.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":6,"AgileSprintModelId":null,"Name":"Add Pyre Spells","Description":"Make Pyre Spells castable and consume Pyre on build order","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":7,"AgileSprintModelId":null,"Name":"Default builds (Rush Thrones)","Description":"Add a dropdown list of default builds.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":8,"AgileSprintModelId":null,"Name":"Load older builds","Description":"Be able to load older builds. How are you going to handle auto correct to current patch?","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":9,"AgileSprintModelId":null,"Name":"How to use Build Calculator step by step","Description":"Need docs","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":10,"AgileSprintModelId":null,"Name":"Compare Health and Damage","Description":"Refer to community example spreadsheet.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":11,"AgileSprintModelId":null,"Name":"Compare Unit\u0027s Damage with it\u0027s own costs","Description":"Refer to community example spreadsheet.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":12,"AgileSprintModelId":4,"Name":"View one unit stats from a link. Make YAML copy and paste","Description":"Design so people can easily copy and paste data into discord","Notes":"Ended up not using exact Yaml. Button in Database controls Detailed vs Plain display ","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":13,"AgileSprintModelId":2,"Name":"Look into SQL","Description":"You really should be using SQL.","Notes":"Agile and Change log pages now use SQL","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":14,"AgileSprintModelId":1,"Name":"Mobile Menu","Description":"You need a real mobile menu. Viewers don\u0027t scroll below the fold, so no one is going to know what happens when you click a button on phones.","Notes":"Added smaller menus for tablets and phones.","Status":"Done","Priority":"High","Task":"Feature","Created":"2022-02-18T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":15,"AgileSprintModelId":2,"Name":"Acropolis Consume Mote","Description":"The Mote is suppose to be consumed when making a Town Hall.","Notes":"Fixed","Status":"Done","Priority":"High","Task":"Bug","Created":"2022-02-18T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":16,"AgileSprintModelId":null,"Name":"Multiple Travel Time in Calculator","Description":"Travel time should be based on the amount of bases used. 3 bases is 3 travel times.","Notes":"Add notes...","Status":"Todo","Priority":"Low","Task":"Feature","Created":"2022-02-18T00:00:00","Finished":null},{"Id":17,"AgileSprintModelId":1,"Name":"Update Database to 0.0.6.8375a","Description":"Xacal tech change, and Hallower damage change. Update Godhead text.","Notes":"Done","Status":"Done","Priority":"None","Task":"Feature","Created":"2022-02-18T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":18,"AgileSprintModelId":null,"Name":"Patch History Viewer","Description":"Add an ability to compare patches, to see all nerfs and buffs made between them.","Notes":"Inspired by Zkay\u0027s post on discord, where he details a possible \u0027patch history viewer\u0027 implementation.","Status":"Fun_Idea","Priority":"None","Task":"Feature","Created":"2022-02-16T00:00:00","Finished":null},{"Id":19,"AgileSprintModelId":1,"Name":"Twitch Page","Description":"Did a ~3 hour test stream, and was personal quite happy with the quality. Make Twitch page, and stream patch, sprint planning and development on Sunday.","Notes":"Page added under General, and named \u0022Streams\u0022.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-16T00:00:00","Finished":"2022-02-16T00:00:00"},{"Id":20,"AgileSprintModelId":1,"Name":"Finish the database","Description":"Add more descriptions for everything. Reduce any data duplication with ids. Add upgrade connections. Add ability connections. Add passives and passives connections.","Notes":"Good enough for now","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-11T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":21,"AgileSprintModelId":1,"Name":"Change Log View","Description":"Add a log to view last changes.","Notes":"Added changelog page. Shows Today, X Days Ago, or exact date if patch is over a week old.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-14T00:00:00","Finished":"2022-02-14T00:00:00"},{"Id":22,"AgileSprintModelId":1,"Name":"Agile View","Description":"Add the agile view.","Notes":"Finished.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-11T00:00:00","Finished":"2022-02-17T00:00:00"},{"Id":23,"AgileSprintModelId":1,"Name":"GUID for Ids","Description":"Stop using enums for ids, and start using guids. Enums are just too limited, I lose out on component and inheritance design with them. Replace all your enums with guids, rip off the bandaid.","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-11T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":24,"AgileSprintModelId":1,"Name":"Co-op overview","Description":"Write some sort of blog on co-op gameplay so you have something the feels very content-ish. Maybe make it a video.","Notes":"Finished and released early.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-11T00:00:00","Finished":"2022-02-12T00:00:00"},{"Id":25,"AgileSprintModelId":1,"Name":"Mobile UI","Description":"Make website work on mobile.","Notes":"Should be good. Will test on phone later.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-15T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":26,"AgileSprintModelId":1,"Name":"Add Making Of View","Description":"View to reference UI designs. Nicely encourages the pratice of making the UI code a lot cleaner.","Notes":"Good enough for now","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-11T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":27,"AgileSprintModelId":3,"Name":"Close Nav Menu on Navigation","Description":"Close Nav Menu on Navigation","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":28,"AgileSprintModelId":3,"Name":"Add Passive Descriptions and Passive","Description":"Have to guess on a bunch of passives","Notes":null,"Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-03-31T00:00:00"},{"Id":29,"AgileSprintModelId":3,"Name":"Tooltips that show referenced units","Description":"I should see any referenced unit by hovering over it","Notes":"Links can now go to links which can go to links.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-04-01T00:00:00"},{"Id":30,"AgileSprintModelId":null,"Name":"Update Logo for Website","Description":"After color scheme is picked","Notes":null,"Status":"Todo","Priority":"Low","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":null},{"Id":31,"AgileSprintModelId":3,"Name":"Documentation page","Description":"Add documents on how to maintain website","Notes":"Added start of documents","Status":"Done","Priority":"Low","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":32,"AgileSprintModelId":null,"Name":"Test Automation","Description":"Selenium Tests","Notes":"Start adding IDs to everything","Status":"Todo","Priority":"Low","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":null},{"Id":33,"AgileSprintModelId":null,"Name":"Unit Test","Description":"Add some unit tests","Notes":null,"Status":"Todo","Priority":"Low","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":null},{"Id":34,"AgileSprintModelId":null,"Name":"Fully Transfer everything to SQL","Description":"Need to regenerate the database once everthing is fully transfered","Notes":null,"Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":null},{"Id":35,"AgileSprintModelId":3,"Name":"Adding a loading Component","Description":"For JSON loading","Notes":"Added loading component to Agile and Changelog screens","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":36,"AgileSprintModelId":3,"Name":"Optimize Loading of Data","Description":"Currently loading non Agile stuff on Agile page","Notes":"Moved SQL database injection to app root","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":37,"AgileSprintModelId":3,"Name":"Convert Notes to Markdown","Description":"Using Markdown and generating the Note pages seems like a better solution to SQL or hardcoding data","Notes":null,"Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-04-01T00:00:00"},{"Id":38,"AgileSprintModelId":3,"Name":"Improve Entity Filter Options","Description":"The options I give you is strange, given it filers on Faction type","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","Created":"2022-04-01T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":39,"AgileSprintModelId":4,"Name":"Refresh Database Bug","Description":"Database dialog UI isn\u0027t refreshing enough","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","Created":"2022-04-03T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":40,"AgileSprintModelId":4,"Name":"Branding Stuff","Description":"Add a schedule, improving branding, etc, ","Notes":"Only improved Twitch overlays","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-04-03T00:00:00","Finished":"2022-04-10T00:00:00"},{"Id":41,"AgileSprintModelId":4,"Name":"Improve Documents/Notes UI","Description":"Should have a left navigation menu. And prev/next buttons","Notes":"Updated UI. Will added prev/next and breadcrumbs later","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-04-05T00:00:00","Finished":"2022-04-10T00:00:00"}] \ No newline at end of file +[{"Id":1,"AgileSprintModelId":null,"Name":"Support Safari","Description":"Consider other web browsers.","Notes":"Added","Status":"Todo","Priority":"Low","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":2,"AgileSprintModelId":2,"Name":"Filter Patch Notes","Description":"You should be showing people what they really want to see in the patch notes.","Notes":"Added","Status":"Done","Priority":"Blocker","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":3,"AgileSprintModelId":5,"Name":"Consider Pyre","Description":"Add Pyre Income. Make it so you can take Pyre Camps and Pyre Miners","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":4,"AgileSprintModelId":5,"Name":"Optimizations","Description":"Build Calculator should be usable.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":5,"AgileSprintModelId":5,"Name":"Change Attack Timing Interval","Description":"Be able to set attack timing.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":6,"AgileSprintModelId":5,"Name":"Add Pyre Spells","Description":"Make Pyre Spells castable and consume Pyre on build order","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":7,"AgileSprintModelId":null,"Name":"Default builds (Rush Thrones)","Description":"Add a dropdown list of default builds.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":8,"AgileSprintModelId":null,"Name":"Load older builds","Description":"Be able to load older builds. How are you going to handle auto correct to current patch?","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":9,"AgileSprintModelId":null,"Name":"How to use Build Calculator step by step","Description":"Need docs","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":10,"AgileSprintModelId":null,"Name":"Compare Health and Damage","Description":"Refer to community example spreadsheet.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":11,"AgileSprintModelId":null,"Name":"Compare Unit\u0027s Damage with it\u0027s own costs","Description":"Refer to community example spreadsheet.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":12,"AgileSprintModelId":4,"Name":"View one unit stats from a link. Make YAML copy and paste","Description":"Design so people can easily copy and paste data into discord","Notes":"Ended up not using exact Yaml. Button in Database controls Detailed vs Plain display ","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":13,"AgileSprintModelId":2,"Name":"Look into SQL","Description":"You really should be using SQL.","Notes":"Agile and Change log pages now use SQL","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-20T00:00:00","Finished":null},{"Id":14,"AgileSprintModelId":1,"Name":"Mobile Menu","Description":"You need a real mobile menu. Viewers don\u0027t scroll below the fold, so no one is going to know what happens when you click a button on phones.","Notes":"Added smaller menus for tablets and phones.","Status":"Done","Priority":"High","Task":"Feature","Created":"2022-02-18T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":15,"AgileSprintModelId":2,"Name":"Acropolis Consume Mote","Description":"The Mote is suppose to be consumed when making a Town Hall.","Notes":"Fixed","Status":"Done","Priority":"High","Task":"Bug","Created":"2022-02-18T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":16,"AgileSprintModelId":5,"Name":"Multiple Travel Time in Harass Calculator","Description":"Travel time should be based on the amount of bases used. 3 bases is 3 travel times.","Notes":"Add notes...","Status":"Todo","Priority":"Low","Task":"Feature","Created":"2022-02-18T00:00:00","Finished":null},{"Id":17,"AgileSprintModelId":1,"Name":"Update Database to 0.0.6.8375a","Description":"Xacal tech change, and Hallower damage change. Update Godhead text.","Notes":"Done","Status":"Done","Priority":"None","Task":"Feature","Created":"2022-02-18T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":18,"AgileSprintModelId":null,"Name":"Patch History Viewer","Description":"Add an ability to compare patches, to see all nerfs and buffs made between them.","Notes":"Inspired by Zkay\u0027s post on discord, where he details a possible \u0027patch history viewer\u0027 implementation.","Status":"Fun_Idea","Priority":"None","Task":"Feature","Created":"2022-02-16T00:00:00","Finished":null},{"Id":19,"AgileSprintModelId":1,"Name":"Twitch Page","Description":"Did a ~3 hour test stream, and was personal quite happy with the quality. Make Twitch page, and stream patch, sprint planning and development on Sunday.","Notes":"Page added under General, and named \u0022Streams\u0022.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-16T00:00:00","Finished":"2022-02-16T00:00:00"},{"Id":20,"AgileSprintModelId":1,"Name":"Finish the database","Description":"Add more descriptions for everything. Reduce any data duplication with ids. Add upgrade connections. Add ability connections. Add passives and passives connections.","Notes":"Good enough for now","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-11T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":21,"AgileSprintModelId":1,"Name":"Change Log View","Description":"Add a log to view last changes.","Notes":"Added changelog page. Shows Today, X Days Ago, or exact date if patch is over a week old.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-14T00:00:00","Finished":"2022-02-14T00:00:00"},{"Id":22,"AgileSprintModelId":1,"Name":"Agile View","Description":"Add the agile view.","Notes":"Finished.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-11T00:00:00","Finished":"2022-02-17T00:00:00"},{"Id":23,"AgileSprintModelId":1,"Name":"GUID for Ids","Description":"Stop using enums for ids, and start using guids. Enums are just too limited, I lose out on component and inheritance design with them. Replace all your enums with guids, rip off the bandaid.","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-11T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":24,"AgileSprintModelId":1,"Name":"Co-op overview","Description":"Write some sort of blog on co-op gameplay so you have something the feels very content-ish. Maybe make it a video.","Notes":"Finished and released early.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-11T00:00:00","Finished":"2022-02-12T00:00:00"},{"Id":25,"AgileSprintModelId":1,"Name":"Mobile UI","Description":"Make website work on mobile.","Notes":"Should be good. Will test on phone later.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-15T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":26,"AgileSprintModelId":1,"Name":"Add Making Of View","Description":"View to reference UI designs. Nicely encourages the pratice of making the UI code a lot cleaner.","Notes":"Good enough for now","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-02-11T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":27,"AgileSprintModelId":3,"Name":"Close Nav Menu on Navigation","Description":"Close Nav Menu on Navigation","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":28,"AgileSprintModelId":3,"Name":"Add Passive Descriptions and Passive","Description":"Have to guess on a bunch of passives","Notes":null,"Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-03-31T00:00:00"},{"Id":29,"AgileSprintModelId":3,"Name":"Tooltips that show referenced units","Description":"I should see any referenced unit by hovering over it","Notes":"Links can now go to links which can go to links.","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-04-01T00:00:00"},{"Id":30,"AgileSprintModelId":null,"Name":"Update Logo for Website","Description":"After color scheme is picked","Notes":null,"Status":"Todo","Priority":"Low","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":null},{"Id":31,"AgileSprintModelId":3,"Name":"Documentation page","Description":"Add documents on how to maintain website","Notes":"Added start of documents","Status":"Done","Priority":"Low","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":32,"AgileSprintModelId":null,"Name":"Test Automation","Description":"Selenium Tests","Notes":"Start adding IDs to everything","Status":"Todo","Priority":"Low","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":null},{"Id":33,"AgileSprintModelId":null,"Name":"Unit Test","Description":"Add some unit tests","Notes":null,"Status":"Todo","Priority":"Low","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":null},{"Id":34,"AgileSprintModelId":4,"Name":"Fully Transfer everything to SQL","Description":"Need to regenerate the database once everthing is fully transfered","Notes":null,"Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-04-09T00:00:00"},{"Id":35,"AgileSprintModelId":3,"Name":"Adding a loading Component","Description":"For JSON loading","Notes":"Added loading component to Agile and Changelog screens","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":36,"AgileSprintModelId":3,"Name":"Optimize Loading of Data","Description":"Currently loading non Agile stuff on Agile page","Notes":"Moved SQL database injection to app root","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":37,"AgileSprintModelId":3,"Name":"Convert Notes to Markdown","Description":"Using Markdown and generating the Note pages seems like a better solution to SQL or hardcoding data","Notes":null,"Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-03-27T00:00:00","Finished":"2022-04-01T00:00:00"},{"Id":38,"AgileSprintModelId":3,"Name":"Improve Entity Filter Options","Description":"The options I give you is strange, given it filers on Faction type","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","Created":"2022-04-01T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":39,"AgileSprintModelId":4,"Name":"Refresh Database Bug","Description":"Database dialog UI isn\u0027t refreshing enough","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","Created":"2022-04-03T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":40,"AgileSprintModelId":4,"Name":"Branding Stuff","Description":"Add a schedule, improving branding, etc, ","Notes":"Only improved Twitch overlays","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-04-03T00:00:00","Finished":"2022-04-10T00:00:00"},{"Id":41,"AgileSprintModelId":4,"Name":"Improve Documents/Notes UI","Description":"Should have a left navigation menu. And prev/next buttons","Notes":"Updated UI. Will added prev/next and breadcrumbs later","Status":"Done","Priority":"Medium","Task":"Feature","Created":"2022-04-05T00:00:00","Finished":"2022-04-10T00:00:00"},{"Id":42,"AgileSprintModelId":5,"Name":"Add GitHub links instead of showing code","Description":"For all code examples","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-04-10T00:00:00","Finished":null},{"Id":43,"AgileSprintModelId":5,"Name":"Research More used RTS calculations","Description":"What other calculators like the Harass Page can be added","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2001-01-01T00:00:00","Finished":null},{"Id":44,"AgileSprintModelId":5,"Name":"Add Error Toasts to Calculator","Description":"Not enough \u0022Ether\u0022","Notes":"Add notes...","Status":"In_Progress","Priority":"Medium","Task":"Feature","Created":"2022-04-10T00:00:00","Finished":null},{"Id":45,"AgileSprintModelId":5,"Name":"Handle Divide by Zero in Harass Calculator","Description":"addDescription","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-04-10T00:00:00","Finished":null},{"Id":46,"AgileSprintModelId":5,"Name":"Harass Calculator first user experience","Description":"Navigate player though the harass calculator steps","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-04-10T00:00:00","Finished":null},{"Id":47,"AgileSprintModelId":5,"Name":"Training Queue","Description":"Add training queue times to the build calculator","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-04-10T00:00:00","Finished":null},{"Id":48,"AgileSprintModelId":5,"Name":"Refresh Button for Build Calculator","Description":"Refresh to regenerate timeline and charts","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-04-10T00:00:00","Finished":null},{"Id":49,"AgileSprintModelId":5,"Name":"Gameplay Warning State Toasts","Description":"\u0022You should upgrade your economy.\u0022 \u0022Your using too much ether, spend alloy\u0022","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-04-10T00:00:00","Finished":null},{"Id":50,"AgileSprintModelId":5,"Name":"Make desktop navigation buttons","Description":"It popping up all the time is a tad tedious","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","Created":"2022-04-10T00:00:00","Finished":null}] \ No newline at end of file diff --git a/IGP/wwwroot/index.html b/IGP/wwwroot/index.html index 95f876a..4ed83b7 100644 --- a/IGP/wwwroot/index.html +++ b/IGP/wwwroot/index.html @@ -13,11 +13,11 @@ - +
- + @@ -28,6 +28,11 @@ integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js"> + diff --git a/Model/Feedback/SeverityType.cs b/Model/Feedback/SeverityType.cs new file mode 100644 index 0000000..57cd158 --- /dev/null +++ b/Model/Feedback/SeverityType.cs @@ -0,0 +1,9 @@ +namespace Model.Feedback; + +public class SeverityType +{ + public static string Warning = "Warning"; + public static string Information = "Information"; + public static string Error = "Error"; + public static string Success = "Success"; +} \ No newline at end of file diff --git a/Model/Feedback/ToastModel.cs b/Model/Feedback/ToastModel.cs new file mode 100644 index 0000000..04bd9f5 --- /dev/null +++ b/Model/Feedback/ToastModel.cs @@ -0,0 +1,8 @@ +namespace Model.Feedback; + +public class ToastModel +{ + public string Title { get; set; } = "addTitle"; + public string Message { get; set; } = "addMessage"; + public string SeverityType { get; set; } = "addType"; +} \ No newline at end of file diff --git a/Services/IServices.cs b/Services/IServices.cs index fbebbd0..1396425 100644 --- a/Services/IServices.cs +++ b/Services/IServices.cs @@ -15,11 +15,23 @@ using Model.Notes; using Model.Website; using Model.Website.Enums; using Model.Development.Git; +using Model.Feedback; using Model.Work.Tasks; using Services.Immortal; namespace Services; +public interface IToastService +{ + public void Subscribe(Action action); + public void Unsubscribe(Action action); + void AddToast(ToastModel toast); + void RemoveToast(ToastModel toast); + bool HasToasts(); + List GetToasts(); + void ClearAllToasts(); +} + public interface IEntityDialogService { diff --git a/Services/Website/ToastService.cs b/Services/Website/ToastService.cs new file mode 100644 index 0000000..122e84b --- /dev/null +++ b/Services/Website/ToastService.cs @@ -0,0 +1,64 @@ +using Model.Feedback; + +namespace Services.Website; + +public class ToastService : IToastService +{ + private readonly List toasts = new(); + + private event Action OnChange = null!; + + #if DEBUG + public ToastService() + { + toasts.Add(new ToastModel(){Message = "Example message", SeverityType = SeverityType.Error, Title = "Example Error"}); + toasts.Add(new ToastModel(){Message = "Example message", SeverityType = SeverityType.Information, Title = "Example Information"}); + toasts.Add(new ToastModel(){Message = "Example message", SeverityType = SeverityType.Success, Title = "Example Success"}); + toasts.Add(new ToastModel(){Message = "Example message", SeverityType = SeverityType.Warning, Title = "Example Warning"}); + } + #endif + + + private void NotifyDataChanged() { + OnChange(); + } + + public void Subscribe(Action action) { + OnChange += action; + } + + public void Unsubscribe(Action action) { + OnChange += action; + } + + public void AddToast(ToastModel toast) + { + toasts.Add(toast); + NotifyDataChanged(); + } + + public void RemoveToast(ToastModel toast) + { + toasts.Remove(toast); + NotifyDataChanged(); + } + + public bool HasToasts() + { + return toasts.Count > 0; + } + + public List GetToasts() + { + return toasts; + } + + public void ClearAllToasts() + { + toasts.Clear(); + NotifyDataChanged(); + } + +} + +