Browse Source

Fix MudBlazor docs to match real ABP module usage

- book-store/part-02: switch the Books page from AbpMudExtensibleDataGrid to
  the standard MudBlazor MudDataGrid + <PropertyColumn> pattern (matches
  Identity.Pro SecurityLogManagement); use RowsPerPage instead of PageSize
- book-store/part-03: replace the abp-internal MudDataGridEntityActionsColumn /
  MudEntityActions / MudEntityAction wrappers with the standard MudBlazor
  TemplateColumn + MudMenu + MudMenuItem so the tutorial stays approachable;
  drop a misleading link to the legacy abp-samples/MudBlazorSample demo;
  add a note that MudDatePicker.@bind-Date requires DateTime?
- book-store/part-09: wrap MudDialog.ShowAsync/CloseAsync calls with
  InvokeAsync (matches Identity.Pro OrganizationUnitsManagement) and harden
  OnDataGridReadAsync against null SortBy entries
pull/25380/head
maliming 6 months ago
parent
commit
1291e8f5eb
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 10
      docs/en/tutorials/book-store/part-02.md
  2. 59
      docs/en/tutorials/book-store/part-03.md
  3. 17
      docs/en/tutorials/book-store/part-09.md

10
docs/en/tutorials/book-store/part-02.md

@ -651,9 +651,9 @@ Open the `Books.razor` and replace the content as the following:
</CardHeaderContent> </CardHeaderContent>
</MudCardHeader> </MudCardHeader>
<MudCardContent> <MudCardContent>
<AbpMudExtensibleDataGrid T="BookDto" <MudDataGrid T="BookDto"
ServerData="OnDataGridReadAsync" ServerData="OnDataGridReadAsync"
RowsPerPage="@PageSize"> RowsPerPage="@PageSize">
<Columns> <Columns>
<PropertyColumn Property="x => x.Name" <PropertyColumn Property="x => x.Name"
Title="@L["Name"]" /> Title="@L["Name"]" />
@ -678,7 +678,7 @@ Open the `Books.razor` and replace the content as the following:
</CellTemplate> </CellTemplate>
</PropertyColumn> </PropertyColumn>
</Columns> </Columns>
</AbpMudExtensibleDataGrid> </MudDataGrid>
</MudCardContent> </MudCardContent>
</MudCard> </MudCard>
@ -696,7 +696,7 @@ Open the `Books.razor` and replace the content as the following:
* Inherited from `AbpMudCrudPageBase<IBookAppService, BookDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateBookDto>` which implements all the CRUD details for us. * Inherited from `AbpMudCrudPageBase<IBookAppService, BookDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateBookDto>` which implements all the CRUD details for us.
* `Entities`, `TotalCount`, `PageSize`, `OnDataGridReadAsync` are defined in the base class. * `Entities`, `TotalCount`, `PageSize`, `OnDataGridReadAsync` are defined in the base class.
* `LocalizationResource` is set to the `BookStoreResource` to localize the texts. * `LocalizationResource` is set to the `BookStoreResource` to localize the texts.
* `AbpMudExtensibleDataGrid` is the ABP-extended `MudDataGrid` that supports the [data table column extension system](../../framework/ui/blazor/data-table-column-extensions.md). * This page uses the standard MudBlazor `MudDataGrid` with `<PropertyColumn>` definitions. ABP also ships an `AbpMudExtensibleDataGrid` that integrates with the [data table column extension system](../../framework/ui/blazor/data-table-column-extensions.md) when you need to extend module pages.
While the code above is pretty easy to understand, you can check the MudBlazor [Card](https://mudblazor.com/components/card) and [DataGrid](https://mudblazor.com/components/datagrid) documents to understand them better. While the code above is pretty easy to understand, you can check the MudBlazor [Card](https://mudblazor.com/components/card) and [DataGrid](https://mudblazor.com/components/datagrid) documents to understand them better.

59
docs/en/tutorials/book-store/part-03.md

@ -1253,7 +1253,7 @@ Open the `Books.razor` and add the following code to the end of the page:
* The form uses `[Required]`/DataAnnotations for validation; messages are localized via the same `AbpResource` localization system. * The form uses `[Required]`/DataAnnotations for validation; messages are localized via the same `AbpResource` localization system.
* The `_createDialog` field, `CloseCreateDialogAsync`, `CreateFormRef` and `CreateEntityAsync` are all defined in `AbpMudCrudPageBase`. Check the [MudBlazor documentation](https://mudblazor.com/components/dialog) if you want to understand the `MudDialog` and other components. * The `_createDialog` field, `CloseCreateDialogAsync`, `CreateFormRef` and `CreateEntityAsync` are all defined in `AbpMudCrudPageBase`. Check the [MudBlazor documentation](https://mudblazor.com/components/dialog) if you want to understand the `MudDialog` and other components.
* `MudDatePicker.@bind-Date` requires a nullable `DateTime?`. If your DTO uses non-nullable `DateTime`, change it to `DateTime?` (`public DateTime? PublishDate { get; set; }`) when using the MudBlazor variant — see [abp-samples/MudBlazorSample](https://github.com/abpframework/abp-samples/tree/master/MudBlazorSample) for a complete reference. * `MudDatePicker.@bind-Date` requires a nullable `DateTime?`. If your DTO uses non-nullable `DateTime`, change it to `DateTime?` (`public DateTime? PublishDate { get; set; }`) when using the MudBlazor variant.
{{end}} {{end}}
@ -1291,23 +1291,23 @@ The `DataGridEntityActionsColumn` component is used to show an "Actions" dropdow
{{if BlazorUI == "MudBlazor"}} {{if BlazorUI == "MudBlazor"}}
Open the `Books.razor` and add the following `MudDataGridEntityActionsColumn` as the first column inside the `<Columns>` section of the `AbpMudExtensibleDataGrid`: Open the `Books.razor` and add the following `TemplateColumn` as the first column inside the `<Columns>` section of the `MudDataGrid`:
````razor ````razor
<MudDataGridEntityActionsColumn T="BookDto" @ref="@EntityActionsColumn"> <TemplateColumn T="BookDto" Title="@L["Actions"]" Sortable="false">
<CellTemplate> <CellTemplate>
<MudEntityActions T="BookDto" Context="entityContext"> <MudMenu Icon="@Icons.Material.Filled.MoreVert" Dense="true">
<MudEntityAction T="BookDto" <MudMenuItem OnClick="@(() => OpenEditDialogAsync(context.Item))">
Text="@L["Edit"]" @L["Edit"]
Clicked="() => OpenEditDialogAsync(entityContext)" /> </MudMenuItem>
</MudEntityActions> </MudMenu>
</CellTemplate> </CellTemplate>
</MudDataGridEntityActionsColumn> </TemplateColumn>
```` ````
* `OpenEditDialogAsync` is defined in the base class which takes the entity (book) to edit. * `OpenEditDialogAsync` is defined in the base class which takes the entity (book) to edit.
The `MudDataGridEntityActionsColumn` component is used to show an "Actions" menu for each row in the data grid. It shows a **single icon button** when there is only one available action and a dropdown menu when there are multiple actions. This renders an "Actions" dropdown menu (`MudMenu`) for each row in the data grid. We will add the **Delete** menu item later in the *Deleting a Book* section.
{{end}} {{end}}
@ -1463,13 +1463,17 @@ Add the following `EntityAction` code under the "Edit" action inside `EntityActi
{{if BlazorUI == "MudBlazor"}} {{if BlazorUI == "MudBlazor"}}
Add the following `MudEntityAction` code under the "Edit" action inside `MudEntityActions`: Add the following `MudMenuItem` after the "Edit" item inside the actions `MudMenu`:
````razor ````razor
<MudEntityAction T="BookDto" <MudMenuItem OnClick="@(async () => {
Text="@L["Delete"]" if (await Message.Confirm(GetDeleteConfirmationMessage(context.Item)))
Clicked="() => DeleteEntityAsync(entityContext)" {
ConfirmationMessage="() => GetDeleteConfirmationMessage(entityContext)" /> await DeleteEntityAsync(context.Item);
}
})">
@L["Delete"]
</MudMenuItem>
```` ````
{{end}} {{end}}
@ -1706,23 +1710,18 @@ Here's the complete code to create the book management CRUD page, that has been
</CardHeaderActions> </CardHeaderActions>
</MudCardHeader> </MudCardHeader>
<MudCardContent> <MudCardContent>
<AbpMudExtensibleDataGrid T="BookDto" <MudDataGrid T="BookDto"
ServerData="OnDataGridReadAsync" ServerData="OnDataGridReadAsync"
RowsPerPage="@PageSize"> RowsPerPage="@PageSize">
<Columns> <Columns>
<MudDataGridEntityActionsColumn T="BookDto" @ref="@EntityActionsColumn"> <TemplateColumn T="BookDto" Title="@L["Actions"]" Sortable="false">
<CellTemplate> <CellTemplate>
<MudEntityActions T="BookDto" Context="entityContext"> <MudMenu Icon="@Icons.Material.Filled.MoreVert" Dense="true">
<MudEntityAction T="BookDto" <MudMenuItem OnClick="@(() => OpenEditDialogAsync(context.Item))">@L["Edit"]</MudMenuItem>
Text="@L["Edit"]" <MudMenuItem OnClick="@(async () => { if (await Message.Confirm(GetDeleteConfirmationMessage(context.Item))) { await DeleteEntityAsync(context.Item); } })">@L["Delete"]</MudMenuItem>
Clicked="() => OpenEditDialogAsync(entityContext)" /> </MudMenu>
<MudEntityAction T="BookDto"
Text="@L["Delete"]"
Clicked="() => DeleteEntityAsync(entityContext)"
ConfirmationMessage="() => GetDeleteConfirmationMessage(entityContext)" />
</MudEntityActions>
</CellTemplate> </CellTemplate>
</MudDataGridEntityActionsColumn> </TemplateColumn>
<PropertyColumn Property="x => x.Name" Title="@L["Name"]" /> <PropertyColumn Property="x => x.Name" Title="@L["Name"]" />
<PropertyColumn Property="x => x.Type" Title="@L["Type"]"> <PropertyColumn Property="x => x.Type" Title="@L["Type"]">
<CellTemplate> <CellTemplate>
@ -1741,7 +1740,7 @@ Here's the complete code to create the book management CRUD page, that has been
</CellTemplate> </CellTemplate>
</PropertyColumn> </PropertyColumn>
</Columns> </Columns>
</AbpMudExtensibleDataGrid> </MudDataGrid>
</MudCardContent> </MudCardContent>
</MudCard> </MudCard>

17
docs/en/tutorials/book-store/part-09.md

@ -1413,8 +1413,9 @@ public partial class Authors
private async Task<GridData<AuthorDto>> OnDataGridReadAsync(GridState<AuthorDto> state) private async Task<GridData<AuthorDto>> OnDataGridReadAsync(GridState<AuthorDto> state)
{ {
CurrentSorting = state.SortDefinitions CurrentSorting = state.SortDefinitions
.Select(s => s.SortBy + (s.Descending ? " DESC" : "")) .Where(s => !string.IsNullOrWhiteSpace(s.SortBy?.ToString()))
.Aggregate("", (a, b) => string.IsNullOrEmpty(a) ? b : a + "," + b); .Select(s => $"{s.SortBy}{(s.Descending ? " DESC" : "")}")
.JoinAsString(",");
CurrentPage = state.Page; CurrentPage = state.Page;
await GetAuthorsAsync(); await GetAuthorsAsync();
@ -1426,12 +1427,12 @@ public partial class Authors
{ {
NewAuthor = new CreateAuthorDto(); NewAuthor = new CreateAuthorDto();
if (CreateFormRef != null) await CreateFormRef.ResetAsync(); if (CreateFormRef != null) await CreateFormRef.ResetAsync();
await CreateAuthorDialog.ShowAsync(); await InvokeAsync(() => CreateAuthorDialog.ShowAsync());
} }
private Task CloseCreateAuthorDialogAsync() private Task CloseCreateAuthorDialogAsync()
{ {
return CreateAuthorDialog.CloseAsync(); return InvokeAsync(() => CreateAuthorDialog.CloseAsync());
} }
private async Task OpenEditAuthorDialogAsync(AuthorDto author) private async Task OpenEditAuthorDialogAsync(AuthorDto author)
@ -1439,12 +1440,12 @@ public partial class Authors
EditingAuthorId = author.Id; EditingAuthorId = author.Id;
EditingAuthor = ObjectMapper.Map<AuthorDto, UpdateAuthorDto>(author); EditingAuthor = ObjectMapper.Map<AuthorDto, UpdateAuthorDto>(author);
if (EditFormRef != null) await EditFormRef.ResetAsync(); if (EditFormRef != null) await EditFormRef.ResetAsync();
await EditAuthorDialog.ShowAsync(); await InvokeAsync(() => EditAuthorDialog.ShowAsync());
} }
private Task CloseEditAuthorDialogAsync() private Task CloseEditAuthorDialogAsync()
{ {
return EditAuthorDialog.CloseAsync(); return InvokeAsync(() => EditAuthorDialog.CloseAsync());
} }
private async Task DeleteAuthorAsync(AuthorDto author) private async Task DeleteAuthorAsync(AuthorDto author)
@ -1475,7 +1476,7 @@ public partial class Authors
{ {
await AuthorAppService.CreateAsync(NewAuthor); await AuthorAppService.CreateAsync(NewAuthor);
await GetAuthorsAsync(); await GetAuthorsAsync();
await CreateAuthorDialog.CloseAsync(); await InvokeAsync(() => CreateAuthorDialog.CloseAsync());
} }
} }
catch(Exception ex) catch(Exception ex)
@ -1493,7 +1494,7 @@ public partial class Authors
{ {
await AuthorAppService.UpdateAsync(EditingAuthorId, EditingAuthor); await AuthorAppService.UpdateAsync(EditingAuthorId, EditingAuthor);
await GetAuthorsAsync(); await GetAuthorsAsync();
await EditAuthorDialog.CloseAsync(); await InvokeAsync(() => EditAuthorDialog.CloseAsync());
} }
} }
catch(Exception ex) catch(Exception ex)

Loading…
Cancel
Save