New styling and files functionality

This commit is contained in:
Eugene ;) 2020-04-17 00:50:23 +02:00
parent 4912e56b1b
commit ae1726ce7a
19 changed files with 432 additions and 58 deletions

View File

@ -1,6 +1,6 @@
@inherits FileItemBase
<div class="level">
<a class="level">
<div class="level-left">
<div class="level-item">
<p class="is-size-7"><sub>@File.Folder</sub></p>
@ -9,4 +9,4 @@
</p>
</div>
</div>
</div>
</a>

View File

@ -1,61 +1,65 @@
@typeparam CFile
<div class="tile is-ancestor">
<div class="filesWithEditor">
<div class="tile is-parent is-vertical is-3">
<div class="content">
<p>
<div class="tile is-parent is-4 is-vertical">
<div class="tile is-child">
<div class="buttons are-small">
<button class="button is-static is-outlined"><span class="icon is-small"><i class="mdi mdi-filter-outline"></i></span></button>
@foreach (var filter in Filters)
{
<span class="tag is-light">@filter</span>
<button @onclick="e => OnFilterClick(e,filter)" class="button is-outlined">@filter</button>
}
</div>
</div>
<div class="tile is-child">
<div class="field">
<p class="control has-icons-left">
<input formnovalidate value="@SearchInput" @onchange="e => SearchInputChanged(e)" class="input is-small is-primary" type="text" placeholder="Search...">
<span class="icon is-small is-left">
<i class="mdi mdi-search-web"></i>
</span>
</p>
</div>
<div class="content">
<div class="field">
<div class="control">
<InputText Value="SearchInput" ValueChanged="SearchInputChanged" class="input is-primary" type="text" placeholder="Search..." />
</div>
</div>
</div>
<div class="content">
<div class="tile is-child is-vertical">
<aside class="menu">
<ul class="menu-list">
@foreach (var file in Files)
{
<li @onclick="e => OnFileClick(file)" @key="file" class="@file.IsVisible">
<FileItem File="file"></FileItem>
<li @onclick="e => OnFileClick(e,file)" @key="file" class="@file.IsVisible">
<FileItem File="file" @key="file"></FileItem>
</li>
}
</ul>
</aside>
</div>
<div class="content">
<div class="buttons has-addons">
<div class="tile is-child">
<div class="buttons are-small is-centered has-addons">
<button class="button is-primary" @onclick="OnAddDialog">
<span class="icon is-small">
<i class="mdi mdi-plus-box-outline"></i>
</span>
Add
<span>Add</span>
</button>
<button class="button is-warning" @onclick="OnUpdateDialog">
<span class="icon is-small">
<i class="mdi mdi-pencil-box-outline"></i>
</span>
Update
<span>Update</span>
</button>
<button class="button is-danger" @onclick="OnDeleteDialog">
<span class="icon is-small">
<i class="mdi mdi-minus-box-outline"></i>
</span>
Delete
<span>Delete</span>
</button>
</div>
</div>
</div>
<div class="tile is-parent is-vertical is-9">
<div class="tile is-parent is-vertical is-8">
@Editor
</div>

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Seenginx.Models;
using System;
using System.Collections.Generic;
@ -47,7 +48,7 @@ namespace Seenginx.Components
[Parameter]
public CFile SelectedFile { get; set; }
protected string SearchInput { get; set; }
protected string SearchInput { get; set; } = string.Empty;
protected async Task OnDeselectClick()
{
@ -55,20 +56,20 @@ namespace Seenginx.Components
await SelectedFileChanged.InvokeAsync(SelectedFile);
}
protected async Task OnFilterClick(EventArgs e, string filter)
protected async Task OnFilterClick(MouseEventArgs e, string filter)
{
await ApplyFilter.InvokeAsync(filter);
for (int index = 0; index < Files.Count; index++)
if (FilteredOutFiles.Contains(index))
Files[index].Hide();
else
Files[index].Unhide();
//for (int index = 0; index < Files.Count; index++)
// if (FilteredOutFiles.Contains(index))
// Files[index].Hide();
// else
// Files[index].Unhide();
}
protected void SearchInputChanged()
protected async Task SearchInputChanged(ChangeEventArgs e)
{
if (string.IsNullOrEmpty(SearchInput))
Files.ForEach(f => f.Hide());
Files.ForEach(f => f.Unhide());
else
Files.ForEach(f =>
{
@ -79,7 +80,7 @@ namespace Seenginx.Components
});
}
protected async Task OnFileClick(CFile file)
protected async Task OnFileClick(MouseEventArgs e, CFile file)
{
await SelectedFileChanged.InvokeAsync(file);
}

View File

@ -18,7 +18,7 @@ namespace Seenginx.Models
public bool CanBeDeleted { get; set; } = true;
public string IsVisible { get; set; } = string.Empty;
public void Hide() { IsVisible = "hide"; }
public void Hide() { IsVisible = "is-hidden"; }
public void Unhide() { IsVisible = string.Empty; }
}
}

View File

@ -0,0 +1,12 @@
@inherits FileItemBase
<a class="level">
<div class="level-left">
<div class="level-item">
<p class="is-size-7"><sub>@File.Folder</sub></p>
<p class="@(File.CanBeDeleted ? "has-text-danger" : null)">
@File.Name
</p>
</div>
</div>
</a>

View File

@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Components;
using Seenginx.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace Seenginx.Components
{
public class FileItemBase : ComponentBase
{
[Parameter]
public ConfigFile File { get; set; }
}
}

View File

@ -0,0 +1,72 @@
@typeparam CFile
<div class="filesWithEditor">
<div class="files">
<div class="field is-horizontal sameMarginBottom">
<div class="control has-icons-left">
<div class="select is-small is-rounded">
<select @onchange="e => OnFilterClick(e.Value.ToString())">
@foreach (var filter in Filters)
{
<option value="@filter">@filter</option>
}
</select>
</div>
<span class="icon is-small is-left">
<i class="mdi mdi-folder-cog-outline"></i>
</span>
</div>
<p class="control has-icons-left">
<input formnovalidate @oninput="e => SearchInputChanged(e.Value.ToString())" class="input is-rounded is-small" type="text" placeholder="Search...">
<span class="icon is-small is-left">
<i class="mdi mdi-search-web"></i>
</span>
</p>
</div>
<div class="filesList neomorphSmall borderRSmall sameMarginBottom">
<aside class="menu">
<ul class="menu-list">
@foreach (var file in Files)
{
<li @onclick="e => OnFileClick(e,file)" @key="file" class="@file.IsVisible">
<FileItem File="file" @key="file"></FileItem>
</li>
}
</ul>
</aside>
</div>
<div class="buttons are-small">
<button class="button is-rounded is-primary" @onclick="OnAddDialog">
<span class="icon is-small">
<i class="mdi mdi-plus-box-outline"></i>
</span>
<span>Add</span>
</button>
<button class="button is-rounded is-warning" @onclick="OnUpdateDialog">
<span class="icon is-small">
<i class="mdi mdi-pencil-box-outline"></i>
</span>
<span>Update</span>
</button>
<button class="button is-rounded is-danger" @onclick="OnDeleteDialog">
<span class="icon is-small">
<i class="mdi mdi-minus-box-outline"></i>
</span>
<span>Delete</span>
</button>
</div>
</div>
<div class="tile is-parent is-vertical is-8">
@Editor
</div>
</div>

View File

@ -0,0 +1,101 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Seenginx.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Seenginx.Components
{
public partial class FilesWithEditor<CFile> : ComponentBase
where CFile : ConfigFile
{
[Parameter]
public List<CFile> Files { get; set; } = new List<CFile>();
[Parameter]
public List<string> Filters { get; set; } = new List<string>();
[Parameter]
public List<int> FilteredOutFiles { get; set; } = new List<int>();
[Parameter]
public EventCallback<string> ApplyFilter { get; set; }
[Parameter]
public EventCallback AddFile { get; set; }
[Parameter]
public EventCallback<CFile> UpdateFile { get; set; }
[Parameter]
public EventCallback<CFile> DeleteFile { get; set; }
[Parameter]
public RenderFragment<CFile> Editor { get; set; }
[Parameter]
public RenderFragment<CFile> CreateDialog { get; set; }
[Parameter]
public RenderFragment<CFile> UpdateDialog { get; set; }
[Parameter]
public RenderFragment<CFile> DeleteDialog { get; set; }
protected string SelectedFilter { get; set; }
protected bool IsAnyFileSelected => SelectedFile != default;
[Parameter]
public EventCallback<CFile> SelectedFileChanged { get; set; }
[Parameter]
public CFile SelectedFile { get; set; }
protected async Task OnDeselectClick()
{
SelectedFile = null;
await SelectedFileChanged.InvokeAsync(SelectedFile);
}
protected async Task OnFilterClick(string filter)
{
await ApplyFilter.InvokeAsync(filter);
//for (int index = 0; index < Files.Count; index++)
// if (FilteredOutFiles.Contains(index))
// Files[index].Hide();
// else
// Files[index].Unhide();
}
protected async Task SearchInputChanged(string searchInput)
{
if (string.IsNullOrEmpty(searchInput))
Files.ForEach(f => f.Unhide());
else
Files.ForEach(f =>
{
if (f.Name.ToLower().Contains(searchInput.ToLower()))
f.Unhide();
else
f.Hide();
});
}
protected async Task OnFileClick(MouseEventArgs e, CFile file)
{
await SelectedFileChanged.InvokeAsync(file);
}
protected async Task OnAddDialog()
{
await AddFile.InvokeAsync(null);
}
protected async Task OnUpdateDialog()
{
await UpdateFile.InvokeAsync(SelectedFile);
}
protected async Task OnDeleteDialog()
{
await UpdateFile.InvokeAsync(SelectedFile);
}
}
}

View File

@ -41,6 +41,14 @@ namespace Seenginx.Pages
{
if (filter == "All")
ConfigFiles.ForEach(f => f.Unhide());
else if (filter == "Root")
ConfigFiles.ForEach(f =>
{
if (f.Folder == FilterFolder[filter])
f.Unhide();
else
f.Hide();
});
else
ConfigFiles.ForEach(f =>
{

View File

@ -25,7 +25,7 @@
<link rel="stylesheet" href="~/css/main.css" asp-append-version="true" />
</environment>
</head>
<body>
<body class="gradientBackground">
<app>
<component type="typeof(App)" render-mode="ServerPrerendered" />
</app>

View File

@ -1,4 +1,6 @@
@import "mixins.scss";
@import "variables.scss";
@import "mixins.scss";
@import "base.scss";
@import "utility.scss";
@import "override-framework.scss";
@import "template.scss";

View File

@ -0,0 +1,44 @@
.main {
display: flex;
flex-wrap: nowrap;
align-items: start;
width: 100%;
height: 100vh;
padding: 2.5%;
&Nav {
overflow-y: auto;
padding: $border-radius;
width: 17%;
margin-right: 40px;
}
&Page {
overflow-y: auto;
padding: $border-radius-b;
width: calc(83% - 40px);
align-self: stretch;
}
}
.files {
display: flex;
flex-direction: column;
align-items: stretch;
&WithEditor {
display: flex;
align-items: stretch;
height: 100%;
}
& .buttons {
justify-content: space-between;
align-items: stretch;
}
&List {
height: 100%;
overflow-y: auto;
}
}

View File

@ -14,5 +14,54 @@
.flexCenter {
display: flex;
align-content: center
align-content: center;
align-items: center
}
.is {
&NoWrap {
white-space: nowrap
}
&Finger {
cursor: pointer
}
}
.neomorph {
/*box-shadow: 0px 0px 4px 4px rgba($background, 1), -8px -8px 16px rgba($light-shadow, 1), 8px 8px 16px rgba($dark-shadow, 1);*/
box-shadow: -8px -8px 16px rgba($light-shadow, .5), 8px 8px 16px rgba($dark-shadow, .5);
&Small {
/*box-shadow: 0px 0px 3px 3px rgba($background, 1), -6px -6px 12px rgba($light-shadow, 1), 6px 6px 12px rgba($dark-shadow, 1);*/
box-shadow: -6px -6px 12px rgba($light-shadow, .5), 6px 6px 12px rgba($dark-shadow, .5);
}
&Bottom {
filter: drop-shadow(8px 8px 14px rgba($dark-shadow, 1));
}
}
.gradientBackground {
background: linear-gradient(to right bottom,$background-light,$background-dark)
}
.borderR {
border-radius: $border-radius;
&Small {
border-radius: $border-radius-s;
}
&Big {
border-radius: $border-radius-b;
}
}
.bg {
background: $background
}
.sameMarginBottom{
margin-bottom: 1rem !important
}

View File

@ -0,0 +1,8 @@
$border-radius: 14px;
$border-radius-s: 7px;
$border-radius-b: 28px;
$background: rgba(246,210,135,1);
$background-light: rgba(247, 215, 148,1);
$background-dark: rgba(245, 205, 121,1);
$light-shadow: hsl(41, 86%, 90%);
$dark-shadow: hsl(41, 86%, 60%);

View File

@ -24,7 +24,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Seenginx.Components\Seenginx.Components.csproj" />
<ProjectReference Include="..\Seenginx.Models\Seenginx.Models.csproj" />
</ItemGroup>

View File

@ -1,21 +1,14 @@
@inherits LayoutComponentBase
<section class="section">
<section class="main">
<div class="tile is-ancestor">
<div class="tile is-3 is-vertical is-parent">
<div class="tile is-child box">
<div class="mainNav neomorph bg borderR">
<NavMenu />
</div>
</div>
<div class="tile is-vertical is-parent">
<div class="tile is-child box">
<div class="mainPage neomorph bg borderR">
@Body
</div>
</div>
</div>
</section>

View File

@ -1,10 +1,10 @@
@inherits NavMenuBase
<aside class="menu">
<p class="menu-label is-size-5 petiteCaps">
<p class="menu-label is-size-5 petiteCaps isNoWrap">
<NavLink href="/" Match="NavLinkMatch.All">
<span class="mdi mdi-tune-vertical"></span>
Seenginx
<span>Seenginx</span>
</NavLink>
</p>
<p class="menu-label flexCenter">

View File

@ -32,7 +32,39 @@
.flexCenter {
display: flex;
align-content: center; }
align-content: center;
align-items: center; }
.isNoWrap {
white-space: nowrap; }
.isFinger {
cursor: pointer; }
.neomorph {
/*box-shadow: 0px 0px 4px 4px rgba($background, 1), -8px -8px 16px rgba($light-shadow, 1), 8px 8px 16px rgba($dark-shadow, 1);*/
box-shadow: -8px -8px 16px rgba(251, 238, 208, 0.5), 8px 8px 16px rgba(241, 185, 65, 0.5); }
.neomorphSmall {
/*box-shadow: 0px 0px 3px 3px rgba($background, 1), -6px -6px 12px rgba($light-shadow, 1), 6px 6px 12px rgba($dark-shadow, 1);*/
box-shadow: -6px -6px 12px rgba(251, 238, 208, 0.5), 6px 6px 12px rgba(241, 185, 65, 0.5); }
.neomorphBottom {
filter: drop-shadow(8px 8px 14px #f1b941); }
.gradientBackground {
background: linear-gradient(to right bottom, #f7d794, #f5cd79); }
.borderR {
border-radius: 14px; }
.borderRSmall {
border-radius: 7px; }
.borderRBig {
border-radius: 28px; }
.bg {
background: #f6d287; }
.sameMarginBottom {
margin-bottom: 1rem !important; }
@font-face {
font-family: 'Ubuntu';
@ -55,3 +87,36 @@ html {
.menu-list li a {
font-family: Ubuntu-Mono,'Noto Mono'; }
.main {
display: flex;
flex-wrap: nowrap;
align-items: start;
width: 100%;
height: 100vh;
padding: 2.5%; }
.mainNav {
overflow-y: auto;
padding: 14px;
width: 17%;
margin-right: 40px; }
.mainPage {
overflow-y: auto;
padding: 28px;
width: calc(83% - 40px);
align-self: stretch; }
.files {
display: flex;
flex-direction: column;
align-items: stretch; }
.filesWithEditor {
display: flex;
align-items: stretch;
height: 100%; }
.files .buttons {
justify-content: space-between;
align-items: stretch; }
.filesList {
height: 100%;
overflow-y: auto; }

View File

@ -1 +1 @@
#blazor-error-ui{background:#ffffe0;bottom:0;box-shadow:0 -1px 2px rgba(0,0,0,.2);display:none;left:0;padding:.6rem 1.25rem .7rem 1.25rem;position:fixed;width:100%;z-index:1000;}#blazor-error-ui .dismiss{cursor:pointer;position:absolute;right:.75rem;top:.5rem;}.isHidden{display:none;}@media only screen and (max-width:37.5em){.isHiddenMobile{display:none;}}.petiteCaps{font-variant:petite-caps;}.flexCenter{display:flex;align-content:center;}@font-face{font-family:'Ubuntu';src:url(/fonts/ubuntu-light-webfont.woff2) format("woff2");font-weight:300;font-style:normal;}@font-face{font-family:'Ubuntu-Mono';src:url(/fonts/ubuntumono-regular-webfont.woff2) format("woff2");font-style:normal;}html{font-family:Ubuntu,sans-serif;}.pure-menu-heading{text-transform:none;font-family:Ubuntu-Mono,'Noto Mono';}.menu-list li a{font-family:Ubuntu-Mono,'Noto Mono';}
#blazor-error-ui{background:#ffffe0;bottom:0;box-shadow:0 -1px 2px rgba(0,0,0,.2);display:none;left:0;padding:.6rem 1.25rem .7rem 1.25rem;position:fixed;width:100%;z-index:1000;}#blazor-error-ui .dismiss{cursor:pointer;position:absolute;right:.75rem;top:.5rem;}.isHidden{display:none;}@media only screen and (max-width:37.5em){.isHiddenMobile{display:none;}}.petiteCaps{font-variant:petite-caps;}.flexCenter{display:flex;align-content:center;align-items:center;}.isNoWrap{white-space:nowrap;}.isFinger{cursor:pointer;}.neomorph{box-shadow:-8px -8px 16px rgba(251,238,208,.5),8px 8px 16px rgba(241,185,65,.5);}.neomorphSmall{box-shadow:-6px -6px 12px rgba(251,238,208,.5),6px 6px 12px rgba(241,185,65,.5);}.neomorphBottom{filter:drop-shadow(8px 8px 14px #f1b941);}.gradientBackground{background:linear-gradient(to right bottom,#f7d794,#f5cd79);}.borderR{border-radius:14px;}.borderRSmall{border-radius:7px;}.borderRBig{border-radius:28px;}.bg{background:#f6d287;}.sameMarginBottom{margin-bottom:1rem !important;}@font-face{font-family:'Ubuntu';src:url(/fonts/ubuntu-light-webfont.woff2) format("woff2");font-weight:300;font-style:normal;}@font-face{font-family:'Ubuntu-Mono';src:url(/fonts/ubuntumono-regular-webfont.woff2) format("woff2");font-style:normal;}html{font-family:Ubuntu,sans-serif;}.pure-menu-heading{text-transform:none;font-family:Ubuntu-Mono,'Noto Mono';}.menu-list li a{font-family:Ubuntu-Mono,'Noto Mono';}.main{display:flex;flex-wrap:nowrap;align-items:start;width:100%;height:100vh;padding:2.5%;}.mainNav{overflow-y:auto;padding:14px;width:17%;margin-right:40px;}.mainPage{overflow-y:auto;padding:28px;width:calc(83% - 40px);align-self:stretch;}.files{display:flex;flex-direction:column;align-items:stretch;}.filesWithEditor{display:flex;align-items:stretch;height:100%;}.files .buttons{justify-content:space-between;align-items:stretch;}.filesList{height:100%;overflow-y:auto;}