Turn the top nav bar into a sidebar
Add an edit mode
This commit is contained in:
parent
91a660ef43
commit
f63798e897
|
@ -58,13 +58,16 @@
|
|||
<BookmarkGroup Group="group" />
|
||||
}
|
||||
|
||||
<div class="addBookmarkGroupButton text-center">
|
||||
<button type="button" class="btn tooltip tooltip-bottom"
|
||||
@onclick="this.ShowCreateGroupForm"
|
||||
aria-label="Create Group" data-tooltip="Create Group">
|
||||
<i class="icon icon-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
@if (this.state.Value.EditMode)
|
||||
{
|
||||
<div class="addBookmarkGroupButton text-center">
|
||||
<button type="button" class="btn tooltip tooltip-bottom"
|
||||
@onclick="this.ShowCreateGroupForm"
|
||||
aria-label="Create Group" data-tooltip="Create Group">
|
||||
<i class="icon icon-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
@using System.Drawing
|
||||
@using Fluxor
|
||||
@using Start.Client.Store.State
|
||||
|
||||
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
|
||||
|
||||
@inject IState<RootState> state
|
||||
@inject IDispatcher dispatch
|
||||
|
||||
<div class="card bookmarkGroup">
|
||||
<div class="card-header" style="background-color: @this.Group.Color">
|
||||
<h2 class="card-title h5 d-inline-block @this.ForegroundTitleColorClass">
|
||||
<h2 class="card-title h6 d-inline-block @this.ForegroundTitleColorClass">
|
||||
@this.Group.Title
|
||||
</h2>
|
||||
<button type="button" class="addBookmarkButton btn btn-sm tooltip tooltip-left"
|
||||
aria-label="Create Bookmark" data-tooltip="Create Bookmark">
|
||||
<i class="icon icon-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="bookmarks">
|
||||
|
@ -34,6 +37,16 @@
|
|||
{
|
||||
<Bookmark Model="bookmark" />
|
||||
}
|
||||
|
||||
@if (this.state.Value.EditMode)
|
||||
{
|
||||
<li class="addBookmarkItem">
|
||||
<button type="button" class="addBookmarkButton btn">
|
||||
<i class="icon icon-plus"></i>
|
||||
Create Bookmark
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -44,8 +57,10 @@
|
|||
[Parameter]
|
||||
public BookmarkGroupDto Group { get; set; } = null!;
|
||||
|
||||
protected string ForegroundTitleColorClass {
|
||||
get {
|
||||
protected string ForegroundTitleColorClass
|
||||
{
|
||||
get
|
||||
{
|
||||
const int threshold = 105;
|
||||
Color bgColor = ColorTranslator.FromHtml(this.Group.Color);
|
||||
|
||||
|
|
87
Start/Client/Components/Sidebar.razor
Normal file
87
Start/Client/Components/Sidebar.razor
Normal file
|
@ -0,0 +1,87 @@
|
|||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
|
||||
@using Start.Client.Store.Features.Sidebar
|
||||
@using Start.Client.Store.State
|
||||
@using Fluxor
|
||||
|
||||
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
|
||||
|
||||
@inject IState<RootState> state
|
||||
@inject IDispatcher dispatch
|
||||
|
||||
@inject NavigationManager Navigation
|
||||
@inject SignOutSessionStateManager SignOutManager
|
||||
|
||||
<div class="off-canvas">
|
||||
@* No off-canvas-toggle - add something that dispatches ShowSidebarAction *@
|
||||
|
||||
<div id="sidebar" class="off-canvas-sidebar @(this.state.Value.ShowSidebar ? "active" : "")">
|
||||
<div id="sidebarHeading">
|
||||
<h1>Start</h1>
|
||||
<button class="btn btn-link" @onclick="this.OnSidebarHideClicked">
|
||||
<i class="icon icon-cross icon-2x"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ul id="sidebarItems" class="nav">
|
||||
<li class="nav-item">
|
||||
<div class="form-group">
|
||||
<label class="form-switch">
|
||||
<input type="checkbox" @onclick="this.OnToggleEditMode" />
|
||||
<i class="form-icon"></i>
|
||||
Edit Mode
|
||||
</label>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav accountActions">
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<li class="nav-item accountName">
|
||||
<figure class="avatar">
|
||||
<i class="icon icon-people ml-2 mt-2"></i>
|
||||
</figure>
|
||||
@context.User.Identity?.Name
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="authentication/profile">Account</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="nav-link btn btn-link" @onclick="BeginSignOut">Log out</button>
|
||||
</li>
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<a href="authentication/login">Log in</a>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a class="off-canvas-overlay" @onclick="this.OnSidebarHideClicked"></a>
|
||||
|
||||
<div class="off-canvas-content">
|
||||
@this.ChildContent
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; } = null!;
|
||||
|
||||
protected void OnSidebarHideClicked()
|
||||
{
|
||||
dispatch.Dispatch(new HideSidebarAction());
|
||||
}
|
||||
|
||||
protected void OnToggleEditMode()
|
||||
{
|
||||
dispatch.Dispatch(new ToggleEditModeAction());
|
||||
}
|
||||
|
||||
private async Task BeginSignOut(MouseEventArgs args)
|
||||
{
|
||||
await SignOutManager.SetSignOutState();
|
||||
Navigation.NavigateTo("authentication/logout");
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
@using Start.Client.Store.Features.CurrentContainer
|
||||
@using Start.Client.Store.Features.CreateContainer
|
||||
@using Start.Client.Store.Features.DeleteContainer
|
||||
@using Start.Client.Store.Features.Sidebar
|
||||
@using Fluxor
|
||||
|
||||
@* Distinguish from Refit.Authorize *@
|
||||
|
@ -17,7 +18,8 @@
|
|||
@inject IState<RootState> state
|
||||
@inject IDispatcher dispatch
|
||||
|
||||
@if (this.state.Value.ContainerListState.ErrorMessage != null) {
|
||||
@if (this.state.Value.ContainerListState.ErrorMessage != null)
|
||||
{
|
||||
<Alert Type="Alert.AlertType.Error">
|
||||
<b>Error</b> @this.state.Value.ContainerListState.ErrorMessage
|
||||
</Alert>
|
||||
|
@ -34,41 +36,60 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
<ul class="containerList tab">
|
||||
@foreach (BookmarkContainerDto container in this.state.Value.ContainerListState.Containers)
|
||||
{
|
||||
string itemClasses = "tab-item";
|
||||
if (container.BookmarkContainerId == this.state.Value.CurrentContainerState.Container?.BookmarkContainerId)
|
||||
itemClasses += " active";
|
||||
<Sidebar>
|
||||
|
||||
<li class="@itemClasses">
|
||||
<a @onclick="() => OnContainerSelected(container.BookmarkContainerId)">
|
||||
@container.Title
|
||||
<button class="btn btn-clear"
|
||||
@onclick="() => this.OnDeleteContainerClicked(container.BookmarkContainerId)">
|
||||
</button>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
<li class="tab-item tab-action">
|
||||
<button @onclick="OnCreateContainerClicked" class="btn btn-link tooltip tooltip-left"
|
||||
title="Create New Container" aria-label="Create New Container"
|
||||
data-tooltip="Create Container">
|
||||
+
|
||||
<div id="containerTabStrip">
|
||||
<button id="menuButton" class="btn btn-link" @onclick="this.ShowSidebar">
|
||||
<i class="icon icon-menu"></i>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="containerList tab">
|
||||
@foreach (BookmarkContainerDto container in this.state.Value.ContainerListState.Containers)
|
||||
{
|
||||
string itemClasses = "tab-item";
|
||||
if (container.BookmarkContainerId == this.state.Value.CurrentContainerState.Container?.BookmarkContainerId)
|
||||
itemClasses += " active";
|
||||
|
||||
<BookmarkContainer />
|
||||
<li class="@itemClasses">
|
||||
<a @onclick="() => OnContainerSelected(container.BookmarkContainerId)">
|
||||
@container.Title
|
||||
@if (this.state.Value.EditMode)
|
||||
{
|
||||
<button class="btn btn-clear"
|
||||
@onclick="() => this.OnDeleteContainerClicked(container.BookmarkContainerId)">
|
||||
</button>
|
||||
}
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
@if (this.state.Value.EditMode)
|
||||
{
|
||||
<li class="tab-item tab-action">
|
||||
<button @onclick="OnCreateContainerClicked" class="btn btn-link tooltip tooltip-left"
|
||||
title="Create New Container" aria-label="Create New Container"
|
||||
data-tooltip="Create Container">
|
||||
+
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<CreateContainer />
|
||||
<DeleteContainer />
|
||||
<BookmarkContainer />
|
||||
|
||||
<CreateGroup />
|
||||
<CreateContainer />
|
||||
<DeleteContainer />
|
||||
|
||||
<CreateGroup />
|
||||
</Sidebar>
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
protected void ShowSidebar()
|
||||
{
|
||||
dispatch.Dispatch(new ShowSidebarAction());
|
||||
}
|
||||
|
||||
protected void OnContainerSelected(int bookmarkContainerId)
|
||||
{
|
||||
dispatch.Dispatch(new LoadCurrentContainerAction(bookmarkContainerId));
|
||||
|
|
|
@ -2,11 +2,6 @@
|
|||
|
||||
<div class="page">
|
||||
<div class="main">
|
||||
<div class="top-row px-4 auth">
|
||||
<LoginDisplay />
|
||||
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
|
||||
</div>
|
||||
|
||||
<div class="content px-4">
|
||||
@Body
|
||||
</div>
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
<None Remove="Store\Features\ContainersList\" />
|
||||
<None Remove="Store\Features\CurrentContainer\" />
|
||||
<None Remove="Store\Features\CreateGroup\" />
|
||||
<None Remove="Store\Features\Sidebar\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Remove="wwwroot\css\Spectre\" />
|
||||
|
@ -60,5 +61,6 @@
|
|||
<Folder Include="Store\Features\ContainersList\" />
|
||||
<Folder Include="Store\Features\CurrentContainer\" />
|
||||
<Folder Include="Store\Features\CreateGroup\" />
|
||||
<Folder Include="Store\Features\Sidebar\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
5
Start/Client/Store/Features/Sidebar/SidebarActions.cs
Normal file
5
Start/Client/Store/Features/Sidebar/SidebarActions.cs
Normal file
|
@ -0,0 +1,5 @@
|
|||
namespace Start.Client.Store.Features.Sidebar {
|
||||
public class ShowSidebarAction { }
|
||||
public class HideSidebarAction { }
|
||||
public class ToggleEditModeAction { }
|
||||
}
|
27
Start/Client/Store/Features/Sidebar/SidebarReducers.cs
Normal file
27
Start/Client/Store/Features/Sidebar/SidebarReducers.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using Fluxor;
|
||||
using Start.Client.Store.State;
|
||||
|
||||
namespace Start.Client.Store.Features.Sidebar {
|
||||
public static class SidebarReducers {
|
||||
[ReducerMethod(typeof(ShowSidebarAction))]
|
||||
public static RootState ShowSidebar(RootState state) {
|
||||
return state with {
|
||||
ShowSidebar = true
|
||||
};
|
||||
}
|
||||
|
||||
[ReducerMethod(typeof(HideSidebarAction))]
|
||||
public static RootState HideSidebar(RootState state) {
|
||||
return state with {
|
||||
ShowSidebar = false
|
||||
};
|
||||
}
|
||||
|
||||
[ReducerMethod(typeof(ToggleEditModeAction))]
|
||||
public static RootState ToggleEditMode(RootState state) {
|
||||
return state with {
|
||||
EditMode = !state.EditMode
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,9 @@ namespace Start.Client.Store.State {
|
|||
public ContainerListState ContainerListState { get; init; }
|
||||
public CurrentContainerState CurrentContainerState { get; init; }
|
||||
|
||||
public bool ShowSidebar { get; init; }
|
||||
public bool EditMode { get; init; }
|
||||
|
||||
public RootState() {
|
||||
this.ContainerListState = new ContainerListState();
|
||||
this.CurrentContainerState = new CurrentContainerState();
|
||||
|
|
|
@ -47,6 +47,65 @@
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
#sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#sidebar #sidebarHeading {
|
||||
padding: 0.5rem 1.5rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#sidebar #sidebarHeading h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#sidebar .nav {
|
||||
padding: 0.5rem 1.5rem;
|
||||
}
|
||||
|
||||
#sidebar #sidebarItems {
|
||||
flex: 1; /* Fill remaining space */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#sidebar .accountActions {
|
||||
border-top: solid 1px #dadee4;
|
||||
}
|
||||
|
||||
#sidebar .accountActions .accountName {
|
||||
font-weight: bold;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.off-canvas .off-canvas-content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#menubutton .icon {
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
#containerTabStrip {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#containerTabStrip #menuButton {
|
||||
flex: 0 0 auto;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
#containerTabStrip .containerList {
|
||||
flex: 1 0 0;
|
||||
}
|
||||
|
||||
#bookmarkGroups {
|
||||
margin-top: 1em;
|
||||
margin-left: auto;
|
||||
|
@ -71,7 +130,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1280px) {
|
||||
@media screen and (min-width: 1440) {
|
||||
#bookmarkGroups {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
width: 70%;
|
||||
|
@ -113,6 +172,5 @@ li.noBookmarksItem {
|
|||
}
|
||||
|
||||
button.addBookmarkButton {
|
||||
float: right;
|
||||
margin-top: 0.5em;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<script src="_content/Fluxor.Blazor.Web/scripts/index.js"></script>
|
||||
|
||||
<link href="css/spectre/spectre.min.css" rel="stylesheet" />
|
||||
<link href="css/spectre/spectre-exp.min.css" rel="stylesheet" />
|
||||
<link href="css/spectre/spectre-icons.css" rel="stylesheet" />
|
||||
<link href="css/app.css" rel="stylesheet" />
|
||||
<link href="Start.Client.styles.css" rel="stylesheet" />
|
||||
|
|
Loading…
Reference in a new issue