Add Taske UI source files
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Tasks.Module.Components.Pages.TasksPage).Assembly }">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
||||
</Found>
|
||||
<NotFound>
|
||||
<LayoutView Layout="@typeof(MainLayout)">
|
||||
<p>Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
||||
@@ -0,0 +1,143 @@
|
||||
@inherits LayoutComponentBase
|
||||
@using Tasks.Module.Services
|
||||
@using Tasks.Module.Models
|
||||
@using Tasks.Module.Components.Dialogs
|
||||
@inject IViewService ViewService
|
||||
@inject IDialogService DialogService
|
||||
|
||||
<MudThemeProvider />
|
||||
<MudPopoverProvider />
|
||||
<MudDialogProvider />
|
||||
<MudSnackbarProvider />
|
||||
|
||||
<MudLayout>
|
||||
<MudAppBar Elevation="1">
|
||||
<MudText Typo="Typo.h5">Taske</MudText>
|
||||
<MudSpacer />
|
||||
</MudAppBar>
|
||||
<MudDrawer Open="_drawerOpen" ClipMode="DrawerClipMode.Always" Elevation="2" Width="300px" Anchor="Anchor.Start" Variant="DrawerVariant.Persistent">
|
||||
<MudStack Orientation="Orientation.Vertical" Spacing="0" Style="height: 100%;">
|
||||
@* My Tasks Section *@
|
||||
<div class="pa-2">
|
||||
<MudLink Href="/tasks" Underline="Underline.None" Class="d-flex align-center pa-2 rounded">
|
||||
<MudIcon Icon="@Icons.Material.Filled.CheckCircle" Color="Color.Primary" Class="mr-2" />
|
||||
<MudText Typo="Typo.body1" Color="Color.Default">My Tasks</MudText>
|
||||
</MudLink>
|
||||
</div>
|
||||
|
||||
<div style="height: 1px; background-color: var(--mud-palette-lines-default); margin: 0 8px;"></div>
|
||||
|
||||
@* Categories Section *@
|
||||
<div class="pa-2">
|
||||
<div class="d-flex align-center justify-space-between px-2 py-1">
|
||||
<MudLink Href="/tasks/categories" Underline="Underline.None" Class="flex-grow-1">
|
||||
<MudText Typo="Typo.caption" Color="Color.Default">CATEGORIES</MudText>
|
||||
</MudLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="height: 1px; background-color: var(--mud-palette-lines-default); margin: 0 8px;"></div>
|
||||
|
||||
@* Tags Section *@
|
||||
<div class="pa-2">
|
||||
<div class="d-flex align-center justify-space-between px-2 py-1">
|
||||
<MudLink Href="/tasks/tags" Underline="Underline.None" Class="flex-grow-1">
|
||||
<MudText Typo="Typo.caption" Color="Color.Default">TAGS</MudText>
|
||||
</MudLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="height: 1px; background-color: var(--mud-palette-lines-default); margin: 0 8px;"></div>
|
||||
|
||||
@* Views Section *@
|
||||
<div class="pa-2">
|
||||
<div class="d-flex align-center justify-space-between px-2 py-1">
|
||||
<MudText Typo="Typo.caption" Color="Color.Default">VIEWS</MudText>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Add" Size="Size.Small" Color="Color.Inherit" OnClick="CreateView" ToolTip="Create View" />
|
||||
</div>
|
||||
@if (_loadingViews)
|
||||
{
|
||||
<MudProgressLinear Indeterminate="true" Class="my-2" />
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (var view in _views)
|
||||
{
|
||||
<MudLink Href="@($"/tasks/view/{view.Id}")" Underline="Underline.None" Class="d-flex align-center pa-2 rounded">
|
||||
<MudIcon Icon="@Icons.Material.Filled.ViewKanban" Color="Color.Default" Class="mr-2" Size="Size.Small" />
|
||||
<MudText Typo="Typo.body2" Color="Color.Default">@view.Name</MudText>
|
||||
</MudLink>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
<div style="height: 1px; background-color: var(--mud-palette-lines-default); margin: 0 8px;"></div>
|
||||
|
||||
@* Files Section *@
|
||||
<div style="flex: 1; overflow-y: auto; min-height: 0;">
|
||||
<FolderSidebar />
|
||||
</div>
|
||||
</MudStack>
|
||||
</MudDrawer>
|
||||
<MudMainContent>
|
||||
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="my-4">
|
||||
@Body
|
||||
</MudContainer>
|
||||
</MudMainContent>
|
||||
</MudLayout>
|
||||
|
||||
<style>
|
||||
.mud-link:hover {
|
||||
background-color: var(--mud-palette-action-default-hover);
|
||||
}
|
||||
</style>
|
||||
|
||||
@code {
|
||||
private bool _drawerOpen = true;
|
||||
private List<TaskViewDto> _views = new();
|
||||
private bool _loadingViews = true;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadViews();
|
||||
}
|
||||
|
||||
private async Task LoadViews()
|
||||
{
|
||||
_loadingViews = true;
|
||||
try
|
||||
{
|
||||
_views = await ViewService.GetAllViewsAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error loading views: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_loadingViews = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CreateView()
|
||||
{
|
||||
var parameters = new DialogParameters<CreateViewDialog>();
|
||||
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true };
|
||||
var dialog = await DialogService.ShowAsync<CreateViewDialog>("Create View", parameters, options);
|
||||
var result = await dialog.Result;
|
||||
|
||||
if (result is { Canceled: false } && result.Data is CreateTaskViewDto createDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var newView = await ViewService.CreateViewAsync(createDto);
|
||||
_views.Add(newView);
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error creating view: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
@page "/"
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
@code {
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Navigation.NavigateTo("/tasks");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
@code {
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Navigation.NavigateTo("/tasks", forceLoad: true);
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using MudBlazor;
|
||||
using MudBlazor.Services;
|
||||
using Tasks.Module.Services;
|
||||
using UI;
|
||||
using UI.Components;
|
||||
|
||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
|
||||
builder.RootComponents.Add<App>("#app");
|
||||
builder.RootComponents.Add<HeadOutlet>("head::after");
|
||||
|
||||
// Configure HTTP client for Tasks API
|
||||
var tasksApiUrl = builder.Configuration["ApiSettings:TasksUrl"] ?? "http://localhost:5000";
|
||||
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(tasksApiUrl) });
|
||||
|
||||
// Add MudBlazor services
|
||||
builder.Services.AddMudServices(config =>
|
||||
{
|
||||
config.SnackbarConfiguration.PositionClass = Defaults.Classes.Position.BottomRight;
|
||||
config.SnackbarConfiguration.PreventDuplicates = false;
|
||||
config.SnackbarConfiguration.ShowCloseIcon = true;
|
||||
config.SnackbarConfiguration.VisibleStateDuration = 3000;
|
||||
config.SnackbarConfiguration.HideTransitionDuration = 100;
|
||||
config.SnackbarConfiguration.ShowTransitionDuration = 100;
|
||||
config.SnackbarConfiguration.SnackbarVariant = Variant.Filled;
|
||||
});
|
||||
|
||||
// Register services
|
||||
builder.Services.AddScoped<ITodoService, TodoService>();
|
||||
builder.Services.AddScoped<IFolderService, FolderService>();
|
||||
builder.Services.AddScoped<IViewService, Tasks.Module.Services.ViewService>();
|
||||
builder.Services.AddScoped<ICategoryService, CategoryService>();
|
||||
builder.Services.AddScoped<ITagService, TagService>();
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"profiles": {
|
||||
"UI": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy",
|
||||
"applicationUrl": "http://localhost:5173",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<RunAOTCompilation>false</RunAOTCompilation>
|
||||
<PublishTrimmed>false</PublishTrimmed>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MudBlazor" Version="8.9.0" />
|
||||
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.1" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Libs\Modules\Tasks.Module\Tasks.Module.csproj" />
|
||||
<ProjectReference Include="..\..\..\Libs\Layouts\LayoutLib.Layout\LayoutLib.Layout.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,17 @@
|
||||
@using System.Net.Http
|
||||
@using System.Net.Http.Json
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
@using MudBlazor
|
||||
@using UI
|
||||
@using UI.Components
|
||||
@using UI.Components.Layout
|
||||
@using UI.Components.Pages
|
||||
@using Tasks.Module
|
||||
@using Tasks.Module.Components
|
||||
@using Tasks.Module.Components.Sidebar
|
||||
@using Tasks.Module.Services
|
||||
@using Tasks.Module.Models
|
||||
@@ -0,0 +1,11 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
"./**/*.{razor,html,cs}",
|
||||
"./_content/MudBlazor/**/*.{razor,html,cs}"
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"ApiSettings": {
|
||||
"TasksUrl": "http://localhost:5000"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
html, body {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
/* Custom styles */
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.gap-2 {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.gap-3 {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.mb-3 {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.mb-4 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.mt-2 {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.mt-3 {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
.ml-2 {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.ml-4 {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.ml-8 {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
.pl-4 {
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.pa-4 {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.pa-8 {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.py-1 {
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-gray-500 {
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.text-red-500 {
|
||||
color: #ef4444;
|
||||
}
|
||||
|
||||
.line-through {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.opacity-70 {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.border-l-2 {
|
||||
border-left-width: 2px;
|
||||
}
|
||||
|
||||
.border-gray-300 {
|
||||
border-color: #d1d5db;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>Taske</title>
|
||||
<base href="/" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
|
||||
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
|
||||
<link href="css/app.css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">Loading...</div>
|
||||
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user