Updated layout to support settings and customization

This commit is contained in:
Ed Charbeneau 2020-07-02 12:09:53 -04:00
Родитель 18e8ee8a87
Коммит b6f84f613c
8 изменённых файлов: 241 добавлений и 73 удалений

Просмотреть файл

@ -1,24 +0,0 @@
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject NavigationManager Navigation
@inject SignOutSessionStateManager SignOutManager
<AuthorizeView>
<Authorized>
<a href="authentication/profile">Hello, @context.User.Identity.Name!</a>
<button class="nav-link btn btn-link" @onclick="BeginSignOut">Log out</button>
</Authorized>
<NotAuthorized>
<a href="authentication/register">Register</a>
<a href="authentication/login">Log in</a>
</NotAuthorized>
</AuthorizeView>
@code{
private async Task BeginSignOut(MouseEventArgs args)
{
await SignOutManager.SetSignOutState();
Navigation.NavigateTo("authentication/logout");
}
}

Просмотреть файл

@ -1,44 +1,81 @@
@inherits LayoutComponentBase
@inject NavigationManager navigationManger
@using BlazingCoffee.Client.Shared.NavMenu
<header class="header">
<div class="nav-container">
<div class="menu-button">
<TelerikButton Icon="@IconName.Menu" OnClick="@(() => Expanded = !Expanded)" />
</div>
<div class="title">
<h1>Blazing Coffee Warehouse</h1>
</div>
<div class="settings">
@*<span>Language</span>*@
<LoginDisplay />
</div>
</div>
</header>
<TelerikRootComponent>
<TelerikDrawer @bind-Expanded="@Expanded" @bind-SelectedItem="SelectedItem"
Data="Data" MiniMode="true" Mode="DrawerMode.Push">
<TelerikDrawer @bind-Expanded="@Expanded" Width="280px" Data="Data" Mode="DrawerMode.Push" Position="DrawerPosition.Left">
<Template>
<DrawTemplate Data="context"></DrawTemplate>
</Template>
<Content>
<header class="header">
<div class="nav-container">
<div class="menu-button">
<TelerikButton Icon="@IconName.Menu" OnClick="@(() => Expanded = !Expanded)" />
</div>
<div class="title">
<h1>Blazing Coffee Warehouse</h1>
</div>
<div class="settings">
<TelerikButton Icon="@IconName.Gear" OnClick="@(() => SettingsExpanded = !SettingsExpanded)" />
</div>
</div>
</header>
@Body
</Content>
</TelerikDrawer>
<TelerikWindow @bind-Visible="SettingsExpanded" Modal="true">
<WindowTitle>
Settings
</WindowTitle>
<WindowActions>
<WindowAction Name="Close" />
</WindowActions>
<WindowContent>
<div class="k-widget k-form">
<div class="k-form-field">
<label class="k-label k-form-label" for="theme">
Theme
</label>
<div class="k-form-field-wrap">
<TelerikDropDownList Id="theme" Data="Themes" TValue="string" TItem="string" @bind-Value="SelectedTheme" />
</div>
</div>
<div class="k-form-field">
<label class="k-label k-form-label" for="language">
Language
</label>
<div class="k-form-field-wrap">
<TelerikDropDownList Id="language" Data="Languages" TValue="string" TItem="string" @bind-Value="SelectedLanguage" />
</div>
</div>
</div>
</WindowContent>
</TelerikWindow>
</TelerikRootComponent>
@code {
bool Expanded { get; set; } = false;
object SelectedItem { get; set; }
bool Expanded { get; set; } = true;
bool SettingsExpanded { get; set; }
IEnumerable<object> Data { get; set; } =
new List<object>
{
new { Text = "Home", Icon = IconName.ArrowRoot, Url="/"},
new { Text = "Sales", Icon = IconName.Dollar, Url="/sales"},
new { Text = "Human Capital", Icon = IconName.TellAFriend, Url="/manage-employees"},
new { Text = "Manage Products", Icon = IconName.Grid, Url="/manage-products"}
};
protected override void OnInitialized()
IEnumerable<DrawerItem> Data =>
new List<DrawerItem>
{
SelectedItem = Data.First();
}
new DrawerItem{ Text = "Home", Icon = IconName.ArrowRoot, Url="/", Group = "app"},
new DrawerItem{ Text = "Sales", Icon = IconName.Dollar, Url="/sales", Group = "app"},
new DrawerItem{ Text = "Human Capital", Icon = IconName.TellAFriend, Url="/manage-employees", Group = "app"},
new DrawerItem{ Text = "Manage Products", Icon = IconName.Grid, Url="/manage-products", Group = "app"},
new DrawerItem{ Text = "GitHub", Icon = IconName.Share, Url="https://github.com/telerik/blazing-coffee", Group = "ext"},
new DrawerItem{ Text = "Telerik", Icon = IconName.HyperlinkGlobe, Url="https://telerik.com", Group = "ext"},
new DrawerItem{ Text = "Documentation", Icon = IconName.Html, Url="https://docs.telerik.com/blazor-ui/introduction", Group = "ext"},
new DrawerItem{ Text = "Support", Icon = IconName.Question, Url="https://www.telerik.com/account/support-tickets", Group = "ext"}
};
string SelectedTheme = "auto";
IEnumerable<string> Themes => new List<string> { "auto" }; // TODO add manual settings, "light", "dark" };
string SelectedLanguage = "en";
IEnumerable<string> Languages => new List<string> { "en" }; // TODO add Globalization
}

Просмотреть файл

@ -0,0 +1,57 @@
@inject NavigationManager navigationManger
@using BlazingCoffee.Client.Shared.NavMenu
<div class="k-drawer-items">
<header>
<LoginDisplay />
</header>
<ul role="menubar" aria-orientation="vertical">
@foreach (DrawerItem item in Data.Where(item => item.Group == "app"))
{
if (item == SelectedItem)
{
<li class="k-drawer-item k-state-selected" data-index="0" tabindex="0" role="menuitem" aria-label="@item.Text">
<TelerikIcon Icon="@item.Icon"></TelerikIcon>
<span class="k-item-text">@item.Text</span>
</li>
}
else
{
<li class="k-drawer-item" data-index="1" tabindex="-1" role="menuitem" aria-label="@item.Text" @onclick="@(()=> ItemSelected(item))">
<TelerikIcon Icon="@item.Icon"></TelerikIcon>
<span class="k-item-text">@item.Text</span>
</li>
}
}
</ul>
<footer>
<h3 class="title">More Info</h3>
<ul role="menubar" aria-orientation="vertical">
@foreach (DrawerItem item in Data.Where(item => item.Group == "ext"))
{
<li class="k-drawer-item" data-index="1" tabindex="-1" role="menuitem" aria-label="@item.Text" @onclick="@(()=>navigationManger.NavigateTo(item.Url))">
<TelerikIcon Icon="@item.Icon"></TelerikIcon>
<span class="k-item-text">@item.Text</span>
</li>
}
</ul>
</footer>
</div>
@code {
[Parameter] public IEnumerable<DrawerItem> Data { get; set; }
DrawerItem SelectedItem;
protected override void OnInitialized()
{
SelectedItem = Data.First();
}
void ItemSelected(DrawerItem item)
{
SelectedItem = item;
navigationManger.NavigateTo(item.Url);
}
}

Просмотреть файл

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BlazingCoffee.Client.Shared.NavMenu
{
public class DrawerItem
{
public string Text { get; set; }
public string Icon { get; set; }
public string Url { get; set; }
public string Group { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,51 @@
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using System.Security.Cryptography
@using System.Text
@inject NavigationManager Navigation
@inject SignOutSessionStateManager SignOutManager
<AuthorizeView>
<Authorized>
<TelerikButton Icon="@IconName.User" @onclick="BeginSignOut">Log out</TelerikButton>
<img class="k-avatar-rounded" src="@HashEmailForGravatar(context.User.Identity.Name)" />
<a href="authentication/profile">@context.User.Identity.Name</a>
</Authorized>
<NotAuthorized>
<a href="authentication/register">Register</a>
<a href="authentication/login">Log in</a>
</NotAuthorized>
</AuthorizeView>
@code{
private async Task BeginSignOut(MouseEventArgs args)
{
await SignOutManager.SetSignOutState();
Navigation.NavigateTo("authentication/logout");
}
/// Hashes an email with MD5. Suitable for use with Gravatar profile
/// image urls
string HashEmailForGravatar(string email)
{
// Create a new instance of the MD5CryptoServiceProvider object.
MD5 md5Hasher = MD5.Create();
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(email));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder("https://www.gravatar.com/avatar/");
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString(); // Return the hexadecimal string.
}
}

Просмотреть файл

@ -1,9 +1,32 @@
.k-drawer-container {
background-color: $background-color;
min-height: calc(100vh - 80px);
min-height: calc(100vh);
.k-drawer {
box-shadow: 0 0 10px rgba(0,0,0,.2);
border-right-width: 0 !important;
}
}
.k-drawer-items {
& .title {
text-transform: uppercase;
font-size: 1em;
padding: 1em;
font-weight: bold;
color: $info;
}
& > header {
display: flex;
flex-direction: column;
align-items: center;
padding: 1em;
& > img {
border: 2px solid $success;
margin: 1em;
max-width: 96px;
}
}
}

Просмотреть файл

@ -15,21 +15,21 @@
}
.menu-button {
flex: 0 0 50px;
flex: 0 0 70px;
text-align: center;
}
.k-button {
border: none;
background-color: transparent;
background-image: none;
color: $primary-contrast;
}
.k-button {
border: none;
background-color: transparent;
background-image: none;
color: $primary-contrast;
}
.k-button:hover {
background-color: $info;
padding: 5px;
border-radius: 50%;
}
.k-button:hover {
background-color: $info;
padding: 5px;
border-radius: 50%;
}
.title {
@ -52,10 +52,6 @@
height: 40px;
}
}
.settings {
display: none;
}
}
@media (min-width: 480px) {
@ -89,7 +85,6 @@
color: $info;
}
}
}
.k-dropdown {

Просмотреть файл

@ -35,4 +35,13 @@ a.k-link.k-state-selected {
.validation-message {
color: $error;
}
.k-window {
border-radius: 3px;
}
.k-window-titlebar {
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}