├── .gitattributes ├── .gitignore ├── BlazorAzure.Functions ├── .gitignore ├── AzureSearchClient.cs ├── BlazorAzure.Functions.csproj ├── BooksDbContextFactory.cs ├── LibraryFunctions.cs └── host.json ├── BlazorAzure.WebApp ├── AdalHelper.cs ├── App.razor ├── BlazorAzure.WebApp.csproj ├── BlazorAzurePageBase.cs ├── BooksAzureFunctionsClient.cs ├── Pages │ ├── Edit.razor │ ├── Edit.razor.cs │ ├── Index.razor │ ├── Index.razor.cs │ └── _Imports.razor ├── Program.cs ├── Properties │ └── launchSettings.json ├── Shared │ ├── MainLayout.razor │ ├── NavMenu.razor │ └── SurveyPrompt.razor ├── Startup.cs ├── _Imports.razor └── wwwroot │ ├── css │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── open-iconic │ │ ├── FONT-LICENSE │ │ ├── ICON-LICENSE │ │ ├── README.md │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ └── site.css │ ├── index.html │ └── js │ ├── adal.js │ └── app.js ├── BlazorDemo.sln ├── BlazorLibrary.AspNetCoreHostedBlazor.Client ├── App.razor ├── BlazorLibrary.AspNetCoreHostedBlazor.Client.csproj ├── BooksClient.cs ├── LibraryPageBase.cs ├── Pages │ ├── EditBook.razor │ ├── EditBook.razor.cs │ ├── Index.razor │ ├── Index.razor.cs │ └── _Imports.razor ├── Program.cs ├── Properties │ └── launchSettings.json ├── Shared │ ├── MainLayout.razor │ ├── NavMenu.razor │ └── SurveyPrompt.razor ├── Startup.cs ├── _Imports.razor └── wwwroot │ ├── css │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── open-iconic │ │ ├── FONT-LICENSE │ │ ├── ICON-LICENSE │ │ ├── README.md │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ └── site.css │ └── index.html ├── BlazorLibrary.AspNetCoreHostedBlazor.Server ├── BlazorLibrary.AspNetCoreHostedBlazor.Server.csproj ├── Controllers │ └── LibraryController.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs └── appsettings.json ├── BlazorLibrary.AspNetCoreHostedBlazor.Shared ├── BlazorLibrary.AspNetCoreHostedBlazor.Shared.csproj └── WeatherForecast.cs ├── BlazorLibrary.Components ├── BlazorLibrary.Components.csproj ├── Pager.razor ├── Pager.razor.cs └── Properties │ └── launchSettings.json ├── BlazorLibrary.Data ├── BlazorLibrary.Data.csproj ├── BooksDbContext.cs └── PagedResultExtensions.cs ├── BlazorLibrary.ServerSideBlazor ├── App.razor ├── BlazorLibrary.ServerSideBlazor.csproj ├── LibraryPageBase.cs ├── Pages │ ├── EditBook.razor │ ├── EditBook.razor.cs │ ├── Index.razor │ ├── Index.razor.cs │ ├── _Host.cshtml │ └── _Imports.razor ├── Program.cs ├── Properties │ └── launchSettings.json ├── Shared │ ├── MainLayout.razor │ └── NavMenu.razor ├── Startup.cs ├── _Imports.razor ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ ├── css │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── open-iconic │ │ ├── FONT-LICENSE │ │ ├── ICON-LICENSE │ │ ├── README.md │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ └── site.css │ └── favicon.ico ├── BlazorLibrary.Shared ├── BlazorLibrary.Shared.csproj ├── Book.cs ├── IBooksClient.cs ├── PagedResultPage.cs └── PagedResultT.cs ├── External Files └── Books.bacpac ├── OutOfBox.AspNetCoreHostedBlazor.Client ├── App.razor ├── OutOfBox.AspNetCoreHostedBlazor.Client.csproj ├── Pages │ ├── Counter.razor │ ├── FetchData.razor │ ├── Index.razor │ └── _Imports.razor ├── Program.cs ├── Properties │ └── launchSettings.json ├── Shared │ ├── MainLayout.razor │ ├── NavMenu.razor │ └── SurveyPrompt.razor ├── Startup.cs ├── _Imports.razor └── wwwroot │ ├── css │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── open-iconic │ │ ├── FONT-LICENSE │ │ ├── ICON-LICENSE │ │ ├── README.md │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ └── site.css │ └── index.html ├── OutOfBox.AspNetCoreHostedBlazor.Server ├── Controllers │ └── SampleDataController.cs ├── OutOfBox.AspNetCoreHostedBlazor.Server.csproj ├── Program.cs ├── Properties │ └── launchSettings.json └── Startup.cs ├── OutOfBox.AspNetCoreHostedBlazor.Shared ├── OutOfBox.AspNetCoreHostedBlazor.Shared.csproj └── WeatherForecast.cs ├── OutOfBox.ClientSideBlazor ├── App.razor ├── OutOfBox.ClientSideBlazor.csproj ├── Pages │ ├── Counter.razor │ ├── FetchData.razor │ ├── Index.razor │ └── _Imports.razor ├── Program.cs ├── Properties │ └── launchSettings.json ├── Shared │ ├── MainLayout.razor │ ├── NavMenu.razor │ └── SurveyPrompt.razor ├── Startup.cs ├── _Imports.razor └── wwwroot │ ├── css │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── open-iconic │ │ ├── FONT-LICENSE │ │ ├── ICON-LICENSE │ │ ├── README.md │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ └── site.css │ ├── index.html │ └── sample-data │ └── weather.json ├── OutOfBox.ServerSideBlazor ├── App.razor ├── Data │ ├── WeatherForecast.cs │ └── WeatherForecastService.cs ├── OutOfBox.ServerSideBlazor.csproj ├── Pages │ ├── Counter.razor │ ├── FetchData.razor │ ├── Index.razor │ ├── _Host.cshtml │ └── _Imports.razor ├── Program.cs ├── Properties │ └── launchSettings.json ├── Shared │ ├── MainLayout.razor │ └── NavMenu.razor ├── Startup.cs ├── _Imports.razor ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ ├── css │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── open-iconic │ │ ├── FONT-LICENSE │ │ ├── ICON-LICENSE │ │ ├── README.md │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ └── site.css │ └── favicon.ico ├── OutOfBox.SharedBlazorComponent ├── Component1.razor ├── OutOfBox.SharedBlazorComponent.csproj ├── Properties │ └── launchSettings.json └── content │ ├── background.png │ └── styles.css ├── OutOfBox.SharedComponentDemoApp ├── App.razor ├── OutOfBox.SharedComponentDemoApp.csproj ├── Pages │ ├── Counter.razor │ ├── FetchData.razor │ ├── Index.razor │ └── _Imports.razor ├── Program.cs ├── Properties │ └── launchSettings.json ├── Shared │ ├── MainLayout.razor │ ├── NavMenu.razor │ └── SurveyPrompt.razor ├── Startup.cs ├── _Imports.razor └── wwwroot │ ├── css │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── open-iconic │ │ ├── FONT-LICENSE │ │ ├── ICON-LICENSE │ │ ├── README.md │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ └── site.css │ ├── index.html │ └── sample-data │ └── weather.json └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /BlazorAzure.Functions/AzureSearchClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using BlazorLibrary.Shared; 4 | using Microsoft.Azure.Search; 5 | using Microsoft.Azure.Search.Models; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace BlazorAzure.Functions 9 | { 10 | public static class AzureSearchClient 11 | { 12 | private static SearchIndexClient GetClient() 13 | { 14 | return new SearchIndexClient("", "books", new SearchCredentials("")); 15 | } 16 | 17 | public static async Task> Search(string term, int page) 18 | { 19 | var searchParams = new SearchParameters(); 20 | searchParams.IncludeTotalResultCount = true; 21 | searchParams.Skip = (page - 1) * 10; 22 | searchParams.Top = 10; 23 | searchParams.OrderBy = new[] { "Title" }; 24 | 25 | using (var client = GetClient()) 26 | { 27 | var results = await client.Documents.SearchAsync(term, searchParams); 28 | var paged = new PagedResult(); 29 | paged.CurrentPage = page; 30 | paged.PageSize = 10; 31 | paged.RowCount = (int)results.Count; 32 | paged.PageCount = (int)Math.Ceiling((decimal)paged.RowCount / 10); 33 | 34 | foreach (var result in results.Results) 35 | { 36 | paged.Results.Add(result.Document); 37 | } 38 | 39 | return paged; 40 | } 41 | } 42 | 43 | public static async Task IndexBook(Book book, ILogger log) 44 | { 45 | using (var client = GetClient()) 46 | { 47 | var azureBook = new { id = book.Id.ToString(), Title = book.Title, ISBN = book.ISBN }; 48 | var batch = IndexBatch.MergeOrUpload(new[] { azureBook }); 49 | 50 | await client.Documents.IndexAsync(batch); 51 | } 52 | } 53 | 54 | public static async Task RemoveBook(int id) 55 | { 56 | using (var client = GetClient()) 57 | { 58 | var batch = IndexBatch.Delete("id", new[] { id.ToString() }); 59 | 60 | await client.Documents.IndexAsync(batch); 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /BlazorAzure.Functions/BlazorAzure.Functions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netcoreapp2.2 4 | v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | PreserveNewest 22 | 23 | 24 | PreserveNewest 25 | Never 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /BlazorAzure.Functions/BooksDbContextFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using BlazorLibrary.Data; 6 | using Microsoft.EntityFrameworkCore; 7 | using Microsoft.EntityFrameworkCore.Design; 8 | using Microsoft.Extensions.Configuration; 9 | 10 | namespace BlazorAzure.Functions 11 | { 12 | public class BooksDbContextFactory : IDesignTimeDbContextFactory 13 | { 14 | private static string _connectionString; 15 | 16 | public BooksDbContext CreateDbContext() 17 | { 18 | return CreateDbContext(null); 19 | } 20 | 21 | public BooksDbContext CreateDbContext(string[] args) 22 | { 23 | if (string.IsNullOrEmpty(_connectionString)) 24 | { 25 | LoadConnectionString(); 26 | } 27 | 28 | var builder = new DbContextOptionsBuilder(); 29 | builder.UseSqlServer(_connectionString); 30 | 31 | return new BooksDbContext(builder.Options); 32 | } 33 | 34 | private static string ConnectionString 35 | { 36 | get 37 | { 38 | if (string.IsNullOrEmpty(_connectionString)) 39 | { 40 | LoadConnectionString(); 41 | } 42 | 43 | return _connectionString; 44 | } 45 | } 46 | 47 | private static void LoadConnectionString() 48 | { 49 | var builder = new ConfigurationBuilder(); 50 | var settingsPath = Path.Combine(Environment.CurrentDirectory, "local.settings.json"); 51 | 52 | builder.AddJsonFile(settingsPath, optional: true); 53 | builder.AddEnvironmentVariables(); 54 | 55 | var configuration = builder.Build(); 56 | 57 | _connectionString = configuration.GetConnectionString("DefaultConnection"); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /BlazorAzure.Functions/LibraryFunctions.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Linq; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using BlazorLibrary.Data; 6 | using BlazorLibrary.Shared; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Azure.WebJobs; 10 | using Microsoft.Azure.WebJobs.Extensions.Http; 11 | using Microsoft.EntityFrameworkCore; 12 | using Microsoft.Extensions.Logging; 13 | using Newtonsoft.Json; 14 | 15 | namespace BlazorAzure.Functions 16 | { 17 | public static class LibraryFunctions 18 | { 19 | [FunctionName("Index")] 20 | public static async Task Index([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "Books/Index/page/{page}")]HttpRequest req, ILogger log, [FromRoute] int page) 21 | { 22 | if (page <= 0) page = 1; 23 | 24 | using (var context = (new BooksDbContextFactory()).CreateDbContext()) 25 | { 26 | var books = await context.Books 27 | .OrderBy(b => b.Title) 28 | .GetPagedAsync(page, 10); 29 | 30 | return new JsonResult(books); 31 | } 32 | } 33 | 34 | [FunctionName("Get")] 35 | public static async Task Get([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "Books/Get/{id}")]HttpRequest req, ILogger log, [FromRoute]int id) 36 | { 37 | using (var context = (new BooksDbContextFactory()).CreateDbContext()) 38 | { 39 | var book = await context.Books.FirstOrDefaultAsync(b => b.Id == id); 40 | 41 | return new JsonResult(book); 42 | } 43 | } 44 | 45 | [FunctionName("Save")] 46 | public static async Task Save([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "Books/Save")]HttpRequest req, ILogger log) 47 | { 48 | using (var reader = new StreamReader(req.Body, Encoding.UTF8)) 49 | using (var context = (new BooksDbContextFactory()).CreateDbContext()) 50 | { 51 | var body = reader.ReadToEnd(); 52 | var book = JsonConvert.DeserializeObject(body); 53 | 54 | context.Update(book); 55 | await context.SaveChangesAsync(); 56 | 57 | //await AzureSearchClient.IndexBook(book, log); 58 | } 59 | } 60 | 61 | [FunctionName("Delete")] 62 | public static async Task Delete([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "Books/Delete/{id}")]HttpRequest req, ILogger log, [FromRoute]int id) 63 | { 64 | using (var context = (new BooksDbContextFactory()).CreateDbContext()) 65 | { 66 | var book = await context.Books.FirstOrDefaultAsync(b => b.Id == id); 67 | if (book == null) 68 | { 69 | return; 70 | } 71 | 72 | context.Books.Remove(book); 73 | await context.SaveChangesAsync(); 74 | 75 | //await AzureSearchClient.RemoveBook(book.Id); 76 | } 77 | } 78 | 79 | [FunctionName("Search")] 80 | public static async Task Search([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "Books/Search/{page}/{term}")]HttpRequest req, ILogger log, [FromRoute]string term, [FromRoute]int page) 81 | { 82 | var results = await AzureSearchClient.Search(term, page); 83 | 84 | return new JsonResult(results); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /BlazorAzure.Functions/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0" 3 | } -------------------------------------------------------------------------------- /BlazorAzure.WebApp/AdalHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace BlazorAzure.WebApp 5 | { 6 | public static class AdalHelper 7 | { 8 | public static async Task RunAction(Action action, string token) 9 | { 10 | await Task.Run(() => action(token)); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /BlazorAzure.WebApp/App.razor: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/BlazorAzure.WebApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; 7 | https://dotnet.myget.org/F/blazor-dev/api/v3/index.json; 8 | 9 | 7.3 10 | 3.0 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/BlazorAzurePageBase.cs: -------------------------------------------------------------------------------- 1 | using BlazorLibrary.Shared; 2 | using Microsoft.AspNetCore.Components; 3 | using Microsoft.JSInterop; 4 | 5 | namespace BlazorAzure.WebApp 6 | { 7 | public abstract class BlazorAzurePageBase : ComponentBase 8 | { 9 | [Inject] 10 | protected IUriHelper UriHelper { get; set; } 11 | 12 | [Inject] 13 | protected IJSRuntime JSRuntime { get; set; } 14 | 15 | [Inject] 16 | protected IBooksClient BooksClient { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /BlazorAzure.WebApp/BooksAzureFunctionsClient.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | using System.Threading.Tasks; 3 | using BlazorLibrary.Shared; 4 | using Microsoft.AspNetCore.Components; 5 | 6 | namespace BlazorAzure.WebApp 7 | { 8 | public class BooksAzureFunctionsClient : IBooksClient 9 | { 10 | private readonly HttpClient _httpClient; 11 | private const string FunctionsHost = ""; 12 | 13 | public string Token { get; set; } 14 | 15 | public BooksAzureFunctionsClient(HttpClient httpClient) 16 | { 17 | _httpClient = httpClient; 18 | } 19 | 20 | public async Task DeleteBook(Book book) 21 | { 22 | if (!string.IsNullOrEmpty(Token)) 23 | { 24 | _httpClient.DefaultRequestHeaders.Remove("Authorization"); 25 | _httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + Token); 26 | } 27 | await DeleteBook(book.Id); 28 | } 29 | 30 | public async Task DeleteBook(int id) 31 | { 32 | if (!string.IsNullOrEmpty(Token)) 33 | { 34 | _httpClient.DefaultRequestHeaders.Remove("Authorization"); 35 | _httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + Token); 36 | } 37 | 38 | var url = FunctionsHost + "/Books/Delete/" + id; 39 | 40 | await _httpClient.PostAsync(url, null); 41 | } 42 | 43 | public async Task> ListBooks(int page, int pageSize) 44 | { 45 | if (!string.IsNullOrEmpty(Token)) 46 | { 47 | _httpClient.DefaultRequestHeaders.Remove("Authorization"); 48 | _httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + Token); 49 | } 50 | 51 | var url = FunctionsHost + "/Books/Index/page/" + page; 52 | 53 | return await _httpClient.GetJsonAsync>(url); 54 | } 55 | 56 | public async Task GetBook(int id) 57 | { 58 | var url = FunctionsHost + "/Books/Get/" + id; 59 | 60 | return await _httpClient.GetJsonAsync(url); 61 | } 62 | 63 | public async Task SaveBook(Book book) 64 | { 65 | if (!string.IsNullOrEmpty(Token)) 66 | { 67 | _httpClient.DefaultRequestHeaders.Remove("Authorization"); 68 | _httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + Token); 69 | } 70 | 71 | var url = FunctionsHost + "/Books/Save"; 72 | 73 | await _httpClient.PostJsonAsync(url, book); 74 | } 75 | 76 | public async Task> SearchBooks(string term, int page) 77 | { 78 | if (!string.IsNullOrEmpty(Token)) 79 | { 80 | _httpClient.DefaultRequestHeaders.Remove("Authorization"); 81 | _httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + Token); 82 | } 83 | 84 | var url = FunctionsHost + "/Books/Search/" + page + "/" + term; 85 | 86 | return await _httpClient.GetJsonAsync>(url); 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /BlazorAzure.WebApp/Pages/Edit.razor: -------------------------------------------------------------------------------- 1 | @page "/edit/{Id}" 2 | @inherits EditModel 3 | 4 |

@PageTitle

5 | 6 | @if (CurrentBook != null) 7 | { 8 |
9 |
10 |
11 |
12 | 13 |
14 | 15 |
16 |
17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 | 25 |
26 | 27 |
28 |
29 |
30 |
31 |
32 | } 33 | else 34 | { 35 |

Loading...

36 | } -------------------------------------------------------------------------------- /BlazorAzure.WebApp/Pages/Edit.razor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BlazorLibrary.Shared; 3 | using Microsoft.AspNetCore.Components; 4 | using Mono.WebAssembly.Interop; 5 | 6 | namespace BlazorAzure.WebApp.Pages 7 | { 8 | public class EditModel : BlazorAzurePageBase 9 | { 10 | [Parameter] 11 | protected string Id { get; private set; } = "0"; 12 | protected string PageTitle { get; private set; } 13 | protected Book CurrentBook { get; set; } 14 | 15 | protected override void OnParametersSet() 16 | { 17 | if (Id == null || Id == "0") 18 | { 19 | PageTitle = "Add book"; 20 | CurrentBook = new Book(); 21 | } 22 | else 23 | { 24 | PageTitle = "Edit book"; 25 | 26 | LoadBook(int.Parse(Id)); 27 | } 28 | } 29 | 30 | protected void LoadBook(int id) 31 | { 32 | Action action = async (token) => 33 | { 34 | BooksClient.Token = token; 35 | CurrentBook = await BooksClient.GetBook(id); 36 | 37 | StateHasChanged(); 38 | }; 39 | 40 | ((MonoWebAssemblyJSRuntime)JSRuntime).InvokeUnmarshalled, bool>("blazorDemoInterop.executeWithToken", action); 41 | } 42 | 43 | protected void Save() 44 | { 45 | var book = CurrentBook; 46 | 47 | Action action = async (token) => 48 | { 49 | try 50 | { 51 | BooksClient.Token = token; 52 | 53 | await BooksClient.SaveBook(book); 54 | } 55 | catch 56 | { 57 | // Let's suppress weird arbitrary errors 58 | } 59 | 60 | UriHelper.NavigateTo("/page/1"); 61 | }; 62 | 63 | ((MonoWebAssemblyJSRuntime)JSRuntime).InvokeUnmarshalled, bool>("blazorDemoInterop.executeWithToken", action); 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /BlazorAzure.WebApp/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @page "/page/{page}" 3 | @inherits IndexModel 4 | 5 |
6 |
7 |

Books database

8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 | 17 | 18 | 19 |
20 |
21 | 22 | @if (Books == null) 23 | { 24 |

Loading...

25 | } 26 | else 27 | { 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | @foreach (var book in Books.Results) 36 | { 37 | var id = book.Id; 38 | var title = book.Title; 39 | 40 | 41 | 42 | 43 | 47 | 48 | } 49 |
IdTitleISBN
@book.Id@book.Title@book.ISBN 44 | 45 | 46 |
50 | 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/Pages/Index.razor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using BlazorLibrary.Shared; 4 | using Microsoft.AspNetCore.Components; 5 | using Mono.WebAssembly.Interop; 6 | 7 | namespace BlazorAzure.WebApp.Pages 8 | { 9 | public class IndexModel : BlazorAzurePageBase 10 | { 11 | [Parameter] 12 | protected string Page { get; set; } = "1"; 13 | 14 | protected int DeleteId { get; set; } = 0; 15 | 16 | protected PagedResult Books { get; set; } 17 | 18 | [Parameter] 19 | protected string SearchTerm { get; set; } 20 | 21 | protected override void OnParametersSet() 22 | { 23 | SearchClick(); 24 | } 25 | 26 | private void LoadBooks(int page) 27 | { 28 | Action action = async (token) => 29 | { 30 | BooksClient.Token = token; 31 | Books = await BooksClient.ListBooks(page, 10); 32 | 33 | StateHasChanged(); 34 | }; 35 | 36 | ((MonoWebAssemblyJSRuntime)JSRuntime).InvokeUnmarshalled, bool>("blazorDemoInterop.executeWithToken", action); 37 | } 38 | 39 | protected void PagerPageChanged(int page) 40 | { 41 | if (string.IsNullOrEmpty(SearchTerm)) 42 | { 43 | UriHelper.NavigateTo("/page/" + page); 44 | } 45 | else 46 | { 47 | UriHelper.NavigateTo("/page/" + page + "/" + SearchTerm); 48 | } 49 | } 50 | 51 | protected void AddNew() 52 | { 53 | UriHelper.NavigateTo("/edit/0"); 54 | } 55 | 56 | protected void SearchClick() 57 | { 58 | if (string.IsNullOrEmpty(SearchTerm)) 59 | { 60 | LoadBooks(int.Parse(Page)); 61 | return; 62 | } 63 | 64 | Search(SearchTerm, int.Parse(Page)); 65 | } 66 | 67 | private void Search(string term, int page) 68 | { 69 | Action action = async (token) => 70 | { 71 | BooksClient.Token = token; 72 | Books = await BooksClient.SearchBooks(term, page); 73 | 74 | StateHasChanged(); 75 | }; 76 | 77 | ((MonoWebAssemblyJSRuntime)JSRuntime).InvokeUnmarshalled, bool>("blazorDemoInterop.executeWithToken", action); 78 | } 79 | 80 | protected void SearchBoxKeyPress(UIKeyboardEventArgs ev) 81 | { 82 | if (ev.Key == "Enter") 83 | { 84 | SearchClick(); 85 | } 86 | } 87 | 88 | protected void ClearClick() 89 | { 90 | SearchTerm = ""; 91 | LoadBooks(1); 92 | } 93 | 94 | protected void EditBook(int id) 95 | { 96 | UriHelper.NavigateTo("/edit/" + id); 97 | } 98 | 99 | protected async Task ConfirmDelete(int id, string title) 100 | { 101 | DeleteId = id; 102 | 103 | await JSRuntime.InvokeAsync("blazorDemoInterop.confirmDelete", title); 104 | } 105 | 106 | protected async void DeleteBook() 107 | { 108 | await JSRuntime.InvokeAsync("blazorDemoInterop.hideDeleteDialog"); 109 | 110 | Action action = async (token) => 111 | { 112 | BooksClient.Token = token; 113 | await BooksClient.DeleteBook(DeleteId); 114 | 115 | LoadBooks(int.Parse(Page)); 116 | StateHasChanged(); 117 | }; 118 | 119 | ((MonoWebAssemblyJSRuntime)JSRuntime).InvokeUnmarshalled, bool>("blazorDemoInterop.executeWithToken", action); 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/Pages/_Imports.razor: -------------------------------------------------------------------------------- 1 | @layout MainLayout 2 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Blazor.Hosting; 2 | 3 | namespace BlazorAzure.WebApp 4 | { 5 | public class Program 6 | { 7 | public static void Main(string[] args) 8 | { 9 | CreateHostBuilder(args).Build().Run(); 10 | } 11 | 12 | public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) => 13 | BlazorWebAssemblyHost.CreateDefaultBuilder() 14 | .UseBlazorStartup(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:44367/", 7 | "sslPort": 44382 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "BlazorAzure.WebApp": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:58676/" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /BlazorAzure.WebApp/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 6 | 7 |
8 |
9 | About 10 |
11 | 12 |
13 | @Body 14 |
15 |
16 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  7 | 8 |
9 | 16 |
17 | 18 | @functions { 19 | bool collapseNavMenu = true; 20 | 21 | string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 22 | 23 | void ToggleNavMenu() 24 | { 25 | collapseNavMenu = !collapseNavMenu; 26 | } 27 | } -------------------------------------------------------------------------------- /BlazorAzure.WebApp/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 |  11 | 12 | @functions { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] string Title { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/Startup.cs: -------------------------------------------------------------------------------- 1 | using BlazorLibrary.Shared; 2 | using Microsoft.AspNetCore.Components.Builder; 3 | using Microsoft.Extensions.DependencyInjection; 4 | 5 | namespace BlazorAzure.WebApp 6 | { 7 | public class Startup 8 | { 9 | public void ConfigureServices(IServiceCollection services) 10 | { 11 | services.AddSingleton(); 12 | } 13 | 14 | public void Configure(IComponentsApplicationBuilder app) 15 | { 16 | app.AddComponent("app"); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Components.Forms 3 | @using Microsoft.AspNetCore.Components.Layouts 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.JSInterop 6 | @using BlazorAzure.WebApp 7 | @using BlazorAzure.WebApp.Shared 8 | @using BlazorLibrary.Components -------------------------------------------------------------------------------- /BlazorAzure.WebApp/wwwroot/css/open-iconic/FONT-LICENSE: -------------------------------------------------------------------------------- 1 | SIL OPEN FONT LICENSE Version 1.1 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | PREAMBLE 6 | The goals of the Open Font License (OFL) are to stimulate worldwide 7 | development of collaborative font projects, to support the font creation 8 | efforts of academic and linguistic communities, and to provide a free and 9 | open framework in which fonts may be shared and improved in partnership 10 | with others. 11 | 12 | The OFL allows the licensed fonts to be used, studied, modified and 13 | redistributed freely as long as they are not sold by themselves. The 14 | fonts, including any derivative works, can be bundled, embedded, 15 | redistributed and/or sold with any software provided that any reserved 16 | names are not used by derivative works. The fonts and derivatives, 17 | however, cannot be released under any other type of license. The 18 | requirement for fonts to remain under this license does not apply 19 | to any document created using the fonts or their derivatives. 20 | 21 | DEFINITIONS 22 | "Font Software" refers to the set of files released by the Copyright 23 | Holder(s) under this license and clearly marked as such. This may 24 | include source files, build scripts and documentation. 25 | 26 | "Reserved Font Name" refers to any names specified as such after the 27 | copyright statement(s). 28 | 29 | "Original Version" refers to the collection of Font Software components as 30 | distributed by the Copyright Holder(s). 31 | 32 | "Modified Version" refers to any derivative made by adding to, deleting, 33 | or substituting -- in part or in whole -- any of the components of the 34 | Original Version, by changing formats or by porting the Font Software to a 35 | new environment. 36 | 37 | "Author" refers to any designer, engineer, programmer, technical 38 | writer or other person who contributed to the Font Software. 39 | 40 | PERMISSION & CONDITIONS 41 | Permission is hereby granted, free of charge, to any person obtaining 42 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 43 | redistribute, and sell modified and unmodified copies of the Font 44 | Software, subject to the following conditions: 45 | 46 | 1) Neither the Font Software nor any of its individual components, 47 | in Original or Modified Versions, may be sold by itself. 48 | 49 | 2) Original or Modified Versions of the Font Software may be bundled, 50 | redistributed and/or sold with any software, provided that each copy 51 | contains the above copyright notice and this license. These can be 52 | included either as stand-alone text files, human-readable headers or 53 | in the appropriate machine-readable metadata fields within text or 54 | binary files as long as those fields can be easily viewed by the user. 55 | 56 | 3) No Modified Version of the Font Software may use the Reserved Font 57 | Name(s) unless explicit written permission is granted by the corresponding 58 | Copyright Holder. This restriction only applies to the primary font name as 59 | presented to the users. 60 | 61 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 62 | Software shall not be used to promote, endorse or advertise any 63 | Modified Version, except to acknowledge the contribution(s) of the 64 | Copyright Holder(s) and the Author(s) or with their explicit written 65 | permission. 66 | 67 | 5) The Font Software, modified or unmodified, in part or in whole, 68 | must be distributed entirely under this license, and must not be 69 | distributed under any other license. The requirement for fonts to 70 | remain under this license does not apply to any document created 71 | using the Font Software. 72 | 73 | TERMINATION 74 | This license becomes null and void if any of the above conditions are 75 | not met. 76 | 77 | DISCLAIMER 78 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 79 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 80 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 81 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 82 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 83 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 84 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 85 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 86 | OTHER DEALINGS IN THE FONT SOFTWARE. 87 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /BlazorAzure.WebApp/wwwroot/css/open-iconic/README.md: -------------------------------------------------------------------------------- 1 | [Open Iconic v1.1.1](http://useiconic.com/open) 2 | =========== 3 | 4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons) 5 | 6 | 7 | 8 | ## What's in Open Iconic? 9 | 10 | * 223 icons designed to be legible down to 8 pixels 11 | * Super-light SVG files - 61.8 for the entire set 12 | * SVG sprite—the modern replacement for icon fonts 13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats 14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats 15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px. 16 | 17 | 18 | ## Getting Started 19 | 20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections. 21 | 22 | ### General Usage 23 | 24 | #### Using Open Iconic's SVGs 25 | 26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute). 27 | 28 | ``` 29 | icon name 30 | ``` 31 | 32 | #### Using Open Iconic's SVG Sprite 33 | 34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack. 35 | 36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.* 37 | 38 | ``` 39 | 40 | 41 | 42 | ``` 43 | 44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions. 45 | 46 | ``` 47 | .icon { 48 | width: 16px; 49 | height: 16px; 50 | } 51 | ``` 52 | 53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag. 54 | 55 | ``` 56 | .icon-account-login { 57 | fill: #f00; 58 | } 59 | ``` 60 | 61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/). 62 | 63 | #### Using Open Iconic's Icon Font... 64 | 65 | 66 | ##### …with Bootstrap 67 | 68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}` 69 | 70 | 71 | ``` 72 | 73 | ``` 74 | 75 | 76 | ``` 77 | 78 | ``` 79 | 80 | ##### …with Foundation 81 | 82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}` 83 | 84 | ``` 85 | 86 | ``` 87 | 88 | 89 | ``` 90 | 91 | ``` 92 | 93 | ##### …on its own 94 | 95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}` 96 | 97 | ``` 98 | 99 | ``` 100 | 101 | ``` 102 | 103 | ``` 104 | 105 | 106 | ## License 107 | 108 | ### Icons 109 | 110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT). 111 | 112 | ### Fonts 113 | 114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web). 115 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorAzure.WebApp/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /BlazorAzure.WebApp/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorAzure.WebApp/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /BlazorAzure.WebApp/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorAzure.WebApp/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /BlazorAzure.WebApp/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorAzure.WebApp/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /BlazorAzure.WebApp/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | app { 8 | position: relative; 9 | display: flex; 10 | flex-direction: column; 11 | } 12 | 13 | .top-row { 14 | height: 3.5rem; 15 | display: flex; 16 | align-items: center; 17 | } 18 | 19 | .main { 20 | flex: 1; 21 | } 22 | 23 | .main .top-row { 24 | background-color: #e6e6e6; 25 | border-bottom: 1px solid #d6d5d5; 26 | } 27 | 28 | .sidebar { 29 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 30 | } 31 | 32 | .sidebar .top-row { 33 | background-color: rgba(0,0,0,0.4); 34 | } 35 | 36 | .sidebar .navbar-brand { 37 | font-size: 1.1rem; 38 | } 39 | 40 | .sidebar .oi { 41 | width: 2rem; 42 | font-size: 1.1rem; 43 | vertical-align: text-top; 44 | top: -2px; 45 | } 46 | 47 | .nav-item { 48 | font-size: 0.9rem; 49 | padding-bottom: 0.5rem; 50 | } 51 | 52 | .nav-item:first-of-type { 53 | padding-top: 1rem; 54 | } 55 | 56 | .nav-item:last-of-type { 57 | padding-bottom: 1rem; 58 | } 59 | 60 | .nav-item a { 61 | color: #d7d7d7; 62 | border-radius: 4px; 63 | height: 3rem; 64 | display: flex; 65 | align-items: center; 66 | line-height: 3rem; 67 | } 68 | 69 | .nav-item a.active { 70 | background-color: rgba(255,255,255,0.25); 71 | color: white; 72 | } 73 | 74 | .nav-item a:hover { 75 | background-color: rgba(255,255,255,0.1); 76 | color: white; 77 | } 78 | 79 | .content { 80 | padding-top: 1.1rem; 81 | } 82 | 83 | .navbar-toggler { 84 | background-color: rgba(255, 255, 255, 0.1); 85 | } 86 | 87 | .valid.modified:not([type=checkbox]) { 88 | outline: 1px solid #26b050; 89 | } 90 | 91 | .invalid { 92 | outline: 1px solid red; 93 | } 94 | 95 | .validation-message { 96 | color: red; 97 | } 98 | 99 | @media (max-width: 767.98px) { 100 | .main .top-row { 101 | display: none; 102 | } 103 | } 104 | 105 | @media (min-width: 768px) { 106 | app { 107 | flex-direction: row; 108 | } 109 | 110 | .sidebar { 111 | width: 250px; 112 | height: 100vh; 113 | position: sticky; 114 | top: 0; 115 | } 116 | 117 | .main .top-row { 118 | position: sticky; 119 | top: 0; 120 | } 121 | 122 | .main > div { 123 | padding-left: 2rem !important; 124 | padding-right: 1.5rem !important; 125 | } 126 | 127 | .navbar-toggler { 128 | display: none; 129 | } 130 | 131 | .sidebar .collapse { 132 | /* Never collapse the sidebar for wide screens */ 133 | display: block; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/wwwroot/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | BlazorAzure.WebApp 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /BlazorAzure.WebApp/wwwroot/js/app.js: -------------------------------------------------------------------------------- 1 | var authContext = null; 2 | var user = null; 3 | 4 | (function () { 5 | window.config = { 6 | instance: 'https://login.microsoftonline.com/', 7 | tenant: '', 8 | clientId: '', 9 | postLogoutRedirectUri: window.location.origin, 10 | cacheLocation: 'localStorage' // enable this for IE, as sessionStorage does not work for localhost. 11 | }; 12 | 13 | authContext = new AuthenticationContext(config); 14 | var isCallback = authContext.isCallback(window.location.hash); 15 | authContext.handleWindowCallback(); 16 | //$errorMessage.html(authContext.getLoginError()); 17 | 18 | if (isCallback && !authContext.getLoginError()) { 19 | window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST); 20 | } 21 | 22 | // Check Login Status, Update UI 23 | user = authContext.getCachedUser(); 24 | if (!user) { 25 | authContext.login(); 26 | } 27 | 28 | }()); 29 | 30 | window.blazorDemoInterop = { 31 | confirmDelete: function (title) { 32 | $('#bookTitleField').text(title); 33 | $('#myModal').modal('show'); 34 | 35 | return true; 36 | }, 37 | hideDeleteDialog: function () { 38 | $('#myModal').modal('hide'); 39 | 40 | return true; 41 | }, 42 | getUserName: function () { 43 | if (user === null) { 44 | return Blazor.platform.toDotNetString(''); 45 | } 46 | 47 | return user.profile.name; 48 | }, 49 | executeWithToken: function (action) { 50 | authContext.acquireToken(authContext.config.clientId, function (error, token) { 51 | let tokenString = Blazor.platform.toDotNetString(token); 52 | 53 | const assemblyName = 'BlazorAzure.WebApp'; 54 | const namespace = 'BlazorAzure.WebApp'; 55 | const typeName = 'AdalHelper'; 56 | const methodName = 'RunAction'; 57 | 58 | const runActionMethod = Blazor.platform.findMethod( 59 | assemblyName, 60 | namespace, 61 | typeName, 62 | methodName 63 | ); 64 | 65 | Blazor.platform.callMethod(runActionMethod, null, [ 66 | action, tokenString 67 | ]); 68 | 69 | }); 70 | 71 | return true; 72 | } 73 | }; -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/App.razor: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/BlazorLibrary.AspNetCoreHostedBlazor.Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | Exe 6 | 7 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; 8 | https://dotnet.myget.org/F/blazor-dev/api/v3/index.json; 9 | 10 | 7.3 11 | 3.0 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/BooksClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Http; 3 | using System.Threading.Tasks; 4 | using BlazorLibrary.Shared; 5 | using Microsoft.AspNetCore.Components; 6 | 7 | namespace BlazorLibrary.AspNetCoreHostedBlazor.Client 8 | { 9 | public class BooksClient : IBooksClient 10 | { 11 | private readonly string _baseUri = "http://localhost:55384"; 12 | private readonly HttpClient _httpClient; 13 | 14 | public string Token { get; set; } 15 | 16 | public BooksClient(HttpClient httpClient) 17 | { 18 | _httpClient = httpClient; 19 | } 20 | 21 | public async Task DeleteBook(Book book) 22 | { 23 | await DeleteBook(book.Id); 24 | } 25 | 26 | public async Task DeleteBook(int id) 27 | { 28 | await _httpClient.DeleteAsync(_baseUri + "/api/library/" + id); 29 | } 30 | 31 | public async Task> ListBooks(int page, int pageSize) 32 | { 33 | var url = _baseUri + "/api/library?page=" + page + "&pageSize=" + pageSize; 34 | 35 | return await _httpClient.GetJsonAsync>(url); 36 | } 37 | 38 | public async Task GetBook(int id) 39 | { 40 | return await _httpClient.GetJsonAsync(_baseUri + "/api/library/" + id); 41 | } 42 | 43 | public async Task SaveBook(Book book) 44 | { 45 | var url = _baseUri + "/api/library"; 46 | 47 | if (book.Id == 0) 48 | { 49 | await _httpClient.PostJsonAsync(url, book); 50 | } 51 | else 52 | { 53 | await _httpClient.PutJsonAsync(url, book); 54 | } 55 | } 56 | 57 | public async Task> SearchBooks(string term, int page) 58 | { 59 | await Task.FromResult(0); 60 | 61 | throw new NotImplementedException(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/LibraryPageBase.cs: -------------------------------------------------------------------------------- 1 | using BlazorLibrary.Shared; 2 | using Microsoft.AspNetCore.Components; 3 | using Microsoft.JSInterop; 4 | 5 | namespace BlazorLibrary.AspNetCoreHostedBlazor.Client 6 | { 7 | public abstract class LibraryPageBase : ComponentBase 8 | { 9 | [Inject] 10 | protected IUriHelper UriHelper { get; set; } 11 | 12 | [Inject] 13 | protected IJSRuntime JSRuntime { get; set; } 14 | 15 | [Inject] 16 | protected IBooksClient BooksClient { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/Pages/EditBook.razor: -------------------------------------------------------------------------------- 1 | @page "/edit" 2 | @page "/edit/{Id}" 3 | @inherits EditBookModel 4 | 5 |

@PageTitle

6 | 7 | @if (CurrentBook != null) 8 | { 9 |
10 |
11 |
12 |
13 | 14 |
15 | 16 |
17 |
18 |
19 | 20 |
21 | 22 |
23 |
24 |
25 | 26 |
27 | 28 |
29 |
30 |
31 |
32 |
33 | } 34 | else 35 | { 36 |

Loading...

37 | } -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/Pages/EditBook.razor.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using BlazorLibrary.Shared; 3 | using Microsoft.AspNetCore.Components; 4 | 5 | namespace BlazorLibrary.AspNetCoreHostedBlazor.Client.Pages 6 | { 7 | public class EditBookModel : LibraryPageBase 8 | { 9 | [Parameter] 10 | protected string Id { get; private set; } = "0"; 11 | protected string PageTitle { get; private set; } 12 | protected Book CurrentBook { get; set; } 13 | 14 | protected override async Task OnParametersSetAsync() 15 | { 16 | if (Id == null || Id == "0") 17 | { 18 | PageTitle = "Add book"; 19 | CurrentBook = new Book(); 20 | } 21 | else 22 | { 23 | PageTitle = "Edit book"; 24 | 25 | await LoadBook(int.Parse(Id)); 26 | } 27 | } 28 | 29 | protected async Task LoadBook(int id) 30 | { 31 | CurrentBook = await BooksClient.GetBook(id); 32 | } 33 | 34 | protected async Task Save() 35 | { 36 | await BooksClient.SaveBook(CurrentBook); 37 | UriHelper.NavigateTo("/"); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @page "/page/{Page}" 3 | @inherits IndexModel 4 | 5 |
6 |
7 |

Books database

8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 | 17 | @if (Books == null) 18 | { 19 |

Loading...

20 | } 21 | else 22 | { 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | @foreach (var book in Books.Results) 31 | { 32 | var id = book.Id; 33 | var title = book.Title; 34 | 35 | 36 | 37 | 38 | 42 | 43 | } 44 |
IdTitleISBN
@book.Id@book.Title@book.ISBN 39 | 40 | 41 |
45 | 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/Pages/Index.razor.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using BlazorLibrary.Shared; 3 | using Microsoft.AspNetCore.Components; 4 | 5 | namespace BlazorLibrary.AspNetCoreHostedBlazor.Client.Pages 6 | { 7 | public class IndexModel : LibraryPageBase 8 | { 9 | [Parameter] 10 | protected string Page { get; set; } = "1"; 11 | 12 | protected int DeleteId { get; set; } = 0; 13 | protected PagedResult Books; 14 | 15 | protected override async Task OnParametersSetAsync() 16 | { 17 | await LoadBooks(int.Parse(Page)); 18 | } 19 | 20 | private async Task LoadBooks(int page) 21 | { 22 | Books = await BooksClient.ListBooks(page, 10); 23 | } 24 | 25 | protected void PagerPageChanged(int page) 26 | { 27 | UriHelper.NavigateTo("/page/" + page); 28 | } 29 | 30 | protected void AddNew() 31 | { 32 | UriHelper.NavigateTo("/edit/0"); 33 | } 34 | 35 | protected void EditBook(int id) 36 | { 37 | UriHelper.NavigateTo("/edit/" + id); 38 | } 39 | 40 | protected async void ConfirmDelete(int id, string title) 41 | { 42 | DeleteId = id; 43 | 44 | await JSRuntime.InvokeAsync("blazorDemoInterop.confirmDelete", title); 45 | } 46 | 47 | protected async Task DeleteBook() 48 | { 49 | await JSRuntime.InvokeAsync("blazorDemoInterop.hideDeleteDialog"); 50 | 51 | await BooksClient.DeleteBook(DeleteId); 52 | await LoadBooks(int.Parse(Page)); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/Pages/_Imports.razor: -------------------------------------------------------------------------------- 1 | @layout MainLayout 2 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Blazor.Hosting; 2 | 3 | namespace BlazorLibrary.AspNetCoreHostedBlazor.Client 4 | { 5 | public class Program 6 | { 7 | public static void Main(string[] args) 8 | { 9 | CreateHostBuilder(args).Build().Run(); 10 | } 11 | 12 | public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) => 13 | BlazorWebAssemblyHost.CreateDefaultBuilder() 14 | .UseBlazorStartup(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:55387/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "BlazorLibrary.AspNetCoreHostedBlazor.Client": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:55389/" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 6 | 7 |
8 |
9 | About 10 |
11 | 12 |
13 | @Body 14 |
15 |
16 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  7 | 8 |
9 | 16 |
17 | 18 | @functions { 19 | bool collapseNavMenu = true; 20 | 21 | string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 22 | 23 | void ToggleNavMenu() 24 | { 25 | collapseNavMenu = !collapseNavMenu; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 |  11 | 12 | @functions { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] string Title { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/Startup.cs: -------------------------------------------------------------------------------- 1 | using BlazorLibrary.Shared; 2 | using Microsoft.AspNetCore.Components.Builder; 3 | using Microsoft.Extensions.DependencyInjection; 4 | 5 | namespace BlazorLibrary.AspNetCoreHostedBlazor.Client 6 | { 7 | public class Startup 8 | { 9 | public void ConfigureServices(IServiceCollection services) 10 | { 11 | services.AddSingleton(); 12 | } 13 | 14 | public void Configure(IComponentsApplicationBuilder app) 15 | { 16 | app.AddComponent("app"); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Components.Forms 3 | @using Microsoft.AspNetCore.Components.Layouts 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.JSInterop 6 | @using BlazorLibrary.AspNetCoreHostedBlazor.Client 7 | @using BlazorLibrary.AspNetCoreHostedBlazor.Client.Shared 8 | @using BlazorLibrary.Components -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/README.md: -------------------------------------------------------------------------------- 1 | [Open Iconic v1.1.1](http://useiconic.com/open) 2 | =========== 3 | 4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons) 5 | 6 | 7 | 8 | ## What's in Open Iconic? 9 | 10 | * 223 icons designed to be legible down to 8 pixels 11 | * Super-light SVG files - 61.8 for the entire set 12 | * SVG sprite—the modern replacement for icon fonts 13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats 14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats 15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px. 16 | 17 | 18 | ## Getting Started 19 | 20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections. 21 | 22 | ### General Usage 23 | 24 | #### Using Open Iconic's SVGs 25 | 26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute). 27 | 28 | ``` 29 | icon name 30 | ``` 31 | 32 | #### Using Open Iconic's SVG Sprite 33 | 34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack. 35 | 36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.* 37 | 38 | ``` 39 | 40 | 41 | 42 | ``` 43 | 44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions. 45 | 46 | ``` 47 | .icon { 48 | width: 16px; 49 | height: 16px; 50 | } 51 | ``` 52 | 53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag. 54 | 55 | ``` 56 | .icon-account-login { 57 | fill: #f00; 58 | } 59 | ``` 60 | 61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/). 62 | 63 | #### Using Open Iconic's Icon Font... 64 | 65 | 66 | ##### …with Bootstrap 67 | 68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}` 69 | 70 | 71 | ``` 72 | 73 | ``` 74 | 75 | 76 | ``` 77 | 78 | ``` 79 | 80 | ##### …with Foundation 81 | 82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}` 83 | 84 | ``` 85 | 86 | ``` 87 | 88 | 89 | ``` 90 | 91 | ``` 92 | 93 | ##### …on its own 94 | 95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}` 96 | 97 | ``` 98 | 99 | ``` 100 | 101 | ``` 102 | 103 | ``` 104 | 105 | 106 | ## License 107 | 108 | ### Icons 109 | 110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT). 111 | 112 | ### Fonts 113 | 114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web). 115 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | app { 8 | position: relative; 9 | display: flex; 10 | flex-direction: column; 11 | } 12 | 13 | .top-row { 14 | height: 3.5rem; 15 | display: flex; 16 | align-items: center; 17 | } 18 | 19 | .main { 20 | flex: 1; 21 | } 22 | 23 | .main .top-row { 24 | background-color: #e6e6e6; 25 | border-bottom: 1px solid #d6d5d5; 26 | } 27 | 28 | .sidebar { 29 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 30 | } 31 | 32 | .sidebar .top-row { 33 | background-color: rgba(0,0,0,0.4); 34 | } 35 | 36 | .sidebar .navbar-brand { 37 | font-size: 1.1rem; 38 | } 39 | 40 | .sidebar .oi { 41 | width: 2rem; 42 | font-size: 1.1rem; 43 | vertical-align: text-top; 44 | top: -2px; 45 | } 46 | 47 | .nav-item { 48 | font-size: 0.9rem; 49 | padding-bottom: 0.5rem; 50 | } 51 | 52 | .nav-item:first-of-type { 53 | padding-top: 1rem; 54 | } 55 | 56 | .nav-item:last-of-type { 57 | padding-bottom: 1rem; 58 | } 59 | 60 | .nav-item a { 61 | color: #d7d7d7; 62 | border-radius: 4px; 63 | height: 3rem; 64 | display: flex; 65 | align-items: center; 66 | line-height: 3rem; 67 | } 68 | 69 | .nav-item a.active { 70 | background-color: rgba(255,255,255,0.25); 71 | color: white; 72 | } 73 | 74 | .nav-item a:hover { 75 | background-color: rgba(255,255,255,0.1); 76 | color: white; 77 | } 78 | 79 | .content { 80 | padding-top: 1.1rem; 81 | } 82 | 83 | .navbar-toggler { 84 | background-color: rgba(255, 255, 255, 0.1); 85 | } 86 | 87 | .valid.modified:not([type=checkbox]) { 88 | outline: 1px solid #26b050; 89 | } 90 | 91 | .invalid { 92 | outline: 1px solid red; 93 | } 94 | 95 | .validation-message { 96 | color: red; 97 | } 98 | 99 | @media (max-width: 767.98px) { 100 | .main .top-row { 101 | display: none; 102 | } 103 | } 104 | 105 | @media (min-width: 768px) { 106 | app { 107 | flex-direction: row; 108 | } 109 | 110 | .sidebar { 111 | width: 250px; 112 | height: 100vh; 113 | position: sticky; 114 | top: 0; 115 | } 116 | 117 | .main .top-row { 118 | position: sticky; 119 | top: 0; 120 | } 121 | 122 | .main > div { 123 | padding-left: 2rem !important; 124 | padding-right: 1.5rem !important; 125 | } 126 | 127 | .navbar-toggler { 128 | display: none; 129 | } 130 | 131 | .sidebar .collapse { 132 | /* Never collapse the sidebar for wide screens */ 133 | display: block; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Client/wwwroot/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | BlazorLibrary.AspNetCoreHostedBlazor 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Server/BlazorLibrary.AspNetCoreHostedBlazor.Server.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.0 5 | 6 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; 7 | https://dotnet.myget.org/F/blazor-dev/api/v3/index.json; 8 | 9 | 7.3 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Server/Controllers/LibraryController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using BlazorLibrary.Data; 3 | using BlazorLibrary.Shared; 4 | using Microsoft.AspNetCore.Mvc; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 8 | 9 | namespace BlazorLibrary.AspNetCoreHostedBlazor.Server.Controllers 10 | { 11 | [Route("api/[controller]")] 12 | public class LibraryController : Controller 13 | { 14 | private readonly BooksDbContext _dataContext; 15 | 16 | public LibraryController(BooksDbContext dataContext) 17 | { 18 | _dataContext = dataContext; 19 | } 20 | 21 | // GET: api/ 22 | [HttpGet] 23 | public async Task> Get(int page=1, int pageSize=10) 24 | { 25 | return await _dataContext.Books.GetPagedAsync(page, pageSize); 26 | } 27 | 28 | // GET api//5 29 | [HttpGet("{id}")] 30 | public async Task Get(int id) 31 | { 32 | var book = await _dataContext.Books.FirstOrDefaultAsync(b => b.Id == id); 33 | 34 | return book; 35 | } 36 | 37 | // POST api/ 38 | [HttpPost] 39 | public async Task Post([FromBody]Book book) 40 | { 41 | _dataContext.Add(book); 42 | 43 | await _dataContext.SaveChangesAsync(); 44 | } 45 | 46 | // PUT api//5 47 | [HttpPut] 48 | public async Task Put([FromBody]Book book) 49 | { 50 | _dataContext.Update(book); 51 | 52 | await _dataContext.SaveChangesAsync(); 53 | } 54 | 55 | // DELETE api//5 56 | [HttpDelete("{id}")] 57 | public async Task Delete(int id) 58 | { 59 | var book = await _dataContext.Books.FirstOrDefaultAsync(b => b.Id == id); 60 | if (book == null) 61 | { 62 | return; 63 | } 64 | 65 | _dataContext.Books.Remove(book); 66 | await _dataContext.SaveChangesAsync(); 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Server/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | 5 | namespace BlazorLibrary.AspNetCoreHostedBlazor.Server 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | BuildWebHost(args).Run(); 12 | } 13 | 14 | public static IWebHost BuildWebHost(string[] args) => 15 | WebHost.CreateDefaultBuilder(args) 16 | .UseConfiguration(new ConfigurationBuilder() 17 | .AddCommandLine(args) 18 | .Build()) 19 | .UseStartup() 20 | .Build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Server/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:55384/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "BlazorLibrary.AspNetCoreHostedBlazor.Server": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:55388/" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Server/Startup.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using BlazorLibrary.Data; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.AspNetCore.ResponseCompression; 6 | using Microsoft.EntityFrameworkCore; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.Extensions.Hosting; 10 | 11 | namespace BlazorLibrary.AspNetCoreHostedBlazor.Server 12 | { 13 | public class Startup 14 | { 15 | private IConfiguration Configuration { get; } 16 | 17 | public Startup(IWebHostEnvironment env, IConfiguration config) 18 | { 19 | Configuration = config; 20 | } 21 | 22 | // This method gets called by the runtime. Use this method to add services to the container. 23 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 24 | public void ConfigureServices(IServiceCollection services) 25 | { 26 | services.AddDbContext(options => 27 | { 28 | options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")); 29 | }); 30 | 31 | services.AddMvc().AddNewtonsoftJson(); 32 | services.AddResponseCompression(opts => 33 | { 34 | opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat( 35 | new[] { "application/octet-stream" }); 36 | }); 37 | } 38 | 39 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 40 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 41 | { 42 | app.UseResponseCompression(); 43 | 44 | if (env.IsDevelopment()) 45 | { 46 | app.UseDeveloperExceptionPage(); 47 | app.UseBlazorDebugging(); 48 | } 49 | 50 | app.UseRouting(); 51 | 52 | app.UseEndpoints(endpoints => 53 | { 54 | endpoints.MapDefaultControllerRoute(); 55 | }); 56 | 57 | app.UseBlazor(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Server/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=Books;Trusted_Connection=True;MultipleActiveResultSets=true" 4 | } 5 | } -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Shared/BlazorLibrary.AspNetCoreHostedBlazor.Shared.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 7.3 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /BlazorLibrary.AspNetCoreHostedBlazor.Shared/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace BlazorLibrary.AspNetCoreHostedBlazor.Shared 6 | { 7 | public class WeatherForecast 8 | { 9 | public DateTime Date { get; set; } 10 | 11 | public int TemperatureC { get; set; } 12 | 13 | public string Summary { get; set; } 14 | 15 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BlazorLibrary.Components/BlazorLibrary.Components.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Library 6 | true 7 | false 8 | 7.3 9 | 3.0 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /BlazorLibrary.Components/Pager.razor: -------------------------------------------------------------------------------- 1 | @inherits PagerModel 2 | @using Microsoft.AspNetCore.Components.Web 3 | 4 | @if (Result != null) 5 | { 6 |
7 |
8 | @if (Result.PageCount > 1) 9 | { 10 |
    11 |
  • 12 | @for (var i = StartIndex; i <= FinishIndex; i++) 13 | { 14 | var currentIndex = i; 15 | @if (i == Result.CurrentPage) 16 | { 17 |
  • @i
  • 18 | } 19 | else 20 | { 21 |
  • 22 | } 23 | } 24 |
  • 25 |
26 | } 27 |
28 |
29 | } -------------------------------------------------------------------------------- /BlazorLibrary.Components/Pager.razor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BlazorLibrary.Shared; 3 | using Microsoft.AspNetCore.Components; 4 | 5 | namespace BlazorLibrary.Components 6 | { 7 | public class PagerModel : ComponentBase 8 | { 9 | [Parameter] 10 | public PagedResultBase Result { get; set; } 11 | 12 | [Parameter] 13 | public Action PageChanged { get; set; } 14 | 15 | protected int StartIndex { get; private set; } = 0; 16 | protected int FinishIndex { get; private set; } = 0; 17 | 18 | protected override void OnParametersSet() 19 | { 20 | StartIndex = Math.Max(Result.CurrentPage - 5, 1); 21 | FinishIndex = Math.Min(Result.CurrentPage + 5, Result.PageCount); 22 | 23 | base.OnParametersSet(); 24 | } 25 | 26 | protected void PagerButtonClicked(int page) 27 | { 28 | PageChanged?.Invoke(page); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /BlazorLibrary.Components/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:61291/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "BlazorLibrary.Components": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:61294/" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /BlazorLibrary.Data/BlazorLibrary.Data.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /BlazorLibrary.Data/BooksDbContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BlazorLibrary.Shared; 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace BlazorLibrary.Data 6 | { 7 | public class BooksDbContext : DbContext 8 | { 9 | public DbSet Books { get; set; } 10 | 11 | public BooksDbContext(DbContextOptions options) : base(options) 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /BlazorLibrary.Data/PagedResultExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using BlazorLibrary.Shared; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace BlazorLibrary.Data 8 | { 9 | public static class PagedResultExtensions 10 | { 11 | public static PagedResult GetPaged(this IQueryable query, int page, int pageSize) where T : class 12 | { 13 | var result = new PagedResult 14 | { 15 | CurrentPage = page, 16 | PageSize = pageSize, 17 | RowCount = query.Count() 18 | }; 19 | 20 | var pageCount = (double)result.RowCount / pageSize; 21 | result.PageCount = (int)Math.Ceiling(pageCount); 22 | 23 | var skip = (page - 1) * pageSize; 24 | result.Results = query.Skip(skip).Take(pageSize).ToList(); 25 | 26 | return result; 27 | } 28 | 29 | public static async Task> GetPagedAsync(this IQueryable query, int page, int pageSize) where T : class 30 | { 31 | var result = new PagedResult 32 | { 33 | CurrentPage = page, 34 | PageSize = pageSize, 35 | RowCount = query.Count() 36 | }; 37 | 38 | var pageCount = (double)result.RowCount / pageSize; 39 | result.PageCount = (int)Math.Ceiling(pageCount); 40 | 41 | var skip = (page - 1) * pageSize; 42 | result.Results = await query.Skip(skip).Take(pageSize).ToListAsync(); 43 | 44 | return result; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/App.razor: -------------------------------------------------------------------------------- 1 | @* 2 | The Router component displays whichever component has a @page 3 | directive matching the current URI. 4 | *@ 5 | 6 | 7 | 8 | 9 | 10 | 11 |

Sorry, there's nothing at this address.

12 |
13 |
14 |
15 | 16 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/BlazorLibrary.ServerSideBlazor.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.0 5 | 7.3 6 | 3.0 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/LibraryPageBase.cs: -------------------------------------------------------------------------------- 1 | using BlazorLibrary.Data; 2 | using Microsoft.AspNetCore.Components; 3 | using Microsoft.JSInterop; 4 | 5 | namespace BlazorLibrary.ServerSideBlazor 6 | { 7 | public abstract class LibraryPageBase : ComponentBase 8 | { 9 | [Inject] 10 | protected NavigationManager UriHelper { get; set; } 11 | 12 | [Inject] 13 | protected IJSRuntime JSRuntime { get; set; } 14 | 15 | [Inject] 16 | protected BooksDbContext DataContext { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/Pages/EditBook.razor: -------------------------------------------------------------------------------- 1 | @page "/edit" 2 | @page "/edit/{Id}" 3 | @inherits EditBookModel 4 | 5 |

@PageTitle

6 | 7 | @if (CurrentBook != null) 8 | { 9 |
10 |
11 |
12 |
13 | 14 |
15 | 16 |
17 |
18 |
19 | 20 |
21 | 22 |
23 |
24 |
25 | 26 |
27 | 28 |
29 |
30 |
31 |
32 |
33 | } 34 | else 35 | { 36 |

Loading...

37 | } -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/Pages/EditBook.razor.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using BlazorLibrary.Shared; 3 | using Microsoft.AspNetCore.Components; 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace BlazorLibrary.ServerSideBlazor.Pages 7 | { 8 | public class EditBookModel : LibraryPageBase 9 | { 10 | [Parameter] 11 | public string Id { get; set; } = "0"; 12 | protected string PageTitle { get; private set; } 13 | protected Book CurrentBook { get; set; } 14 | 15 | protected override async Task OnParametersSetAsync() 16 | { 17 | if (Id == null || Id == "0") 18 | { 19 | PageTitle = "Add book"; 20 | CurrentBook = new Book(); 21 | } 22 | else 23 | { 24 | PageTitle = "Edit book"; 25 | 26 | await LoadBook(int.Parse(Id)); 27 | } 28 | } 29 | 30 | protected async Task LoadBook(int id) 31 | { 32 | CurrentBook = await DataContext.Books.FirstOrDefaultAsync(b => b.Id == id); 33 | } 34 | 35 | protected async Task Save() 36 | { 37 | await DataContext.SaveChangesAsync(); 38 | UriHelper.NavigateTo("/"); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @page "/page/{Page}" 3 | @inherits IndexModel 4 | 5 |
6 |
7 |

Books database

8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 | 17 | @if (Books == null) 18 | { 19 |

Loading...

20 | } 21 | else 22 | { 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | @foreach (var book in Books.Results) 31 | { 32 | var id = book.Id; 33 | var title = book.Title; 34 | 35 | 36 | 37 | 38 | 42 | 43 | } 44 |
IdTitleISBN
@book.Id@book.Title@book.ISBN 39 | 40 | 41 |
45 | 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/Pages/Index.razor.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using BlazorLibrary.Shared; 3 | using BlazorLibrary.Data; 4 | using Microsoft.AspNetCore.Components; 5 | using Microsoft.EntityFrameworkCore; 6 | using Microsoft.JSInterop; 7 | 8 | namespace BlazorLibrary.ServerSideBlazor.Pages 9 | { 10 | public class IndexModel : LibraryPageBase 11 | { 12 | [Parameter] 13 | public string Page { get; set; } = "1"; 14 | 15 | protected int DeleteId { get; set; } = 0; 16 | protected PagedResult Books; 17 | 18 | protected override async Task OnParametersSetAsync() 19 | { 20 | await LoadBooks(int.Parse(Page ?? "1")); 21 | } 22 | 23 | private async Task LoadBooks(int page) 24 | { 25 | Books = await DataContext.Books.GetPagedAsync(page, 10); 26 | } 27 | 28 | protected void PagerPageChanged(int page) 29 | { 30 | UriHelper.NavigateTo("/page/" + page); 31 | } 32 | 33 | protected void AddNew() 34 | { 35 | UriHelper.NavigateTo("/edit/0"); 36 | } 37 | 38 | protected void EditBook(int id) 39 | { 40 | UriHelper.NavigateTo("/edit/" + id); 41 | } 42 | 43 | protected async void ConfirmDelete(int id, string title) 44 | { 45 | DeleteId = id; 46 | 47 | await JSRuntime.InvokeAsync("blazorDemoInterop.confirmDelete", title); 48 | } 49 | 50 | protected async Task DeleteBook() 51 | { 52 | await JSRuntime.InvokeAsync("blazorDemoInterop.hideDeleteDialog"); 53 | 54 | var book = await DataContext.Books.FirstOrDefaultAsync(b => b.Id == DeleteId); 55 | if(book != null) 56 | { 57 | DataContext.Books.Remove(book); 58 | 59 | await DataContext.SaveChangesAsync(); 60 | } 61 | 62 | //await BooksClient.DeleteBook(DeleteId); 63 | await LoadBooks(int.Parse(Page)); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/Pages/_Host.cshtml: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @namespace BlazorLibrary.ServerSideBlazor.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | 5 | 6 | 7 | 8 | 9 | 10 | BlazorLibrary.ServerSideBlazor 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | @(await Html.RenderComponentAsync(RenderMode.ServerPrerendered)) 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/Pages/_Imports.razor: -------------------------------------------------------------------------------- 1 | @layout MainLayout 2 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Hosting; 10 | using Microsoft.Extensions.Logging; 11 | 12 | namespace BlazorLibrary.ServerSideBlazor 13 | { 14 | public class Program 15 | { 16 | public static void Main(string[] args) 17 | { 18 | CreateHostBuilder(args).Build().Run(); 19 | } 20 | 21 | public static IHostBuilder CreateHostBuilder(string[] args) => 22 | Host.CreateDefaultBuilder(args) 23 | .ConfigureWebHostDefaults(webBuilder => 24 | { 25 | webBuilder.UseStartup(); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:58901", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "BlazorLibrary.ServerSideBlazor": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "applicationUrl": "http://localhost:5000", 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 6 | 7 |
8 |
9 | About 10 |
11 | 12 |
13 | @Body 14 |
15 |
16 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 | 7 | 8 |
9 | 16 |
17 | 18 | @functions { 19 | bool collapseNavMenu = true; 20 | 21 | string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 22 | 23 | void ToggleNavMenu() 24 | { 25 | collapseNavMenu = !collapseNavMenu; 26 | } 27 | } -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/Startup.cs: -------------------------------------------------------------------------------- 1 | using BlazorLibrary.Data; 2 | using Microsoft.AspNetCore.Builder; 3 | using Microsoft.AspNetCore.Hosting; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.Hosting; 8 | 9 | namespace BlazorLibrary.ServerSideBlazor 10 | { 11 | public class Startup 12 | { 13 | private IConfiguration Configuration { get; } 14 | 15 | public Startup(IWebHostEnvironment env, IConfiguration config) 16 | { 17 | Configuration = config; 18 | } 19 | 20 | // This method gets called by the runtime. Use this method to add services to the container. 21 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddDbContext(options => 25 | { 26 | options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")); 27 | }); 28 | 29 | services.AddRazorPages(); 30 | services.AddServerSideBlazor().AddCircuitOptions(options => { options.DetailedErrors = true; }); ; 31 | } 32 | 33 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 34 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 35 | { 36 | if (env.IsDevelopment()) 37 | { 38 | app.UseDeveloperExceptionPage(); 39 | } 40 | 41 | app.UseStaticFiles(); 42 | 43 | app.UseRouting(); 44 | 45 | app.UseEndpoints(endpoints => 46 | { 47 | endpoints.MapBlazorHub(); 48 | endpoints.MapFallbackToPage("/_Host"); 49 | }); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Components.Forms 3 | @using Microsoft.AspNetCore.Components.Web 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.JSInterop 6 | @using BlazorLibrary.ServerSideBlazor.Shared 7 | @using BlazorLibrary.Components -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=Books;Trusted_Connection=True;MultipleActiveResultSets=true" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Information", 8 | "Microsoft": "Warning", 9 | "Microsoft.Hosting.Lifetime": "Information" 10 | } 11 | }, 12 | "AllowedHosts": "*" 13 | } 14 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/wwwroot/css/open-iconic/README.md: -------------------------------------------------------------------------------- 1 | [Open Iconic v1.1.1](http://useiconic.com/open) 2 | =========== 3 | 4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons) 5 | 6 | 7 | 8 | ## What's in Open Iconic? 9 | 10 | * 223 icons designed to be legible down to 8 pixels 11 | * Super-light SVG files - 61.8 for the entire set 12 | * SVG sprite—the modern replacement for icon fonts 13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats 14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats 15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px. 16 | 17 | 18 | ## Getting Started 19 | 20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections. 21 | 22 | ### General Usage 23 | 24 | #### Using Open Iconic's SVGs 25 | 26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute). 27 | 28 | ``` 29 | icon name 30 | ``` 31 | 32 | #### Using Open Iconic's SVG Sprite 33 | 34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack. 35 | 36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.* 37 | 38 | ``` 39 | 40 | 41 | 42 | ``` 43 | 44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions. 45 | 46 | ``` 47 | .icon { 48 | width: 16px; 49 | height: 16px; 50 | } 51 | ``` 52 | 53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag. 54 | 55 | ``` 56 | .icon-account-login { 57 | fill: #f00; 58 | } 59 | ``` 60 | 61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/). 62 | 63 | #### Using Open Iconic's Icon Font... 64 | 65 | 66 | ##### …with Bootstrap 67 | 68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}` 69 | 70 | 71 | ``` 72 | 73 | ``` 74 | 75 | 76 | ``` 77 | 78 | ``` 79 | 80 | ##### …with Foundation 81 | 82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}` 83 | 84 | ``` 85 | 86 | ``` 87 | 88 | 89 | ``` 90 | 91 | ``` 92 | 93 | ##### …on its own 94 | 95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}` 96 | 97 | ``` 98 | 99 | ``` 100 | 101 | ``` 102 | 103 | ``` 104 | 105 | 106 | ## License 107 | 108 | ### Icons 109 | 110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT). 111 | 112 | ### Fonts 113 | 114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web). 115 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorLibrary.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorLibrary.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorLibrary.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorLibrary.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | app { 8 | position: relative; 9 | display: flex; 10 | flex-direction: column; 11 | } 12 | 13 | .top-row { 14 | height: 3.5rem; 15 | display: flex; 16 | align-items: center; 17 | } 18 | 19 | .main { 20 | flex: 1; 21 | } 22 | 23 | .main .top-row { 24 | background-color: #e6e6e6; 25 | border-bottom: 1px solid #d6d5d5; 26 | } 27 | 28 | .sidebar { 29 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 30 | } 31 | 32 | .sidebar .top-row { 33 | background-color: rgba(0,0,0,0.4); 34 | } 35 | 36 | .sidebar .navbar-brand { 37 | font-size: 1.1rem; 38 | } 39 | 40 | .sidebar .oi { 41 | width: 2rem; 42 | font-size: 1.1rem; 43 | vertical-align: text-top; 44 | top: -2px; 45 | } 46 | 47 | .nav-item { 48 | font-size: 0.9rem; 49 | padding-bottom: 0.5rem; 50 | } 51 | 52 | .nav-item:first-of-type { 53 | padding-top: 1rem; 54 | } 55 | 56 | .nav-item:last-of-type { 57 | padding-bottom: 1rem; 58 | } 59 | 60 | .nav-item a { 61 | color: #d7d7d7; 62 | border-radius: 4px; 63 | height: 3rem; 64 | display: flex; 65 | align-items: center; 66 | line-height: 3rem; 67 | } 68 | 69 | .nav-item a.active { 70 | background-color: rgba(255,255,255,0.25); 71 | color: white; 72 | } 73 | 74 | .nav-item a:hover { 75 | background-color: rgba(255,255,255,0.1); 76 | color: white; 77 | } 78 | 79 | .content { 80 | padding-top: 1.1rem; 81 | } 82 | 83 | .navbar-toggler { 84 | background-color: rgba(255, 255, 255, 0.1); 85 | } 86 | 87 | .valid.modified:not([type=checkbox]) { 88 | outline: 1px solid #26b050; 89 | } 90 | 91 | .invalid { 92 | outline: 1px solid red; 93 | } 94 | 95 | .validation-message { 96 | color: red; 97 | } 98 | 99 | @media (max-width: 767.98px) { 100 | .main .top-row { 101 | display: none; 102 | } 103 | } 104 | 105 | @media (min-width: 768px) { 106 | app { 107 | flex-direction: row; 108 | } 109 | 110 | .sidebar { 111 | width: 250px; 112 | height: 100vh; 113 | position: sticky; 114 | top: 0; 115 | } 116 | 117 | .main .top-row { 118 | position: sticky; 119 | top: 0; 120 | } 121 | 122 | .main > div { 123 | padding-left: 2rem !important; 124 | padding-right: 1.5rem !important; 125 | } 126 | 127 | .navbar-toggler { 128 | display: none; 129 | } 130 | 131 | .sidebar .collapse { 132 | /* Never collapse the sidebar for wide screens */ 133 | display: block; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /BlazorLibrary.ServerSideBlazor/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/BlazorLibrary.ServerSideBlazor/wwwroot/favicon.ico -------------------------------------------------------------------------------- /BlazorLibrary.Shared/BlazorLibrary.Shared.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /BlazorLibrary.Shared/Book.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace BlazorLibrary.Shared 4 | { 5 | public class Book 6 | { 7 | [Key] 8 | public int Id { get; set; } 9 | 10 | [Required] 11 | [StringLength(100)] 12 | public string Title { get; set; } 13 | 14 | [Required] 15 | [StringLength(13)] 16 | public string ISBN { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /BlazorLibrary.Shared/IBooksClient.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace BlazorLibrary.Shared 4 | { 5 | public interface IBooksClient 6 | { 7 | Task> ListBooks(int page, int pageSize); 8 | Task GetBook(int id); 9 | Task SaveBook(Book book); 10 | Task DeleteBook(Book book); 11 | Task DeleteBook(int id); 12 | Task> SearchBooks(string term, int page); 13 | string Token { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /BlazorLibrary.Shared/PagedResultPage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BlazorLibrary.Shared 4 | { 5 | public abstract class PagedResultBase 6 | { 7 | public int CurrentPage { get; set; } 8 | public int PageCount { get; set; } 9 | public int PageSize { get; set; } 10 | public int RowCount { get; set; } 11 | 12 | public int FirstRowOnPage 13 | { 14 | 15 | get { return (CurrentPage - 1) * PageSize + 1; } 16 | } 17 | 18 | public int LastRowOnPage 19 | { 20 | get { return Math.Min(CurrentPage * PageSize, RowCount); } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /BlazorLibrary.Shared/PagedResultT.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace BlazorLibrary.Shared 4 | { 5 | public class PagedResult : PagedResultBase where T : class 6 | { 7 | public IList Results { get; set; } 8 | 9 | public PagedResult() 10 | { 11 | Results = new List(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /External Files/Books.bacpac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/External Files/Books.bacpac -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/App.razor: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/OutOfBox.AspNetCoreHostedBlazor.Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | Exe 6 | 7 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; 8 | https://dotnet.myget.org/F/blazor-dev/api/v3/index.json; 9 | 10 | 7.3 11 | 3.0 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 |

Counter

4 | 5 |

Current count: @currentCount

6 | 7 | 8 | 9 | @functions { 10 | int currentCount = 0; 11 | 12 | void IncrementCount() 13 | { 14 | currentCount++; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/Pages/FetchData.razor: -------------------------------------------------------------------------------- 1 | @page "/fetchdata" 2 | @using OutOfBox.AspNetCoreHostedBlazor.Shared 3 | @inject HttpClient Http 4 | 5 |

Weather forecast

6 | 7 |

This component demonstrates fetching data from the server.

8 | 9 | @if (forecasts == null) 10 | { 11 |

Loading...

12 | } 13 | else 14 | { 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | @foreach (var forecast in forecasts) 26 | { 27 | 28 | 29 | 30 | 31 | 32 | 33 | } 34 | 35 |
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
36 | } 37 | 38 | @functions { 39 | WeatherForecast[] forecasts; 40 | 41 | protected override async Task OnInitAsync() 42 | { 43 | forecasts = await Http.GetJsonAsync("api/SampleData/WeatherForecasts"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 |

Hello, world!

4 | 5 | Welcome to your new app. 6 | 7 | 8 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/Pages/_Imports.razor: -------------------------------------------------------------------------------- 1 | @layout MainLayout 2 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Blazor.Hosting; 2 | 3 | namespace OutOfBox.AspNetCoreHostedBlazor.Client 4 | { 5 | public class Program 6 | { 7 | public static void Main(string[] args) 8 | { 9 | CreateHostBuilder(args).Build().Run(); 10 | } 11 | 12 | public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) => 13 | BlazorWebAssemblyHost.CreateDefaultBuilder() 14 | .UseBlazorStartup(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:51268/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "OutOfBox.AspNetCoreHostedBlazor.Client": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:51270/" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 6 | 7 |
8 |
9 | About 10 |
11 | 12 |
13 | @Body 14 |
15 |
16 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  7 | 8 |
9 | 26 |
27 | 28 | @functions { 29 | bool collapseNavMenu = true; 30 | 31 | string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 32 | 33 | void ToggleNavMenu() 34 | { 35 | collapseNavMenu = !collapseNavMenu; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 |  11 | 12 | @functions { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] string Title { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.Builder; 2 | using Microsoft.Extensions.DependencyInjection; 3 | 4 | namespace OutOfBox.AspNetCoreHostedBlazor.Client 5 | { 6 | public class Startup 7 | { 8 | public void ConfigureServices(IServiceCollection services) 9 | { 10 | } 11 | 12 | public void Configure(IComponentsApplicationBuilder app) 13 | { 14 | app.AddComponent("app"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Components.Forms 3 | @using Microsoft.AspNetCore.Components.Layouts 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.JSInterop 6 | @using OutOfBox.AspNetCoreHostedBlazor.Client 7 | @using OutOfBox.AspNetCoreHostedBlazor.Client.Shared 8 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/README.md: -------------------------------------------------------------------------------- 1 | [Open Iconic v1.1.1](http://useiconic.com/open) 2 | =========== 3 | 4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons) 5 | 6 | 7 | 8 | ## What's in Open Iconic? 9 | 10 | * 223 icons designed to be legible down to 8 pixels 11 | * Super-light SVG files - 61.8 for the entire set 12 | * SVG sprite—the modern replacement for icon fonts 13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats 14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats 15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px. 16 | 17 | 18 | ## Getting Started 19 | 20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections. 21 | 22 | ### General Usage 23 | 24 | #### Using Open Iconic's SVGs 25 | 26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute). 27 | 28 | ``` 29 | icon name 30 | ``` 31 | 32 | #### Using Open Iconic's SVG Sprite 33 | 34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack. 35 | 36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.* 37 | 38 | ``` 39 | 40 | 41 | 42 | ``` 43 | 44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions. 45 | 46 | ``` 47 | .icon { 48 | width: 16px; 49 | height: 16px; 50 | } 51 | ``` 52 | 53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag. 54 | 55 | ``` 56 | .icon-account-login { 57 | fill: #f00; 58 | } 59 | ``` 60 | 61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/). 62 | 63 | #### Using Open Iconic's Icon Font... 64 | 65 | 66 | ##### …with Bootstrap 67 | 68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}` 69 | 70 | 71 | ``` 72 | 73 | ``` 74 | 75 | 76 | ``` 77 | 78 | ``` 79 | 80 | ##### …with Foundation 81 | 82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}` 83 | 84 | ``` 85 | 86 | ``` 87 | 88 | 89 | ``` 90 | 91 | ``` 92 | 93 | ##### …on its own 94 | 95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}` 96 | 97 | ``` 98 | 99 | ``` 100 | 101 | ``` 102 | 103 | ``` 104 | 105 | 106 | ## License 107 | 108 | ### Icons 109 | 110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT). 111 | 112 | ### Fonts 113 | 114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web). 115 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | app { 8 | position: relative; 9 | display: flex; 10 | flex-direction: column; 11 | } 12 | 13 | .top-row { 14 | height: 3.5rem; 15 | display: flex; 16 | align-items: center; 17 | } 18 | 19 | .main { 20 | flex: 1; 21 | } 22 | 23 | .main .top-row { 24 | background-color: #e6e6e6; 25 | border-bottom: 1px solid #d6d5d5; 26 | } 27 | 28 | .sidebar { 29 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 30 | } 31 | 32 | .sidebar .top-row { 33 | background-color: rgba(0,0,0,0.4); 34 | } 35 | 36 | .sidebar .navbar-brand { 37 | font-size: 1.1rem; 38 | } 39 | 40 | .sidebar .oi { 41 | width: 2rem; 42 | font-size: 1.1rem; 43 | vertical-align: text-top; 44 | top: -2px; 45 | } 46 | 47 | .nav-item { 48 | font-size: 0.9rem; 49 | padding-bottom: 0.5rem; 50 | } 51 | 52 | .nav-item:first-of-type { 53 | padding-top: 1rem; 54 | } 55 | 56 | .nav-item:last-of-type { 57 | padding-bottom: 1rem; 58 | } 59 | 60 | .nav-item a { 61 | color: #d7d7d7; 62 | border-radius: 4px; 63 | height: 3rem; 64 | display: flex; 65 | align-items: center; 66 | line-height: 3rem; 67 | } 68 | 69 | .nav-item a.active { 70 | background-color: rgba(255,255,255,0.25); 71 | color: white; 72 | } 73 | 74 | .nav-item a:hover { 75 | background-color: rgba(255,255,255,0.1); 76 | color: white; 77 | } 78 | 79 | .content { 80 | padding-top: 1.1rem; 81 | } 82 | 83 | .navbar-toggler { 84 | background-color: rgba(255, 255, 255, 0.1); 85 | } 86 | 87 | .valid.modified:not([type=checkbox]) { 88 | outline: 1px solid #26b050; 89 | } 90 | 91 | .invalid { 92 | outline: 1px solid red; 93 | } 94 | 95 | .validation-message { 96 | color: red; 97 | } 98 | 99 | @media (max-width: 767.98px) { 100 | .main .top-row { 101 | display: none; 102 | } 103 | } 104 | 105 | @media (min-width: 768px) { 106 | app { 107 | flex-direction: row; 108 | } 109 | 110 | .sidebar { 111 | width: 250px; 112 | height: 100vh; 113 | position: sticky; 114 | top: 0; 115 | } 116 | 117 | .main .top-row { 118 | position: sticky; 119 | top: 0; 120 | } 121 | 122 | .main > div { 123 | padding-left: 2rem !important; 124 | padding-right: 1.5rem !important; 125 | } 126 | 127 | .navbar-toggler { 128 | display: none; 129 | } 130 | 131 | .sidebar .collapse { 132 | /* Never collapse the sidebar for wide screens */ 133 | display: block; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Client/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | OutOfBox.AspNetCoreHostedBlazor 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Server/Controllers/SampleDataController.cs: -------------------------------------------------------------------------------- 1 | using OutOfBox.AspNetCoreHostedBlazor.Shared; 2 | using Microsoft.AspNetCore.Mvc; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace OutOfBox.AspNetCoreHostedBlazor.Server.Controllers 9 | { 10 | [Route("api/[controller]")] 11 | public class SampleDataController : Controller 12 | { 13 | private static string[] Summaries = new[] 14 | { 15 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 16 | }; 17 | 18 | [HttpGet("[action]")] 19 | public IEnumerable WeatherForecasts() 20 | { 21 | var rng = new Random(); 22 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 23 | { 24 | Date = DateTime.Now.AddDays(index), 25 | TemperatureC = rng.Next(-20, 55), 26 | Summary = Summaries[rng.Next(Summaries.Length)] 27 | }); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Server/OutOfBox.AspNetCoreHostedBlazor.Server.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.0 5 | 6 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; 7 | https://dotnet.myget.org/F/blazor-dev/api/v3/index.json; 8 | 9 | 7.3 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Server/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | 5 | namespace OutOfBox.AspNetCoreHostedBlazor.Server 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | BuildWebHost(args).Run(); 12 | } 13 | 14 | public static IWebHost BuildWebHost(string[] args) => 15 | WebHost.CreateDefaultBuilder(args) 16 | .UseConfiguration(new ConfigurationBuilder() 17 | .AddCommandLine(args) 18 | .Build()) 19 | .UseStartup() 20 | .Build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Server/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:51267/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "OutOfBox.AspNetCoreHostedBlazor.Server": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:51269/" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Server/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.AspNetCore.ResponseCompression; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Newtonsoft.Json.Serialization; 7 | using System.Linq; 8 | 9 | namespace OutOfBox.AspNetCoreHostedBlazor.Server 10 | { 11 | public class Startup 12 | { 13 | // This method gets called by the runtime. Use this method to add services to the container. 14 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 15 | public void ConfigureServices(IServiceCollection services) 16 | { 17 | services.AddMvc().AddNewtonsoftJson(); 18 | services.AddResponseCompression(opts => 19 | { 20 | opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat( 21 | new[] { "application/octet-stream" }); 22 | }); 23 | } 24 | 25 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 26 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 27 | { 28 | app.UseResponseCompression(); 29 | 30 | if (env.IsDevelopment()) 31 | { 32 | app.UseDeveloperExceptionPage(); 33 | app.UseBlazorDebugging(); 34 | } 35 | 36 | app.UseRouting(); 37 | 38 | app.UseEndpoints(endpoints => 39 | { 40 | endpoints.MapDefaultControllerRoute(); 41 | }); 42 | 43 | app.UseBlazor(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Shared/OutOfBox.AspNetCoreHostedBlazor.Shared.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 7.3 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /OutOfBox.AspNetCoreHostedBlazor.Shared/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace OutOfBox.AspNetCoreHostedBlazor.Shared 6 | { 7 | public class WeatherForecast 8 | { 9 | public DateTime Date { get; set; } 10 | 11 | public int TemperatureC { get; set; } 12 | 13 | public string Summary { get; set; } 14 | 15 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/App.razor: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/OutOfBox.ClientSideBlazor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 6 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; 7 | https://dotnet.myget.org/F/blazor-dev/api/v3/index.json; 8 | 9 | 7.3 10 | 3.0 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 |

Counter

4 | 5 |

Current count: @currentCount

6 | 7 | 8 | 9 | @functions { 10 | int currentCount = 0; 11 | 12 | void IncrementCount() 13 | { 14 | currentCount++; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/Pages/FetchData.razor: -------------------------------------------------------------------------------- 1 | @page "/fetchdata" 2 | @inject HttpClient Http 3 | 4 |

Weather forecast

5 | 6 |

This component demonstrates fetching data from the server.

7 | 8 | @if (forecasts == null) 9 | { 10 |

Loading...

11 | } 12 | else 13 | { 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | @foreach (var forecast in forecasts) 25 | { 26 | 27 | 28 | 29 | 30 | 31 | 32 | } 33 | 34 |
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
35 | } 36 | 37 | @functions { 38 | WeatherForecast[] forecasts; 39 | 40 | protected override async Task OnInitAsync() 41 | { 42 | forecasts = await Http.GetJsonAsync("sample-data/weather.json"); 43 | } 44 | 45 | class WeatherForecast 46 | { 47 | public DateTime Date { get; set; } 48 | 49 | public int TemperatureC { get; set; } 50 | 51 | public int TemperatureF { get; set; } 52 | 53 | public string Summary { get; set; } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 |

Hello, world!

4 | 5 | Welcome to your new app. 6 | 7 | 8 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/Pages/_Imports.razor: -------------------------------------------------------------------------------- 1 | @layout MainLayout 2 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Blazor.Hosting; 2 | 3 | namespace OutOfBox.ClientSideBlazor 4 | { 5 | public class Program 6 | { 7 | public static void Main(string[] args) 8 | { 9 | CreateHostBuilder(args).Build().Run(); 10 | } 11 | 12 | public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) => 13 | BlazorWebAssemblyHost.CreateDefaultBuilder() 14 | .UseBlazorStartup(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:50603/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "OutOfBox.ClientSideBlazor": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:50604/" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 6 | 7 |
8 |
9 | About 10 |
11 | 12 |
13 | @Body 14 |
15 |
16 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  7 | 8 |
9 | 26 |
27 | 28 | @functions { 29 | bool collapseNavMenu = true; 30 | 31 | string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 32 | 33 | void ToggleNavMenu() 34 | { 35 | collapseNavMenu = !collapseNavMenu; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 |  11 | 12 | @functions { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] string Title { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.Builder; 2 | using Microsoft.Extensions.DependencyInjection; 3 | 4 | namespace OutOfBox.ClientSideBlazor 5 | { 6 | public class Startup 7 | { 8 | public void ConfigureServices(IServiceCollection services) 9 | { 10 | } 11 | 12 | public void Configure(IComponentsApplicationBuilder app) 13 | { 14 | app.AddComponent("app"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Components.Forms 3 | @using Microsoft.AspNetCore.Components.Layouts 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.JSInterop 6 | @using OutOfBox.ClientSideBlazor 7 | @using OutOfBox.ClientSideBlazor.Shared 8 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/wwwroot/css/open-iconic/README.md: -------------------------------------------------------------------------------- 1 | [Open Iconic v1.1.1](http://useiconic.com/open) 2 | =========== 3 | 4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons) 5 | 6 | 7 | 8 | ## What's in Open Iconic? 9 | 10 | * 223 icons designed to be legible down to 8 pixels 11 | * Super-light SVG files - 61.8 for the entire set 12 | * SVG sprite—the modern replacement for icon fonts 13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats 14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats 15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px. 16 | 17 | 18 | ## Getting Started 19 | 20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections. 21 | 22 | ### General Usage 23 | 24 | #### Using Open Iconic's SVGs 25 | 26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute). 27 | 28 | ``` 29 | icon name 30 | ``` 31 | 32 | #### Using Open Iconic's SVG Sprite 33 | 34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack. 35 | 36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.* 37 | 38 | ``` 39 | 40 | 41 | 42 | ``` 43 | 44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions. 45 | 46 | ``` 47 | .icon { 48 | width: 16px; 49 | height: 16px; 50 | } 51 | ``` 52 | 53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag. 54 | 55 | ``` 56 | .icon-account-login { 57 | fill: #f00; 58 | } 59 | ``` 60 | 61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/). 62 | 63 | #### Using Open Iconic's Icon Font... 64 | 65 | 66 | ##### …with Bootstrap 67 | 68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}` 69 | 70 | 71 | ``` 72 | 73 | ``` 74 | 75 | 76 | ``` 77 | 78 | ``` 79 | 80 | ##### …with Foundation 81 | 82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}` 83 | 84 | ``` 85 | 86 | ``` 87 | 88 | 89 | ``` 90 | 91 | ``` 92 | 93 | ##### …on its own 94 | 95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}` 96 | 97 | ``` 98 | 99 | ``` 100 | 101 | ``` 102 | 103 | ``` 104 | 105 | 106 | ## License 107 | 108 | ### Icons 109 | 110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT). 111 | 112 | ### Fonts 113 | 114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web). 115 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.ClientSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.ClientSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.ClientSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.ClientSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | app { 8 | position: relative; 9 | display: flex; 10 | flex-direction: column; 11 | } 12 | 13 | .top-row { 14 | height: 3.5rem; 15 | display: flex; 16 | align-items: center; 17 | } 18 | 19 | .main { 20 | flex: 1; 21 | } 22 | 23 | .main .top-row { 24 | background-color: #e6e6e6; 25 | border-bottom: 1px solid #d6d5d5; 26 | } 27 | 28 | .sidebar { 29 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 30 | } 31 | 32 | .sidebar .top-row { 33 | background-color: rgba(0,0,0,0.4); 34 | } 35 | 36 | .sidebar .navbar-brand { 37 | font-size: 1.1rem; 38 | } 39 | 40 | .sidebar .oi { 41 | width: 2rem; 42 | font-size: 1.1rem; 43 | vertical-align: text-top; 44 | top: -2px; 45 | } 46 | 47 | .nav-item { 48 | font-size: 0.9rem; 49 | padding-bottom: 0.5rem; 50 | } 51 | 52 | .nav-item:first-of-type { 53 | padding-top: 1rem; 54 | } 55 | 56 | .nav-item:last-of-type { 57 | padding-bottom: 1rem; 58 | } 59 | 60 | .nav-item a { 61 | color: #d7d7d7; 62 | border-radius: 4px; 63 | height: 3rem; 64 | display: flex; 65 | align-items: center; 66 | line-height: 3rem; 67 | } 68 | 69 | .nav-item a.active { 70 | background-color: rgba(255,255,255,0.25); 71 | color: white; 72 | } 73 | 74 | .nav-item a:hover { 75 | background-color: rgba(255,255,255,0.1); 76 | color: white; 77 | } 78 | 79 | .content { 80 | padding-top: 1.1rem; 81 | } 82 | 83 | .navbar-toggler { 84 | background-color: rgba(255, 255, 255, 0.1); 85 | } 86 | 87 | .valid.modified:not([type=checkbox]) { 88 | outline: 1px solid #26b050; 89 | } 90 | 91 | .invalid { 92 | outline: 1px solid red; 93 | } 94 | 95 | .validation-message { 96 | color: red; 97 | } 98 | 99 | @media (max-width: 767.98px) { 100 | .main .top-row { 101 | display: none; 102 | } 103 | } 104 | 105 | @media (min-width: 768px) { 106 | app { 107 | flex-direction: row; 108 | } 109 | 110 | .sidebar { 111 | width: 250px; 112 | height: 100vh; 113 | position: sticky; 114 | top: 0; 115 | } 116 | 117 | .main .top-row { 118 | position: sticky; 119 | top: 0; 120 | } 121 | 122 | .main > div { 123 | padding-left: 2rem !important; 124 | padding-right: 1.5rem !important; 125 | } 126 | 127 | .navbar-toggler { 128 | display: none; 129 | } 130 | 131 | .sidebar .collapse { 132 | /* Never collapse the sidebar for wide screens */ 133 | display: block; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | OutOfBox.ClientSideBlazor 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /OutOfBox.ClientSideBlazor/wwwroot/sample-data/weather.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "date": "2018-05-06", 4 | "temperatureC": 1, 5 | "summary": "Freezing", 6 | "temperatureF": 33 7 | }, 8 | { 9 | "date": "2018-05-07", 10 | "temperatureC": 14, 11 | "summary": "Bracing", 12 | "temperatureF": 57 13 | }, 14 | { 15 | "date": "2018-05-08", 16 | "temperatureC": -13, 17 | "summary": "Freezing", 18 | "temperatureF": 9 19 | }, 20 | { 21 | "date": "2018-05-09", 22 | "temperatureC": -16, 23 | "summary": "Balmy", 24 | "temperatureF": 4 25 | }, 26 | { 27 | "date": "2018-05-10", 28 | "temperatureC": -2, 29 | "summary": "Chilly", 30 | "temperatureF": 29 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/App.razor: -------------------------------------------------------------------------------- 1 | @* 2 | The Router component displays whichever component has a @page 3 | directive matching the current URI. 4 | *@ 5 | 6 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Data/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace OutOfBox.ServerSideBlazor.Data 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF { get; set; } 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Data/WeatherForecastService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | 5 | namespace OutOfBox.ServerSideBlazor.Data 6 | { 7 | public class WeatherForecastService 8 | { 9 | private static string[] Summaries = new[] 10 | { 11 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 12 | }; 13 | 14 | public Task GetForecastAsync(DateTime startDate) 15 | { 16 | var rng = new Random(); 17 | return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast 18 | { 19 | Date = startDate.AddDays(index), 20 | TemperatureC = rng.Next(-20, 55), 21 | Summary = Summaries[rng.Next(Summaries.Length)] 22 | }).ToArray()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/OutOfBox.ServerSideBlazor.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.0 5 | 7.3 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 |

Counter

4 | 5 |

Current count: @currentCount

6 | 7 | 8 | 9 | @functions { 10 | int currentCount = 0; 11 | 12 | void IncrementCount() 13 | { 14 | currentCount++; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Pages/FetchData.razor: -------------------------------------------------------------------------------- 1 | @page "/fetchdata" 2 | @using OutOfBox.ServerSideBlazor.Data 3 | @inject WeatherForecastService ForecastService 4 | 5 |

Weather forecast

6 | 7 |

This component demonstrates fetching data from a service.

8 | 9 | @if (forecasts == null) 10 | { 11 |

Loading...

12 | } 13 | else 14 | { 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | @foreach (var forecast in forecasts) 26 | { 27 | 28 | 29 | 30 | 31 | 32 | 33 | } 34 | 35 |
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
36 | } 37 | 38 | @functions { 39 | WeatherForecast[] forecasts; 40 | 41 | protected override async Task OnInitAsync() 42 | { 43 | forecasts = await ForecastService.GetForecastAsync(DateTime.Now); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 |

Hello, world!

4 | 5 | Welcome to your new app. 6 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Pages/_Host.cshtml: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @namespace OutOfBox.ServerSideBlazor.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | 5 | 6 | 7 | 8 | 9 | 10 | OutOfBox.ServerSideBlazor 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | @(await Html.RenderComponentAsync()) 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Pages/_Imports.razor: -------------------------------------------------------------------------------- 1 | @layout MainLayout 2 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Hosting; 10 | using Microsoft.Extensions.Logging; 11 | 12 | namespace OutOfBox.ServerSideBlazor 13 | { 14 | public class Program 15 | { 16 | public static void Main(string[] args) 17 | { 18 | CreateHostBuilder(args).Build().Run(); 19 | } 20 | 21 | public static IHostBuilder CreateHostBuilder(string[] args) => 22 | Host.CreateDefaultBuilder(args) 23 | .ConfigureWebHostDefaults(webBuilder => 24 | { 25 | webBuilder.UseStartup(); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:50538", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "OutOfBox.ServerSideBlazor": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "applicationUrl": "http://localhost:5000", 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 6 | 7 |
8 |
9 | About 10 |
11 | 12 |
13 | @Body 14 |
15 |
16 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 | 7 | 8 |
9 | 26 |
27 | 28 | @functions { 29 | bool collapseNavMenu = true; 30 | 31 | string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 32 | 33 | void ToggleNavMenu() 34 | { 35 | collapseNavMenu = !collapseNavMenu; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.Extensions.Hosting; 10 | using OutOfBox.ServerSideBlazor.Data; 11 | 12 | namespace OutOfBox.ServerSideBlazor 13 | { 14 | public class Startup 15 | { 16 | // This method gets called by the runtime. Use this method to add services to the container. 17 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 18 | public void ConfigureServices(IServiceCollection services) 19 | { 20 | services.AddRazorPages(); 21 | services.AddServerSideBlazor(); 22 | services.AddSingleton(); 23 | } 24 | 25 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 26 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 27 | { 28 | if (env.IsDevelopment()) 29 | { 30 | app.UseDeveloperExceptionPage(); 31 | } 32 | 33 | app.UseStaticFiles(); 34 | 35 | app.UseRouting(); 36 | 37 | app.UseEndpoints(endpoints => 38 | { 39 | endpoints.MapBlazorHub(); 40 | endpoints.MapFallbackToPage("/_Host"); 41 | }); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Components.Forms 3 | @using Microsoft.AspNetCore.Components.Layouts 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.JSInterop 6 | @using OutOfBox.ServerSideBlazor.Shared 7 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/wwwroot/css/open-iconic/README.md: -------------------------------------------------------------------------------- 1 | [Open Iconic v1.1.1](http://useiconic.com/open) 2 | =========== 3 | 4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons) 5 | 6 | 7 | 8 | ## What's in Open Iconic? 9 | 10 | * 223 icons designed to be legible down to 8 pixels 11 | * Super-light SVG files - 61.8 for the entire set 12 | * SVG sprite—the modern replacement for icon fonts 13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats 14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats 15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px. 16 | 17 | 18 | ## Getting Started 19 | 20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections. 21 | 22 | ### General Usage 23 | 24 | #### Using Open Iconic's SVGs 25 | 26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute). 27 | 28 | ``` 29 | icon name 30 | ``` 31 | 32 | #### Using Open Iconic's SVG Sprite 33 | 34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack. 35 | 36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.* 37 | 38 | ``` 39 | 40 | 41 | 42 | ``` 43 | 44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions. 45 | 46 | ``` 47 | .icon { 48 | width: 16px; 49 | height: 16px; 50 | } 51 | ``` 52 | 53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag. 54 | 55 | ``` 56 | .icon-account-login { 57 | fill: #f00; 58 | } 59 | ``` 60 | 61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/). 62 | 63 | #### Using Open Iconic's Icon Font... 64 | 65 | 66 | ##### …with Bootstrap 67 | 68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}` 69 | 70 | 71 | ``` 72 | 73 | ``` 74 | 75 | 76 | ``` 77 | 78 | ``` 79 | 80 | ##### …with Foundation 81 | 82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}` 83 | 84 | ``` 85 | 86 | ``` 87 | 88 | 89 | ``` 90 | 91 | ``` 92 | 93 | ##### …on its own 94 | 95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}` 96 | 97 | ``` 98 | 99 | ``` 100 | 101 | ``` 102 | 103 | ``` 104 | 105 | 106 | ## License 107 | 108 | ### Icons 109 | 110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT). 111 | 112 | ### Fonts 113 | 114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web). 115 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.ServerSideBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | app { 8 | position: relative; 9 | display: flex; 10 | flex-direction: column; 11 | } 12 | 13 | .top-row { 14 | height: 3.5rem; 15 | display: flex; 16 | align-items: center; 17 | } 18 | 19 | .main { 20 | flex: 1; 21 | } 22 | 23 | .main .top-row { 24 | background-color: #e6e6e6; 25 | border-bottom: 1px solid #d6d5d5; 26 | } 27 | 28 | .sidebar { 29 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 30 | } 31 | 32 | .sidebar .top-row { 33 | background-color: rgba(0,0,0,0.4); 34 | } 35 | 36 | .sidebar .navbar-brand { 37 | font-size: 1.1rem; 38 | } 39 | 40 | .sidebar .oi { 41 | width: 2rem; 42 | font-size: 1.1rem; 43 | vertical-align: text-top; 44 | top: -2px; 45 | } 46 | 47 | .nav-item { 48 | font-size: 0.9rem; 49 | padding-bottom: 0.5rem; 50 | } 51 | 52 | .nav-item:first-of-type { 53 | padding-top: 1rem; 54 | } 55 | 56 | .nav-item:last-of-type { 57 | padding-bottom: 1rem; 58 | } 59 | 60 | .nav-item a { 61 | color: #d7d7d7; 62 | border-radius: 4px; 63 | height: 3rem; 64 | display: flex; 65 | align-items: center; 66 | line-height: 3rem; 67 | } 68 | 69 | .nav-item a.active { 70 | background-color: rgba(255,255,255,0.25); 71 | color: white; 72 | } 73 | 74 | .nav-item a:hover { 75 | background-color: rgba(255,255,255,0.1); 76 | color: white; 77 | } 78 | 79 | .content { 80 | padding-top: 1.1rem; 81 | } 82 | 83 | .navbar-toggler { 84 | background-color: rgba(255, 255, 255, 0.1); 85 | } 86 | 87 | .valid.modified:not([type=checkbox]) { 88 | outline: 1px solid #26b050; 89 | } 90 | 91 | .invalid { 92 | outline: 1px solid red; 93 | } 94 | 95 | .validation-message { 96 | color: red; 97 | } 98 | 99 | @media (max-width: 767.98px) { 100 | .main .top-row { 101 | display: none; 102 | } 103 | } 104 | 105 | @media (min-width: 768px) { 106 | app { 107 | flex-direction: row; 108 | } 109 | 110 | .sidebar { 111 | width: 250px; 112 | height: 100vh; 113 | position: sticky; 114 | top: 0; 115 | } 116 | 117 | .main .top-row { 118 | position: sticky; 119 | top: 0; 120 | } 121 | 122 | .main > div { 123 | padding-left: 2rem !important; 124 | padding-right: 1.5rem !important; 125 | } 126 | 127 | .navbar-toggler { 128 | display: none; 129 | } 130 | 131 | .sidebar .collapse { 132 | /* Never collapse the sidebar for wide screens */ 133 | display: block; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /OutOfBox.ServerSideBlazor/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.ServerSideBlazor/wwwroot/favicon.ico -------------------------------------------------------------------------------- /OutOfBox.SharedBlazorComponent/Component1.razor: -------------------------------------------------------------------------------- 1 | 
2 | This Blazor component is defined in the OutOfBox.SharedBlazorComponent package. 3 |
4 | -------------------------------------------------------------------------------- /OutOfBox.SharedBlazorComponent/OutOfBox.SharedBlazorComponent.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Library 6 | true 7 | false 8 | 7.3 9 | 3.0 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /OutOfBox.SharedBlazorComponent/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:51676/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "OutOfBox.SharedBlazorComponent": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:51677/" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /OutOfBox.SharedBlazorComponent/content/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.SharedBlazorComponent/content/background.png -------------------------------------------------------------------------------- /OutOfBox.SharedBlazorComponent/content/styles.css: -------------------------------------------------------------------------------- 1 | /* 2 | This file is to show how CSS and other static resources (such as images) can be 3 | used from a library project/package. 4 | */ 5 | 6 | .my-component { 7 | border: 2px dashed red; 8 | padding: 1em; 9 | margin: 1em 0; 10 | background-image: url('background.png'); 11 | } 12 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/App.razor: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/OutOfBox.SharedComponentDemoApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; 7 | https://dotnet.myget.org/F/blazor-dev/api/v3/index.json; 8 | 9 | 7.3 10 | 3.0 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 |

Counter

4 | 5 |

Current count: @currentCount

6 | 7 | 8 | 9 | @functions { 10 | int currentCount = 0; 11 | 12 | void IncrementCount() 13 | { 14 | currentCount++; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/Pages/FetchData.razor: -------------------------------------------------------------------------------- 1 | @page "/fetchdata" 2 | @inject HttpClient Http 3 | 4 |

Weather forecast

5 | 6 |

This component demonstrates fetching data from the server.

7 | 8 | @if (forecasts == null) 9 | { 10 |

Loading...

11 | } 12 | else 13 | { 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | @foreach (var forecast in forecasts) 25 | { 26 | 27 | 28 | 29 | 30 | 31 | 32 | } 33 | 34 |
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
35 | } 36 | 37 | @functions { 38 | WeatherForecast[] forecasts; 39 | 40 | protected override async Task OnInitAsync() 41 | { 42 | forecasts = await Http.GetJsonAsync("sample-data/weather.json"); 43 | } 44 | 45 | class WeatherForecast 46 | { 47 | public DateTime Date { get; set; } 48 | 49 | public int TemperatureC { get; set; } 50 | 51 | public int TemperatureF { get; set; } 52 | 53 | public string Summary { get; set; } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | 9 | 10 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/Pages/_Imports.razor: -------------------------------------------------------------------------------- 1 | @layout MainLayout 2 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Blazor.Hosting; 2 | 3 | namespace OutOfBox.SharedComponentDemoApp 4 | { 5 | public class Program 6 | { 7 | public static void Main(string[] args) 8 | { 9 | CreateHostBuilder(args).Build().Run(); 10 | } 11 | 12 | public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) => 13 | BlazorWebAssemblyHost.CreateDefaultBuilder() 14 | .UseBlazorStartup(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:56553/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "OutOfBox.SharedComponentDemoApp": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:56557/" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 6 | 7 |
8 |
9 | About 10 |
11 | 12 |
13 | @Body 14 |
15 |
16 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  7 | 8 |
9 | 26 |
27 | 28 | @functions { 29 | bool collapseNavMenu = true; 30 | 31 | string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 32 | 33 | void ToggleNavMenu() 34 | { 35 | collapseNavMenu = !collapseNavMenu; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 |  11 | 12 | @functions { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] string Title { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.Builder; 2 | using Microsoft.Extensions.DependencyInjection; 3 | 4 | namespace OutOfBox.SharedComponentDemoApp 5 | { 6 | public class Startup 7 | { 8 | public void ConfigureServices(IServiceCollection services) 9 | { 10 | } 11 | 12 | public void Configure(IComponentsApplicationBuilder app) 13 | { 14 | app.AddComponent("app"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Components.Forms 3 | @using Microsoft.AspNetCore.Components.Layouts 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.JSInterop 6 | @using OutOfBox.SharedComponentDemoApp 7 | @using OutOfBox.SharedComponentDemoApp.Shared 8 | @using OutOfBox.SharedBlazorComponent -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/wwwroot/css/open-iconic/README.md: -------------------------------------------------------------------------------- 1 | [Open Iconic v1.1.1](http://useiconic.com/open) 2 | =========== 3 | 4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons) 5 | 6 | 7 | 8 | ## What's in Open Iconic? 9 | 10 | * 223 icons designed to be legible down to 8 pixels 11 | * Super-light SVG files - 61.8 for the entire set 12 | * SVG sprite—the modern replacement for icon fonts 13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats 14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats 15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px. 16 | 17 | 18 | ## Getting Started 19 | 20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections. 21 | 22 | ### General Usage 23 | 24 | #### Using Open Iconic's SVGs 25 | 26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute). 27 | 28 | ``` 29 | icon name 30 | ``` 31 | 32 | #### Using Open Iconic's SVG Sprite 33 | 34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack. 35 | 36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.* 37 | 38 | ``` 39 | 40 | 41 | 42 | ``` 43 | 44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions. 45 | 46 | ``` 47 | .icon { 48 | width: 16px; 49 | height: 16px; 50 | } 51 | ``` 52 | 53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag. 54 | 55 | ``` 56 | .icon-account-login { 57 | fill: #f00; 58 | } 59 | ``` 60 | 61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/). 62 | 63 | #### Using Open Iconic's Icon Font... 64 | 65 | 66 | ##### …with Bootstrap 67 | 68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}` 69 | 70 | 71 | ``` 72 | 73 | ``` 74 | 75 | 76 | ``` 77 | 78 | ``` 79 | 80 | ##### …with Foundation 81 | 82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}` 83 | 84 | ``` 85 | 86 | ``` 87 | 88 | 89 | ``` 90 | 91 | ``` 92 | 93 | ##### …on its own 94 | 95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}` 96 | 97 | ``` 98 | 99 | ``` 100 | 101 | ``` 102 | 103 | ``` 104 | 105 | 106 | ## License 107 | 108 | ### Icons 109 | 110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT). 111 | 112 | ### Fonts 113 | 114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web). 115 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.SharedComponentDemoApp/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.SharedComponentDemoApp/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.SharedComponentDemoApp/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpeipman/BlazorDemo/286883c9a8a768defb3b2ea381f07f4f137f8030/OutOfBox.SharedComponentDemoApp/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | app { 8 | position: relative; 9 | display: flex; 10 | flex-direction: column; 11 | } 12 | 13 | .top-row { 14 | height: 3.5rem; 15 | display: flex; 16 | align-items: center; 17 | } 18 | 19 | .main { 20 | flex: 1; 21 | } 22 | 23 | .main .top-row { 24 | background-color: #e6e6e6; 25 | border-bottom: 1px solid #d6d5d5; 26 | } 27 | 28 | .sidebar { 29 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 30 | } 31 | 32 | .sidebar .top-row { 33 | background-color: rgba(0,0,0,0.4); 34 | } 35 | 36 | .sidebar .navbar-brand { 37 | font-size: 1.1rem; 38 | } 39 | 40 | .sidebar .oi { 41 | width: 2rem; 42 | font-size: 1.1rem; 43 | vertical-align: text-top; 44 | top: -2px; 45 | } 46 | 47 | .nav-item { 48 | font-size: 0.9rem; 49 | padding-bottom: 0.5rem; 50 | } 51 | 52 | .nav-item:first-of-type { 53 | padding-top: 1rem; 54 | } 55 | 56 | .nav-item:last-of-type { 57 | padding-bottom: 1rem; 58 | } 59 | 60 | .nav-item a { 61 | color: #d7d7d7; 62 | border-radius: 4px; 63 | height: 3rem; 64 | display: flex; 65 | align-items: center; 66 | line-height: 3rem; 67 | } 68 | 69 | .nav-item a.active { 70 | background-color: rgba(255,255,255,0.25); 71 | color: white; 72 | } 73 | 74 | .nav-item a:hover { 75 | background-color: rgba(255,255,255,0.1); 76 | color: white; 77 | } 78 | 79 | .content { 80 | padding-top: 1.1rem; 81 | } 82 | 83 | .navbar-toggler { 84 | background-color: rgba(255, 255, 255, 0.1); 85 | } 86 | 87 | .valid.modified:not([type=checkbox]) { 88 | outline: 1px solid #26b050; 89 | } 90 | 91 | .invalid { 92 | outline: 1px solid red; 93 | } 94 | 95 | .validation-message { 96 | color: red; 97 | } 98 | 99 | @media (max-width: 767.98px) { 100 | .main .top-row { 101 | display: none; 102 | } 103 | } 104 | 105 | @media (min-width: 768px) { 106 | app { 107 | flex-direction: row; 108 | } 109 | 110 | .sidebar { 111 | width: 250px; 112 | height: 100vh; 113 | position: sticky; 114 | top: 0; 115 | } 116 | 117 | .main .top-row { 118 | position: sticky; 119 | top: 0; 120 | } 121 | 122 | .main > div { 123 | padding-left: 2rem !important; 124 | padding-right: 1.5rem !important; 125 | } 126 | 127 | .navbar-toggler { 128 | display: none; 129 | } 130 | 131 | .sidebar .collapse { 132 | /* Never collapse the sidebar for wide screens */ 133 | display: block; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | OutOfBox.SharedComponentDemoApp 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /OutOfBox.SharedComponentDemoApp/wwwroot/sample-data/weather.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "date": "2018-05-06", 4 | "temperatureC": 1, 5 | "summary": "Freezing", 6 | "temperatureF": 33 7 | }, 8 | { 9 | "date": "2018-05-07", 10 | "temperatureC": 14, 11 | "summary": "Bracing", 12 | "temperatureF": 57 13 | }, 14 | { 15 | "date": "2018-05-08", 16 | "temperatureC": -13, 17 | "summary": "Freezing", 18 | "temperatureF": 9 19 | }, 20 | { 21 | "date": "2018-05-09", 22 | "temperatureC": -16, 23 | "summary": "Balmy", 24 | "temperatureF": 4 25 | }, 26 | { 27 | "date": "2018-05-10", 28 | "temperatureC": -2, 29 | "summary": "Chilly", 30 | "temperatureF": 29 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BlazorDemo 2 | 3 | This is my simple Blazor application that demonstrates how to build SPA on Blazor and how to communicate with ASP.NET Core backend. 4 | Demo application is simple books database. 5 | 6 | Solution contains: 7 | 8 | * Sample database BACPAC file (can be imported to MSSQL using SSMS) 9 | * Client application with Blazor UI 10 | * Basic select and CRUD operations are implemented in UI and in back-end 11 | * Displaying of delete confirmation dialog and deleting of books 12 | * Fully functioning add/edit form 13 | * Pager component and support for data paging 14 | * Dependency injection with custom service classes 15 | * Protecting Blazor application and Azure Functions based back-end using Azure AD 16 | 17 | ## Azure AD example 18 | 19 | For Azure AD there are two project in solution: 20 | 21 | * BlazorDemo.AdalClient - Blazor web application that supports Azure AD 22 | * BlazorDemo.AzureFunctionsBackend - Azure Functions project with all functions that form back-end for Blazor application 23 | 24 | On Azure the following services are needed: 25 | 26 | * Azure AD - free one is okay 27 | * Azure SQL - instance with minimal size is okay 28 | * Azure Search - free tier is okay 29 | * App regitration on Azure AD - Web/Web API type of application 30 | * Azure Functions - minimal App Service where functions run is okay 31 | * Azure Storage GPv2 with static websites enabled (optional) 32 | 33 | Configuration in code files: 34 | 35 | * BlazorDemo.AdalClient project wwwroot/js/app.js - Azure AD tenant ID and application ID 36 | * BlazorDemo.AdalClient project BooksAzureFunctionsClient.cs - Azure Functions host and Azure AD application ID 37 | * BlazorDemo.AzureFunctionsBackend project AzureSearchClient - Azure Search service and index name, access key 38 | 39 | To use search you have to comment in calls to search service in BooksAzureFunctionsClient.cs (BlazorDemo.AdalClient project) 40 | 41 | BACPAC for SQL Server is in External Files folder. After creating database on SQL Azure it is possible to import it as a data-tier application. Same way it is possible to import it to SQL Server LocalDb used by BlazorDemo.Client project. 42 | 43 | More information is available in my blog post [Azure AD authentication in Blazor using ADAL.js](https://gunnarpeipman.com/aspnet/blazor-azure-ad-adal/). 44 | 45 | ## Tools 46 | 47 | As of 2019-05-20 the following tooling is needed to build and run this solution: 48 | 49 | * [.NET Core 3.0 Preview 5 SDK](https://dotnet.microsoft.com/download/thank-you/dotnet-sdk-3.0.100-preview5-windows-x86-installer) 50 | * [Visual Studio 2019 Preview](https://visualstudio.microsoft.com/vs/preview/) 51 | * ASP.NET and web development workload for Visual Studio (activate during VS installation) 52 | * [ASP.NET Core Blazor Language Services extension](https://go.microsoft.com/fwlink/?linkid=870389) 53 | * [Getting started with Blazor](http://gunnarpeipman.com/2018/04/blazor-preview/) 54 | 55 | ## Your opinion matters 56 | 57 | If you tried out this solution and you understand how Blazor works then please find some moments to 58 | take [brief survey by Microsoft](https://go.microsoft.com/fwlink/?linkid=873042) helping to make Blazor 59 | even better. 60 | 61 | ## References 62 | 63 | * [Azure AD authentication in Blazor using ADAL.js](https://gunnarpeipman.com/aspnet/blazor-azure-ad-adal/) 64 | * [Hosting Azure Functions backed Blazor application on Azure Storage static website](https://gunnarpeipman.com/azure/blazor-azure-function-static-website/) 65 | * [Building confirm delete dialog on Blazor](https://gunnarpeipman.com/aspnet/blazor-confirm-delete-dialog/) 66 | * [Dependency injection in Blazor](https://gunnarpeipman.com/aspnet/blazor-dependency-injection/) 67 | * [Building Blazor pager component](https://gunnarpeipman.com/aspnet/blazor-pager-component/) 68 | * [Separating code and presentation of Blazor pages](https://gunnarpeipman.com/aspnet/blazor-code-behind/) 69 | * [WebAssembly apps with Blazor](https://gunnarpeipman.com/aspnet/blazor-preview/) --------------------------------------------------------------------------------