Komponenty CloudFlow
CloudFlow dostarcza zestaw komponentów UI opartych na Radzen Blazor, rozszerzonych o automatyczną walidację, lokalizację i integrację z systemem.
CFComponentBase
Klasa bazowa dla wszystkich komponentów CloudFlow. Zapewnia wstrzyknięcie serwisów i wspólne parametry.
Wstrzyknięte serwisy
| Serwis | Typ | Opis |
|---|---|---|
NavigationManager | NavigationManager | Nawigacja między stronami |
DialogService | DialogService | Dialogi i modalne okna Radzen |
NotificationService | NotificationService | Powiadomienia toast |
DatabaseService | DatabaseRequestorService | Operacje bazodanowe (CRUD) |
ClassLocalizer | ClassLocalizer<T> | Lokalizacja pól modelu |
SecurityService | SecurityService | Autoryzacja i uprawnienia |
TabsService | TabsService | Zarządzanie zakładkami |
LocalStorage | ILocalStorageService | Blazored Local Storage |
Logger | ILogger<T> | Logowanie |
JSRuntime | IJSRuntime | Interop JavaScript |
ContextMenuService | ContextMenuService | Menu kontekstowe |
TooltipService | TooltipService | Tooltips |
VariablesService | VariablesService | Zmienne globalne |
Parametry bazowe
| Parametr | Typ | Opis |
|---|---|---|
Record | T? | Aktualny rekord |
RecId | Guid | ID rekordu |
TabItem | TabItem? | Informacje o zakładce |
ParentObject | CFEntity? | Obiekt nadrzędny (dla relacji) |
ParentObjectId | Guid? | ID obiektu nadrzędnego |
IsBusy | bool | Wskaźnik zajętości |
Użycie
@inherits CFComponentBase<Product>
@code {
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
// Dostęp do serwisów
var products = await DatabaseService.GetAsync<Product>();
// Logowanie
Logger.LogInformation("Załadowano {Count} produktów", products.Count());
// Nawigacja
NavigationManager.NavigateTo("/products");
// Powiadomienia
NotificationService.Notify(NotificationSeverity.Success, "Sukces", "Operacja zakończona");
}
}
CFForm
Główny komponent formularza obsługujący walidację, zapis i anulowanie.
Parametry
| Parametr | Typ | Opis |
|---|---|---|
TItem | Type | Typ encji (dziedziczy po CFEntity) |
Record | TItem? | Rekord do edycji |
Expand | string | Relacje do załadowania |
Select | string | Pola do pobrania |
Filter | string | Filtr OData |
IsModal | bool | Czy formularz w modalu |
EnableAIFill | bool | Włącz AI fill |
AIFillFields | IEnumerable<string>? | Pola do wypełnienia przez AI |
Callbacki
| Callback | Typ | Kiedy wywoływany |
|---|---|---|
OnSubmit | EventCallback | Po wysłaniu formularza |
OnCancel | EventCallback<MouseEventArgs> | Po anulowaniu |
OnLoad | EventCallback<TItem> | Po załadowaniu rekordu |
OnAfterCreate | EventCallback<TItem> | Po utworzeniu nowego |
OnAfterUpdate | EventCallback<TItem> | Po aktualizacji |
Przykład
<CFForm TItem="Product"
Record="@Record"
Expand="Category,Variants"
EnableAIFill="true"
OnAfterCreate="HandleCreated">
<RadzenStack>
<RadzenRow>
<CFTextBox SizeMD="6" @bind-Value="@context.Name" Required="true" />
</RadzenRow>
</RadzenStack>
</CFForm>
@code {
private async Task HandleCreated(Product product)
{
NotificationService.Notify(NotificationSeverity.Success,
"Sukces", $"Utworzono produkt: {product.Name}");
}
}
CFDataGrid
Komponent gridu z automatycznym ładowaniem danych, paginacją, sortowaniem i filtrowaniem.
Parametry
| Parametr | Typ | Opis |
|---|---|---|
TItem | Type | Typ encji |
TForm | Type | Typ formularza |
Expand | string | Relacje do załadowania |
Select | string | Pola do pobrania |
Filter | string | Domyślny filtr OData |
OrderBy | string | Domyślne sortowanie |
AllowAdd | bool | Przycisk dodawania |
ConfirmDelete | bool | Potwierdzenie usunięcia |
UseTabs | bool | Otwórz w zakładce |
CreateInModal | bool | Twórz w modalu |
DialogOptions | DialogOptions? | Opcje dialogu |
FormParameters | Dictionary<string, object>? | Parametry formularza |
Przykład
<CFDataGrid TItem="Product"
TForm="ProductForm"
Expand="Category"
OrderBy="Name asc"
AllowAdd="true">
<ChildContent>
<RadzenDataGridColumn TItem="Product" Property="Name" Title="Nazwa" />
<RadzenDataGridColumn TItem="Product" Property="Price" Title="Cena" FormatString="{0:C2}" />
</ChildContent>
</CFDataGrid>
CFDataGridEmbedded
Grid osadzony w formularzu dla edycji kolekcji podrzędnych (np. pozycje faktury).
Parametry
| Parametr | Typ | Opis |
|---|---|---|
TItem | Type | Typ encji podrzędnej |
TForm | Type | Typ formularza (lub DummyForm) |
Data | ICollection<TItem> | Kolekcja danych |
ParentObject | CFEntity? | Obiekt nadrzędny |
Przykład
<CFDataGridEmbedded TItem="OrderItem"
TForm="DummyForm"
@bind-Data="context.Items"
ParentObject="context">
<ChildContent Context="items">
<RadzenDataGridColumn TItem="OrderItem" Property="ProductName" Title="Produkt">
<EditTemplate Context="row">
<RadzenTextBox @bind-Value="@row.ProductName" class="rz-w-100" />
</EditTemplate>
</RadzenDataGridColumn>
<RadzenDataGridColumn TItem="OrderItem" Property="Quantity" Title="Ilość">
<EditTemplate Context="row">
<RadzenNumeric @bind-Value="@row.Quantity" class="rz-w-100" />
</EditTemplate>
</RadzenDataGridColumn>
</ChildContent>
</CFDataGridEmbedded>
Komponenty pól formularza
CFTextBox
Pole tekstowe z walidacją.
<CFTextBox SizeMD="6"
@bind-Value="@context.Name"
Required="true"
LabelText="Nazwa"
Placeholder="Wpisz nazwę..."
MaxLength="255" />
CFTextArea
Pole wieloliniowe.
<CFTextArea SizeMD="12"
@bind-Value="@context.Description"
LabelText="Opis"
Rows="5"
Placeholder="Wprowadź opis..." />
CFNumeric
Pole numeryczne.
<CFNumeric SizeMD="4"
@bind-Value="@context.Price"
LabelText="Cena"
Format="C2"
Min="0"
Max="999999.99"
Step="0.01" />
CFDatePicker
Wybór daty.
<CFDatePicker SizeMD="4"
@bind-Value="@context.StartDate"
Required="true"
LabelText="Data rozpoczęcia"
DateFormat="dd.MM.yyyy" />
CFDropDown
Lista rozwijana dla enumów lub prostych list.
<CFDropDown SizeMD="4"
TValue="ProductStatus"
Data="@(Tools.GenerateDropdownList<ProductStatus>())"
@bind-Value="@context.Status"
TextProperty="Text"
ValueProperty="Value"
LabelText="Status"
Placeholder="Wybierz status..." />
CFDropDownDataGrid
Lista rozwijana z gridem dla wyboru rekordu z relacji.
<CFDropDownDataGrid SizeMD="6"
TValue="Guid?"
@bind-Value="@context.CategoryId"
LabelText="Kategoria"
Placeholder="Wybierz kategorię..." />
CFCheckbox
Pole wyboru.
<CFCheckbox @bind-Value="@context.IsActive"
LabelText="Aktywny" />
CFMask
Pole z maską wprowadzania.
<CFMask SizeMD="4"
@bind-Value="@context.NIP"
LabelText="NIP"
Mask="***-***-**-**"
CharacterPattern="[0-9]"
Placeholder="000-000-00-00" />
CFRadioButton
Przyciski radio.
<CFRadioButton TValue="PaymentMethod"
@bind-Value="@context.PaymentMethod"
Data="@paymentMethods"
TextProperty="Name"
ValueProperty="Value"
Orientation="Orientation.Horizontal" />
Wspólne parametry komponentów
| Parametr | Typ | Opis |
|---|---|---|
@bind-Value | TValue | Wiązanie wartości (two-way binding) |
LabelText | string | Etykieta pola |
Required | bool | Pole wymagane |
Disabled | bool | Pole wyłączone |
Placeholder | string | Tekst placeholder |
Size | int | Szerokość (1-12) dla wszystkich |
SizeMD | int | Szerokość dla medium screens |
SizeLG | int | Szerokość dla large screens |
Narzędzia pomocnicze
Tools.GenerateDropdownList
Generuje listę dla dropdowna z enuma:
var statusList = Tools.GenerateDropdownList<ProductStatus>();
// Zwraca IEnumerable<{ Text, Value }> z Display names
ClassLocalizer
Automatyczne tłumaczenie nazw pól:
<CFTextBox LabelText="@ClassLocalizer["Name"]" />
@* Pobiera "Nazwa produktu" z Product.pl-PL.resx *@
GetDisplayName()
Rozszerzenie dla enumów:
var displayName = product.Status.GetDisplayName();
// Zwraca "Aktywny" zamiast "Active"
Troubleshooting
Problem: Formularz nie ładuje rekordu
Rozwiązanie:
- Sprawdź czy
Expandzawiera wszystkie potrzebne relacje - Sprawdź konsolę przeglądarki na błędy HTTP
- Upewnij się że
RecIdlubRecordjest przekazany
Problem: Kolumna nie wyświetla danych relacji
Rozwiązanie:
- Dodaj relację do
Expand:Expand="Category" - Sprawdź czy FK jest prawidłowo skonfigurowany
Problem: Tłumaczenia nie działają
Rozwiązanie:
- Sprawdź czy plik
.pl-PL.resxistnieje - Upewnij się że klucz odpowiada nazwie właściwości
- Przebuduj projekt (
dotnet build)
Problem: Walidacja nie działa
Rozwiązanie:
- Sprawdź czy pole ma atrybut
[Required]w modelu - Upewnij się że używasz
Required="true"w komponencie - Sprawdź czy formularz jest wewnątrz
CFForm