Finished documentation

This commit is contained in:
2025-02-13 18:10:43 +01:00
parent 08d4ddb2c6
commit 93d41ad6d3
14 changed files with 520 additions and 19 deletions

View File

@@ -8,6 +8,7 @@
<toc-element topic="starter.md"/>
<toc-element topic="Installation.md"/>
<toc-element topic="Authentication.md"/>
<toc-element toc-title="Core Module">
<toc-element toc-title="Configurations">
<toc-element topic="HopFrameConfig.md"/>
@@ -19,20 +20,12 @@
</toc-element>
<toc-element toc-title="Web Module">
<toc-element toc-title="Interface">
<toc-element topic="Custom-Views.md"/>
<toc-element topic="Table.md"/>
<toc-element topic="Dashboard.md"/>
</toc-element>
<toc-element topic="Plugins.md">
<toc-element topic="Events.md">
<toc-element topic="SelectEntityEvent.md"/>
<toc-element topic="UpdateEntityEvent.md"/>
<toc-element topic="CreateEntityEvent.md"/>
<toc-element topic="DeleteEntityEvent.md"/>
<toc-element topic="TableInitializedEvent.md"/>
<toc-element topic="PageChangeEvent.md"/>
<toc-element topic="ReloadEvent.md"/>
<toc-element topic="SearchEvent.md"/>
<toc-element topic="ValidationEvent.md"/>
</toc-element>
</toc-element>
</toc-element>

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rules SYSTEM "https://resources.jetbrains.com/writerside/1.0/redirection-rules.dtd">
<rules>
<!-- format is as follows
<rule id="<unique id>">
<accepts>page.html</accepts>
</rule>
-->
<rule id="50095ff3">
<description>Created after removal of "SelectEntityEvent" from HopFrame</description>
<accepts>SelectEntityEvent.html</accepts>
</rule>
<rule id="7d9a1af8">
<description>Created after removal of "UpdateEntityEvent" from HopFrame</description>
<accepts>UpdateEntityEvent.html</accepts>
</rule>
<rule id="701228d0">
<description>Created after removal of "CreateEntityEvent" from HopFrame</description>
<accepts>CreateEntityEvent.html</accepts>
</rule>
<rule id="4b4c2b45">
<description>Created after removal of "DeleteEntityEvent" from HopFrame</description>
<accepts>DeleteEntityEvent.html</accepts>
</rule>
<rule id="39604ad3">
<description>Created after removal of "TableInitializedEvent" from HopFrame</description>
<accepts>TableInitializedEvent.html</accepts>
</rule>
<rule id="2d6b7079">
<description>Created after removal of "PageChangeEvent" from HopFrame</description>
<accepts>PageChangeEvent.html</accepts>
</rule>
<rule id="6933278d">
<description>Created after removal of "ReloadEvent" from HopFrame</description>
<accepts>ReloadEvent.html</accepts>
</rule>
<rule id="2043e755">
<description>Created after removal of "SearchEvent" from HopFrame</description>
<accepts>SearchEvent.html</accepts>
</rule>
<rule id="2dee3925">
<description>Created after removal of "ValidationEvent" from HopFrame</description>
<accepts>ValidationEvent.html</accepts>
</rule>
</rules>

View File

@@ -0,0 +1,35 @@
# Authentication
The HopFrame is a powerful tool to manage your backend data. So you probably don't want anybody to access the pages.
Luckily the HopFrame supports policy based authentication. By default, everybody is allowed to access the whole
HopFrame, but you can restrict that by registering a scoped service implementing the `IHopFrameAuthHandler`.
If no service is registered, the default handler gets registered, but it lets any traffic pass.
## Example
Create a service that handles authentication:
```C#
public class AuthService(IAuthStore store) : IHopFrameAuthHandler {
public async Task<bool> IsAuthenticatedAsync(string? policy) {
var currentUser = await store.GetCurrentUser();
return await store.IsPermitted(currentUser, policy);
}
public async Task<string> GetCurrentUserDisplayNameAsync() {
var currentUser = await store.GetCurrentUser();
return currentUser.FullName;
}
}
```
Now register it in the DI container:
```C#
builder.Services.AddScoped<IHopFrameAuthHandler, AuthService>();
```
**Hint:** You can display the current users name in the ui by enabling the feature in
the [HopFrameConfig](HopFrameConfig.md#displayuserinfo).

View File

@@ -0,0 +1,101 @@
# Custom Views
You can also add your own pages to the HopFrame UI by defining the routes as custom views.
You can do that by using the following extension methods for the [](HopFrameConfig.md):
## Configuration methods
### AddCustomView (With configurator delegate)
Creates an entry to the side menu and dashboard with a custom URL.
```c#
HopFrameConfigurator AddCustomView(string name, string url, Action<CustomViewConfigurator> configuratorDelegate)
```
- **Parameters:**
- `configurator`: The configurator for the HopFrame config that is being created.
- `name`: The name of the navigation entry.
- `url`: The target URL of the navigation entry.
- `configuratorDelegate`: The delegate for configuring the view.
- **Returns:** `HopFrameConfigurator`
### AddCustomView (Without configurator delegate)
Creates an entry to the side menu and dashboard with a custom URL.
```c#
CustomViewConfigurator AddCustomView(string name, string url)
```
- **Parameters:**
- `configurator`: The configurator for the HopFrame config that is being created.
- `name`: The name of the navigation entry.
- `url`: The target URL of the navigation entry.
- **Returns:** `CustomViewConfigurator`
## CustomViewConfigurator
### SetDescription
Sets the description displayed in the dashboard.
```c#
CustomViewConfigurator SetDescription(string description)
```
- **Parameters:**
- `description`: The desired description.
- **Returns:** `CustomViewConfigurator`
### SetPolicy
Sets the policy needed in order to access the view.
```c#
CustomViewConfigurator SetPolicy(string policy)
```
- **Parameters:**
- `policy`: The desired policy.
- **Returns:** `CustomViewConfigurator`
### SetIcon
Sets the icon displayed in the sidebar.
```c#
CustomViewConfigurator SetIcon(string icon)
```
- **Parameters:**
- `icon`: The desired [fluent-icon](https://www.fluentui-blazor.net/Icon#explorer).
- **Returns:** `CustomViewConfigurator`
### SetLinkMatch
Sets the rule for the sidebar to determine if the link is active.
```c#
CustomViewConfigurator SetLinkMatch(NavLinkMatch match)
```
- **Parameters:**
- `match`: The desired match rule.
- **Returns:** `CustomViewConfigurator`
## Example
```C#
builder.Services.AddHopFrame(options => {
options.AddCustomView("Counter", "/counter")
.SetDescription("A custom view")
.SetPolicy("counter.view");
});
```

View File

@@ -1,3 +1,9 @@
# Dashboard
Start typing here...
The dashboard gives you an overview of all pages accessible through the HopFrame interface.
An example configuration could lead to something like this:
![dashboard.png](dashboard.png)
You could use the sidebar or the `Open` button to open any page that you have access to.

View File

@@ -1,3 +1,214 @@
# Events
Start typing here...
## Base event
Every event inherits from the base event, so these properties and methods are always available
```C#
public abstract class HopFrameEventArgs {
public TSender Sender { get; }
public bool IsCanceled { get; }
public TableConfig Table { get; }
public void SetCancelled(bool canceled);
}
```
### Properties
- **Sender**: The sender of the event.
- **Type:** `TSender`
- **IsCanceled**: Indicates whether the event is canceled.
- **Type:** `bool`
- **Table**: The table configuration related to the event.
- **Type:** `TableConfig`
### Methods
- **SetCancelled**
- **Parameters:**
- `canceled`: A boolean value to set the cancellation state.
- **Returns:** `void`
## DeleteEntryEvent
Event arguments for a delete entry event.
```C#
public sealed class DeleteEntryEvent : HopFrameEventArgs {
public object Entity { get; }
}
```
### Properties
- **Entity**: The entity being deleted.
- **Type:** `object`
## CreateEntryEvent
Event arguments for a create entry event.
```C#
public sealed class CreateEntryEvent : HopFrameEventArgs {
}
```
## UpdateEntryEvent
Event arguments for an update entry event.
```C#
public sealed class UpdateEntryEvent : HopFrameEventArgs {
public object Entity { get; }
}
```
### Properties
- **Entity**: The entity being updated.
- **Type:** `object`
## SelectEntryEvent
Event arguments for a select entry event.
```C#
public sealed class SelectEntryEvent : HopFrameEventArgs {
public object Entity { get; }
public bool Selected { get; set; }
}
```
### Properties
- **Entity**: The entity being selected.
- **Type:** `object`
- **Selected**: Indicates whether the entity is selected.
- **Type:** `bool`
## PageChangeEvent
Event arguments for a page change event.
```C#
public sealed class PageChangeEvent : HopFrameEventArgs {
public int CurrentPage { get; }
public int TotalPages { get; }
public int NewPage { get; set; }
}
```
### Properties
- **CurrentPage**: The current page number.
- **Type:** `int`
- **TotalPages**: The total number of pages.
- **Type:** `int`
- **NewPage**: The new page number to navigate to.
- **Type:** `int`
## ReloadEvent
Event arguments for a reload event.
```C#
public sealed class ReloadEvent : HopFrameEventArgs {
}
```
## SearchEvent
Event arguments for a search event.
```C#
public sealed class SearchEvent : HopFrameEventArgs {
public string SearchTerm { get; set; }
public int CurrentPage { get; }
public void SetSearchResult(IEnumerable result, int totalPages);
}
```
### Properties
- **SearchTerm**: The search term used.
- **Type:** `string`
- **CurrentPage**: The current page number.
- **Type:** `int`
- **SearchResult**: The search results.
- **Type:** `IEnumerable<object>?`
- **TotalPages**: The total number of pages of search results.
- **Type:** `int`
### Methods
- **SetSearchResult**
- **Parameters:**
- `result`: The current page of search results.
- `totalPages`: The total pages of search results.
- **Returns:** `void`
## TableInitializedEvent
Event arguments for a table initialization event.
```C#
public class TableInitializedEvent : HopFrameEventArgs {
public List<PluginButton> PluginButtons { get; };
public DefaultButtonToggles DefaultButtons { get; set; };
public void AddPageButton(string title, Func<Task> callback, bool pushRight = false, IconInfo? icon = null);
public void AddPageButton(string title, Action callback, bool pushRight = false, IconInfo? icon = null);
public void AddPageButton<TEntity>(string title, Func<Task> callback, bool pushRight = false, IconInfo? icon = null);
public void AddPageButton<TEntity>(string title, Action callback, bool pushRight = false, IconInfo? icon = null);
public void AddEntityButton(IconInfo icon, Func<object, TableConfig, Task> callback);
public void AddEntityButton(IconInfo icon, Action<object, TableConfig> callback);
public void AddEntityButton<TEntity>(IconInfo icon, Func<TEntity, TableConfig, Task> callback);
public void AddEntityButton<TEntity>(IconInfo icon, Action<TEntity, TableConfig> callback);
}
```
### Properties
- **PluginButtons**: The list of plugin buttons for the table.
- **Type:** `List<PluginButton>`
- **DefaultButtons**: The default button toggles for the table.
- **Type:** `DefaultButtonToggles`
### Methods
- **AddPageButton**
- **Parameters:**
- `title`: The title of the button.
- `callback`: The callback function for the button.
- `pushRight`: Indicates whether to push the button to the right. (default: `false`)
- `icon`: The icon for the button. (default: `null`)
- **Returns:** `void`
- **AddEntityButton**
- **Parameters:**
- `icon`: The icon for the button.
- `callback`: The callback function for the button.
- **Returns:** `void`
## ValidationEvent
Event arguments for a validation event.
```C#
public sealed class ValidationEvent : HopFrameEventArgs {
public IList<string> Errors { get; }
public PropertyConfig Property { get; }
}
```
### Properties
- **Errors**: The list of validation errors.
- **Type:** `IList<string>`
- **Property**: The property being validated.
- **Type:** `PropertyConfig`

View File

@@ -1,3 +1,62 @@
# Plugins
Start typing here...
If the default functionality of the HopFrame does not fit your needs, you can easily extend the pages
by using Plugins. They are registered as scoped services so you can use DI like everywhere else.
## Add a plugin
Create a class that extends the `HopFramePlugin` class:
```C#
public class SearchExtension : HopFramePlugin {
}
```
Then add the plugin to the HopFrame by using the extension method on the [](HopFrameConfig.md):
```C#
builder.Services.AddHopFrame(options => {
options.AddPlugin<SearchExtension>();
});
```
## Configuring the plugin
If you want to change the HopFrame configuration from within your plugin, you can create a static method
and decorate it with the `PluginConfigurator` attribute. Here you can inject the `HopFrameConfigurator`
as an argument and change the configuration. Keep in mind, that this function automatically gets called
when you register your plugin, so any changes after that override the changes made in the plugin.
### Example
```C#
[PluginConfigurator]
public static void Configure(HopFrameConfigurator configurator) {
configurator.AddCustomView("Counter", "/counter")
.SetDescription("A custom view")
.SetPolicy("counter.view");
}
```
## Events
The HopFrame provides various [events](Events.md) that can change how the corresponding action behaves. You can register
event handlers similar to the [configurator method](#configuring-the-plugin). Create a method, that is **not** static
and decorate it with the `EventHandler` attribute. This method can return either `void` or a `Task`. Then declare the
Event type as an argument and the function gets automatically registered as an event handler for the corresponding event.
### Examples
```C#
[EventHandler]
public async Task OnSearch(SearchEvent e) {
var result = await searchHandler.Search(e.Table, e.SearchTerm);
e.SetSearchResult(result.Items, result.TotalPages);
}
[EventHandler]
public void OnDelete(DeleteEntryEvent e) {
cacheHandler.ClearCache(e.Entity);
}
```

View File

@@ -1,3 +1,41 @@
# Table
Start typing here...
On the table page you can view, edit, delete and create entries in that table.
You can use the many configuration methods provided by the [](TableConfig.md) to modify the look
of this page.
An example configuration could look something like this:
![table.png](table.png)
Here you can use the various buttons to interact with your entities.
## Data grid
The main aspect of this site is the data grid that displays all your entries of that table.
For performance reasons this data is paginated, you can **change the page** at the bottom of the screen
using either the arrow button or the page selector. You can **sort** your entries by clicking on
the name of the column. If you don't want a column to be sortable, you can configure this in the
[PropertyConfig](PropertyConfig.md#issortable).
## Search
The search bar will search through all entities in your database, not only the ones displayed.
Simply enter a search term and the search is performed automatically. You can configure the
columns that should be searchable in the [PropertyConfig](PropertyConfig.md#issearchable)
## Edit dialog
If you click on the pen button next to one of the entries, the edit dialog will appear,
it could look something like this:
![editor.png](editor.png)
You can modify the data of the selected entity based on your [PropertyConfigs](PropertyConfig.md).
The HopFrame can handle various property types like strings, numbers, enums, relations and many more.
### Validation
The HopFrame also supports input validation. By default, a required validation is automatically applied
to every property that's not nullable. You can change the validation behavior in the
[PropertyConfig](PropertyConfig.md#setvalidator-synchronous).