diff --git a/Components/Components.csproj b/Components/Components.csproj index 899beed..a2fe5ef 100644 --- a/Components/Components.csproj +++ b/Components/Components.csproj @@ -15,7 +15,7 @@ - + @@ -25,14 +25,14 @@ - + - - + + - + diff --git a/Components/Form/FormTextComponent.razor b/Components/Form/FormTextComponent.razor index 5e642a7..ee64d2c 100644 --- a/Components/Form/FormTextComponent.razor +++ b/Components/Form/FormTextComponent.razor @@ -12,6 +12,7 @@ type="text" value="@Value" id="@labelId" + @oninput="OnChange" @onchange="OnChange"/> @if (Info != "") @@ -61,6 +62,7 @@ [Parameter] public EventCallback OnChange { get; set; } + [Parameter] public bool ReadOnly { get; set; } diff --git a/Components/Inputs/SearchButtonComponent.razor b/Components/Inputs/SearchButtonComponent.razor new file mode 100644 index 0000000..5fb8f62 --- /dev/null +++ b/Components/Inputs/SearchButtonComponent.razor @@ -0,0 +1,61 @@ +@using System.Runtime.InteropServices +@inject ISearchService searchService +@inject NavigationManager navigationManager +@inject IJSRuntime jsRuntime + + + + + + +@code { + [Parameter] + public RenderFragment ChildContent { get; set; } = default!; + + private string userAgent = ""; + + string CommandKey => userAgent.Contains("Mac OS") ? "CMD" : "Ctrl"; + + private void ButtonClicked(EventArgs eventArgs) + { + searchService.Show(); + } + + protected override async Task OnInitializedAsync() + { + userAgent = await jsRuntime.InvokeAsync("getUserAgent"); + } +} \ No newline at end of file diff --git a/Components/Navigation/DesktopNavComponent.razor b/Components/Navigation/DesktopNavComponent.razor index 9d48183..bf55d5f 100644 --- a/Components/Navigation/DesktopNavComponent.razor +++ b/Components/Navigation/DesktopNavComponent.razor @@ -16,6 +16,7 @@ IGP Fan Reference +
@foreach (var webSection in WebSections) { var isSelected = navigationService.GetNavigationSectionId().Equals(webSection.Id); @@ -25,7 +26,7 @@ sectionButtonStyle += " sectionButtonSelected"; } -
+
@if (isSelected) @@ -38,6 +39,9 @@ }
} +
+ +
@@ -57,10 +61,7 @@ .sectionButton { cursor: pointer; - padding-left: 12px; - padding-right: 12px; - padding-top: 10px; - top: -11px; + padding: 12px; position: relative; z-index: 50000; } @@ -78,14 +79,32 @@ border-bottom: 4px solid black; position: fixed; width: 100%; - padding: 12px; + padding-top: 12px; + padding-bottom: 12px; + + padding-left: 24px; + padding-right: 24px; + display: flex; - justify-content: center; - gap: 8px; - height: 50px; background-color: var(--accent); + + justify-content: space-between; + align-items: center; + + } + + + .sectionNavs { + display: flex; + gap: 8px; + align-items: center; } +.sectionNav { + display: flex; + align-items: center; + height: 100%; +} .websiteTitle { font-weight: bold; @@ -95,8 +114,8 @@ .navMenuPosition { position: relative; - top: calc(100% - 36px); - left: calc(50% + -330px / 2); + top: 18px; + left: calc(-50% + -330px / 2); width: 0; height: 0; } @@ -119,7 +138,6 @@ } .sectionButtonSelected { - padding-bottom: 14px; box-shadow: 0 2px 3px black; background-color: var(--info); transform: translateY(-1px) scale(1.08); diff --git a/Components/_Imports.razor b/Components/_Imports.razor index 38adde9..91c027e 100644 --- a/Components/_Imports.razor +++ b/Components/_Imports.razor @@ -15,4 +15,5 @@ @using System.Threading.Tasks; @using System.Timers; @using System; -@using YamlDotNet.Serialization \ No newline at end of file +@using YamlDotNet.Serialization +@using Components.Inputs; \ No newline at end of file diff --git a/IGP/App.razor b/IGP/App.razor index 31d0d76..736e77d 100644 --- a/IGP/App.razor +++ b/IGP/App.razor @@ -1,4 +1,4 @@ -@inject HttpClient HttpClient +@inject HttpClient httpClient @@ -15,6 +15,7 @@ + + +@code { + + private ElementReference searchBox; + + private string SearchText { get; set; } = ""; + + protected override void OnInitialized() + { + searchService.Subscribe(OnSearchChanged); + } + + private void OnSearchChanged() + { + if (searchService.IsVisible) + { + jsRuntime.InvokeVoidAsync("SetFocusToElement", "search-dialog-input"); + + } + } + + public void Dispose() + { + searchService.Unsubscribe(OnSearchChanged); + } + + + public void CloseDialog() + { + searchService.Hide(); + } + + public void NavigateTo(string url) + { + if (url.Contains("#")) + { + + navigationManager.NavigateTo(url, + navigationManager.Uri.Split("#").First().Contains(url.Split("#").First())); + } + else + { + navigationManager.NavigateTo(url); + } + + } + + private void SearchChanged(ChangeEventArgs obj) + { + SearchText = obj.Value!.ToString()!; + } + + private void OnSearch(SearchPointModel searchPoint) + { + NavigateTo(searchPoint.Href); + searchService.Hide(); + } + +} \ No newline at end of file diff --git a/IGP/Index.razor b/IGP/Index.razor index 891cd80..cd21fe1 100644 --- a/IGP/Index.razor +++ b/IGP/Index.razor @@ -2,4 +2,8 @@ @layout PageLayout + + + + \ No newline at end of file diff --git a/IGP/PageLayout.razor b/IGP/PageLayout.razor index 728186f..b799c7f 100644 --- a/IGP/PageLayout.razor +++ b/IGP/PageLayout.razor @@ -1,39 +1,36 @@ @inherits LayoutComponentBase; +@inject IJSRuntime jsRuntime +@inject ISearchService searchService @inject IWebsiteService webService; @implements IDisposable; -
- @if (!webService.IsLoaded()) - { - - } - else - { -
- @Body -
+
+
+ @if (!webService.IsLoaded()) + { + + } + else + { +
+ @Body +
- - - - } + + + + } +
+
@code { -#if NO_SQL - -#else - [Inject] - DatabaseContext Database { get; set; } -#endif - - protected override void OnInitialized() { webService.Subscribe(HasChanged); @@ -42,6 +39,19 @@ protected override async Task OnInitializedAsync() { await webService.Load(); + + await Focus(); + + } + + private async Task Focus() + { + // await jsRuntime.InvokeVoidAsync("SetFocusToElement", pageContents); + } + + protected override async void OnAfterRender(bool firstRender) + { + // await jsRuntime.InvokeVoidAsync("SetFocusToElement", pageContents); } void IDisposable.Dispose() @@ -54,4 +64,15 @@ StateHasChanged(); } + private void HandleKeyDown(KeyboardEventArgs keyboardEventArgs) + { + if ((keyboardEventArgs.CtrlKey || keyboardEventArgs.MetaKey) && keyboardEventArgs.Key.ToLower() == "k") + { + searchService.Show(); + } + + Console.WriteLine(keyboardEventArgs.CtrlKey + " " + keyboardEventArgs.Key); + } + + } \ No newline at end of file diff --git a/IGP/Pages/Database/DatabaseSinglePage.razor b/IGP/Pages/Database/DatabaseSinglePage.razor index 6acd557..56ede3d 100644 --- a/IGP/Pages/Database/DatabaseSinglePage.razor +++ b/IGP/Pages/Database/DatabaseSinglePage.razor @@ -69,7 +69,7 @@ foreach (var e in DATA.Get().Values) { - if (e.Info().Name.Equals(Text)) + if (e.Info().Name.ToLower().Equals(Text!.ToLower())) { entity = e; return; diff --git a/IGP/Pages/RawDatabase.razor b/IGP/Pages/RawDatabase.razor index eaf4462..2d76508 100644 --- a/IGP/Pages/RawDatabase.razor +++ b/IGP/Pages/RawDatabase.razor @@ -5,7 +5,6 @@ Placeholders and Speculative The data I am using contains placeholders and speculation on future mechanics. Ignore said data when using this JSON. - @DATA.AsJson() diff --git a/IGP/Portals/SearchPortal.razor b/IGP/Portals/SearchPortal.razor new file mode 100644 index 0000000..6ec26c7 --- /dev/null +++ b/IGP/Portals/SearchPortal.razor @@ -0,0 +1,28 @@ +@implements IDisposable; + +@inject ISearchService searchService + +@if (searchService.IsVisible) +{ + +} + +@code { + + protected override void OnInitialized() + { + searchService.Subscribe(OnUpdate); + + searchService.Load(); + } + + public void Dispose() + { + searchService.Unsubscribe(OnUpdate); + } + + void OnUpdate() + { + StateHasChanged(); + } +} \ No newline at end of file diff --git a/IGP/Program.cs b/IGP/Program.cs index 5301df6..c259077 100644 --- a/IGP/Program.cs +++ b/IGP/Program.cs @@ -36,6 +36,7 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); +builder.Services.AddSingleton(); builder.Services.AddSingleton(new HttpClient { diff --git a/IGP/wwwroot/content/notes/settings/hotkeys.md b/IGP/wwwroot/content/notes/settings/hotkeys.md index f141387..e2cd9a4 100644 --- a/IGP/wwwroot/content/notes/settings/hotkeys.md +++ b/IGP/wwwroot/content/notes/settings/hotkeys.md @@ -9,7 +9,7 @@ In the pre-alpha, IGP comes with some Unreal default hotkey setup. This document will explain how to set up, modify, and use a new hotkey setup. -## Save the "Input.ini" file +# Save the "Input.ini" file ***Copy the below content and save the file as `Input.ini`.*** @@ -90,15 +90,14 @@ ActionMappings = (ActionName="UnitTypeSelectionModifier",bShift=False,bCtrl=Fals ***Copy the above content and save the file as `Input.ini`.*** -## Understand the Input.ini +# Understand the Input.ini You can notice a single line of this file can be broken down like this. `ActionMappings=(ActionName="AttackMove",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=A)` - `ActionMappings=(***)`: Indicates content is an action mapping. i.e. a hotkey -- `ActionName="AttackMove"`: Indicates the name of the selected action. Here, we are using the `AttackMove` move action, - that forces your selected army to attack. +- `ActionName="AttackMove"`: Indicates the name of the selected action. Here, we are using the `AttackMove` move action, that forces your selected army to attack. - `Key=A`: Indicates key being mapped to the action. Set to `Key=Tab` to require the Tab key to be pressed instead, to perform the `AttackMove` action. - `bShift=False`: Indicates that the Shift key is not held. Set to `bShift=True` to require a shift key held to @@ -110,7 +109,7 @@ You can notice a single line of this file can be broken down like this. - `bCmd=False`: Indicates that the Cmd key is not held. Set to `bCmd=True` to require a cmd key held to perform the mapped action. (Macs not supported by IGP) -## Modify the Input.ini file +# Modify the Input.ini file You are now going to want to modify the file with your own hotkey setup. @@ -258,10 +257,10 @@ to use proper values for `YOUR_USER` and `CURRENT_IMMORTAL_CLIENT`. There will be a blank `Input.ini` file in this folder. You can safely override it with your modified file. -## Testing +# Testing Restart the IGP client, and try out your new hotkey setup! -## Trouble Shooting +# Trouble Shooting If running into trouble, ask for help in the `hotkeys` channel in the IGP Discord. \ No newline at end of file diff --git a/IGP/wwwroot/generated/AgileTaskModels.json b/IGP/wwwroot/generated/AgileTaskModels.json index cf64951..8ec117f 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","OrderPriority":2,"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","OrderPriority":3,"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","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":4,"AgileSprintModelId":5,"Name":"Optimizations","Description":"Build Calculator should be usable.","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-13T00:00:00"},{"Id":5,"AgileSprintModelId":5,"Name":"Change Attack Timing Interval","Description":"Be able to set attack timing.","Notes":"Add notes...","Status":"In_Progress","Priority":"Medium","Task":"Feature","OrderPriority":1,"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","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":2,"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","OrderPriority":3,"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","OrderPriority":5,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":2,"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","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":32,"AgileSprintModelId":6,"Name":"Test Automation","Description":"Selenium Tests","Notes":"Start adding IDs to everything","Status":"Todo","Priority":"Low","Task":"Feature","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"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","OrderPriority":2,"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":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"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","OrderPriority":2,"Created":"2022-04-10T00:00:00","Finished":null},{"Id":46,"AgileSprintModelId":5,"Name":"Harass Calculator first client experience","Description":"Navigate player though the harass calculator steps","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"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","OrderPriority":2,"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":"Adding a loading screen for charts. Remove redundant renders","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-13T00:00:00"},{"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","OrderPriority":2,"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":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-12T00:00:00"},{"Id":51,"AgileSprintModelId":5,"Name":"Working Timers","Description":"Toast dismiss timers not making sense. Look into proper Timers","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-13T00:00:00"},{"Id":52,"AgileSprintModelId":5,"Name":"Clean up Build Calculator code","Description":"Code needs to be easily readable so it can be updated, maintained, and optimized","Notes":"addNotes","Status":"In_Progress","Priority":"Medium","Task":"Feature","OrderPriority":1,"Created":"2022-04-12T00:00:00","Finished":null},{"Id":53,"AgileSprintModelId":0,"Name":"Armor Types","Description":"Explain Light, Medium and Heavy armor types, and damage works","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":54,"AgileSprintModelId":0,"Name":"Economy Overview","Description":"How long it takes bases to mine out. How good natruals area","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":55,"AgileSprintModelId":0,"Name":"Timing and Scouting","Description":"Attacking and reacting to what the enemy is doing","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":56,"AgileSprintModelId":0,"Name":"Families, Factions, and Immortal Vanguards","Description":"How factions could be viewed.","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":57,"AgileSprintModelId":0,"Name":"Immortals Spells and Pyre","Description":"Using your Immortal","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":58,"AgileSprintModelId":null,"Name":"Organize Sprint Order","Description":"Sprints should be ordered as, current sprint, previous sprint, backlog, easy tasks, future sprints, old sprints","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":59,"AgileSprintModelId":5,"Name":"Better Sorting Algorithms ","Description":"Be smarted with searching through and sorting lists","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":60,"AgileSprintModelId":6,"Name":"Settings Section","Description":"Add a settings area, for permission and cookie related content","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":61,"AgileSprintModelId":6,"Name":"Analytics","Description":"Track client going to each page.","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":62,"AgileSprintModelId":6,"Name":"Cookies","Description":"Cookies to remember a the client permission options ","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":63,"AgileSprintModelId":6,"Name":"Permission Controls Page","Description":"Allow clients to enable cookies, analytics, and perhaps make things more granular. ","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":64,"AgileSprintModelId":6,"Name":"Defaults Page","Description":"Let clients set a cookie for Plain/Detailed view. Perhaps default Immortal. Etc.","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":65,"AgileSprintModelId":6,"Name":"Analytics Page","Description":"Let\u0027s have a page that shows the analytics collected during a client\u0027s session","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":66,"AgileSprintModelId":5,"Name":"Economy Comparison","Description":"Compare different economies. Make this a page under resources","Notes":"addNotes","Status":"In_Progress","Priority":"Medium","Task":"Feature","OrderPriority":1,"Created":"2022-04-15T00:00:00","Finished":null}] \ 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","OrderPriority":2,"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","OrderPriority":3,"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","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":4,"AgileSprintModelId":5,"Name":"Optimizations","Description":"Build Calculator should be usable.","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-13T00:00:00"},{"Id":5,"AgileSprintModelId":5,"Name":"Change Attack Timing Interval","Description":"Be able to set attack timing.","Notes":"Add notes...","Status":"In_Progress","Priority":"Medium","Task":"Feature","OrderPriority":1,"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","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":2,"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","OrderPriority":3,"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","OrderPriority":5,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":2,"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","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":32,"AgileSprintModelId":6,"Name":"Test Automation","Description":"Selenium Tests","Notes":"Start adding IDs to everything","Status":"Todo","Priority":"Low","Task":"Feature","OrderPriority":2,"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","OrderPriority":2,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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","OrderPriority":3,"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":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"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","OrderPriority":2,"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":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"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","OrderPriority":2,"Created":"2022-04-10T00:00:00","Finished":null},{"Id":46,"AgileSprintModelId":5,"Name":"Harass Calculator first client experience","Description":"Navigate player though the harass calculator steps","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"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","OrderPriority":2,"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":"Adding a loading screen for charts. Remove redundant renders","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-13T00:00:00"},{"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","OrderPriority":2,"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":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-12T00:00:00"},{"Id":51,"AgileSprintModelId":5,"Name":"Working Timers","Description":"Toast dismiss timers not making sense. Look into proper Timers","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-13T00:00:00"},{"Id":52,"AgileSprintModelId":5,"Name":"Clean up Build Calculator code","Description":"Code needs to be easily readable so it can be updated, maintained, and optimized","Notes":"addNotes","Status":"In_Progress","Priority":"Medium","Task":"Feature","OrderPriority":1,"Created":"2022-04-12T00:00:00","Finished":null},{"Id":53,"AgileSprintModelId":0,"Name":"Armor Types","Description":"Explain Light, Medium and Heavy armor types, and damage works","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":54,"AgileSprintModelId":0,"Name":"Economy Overview","Description":"How long it takes bases to mine out. How good natruals area","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":55,"AgileSprintModelId":0,"Name":"Timing and Scouting","Description":"Attacking and reacting to what the enemy is doing","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":56,"AgileSprintModelId":0,"Name":"Families, Factions, and Immortal Vanguards","Description":"How factions could be viewed.","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":57,"AgileSprintModelId":0,"Name":"Immortals Spells and Pyre","Description":"Using your Immortal","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":58,"AgileSprintModelId":null,"Name":"Organize Sprint Order","Description":"Sprints should be ordered as, current sprint, previous sprint, backlog, easy tasks, future sprints, old sprints","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":59,"AgileSprintModelId":5,"Name":"Better Sorting Algorithms ","Description":"Be smarted with searching through and sorting lists","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":60,"AgileSprintModelId":6,"Name":"Settings Section","Description":"Add a settings area, for permission and cookie related content","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":61,"AgileSprintModelId":6,"Name":"Analytics","Description":"Track client going to each page.","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":62,"AgileSprintModelId":6,"Name":"Cookies","Description":"Cookies to remember a the client permission options ","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":63,"AgileSprintModelId":6,"Name":"Permission Controls Page","Description":"Allow clients to enable cookies, analytics, and perhaps make things more granular. ","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":64,"AgileSprintModelId":6,"Name":"Defaults Page","Description":"Let clients set a cookie for Plain/Detailed view. Perhaps default Immortal. Etc.","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":65,"AgileSprintModelId":6,"Name":"Analytics Page","Description":"Let\u0027s have a page that shows the analytics collected during a client\u0027s session","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":66,"AgileSprintModelId":5,"Name":"Economy Comparison","Description":"Compare different economies. Make this a page under resources","Notes":"addNotes","Status":"In_Progress","Priority":"Medium","Task":"Feature","OrderPriority":1,"Created":"2022-04-15T00:00:00","Finished":null},{"Id":67,"AgileSprintModelId":5,"Name":"[Ctrl \u002B K] Search feature","Description":"","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-16T00:00:00","Finished":null}] \ No newline at end of file diff --git a/IGP/wwwroot/generated/NoteContentModels.json b/IGP/wwwroot/generated/NoteContentModels.json index fcab720..72c13cb 100644 --- a/IGP/wwwroot/generated/NoteContentModels.json +++ b/IGP/wwwroot/generated/NoteContentModels.json @@ -1 +1 @@ -[{"Id":1,"ParentId":null,"NoteSectionModelId":3,"Href":"holdout","CreatedDate":"2022-02-18T00:00:00","UpdatedDate":"2022-02-18T00:00:00","Name":"Coop Holdout, Some distant place (Nuath)","Description":"First coop test map in pre-alpha.","Content":"coop/holdout","IsHidden":"False","IsPreAlpha":"True","NoteContentModels":[],"Parent":null,"PageOrder":0},{"Id":2,"ParentId":null,"NoteSectionModelId":2,"Href":"hotkeys","CreatedDate":"2022-04-13T00:00:00","UpdatedDate":"2022-04-13T00:00:00","Name":"Custom HotKey Setup","Description":"Customize your hotkeys in the pre-alpha.","Content":"settings/hotkeys","IsHidden":"False","IsPreAlpha":"True","NoteContentModels":[],"Parent":null,"PageOrder":0},{"Id":3,"ParentId":null,"NoteSectionModelId":1,"Href":"armor-types","CreatedDate":"2022-04-13T00:00:00","UpdatedDate":"2022-04-13T00:00:00","Name":"Armor Types","Description":"Heavy, Medium, and Light. What does it mean?","Content":"the-basics/armor-types","IsHidden":"False","IsPreAlpha":"True","NoteContentModels":[],"Parent":null,"PageOrder":0}] \ No newline at end of file +[{"Id":1,"ParentId":null,"NoteSectionModelId":3,"Href":"holdout","CreatedDate":"2022-02-18T00:00:00","UpdatedDate":"2022-02-18T00:00:00","Name":"Coop Holdout, Some distant place (Nuath)","Description":"First coop test map in pre-alpha.","Content":"coop/holdout","LoadedContent":null,"IsHidden":"False","IsPreAlpha":"True","NoteContentModels":[],"Parent":null,"PageOrder":0},{"Id":2,"ParentId":null,"NoteSectionModelId":2,"Href":"hotkeys","CreatedDate":"2022-04-13T00:00:00","UpdatedDate":"2022-04-13T00:00:00","Name":"Custom HotKey Setup","Description":"Customize your hotkeys in the pre-alpha.","Content":"settings/hotkeys","LoadedContent":null,"IsHidden":"False","IsPreAlpha":"True","NoteContentModels":[],"Parent":null,"PageOrder":0},{"Id":3,"ParentId":null,"NoteSectionModelId":1,"Href":"armor-types","CreatedDate":"2022-04-13T00:00:00","UpdatedDate":"2022-04-13T00:00:00","Name":"Armor Types","Description":"Heavy, Medium, and Light. What does it mean?","Content":"the-basics/armor-types","LoadedContent":null,"IsHidden":"False","IsPreAlpha":"True","NoteContentModels":[],"Parent":null,"PageOrder":0}] \ No newline at end of file diff --git a/IGP/wwwroot/generated/WebSectionModels.json b/IGP/wwwroot/generated/WebSectionModels.json index 1718362..fe0eaa1 100644 --- a/IGP/wwwroot/generated/WebSectionModels.json +++ b/IGP/wwwroot/generated/WebSectionModels.json @@ -1 +1 @@ -[{"Id":1,"Name":"Tools","Description":"Tools Stuff","Href":null,"Order":1,"IsPrivate":"False","WebPageModels":[]},{"Id":2,"Name":"Resources","Description":"Resources Stuff","Href":null,"Order":2,"IsPrivate":"False","WebPageModels":[]},{"Id":3,"Name":"General","Description":"About Stuff","Href":null,"Order":3,"IsPrivate":"False","WebPageModels":[]},{"Id":4,"Name":"Development","Description":"Development Stuff","Href":null,"Order":4,"IsPrivate":"False","WebPageModels":[]},{"Id":5,"Name":"Settings","Description":"Settings Stuff","Href":null,"Order":5,"IsPrivate":"False","WebPageModels":[]}] \ No newline at end of file +[{"Id":1,"Name":"Tools","Description":"Tools Stuff","Order":1,"IsPrivate":"False","WebPageModels":[]},{"Id":2,"Name":"Resources","Description":"Resources Stuff","Order":2,"IsPrivate":"False","WebPageModels":[]},{"Id":3,"Name":"General","Description":"About Stuff","Order":3,"IsPrivate":"False","WebPageModels":[]},{"Id":4,"Name":"Development","Description":"Development Stuff","Order":4,"IsPrivate":"False","WebPageModels":[]},{"Id":5,"Name":"Settings","Description":"Settings Stuff","Order":5,"IsPrivate":"False","WebPageModels":[]}] \ No newline at end of file diff --git a/IGP/wwwroot/index.html b/IGP/wwwroot/index.html index f1521de..23444ac 100644 --- a/IGP/wwwroot/index.html +++ b/IGP/wwwroot/index.html @@ -36,6 +36,17 @@ applicationCulture: 'en-US' }); + + + diff --git a/Model/Notes/NoteContentModel.cs b/Model/Notes/NoteContentModel.cs index 173dfd7..ea3d71a 100644 --- a/Model/Notes/NoteContentModel.cs +++ b/Model/Notes/NoteContentModel.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using System.Text.RegularExpressions; +using Model.Website; namespace Model.Notes; @@ -22,9 +24,42 @@ public class NoteContentModel public string Description { get; set; } public string Content { get; set; } + + + [NotMapped] + public virtual string LoadedContent { get; set; } + + public string IsHidden { get; set; } = "False"; public string IsPreAlpha { get; set; } = "True"; + public List GetHeaders() + { + var regex = new Regex(@"^#* (.*)$", RegexOptions.Multiline); + var listOfMatches = regex.Matches(LoadedContent); + + Console.WriteLine($"Name: {Name}"); + + Console.WriteLine($"Matches: {listOfMatches.Count}"); + + List foundHeaders = new List(); + + foreach (var capture in listOfMatches) + { + var cleanUp = capture.ToString(); + cleanUp = cleanUp.ToLower(); + cleanUp = cleanUp.Replace("#", ""); + cleanUp = cleanUp.Replace("#", ""); + cleanUp = cleanUp.Replace("\"", ""); + cleanUp = cleanUp.Trim(); + cleanUp = cleanUp.Replace(" ", "-"); + foundHeaders.Add(new SearchPointModel(){ Title = capture.ToString().Trim(), Href = cleanUp}); + Console.WriteLine($"Capture: {cleanUp}"); + } + + return foundHeaders; + } + [NotMapped] public virtual ICollection NoteContentModels { get; set; } = new List(); diff --git a/Model/Website/SearchPointModel.cs b/Model/Website/SearchPointModel.cs new file mode 100644 index 0000000..cf853b4 --- /dev/null +++ b/Model/Website/SearchPointModel.cs @@ -0,0 +1,9 @@ +namespace Model.Website; + +public class SearchPointModel +{ + public string Title { get; set; } = ""; + public string Tags { get; set; } = ""; + public string PointType { get; set; } = ""; + public string Href { get; set; } = ""; +} \ No newline at end of file diff --git a/Model/Website/WebSectionModel.cs b/Model/Website/WebSectionModel.cs index 3938b6a..3debdca 100644 --- a/Model/Website/WebSectionModel.cs +++ b/Model/Website/WebSectionModel.cs @@ -8,7 +8,6 @@ public class WebSectionModel public int Id { get; set; } public string Name { get; set; } = "Add name"; public string Description { get; set; } = "Add description"; - public string Href { get; set; } = null; public int Order { get; set; } = 0; public string IsPrivate { get; set; } = "True"; diff --git a/Services/Development/NoteService.cs b/Services/Development/NoteService.cs index 7c1ac83..7ad0c11 100644 --- a/Services/Development/NoteService.cs +++ b/Services/Development/NoteService.cs @@ -59,6 +59,11 @@ public class NoteService : INoteService isLoaded = true; + foreach (var content in NoteContentModels) + { + content.LoadedContent = await httpClient.GetStringAsync($"content/notes/{content.Content}.md"); + } + SortSQL(); NotifyDataChanged(); diff --git a/Services/IServices.cs b/Services/IServices.cs index 5822b3a..1326124 100644 --- a/Services/IServices.cs +++ b/Services/IServices.cs @@ -25,6 +25,26 @@ public interface IToastService void ClearAllToasts(); } +public interface ISearchService +{ + public List SearchPoints { get; set; } + + public Dictionary> Searches { get; set; } + + public bool IsVisible { get; set; } + + public void Subscribe(Action action); + public void Unsubscribe(Action action); + + public void Search(string entityId); + + public Task Load(); + + public bool IsLoaded(); + void Show(); + void Hide(); +} + public interface IEntityDialogService { public void Subscribe(Action action); @@ -70,7 +90,7 @@ public interface IAgileService public void Unsubscribe(Action? action); public void Update(); - public Task Load(); + public Task Load(); public bool IsLoaded(); } diff --git a/Services/Services.csproj b/Services/Services.csproj index 14ad851..48f7133 100644 --- a/Services/Services.csproj +++ b/Services/Services.csproj @@ -15,12 +15,12 @@ - + - - + + diff --git a/Services/Website/SearchService.cs b/Services/Website/SearchService.cs new file mode 100644 index 0000000..52f8dba --- /dev/null +++ b/Services/Website/SearchService.cs @@ -0,0 +1,131 @@ +using Model.Entity.Data; +using Model.Feedback; +using Model.Website; + +namespace Services.Website; + +public class SearchService : ISearchService +{ + + private bool isLoaded = false; + public List SearchPoints { get; set; } = new(); + + public Dictionary> Searches { get; set; } = new(); + + + private IWebsiteService websiteService; + private INoteService noteService; + private IDocumentationService documentationService; + + public SearchService(IWebsiteService websiteService, INoteService noteService, IDocumentationService documentationService) + { + this.websiteService = websiteService; + this.noteService = noteService; + this.documentationService = documentationService; + + // All Unit Data + } + + public bool IsVisible { get; set; } + + public void Subscribe(Action action) + { + OnChange += action; + } + + public void Unsubscribe(Action action) + { + OnChange += action; + } + + public void Search(string entityId) + { + } + + public async Task Load() + { + await websiteService.Load(); + await noteService.Load(); + await documentationService.Load(); + + + Searches.Add("Pages", new List()); + Searches.Add("Notes", new List()); + Searches.Add("Documents", new List()); + Searches.Add("Entities", new List()); + + foreach (var webPage in websiteService.WebPageModels) + { + SearchPoints.Add(new SearchPointModel{ Title = webPage.Name, + PointType = "WebPage", + Href=webPage.Href + }); + + Searches["Pages"].Add(SearchPoints.Last()); + } + + foreach (var note in noteService.NoteContentModels) + { + SearchPoints.Add(new SearchPointModel(){ Title = note.Name, + PointType = "Note", Href = note.GetNoteLink()}); + + Searches["Notes"].Add(SearchPoints.Last()); + + foreach (var noteHeader in note.GetHeaders()) + { + SearchPoints.Add(new SearchPointModel { Title = noteHeader.Title, + PointType = "NoteHeader", Href = $"{note.GetNoteLink()}/#{noteHeader.Href}"}); + } + } + + + foreach (var entity in DATA.Get().Values) + { + SearchPoints.Add(new SearchPointModel(){ + Title = entity.Info().Name, + Tags = $"{entity.EntityType},{entity.Descriptive}", + PointType = "Entity", + Href = $"database/{entity.Info().Name.ToLower()}" + }); + + Searches["Entities"].Add(SearchPoints.Last()); + } + + + foreach (var doc in documentationService.DocContentModels) + { + SearchPoints.Add(new SearchPointModel { Title = doc.Name, + PointType = "Document", Href = doc.GetDocLink()}); + + Searches["Documents"].Add(SearchPoints.Last()); + } + + isLoaded = true; + } + + public bool IsLoaded() + { + return isLoaded; + } + + public void Show() + { + IsVisible = true; + + NotifyDataChanged(); + } + + public void Hide() + { + IsVisible = false; + + NotifyDataChanged(); + } + + private event Action OnChange = null!; + + private void NotifyDataChanged() + { + OnChange(); + } +} \ No newline at end of file