Release/v3.0.0 #57

Merged
leon.hoppe merged 2 commits from release/v3.0.0 into dev 2025-01-19 16:40:25 +01:00
8 changed files with 207 additions and 66 deletions

View File

@@ -9,33 +9,11 @@
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="0648788e-7696-4e60-bf12-5d5601f33d8c" name="Changes" comment=""> <list default="true" id="0648788e-7696-4e60-bf12-5d5601f33d8c" name="Changes" comment="prepared project for release">
<change afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Web/Components/Dialogs/HopFrameEditorTests.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Web/Components/Layout/HopFrameLayoutTests.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Web/Components/Layout/HopFrameNavigationTests.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Web/Components/Layout/HopFrameSideMenuTests.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Web/Components/Pages/HopFrameHomeTests.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Web/Components/Pages/HopFrameTablePageTests.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Web/Helpers/EnumerableExtensions.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Web/HopFrame.Tests.Web.csproj" afterDir="false" />
<change afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Web/Models/MyDbContext.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Web/Models/MyTable.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.HopFrame/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.HopFrame/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/.idea.HopFrame/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.HopFrame/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/HopFrame.sln" beforeDir="false" afterPath="$PROJECT_DIR$/HopFrame.sln" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Core/HopFrame.Core.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Core/HopFrame.Core.csproj" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/HopFrame.Core/HopFrame.Core.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Core/HopFrame.Core.csproj" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Config/DbContextConfiguratorTests.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Config/DbContextConfiguratorTests.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/HopFrame.Web/HopFrame.Web.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Web/HopFrame.Web.csproj" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Config/HopFrameConfiguratorTests.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Config/HopFrameConfiguratorTests.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/testing/HopFrame.Testing/HopFrame.Testing.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/testing/HopFrame.Testing/HopFrame.Testing.csproj" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Config/PropertyConfiguratorTests.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Config/PropertyConfiguratorTests.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Config/TableConfiguratorTests.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Config/TableConfiguratorTests.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/HopFrame.Core.Tests.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/HopFrame.Tests.Core.csproj" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Models/MockDbContext.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Models/MockDbContext.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Models/MockModel.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Models/MockModel.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Models/MockModel2.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Models/MockModel2.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Models/QueryProvider.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Models/QueryProvider.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Services/ContextExplorerTests.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Services/ContextExplorerTests.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Services/DefaultAuthHandlerTests.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Services/DefaultAuthHandlerTests.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Services/DisplayPropertyTests.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Services/DisplayPropertyTests.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/HopFrame.Core.Tests/Services/TableManagerTests.cs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/HopFrame.Tests.Core/Services/TableManagerTests.cs" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -55,7 +33,7 @@
<component name="Git.Settings"> <component name="Git.Settings">
<option name="RECENT_BRANCH_BY_REPOSITORY"> <option name="RECENT_BRANCH_BY_REPOSITORY">
<map> <map>
<entry key="$PROJECT_DIR$" value="feature/documentation" /> <entry key="$PROJECT_DIR$" value="dev" />
</map> </map>
</option> </option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
@@ -102,26 +80,26 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent">{ <component name="PropertiesComponent"><![CDATA[{
&quot;keyToString&quot;: { "keyToString": {
&quot;.NET Launch Settings Profile.HopFrame.Testing.executor&quot;: &quot;Run&quot;, ".NET Launch Settings Profile.HopFrame.Testing.executor": "Run",
&quot;.NET Launch Settings Profile.HopFrame.Testing: https.executor&quot;: &quot;Run&quot;, ".NET Launch Settings Profile.HopFrame.Testing: https.executor": "Run",
&quot;.NET Project.HopFrame.Testing.executor&quot;: &quot;Run&quot;, ".NET Project.HopFrame.Testing.executor": "Run",
&quot;72b118b0-a6fc-4561-acdf-74f0b454dbb8.executor&quot;: &quot;Debug&quot;, "72b118b0-a6fc-4561-acdf-74f0b454dbb8.executor": "Debug",
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, "RunOnceActivity.ShowReadmeOnStart": "true",
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;, "RunOnceActivity.git.unshallow": "true",
&quot;dcdf1689-dc07-47e4-8824-2e60a4fbf301.executor&quot;: &quot;Debug&quot;, "dcdf1689-dc07-47e4-8824-2e60a4fbf301.executor": "Debug",
&quot;git-widget-placeholder&quot;: &quot;!18 on feature/unit-tests&quot;, "git-widget-placeholder": "release/v3.0.0",
&quot;list.type.of.created.stylesheet&quot;: &quot;CSS&quot;, "list.type.of.created.stylesheet": "CSS",
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;, "node.js.detected.package.eslint": "true",
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;, "node.js.detected.package.tslint": "true",
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.eslint": "(autodetect)",
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.tslint": "(autodetect)",
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;, "nodejs_package_manager_path": "npm",
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.environmentSetup&quot;, "settings.editor.selected.configurable": "preferences.environmentSetup",
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot; "vue.rearranger.settings.migration": "true"
} }
}</component> }]]></component>
<component name="RunManager" selected=".NET Launch Settings Profile.HopFrame.Testing: https"> <component name="RunManager" selected=".NET Launch Settings Profile.HopFrame.Testing: https">
<configuration name="HopFrame.Testing: http" type="LaunchSettings" factoryName=".NET Launch Settings Profile"> <configuration name="HopFrame.Testing: http" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
<option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/testing/HopFrame.Testing/HopFrame.Testing.csproj" /> <option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/testing/HopFrame.Testing/HopFrame.Testing.csproj" />
@@ -181,7 +159,7 @@
<workItem from="1737199714142" duration="8344000" /> <workItem from="1737199714142" duration="8344000" />
<workItem from="1737208313207" duration="4612000" /> <workItem from="1737208313207" duration="4612000" />
<workItem from="1737281957060" duration="3232000" /> <workItem from="1737281957060" duration="3232000" />
<workItem from="1737293153907" duration="5484000" /> <workItem from="1737293153907" duration="7750000" />
</task> </task>
<task id="LOCAL-00001" summary="Added basic configuration"> <task id="LOCAL-00001" summary="Added basic configuration">
<option name="closed" value="true" /> <option name="closed" value="true" />
@@ -327,48 +305,72 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1737285123218</updated> <updated>1737285123218</updated>
</task> </task>
<option name="localTasksCounter" value="19" /> <task id="LOCAL-00019" summary="Added web module tests">
<option name="closed" value="true" />
<created>1737298835225</created>
<option name="number" value="00019" />
<option name="presentableId" value="LOCAL-00019" />
<option name="project" value="LOCAL" />
<updated>1737298835225</updated>
</task>
<task id="LOCAL-00020" summary="Tested login functionality">
<option name="closed" value="true" />
<created>1737299111987</created>
<option name="number" value="00020" />
<option name="presentableId" value="LOCAL-00020" />
<option name="project" value="LOCAL" />
<updated>1737299111987</updated>
</task>
<task id="LOCAL-00021" summary="prepared project for release">
<option name="closed" value="true" />
<created>1737300408069</created>
<option name="number" value="00021" />
<option name="presentableId" value="LOCAL-00021" />
<option name="project" value="LOCAL" />
<updated>1737300408069</updated>
</task>
<option name="localTasksCounter" value="22" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" /> <option name="version" value="3" />
</component> </component>
<component name="UnitTestsCoverage.Settings"> <component name="UnitTestsCoverage.Settings">
<option name="coveragePercentColumnWidth" value="131" /> <option name="coveragePercentColumnWidth" value="129" />
<option name="sortOrder" value="DESCENDING" /> <option name="sortOrder" value="DESCENDING" />
<option name="sortedColumn" value="1" /> <option name="sortedColumn" value="1" />
<option name="symbolColumnWidth" value="457" /> <option name="symbolColumnWidth" value="451" />
<coverage-tree-state> <coverage-tree-state>
<expand> <expand>
<path> <path>
<item name="rootNode" type="c53c71d1:RiderDotCoverCoverageTreeModel$RootNode" /> <item name="rootNode" type="c53c71d1:RiderDotCoverCoverageTreeModel$RootNode" />
<item name="Total 61% 571/1454" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="Total 32% 1123/1657" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
</path> </path>
<path> <path>
<item name="rootNode" type="c53c71d1:RiderDotCoverCoverageTreeModel$RootNode" /> <item name="rootNode" type="c53c71d1:RiderDotCoverCoverageTreeModel$RootNode" />
<item name="Total 61% 571/1454" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="Total 32% 1123/1657" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
<item name="Core 46% 401/743" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="Core 46% 398/743" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
</path> </path>
<path> <path>
<item name="rootNode" type="c53c71d1:RiderDotCoverCoverageTreeModel$RootNode" /> <item name="rootNode" type="c53c71d1:RiderDotCoverCoverageTreeModel$RootNode" />
<item name="Total 61% 571/1454" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="Total 32% 1123/1657" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
<item name="Core 46% 401/743" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="Core 46% 398/743" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
<item name="HopFrame.Core 93% 25/367" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="HopFrame.Core 94% 22/367" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
</path> </path>
<path> <path>
<item name="rootNode" type="c53c71d1:RiderDotCoverCoverageTreeModel$RootNode" /> <item name="rootNode" type="c53c71d1:RiderDotCoverCoverageTreeModel$RootNode" />
<item name="Total 61% 571/1454" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="Total 32% 1123/1657" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
<item name="Core 46% 401/743" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="Core 46% 398/743" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
<item name="HopFrame.Core 93% 25/367" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="HopFrame.Core 94% 22/367" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
<item name="HopFrame.Core 93% 25/367" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="HopFrame.Core 94% 22/367" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
</path> </path>
<path> <path>
<item name="rootNode" type="c53c71d1:RiderDotCoverCoverageTreeModel$RootNode" /> <item name="rootNode" type="c53c71d1:RiderDotCoverCoverageTreeModel$RootNode" />
<item name="Total 61% 571/1454" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="Total 32% 1123/1657" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
<item name="Core 46% 401/743" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="Core 46% 398/743" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
<item name="HopFrame.Core 93% 25/367" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="HopFrame.Core 94% 22/367" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
<item name="HopFrame.Core 93% 25/367" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="HopFrame.Core 94% 22/367" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
<item name="Services.Implementations 96% 5/136" type="8b8fad3a:RiderDotCoverCoverageTreeNode" /> <item name="Config 93% 17/228" type="8b8fad3a:RiderDotCoverCoverageTreeNode" />
</path> </path>
</expand> </expand>
<select /> <select />
@@ -396,6 +398,9 @@
<MESSAGE value="Added documentation for the configurators and service extensions methods" /> <MESSAGE value="Added documentation for the configurators and service extensions methods" />
<MESSAGE value="Created tests for the core module" /> <MESSAGE value="Created tests for the core module" />
<MESSAGE value="Added more tests" /> <MESSAGE value="Added more tests" />
<option name="LAST_COMMIT_MESSAGE" value="Added more tests" /> <MESSAGE value="Added web module tests" />
<MESSAGE value="Tested login functionality" />
<MESSAGE value="prepared project for release" />
<option name="LAST_COMMIT_MESSAGE" value="prepared project for release" />
</component> </component>
</project> </project>

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Leon Hoppe
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

87
README.md Normal file
View File

@@ -0,0 +1,87 @@
# HopFrame
## Overview
Welcome to the **HopFrame**! This project aims to provide a comprehensive and modular framework for easy management of your database.
The framework is designed to be highly configurable, ensuring that developers either quickly add the framework for simple data editing or
configure it to their needs to implement it fully in their data management pipeline.
## Features
- **Dynamic Table Management**: Create, edit, and delete records dynamically with support for various data types including numeric, text, boolean, dates, and relational data.
- **Role-Based Access Control (RBAC)**: Implement fine-grained access control policies for viewing, creating, updating, and deleting records.
- **Modern Design**: A modern and user-friendly interface built with Fluent UI components, ensuring easy to use and pleasing administration pages.
- **Validation and Error Handling**: Comprehensive input validation and error handling to ensure data integrity and provide feedback to users.
- **Support for Complex Data Relationships**: Manage complex relationships between data entities with ease.
## Getting Started
### Configuration
Configuring HopFrame is straightforward and flexible. You can easily define your contexts, tables, and their properties using the provided configurators.
Simply use your editors intelli-sense to find out what you can configure.
```csharp
builder.Services.AddHopFrame(options => {
options.DisplayUserInfo(false);
options.AddDbContext<DatabaseContext>(context => {
context.Table<User>(table => {
table.Property(u => u.Password)
.DisplayValue(false);
table.Property(u => u.FirstName)
.List(false);
table.Property(u => u.LastName)
.List(false);
table.Property(u => u.Id)
.IsSortable(false)
.SetOrderIndex(3);
table.AddVirtualProperty("Name", (user, _) => $"{user.FirstName} {user.LastName}")
.SetOrderIndex(2);
table.SetDisplayName("Clients");
table.SetDescription("This table is used for user data store and user authentication");
table.SetViewPolicy("users.view");
table.Property(u => u.Posts)
.FormatEach<Post>((post, _) => post.Caption);
});
context.Table<Post>()
.Property(p => p.Content)
.IsTextArea(true)
.Validator(input => {
var errors = new List<string>();
if (input is null)
errors.Add("Value cannot be null");
if (input?.Length > 10)
errors.Add("Value can only be 10 characters long");
return errors;
});
context.Table<Post>()
.SetOrderIndex(-1);
});
});
```
### Usage
- Navigate to `/admin` to access the admin dashboard and start managing your tables.
- Use the side menu to switch between different tables.
- Utilize the built-in CRUD functionality to manage your data seamlessly.
## Contributing
Contributions are welcome! Feel free to open an issue or submit a pull request if you have suggestions or improvements.
## License
This project is licensed under the MIT License. See the LICENSE file for details.

View File

@@ -4,8 +4,20 @@
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<IsPackable>true</IsPackable>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageId>HopFrame.Core</PackageId>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Content Include="../../README.md">
<Pack>true</Pack>
<PackagePath>/</PackagePath>
</Content>
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
</ItemGroup> </ItemGroup>

View File

@@ -4,8 +4,19 @@
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<IsPackable>true</IsPackable>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageId>HopFrame.Web</PackageId>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Content Include="../../README.md">
<Pack>true</Pack>
<PackagePath>/</PackagePath>
</Content>
</ItemGroup>
<ItemGroup> <ItemGroup>
<SupportedPlatform Include="browser"/> <SupportedPlatform Include="browser"/>

View File

@@ -36,6 +36,9 @@ public static class ServiceCollectionExtensions {
return services; return services;
} }
/// <summary>
/// Maps the HopFrame admin ui endpoints
/// </summary>
public static RazorComponentsEndpointConventionBuilder MapHopFramePages(this RazorComponentsEndpointConventionBuilder builder) { public static RazorComponentsEndpointConventionBuilder MapHopFramePages(this RazorComponentsEndpointConventionBuilder builder) {
builder builder
.AddInteractiveServerRenderMode() .AddInteractiveServerRenderMode()

View File

@@ -4,6 +4,8 @@
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@@ -23,7 +23,7 @@ builder.Services.AddHopFrame(options => {
options.AddDbContext<DatabaseContext>(context => { options.AddDbContext<DatabaseContext>(context => {
context.Table<User>(table => { context.Table<User>(table => {
table.Property(u => u.Password) table.Property(u => u.Password)
.SetParser((pwd, _) => pwd + "-edited"); .DisplayValue(false);
table.Property(u => u.FirstName) table.Property(u => u.FirstName)
.List(false); .List(false);