Browse Source

Merge pull request #15250 from abpframework/update-tutorial-for-v7-0

Update tutorial for v7 0 and MVC / EF Core
pull/15251/head
Halil İbrahim Kalkan 4 years ago
committed by GitHub
parent
commit
a0b5f102c6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      docs/en/Tutorials/Part-10.md
  2. 4
      docs/en/Tutorials/Part-2.md
  3. 8
      docs/en/Tutorials/Part-3.md
  4. 92
      docs/en/Tutorials/Part-5.md
  5. 2
      docs/en/Tutorials/Part-6.md
  6. 3
      docs/en/Tutorials/Part-8.md
  7. 35
      docs/en/Tutorials/Part-9.md
  8. BIN
      docs/en/Tutorials/images/bookstore-added-author-to-book-list-2.png
  9. BIN
      docs/en/Tutorials/images/bookstore-added-authors-to-modals-2.png
  10. BIN
      docs/en/Tutorials/images/bookstore-author-permissions-2.png
  11. BIN
      docs/en/Tutorials/images/bookstore-authors-page-2.png
  12. BIN
      docs/en/Tutorials/images/bookstore-book-list-4.png
  13. BIN
      docs/en/Tutorials/images/bookstore-create-dialog-3.png
  14. BIN
      docs/en/Tutorials/images/bookstore-edit-button-3.png
  15. BIN
      docs/en/Tutorials/images/bookstore-edit-delete-actions-2.png
  16. BIN
      docs/en/Tutorials/images/bookstore-new-author-modal-2.png
  17. BIN
      docs/en/Tutorials/images/bookstore-new-book-button-3.png
  18. BIN
      docs/en/Tutorials/images/bookstore-new-book-button-small-2.png
  19. BIN
      docs/en/Tutorials/images/bookstore-new-menu-item-2.png
  20. BIN
      docs/en/Tutorials/images/bookstore-permissions-ui-2.png

9
docs/en/Tutorials/Part-10.md

@ -55,7 +55,7 @@ public Guid AuthorId { get; set; }
{{if DB=="EF"}} {{if DB=="EF"}}
> In this tutorial, we preferred to not add a **navigation property** to the `Author` entity from the `Book` class (like `public Author Author { get; set; }`). This is due to follow the DDD best practices (rule: refer to other aggregates only by id). However, you can add such a navigation property and configure it for the EF Core. In this way, you don't need to write join queries while getting books with their authors (like we will done below) which makes your application code simpler. > In this tutorial, we preferred to not add a **navigation property** to the `Author` entity from the `Book` class (like `public Author Author { get; set; }`). This is due to follow the DDD best practices (rule: refer to other aggregates only by id). However, you can add such a navigation property and configure it for the EF Core. In this way, you don't need to write join queries while getting books with their authors (like we will be doing below) which makes your application code simpler.
{{end}} {{end}}
@ -105,6 +105,7 @@ This should create a new migration class with the following code in its `Up` met
migrationBuilder.AddColumn<Guid>( migrationBuilder.AddColumn<Guid>(
name: "AuthorId", name: "AuthorId",
table: "AppBooks", table: "AppBooks",
type: "uniqueidentifier",
nullable: false, nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
@ -708,7 +709,7 @@ namespace Acme.BookStore.Books
### The Book List ### The Book List
Book list page change is trivial. Open the `Pages/Books/Index.js` in the `Acme.BookStore.Web` project and add the following column definition between the `name` and `type` columns: Book list page change is trivial. Open the `Pages/Books/Index.js` in the `Acme.BookStore.Web` project and add an `authorName` column between the `name` and `type` columns:
````js ````js
... ...
@ -735,7 +736,7 @@ Book list page change is trivial. Open the `Pages/Books/Index.js` in the `Acme.B
When you run the application, you can see the *Author* column on the table: When you run the application, you can see the *Author* column on the table:
![bookstore-added-author-to-book-list](images/bookstore-added-author-to-book-list.png) ![bookstore-added-author-to-book-list](images/bookstore-added-author-to-book-list-2.png)
### Create Modal ### Create Modal
@ -937,7 +938,7 @@ CreateMap<Pages.Books.EditModalModel.EditBookViewModel, CreateUpdateBookDto>();
You can run the application and try to create a new book or update an existing book. You will see a drop down list on the create/update form to select the author of the book: You can run the application and try to create a new book or update an existing book. You will see a drop down list on the create/update form to select the author of the book:
![bookstore-added-authors-to-modals](images/bookstore-added-authors-to-modals.png) ![bookstore-added-authors-to-modals](images/bookstore-added-authors-to-modals-2.png)
{{else if UI=="NG"}} {{else if UI=="NG"}}

4
docs/en/Tutorials/Part-2.md

@ -215,7 +215,7 @@ context.Menu.AddItem(
Run the project, login to the application with the username `admin` and the password `1q2w3E*` and you can see that the new menu item has been added to the main menu: Run the project, login to the application with the username `admin` and the password `1q2w3E*` and you can see that the new menu item has been added to the main menu:
![bookstore-menu-items](images/bookstore-new-menu-item.png) ![bookstore-menu-items](images/bookstore-new-menu-item-2.png)
When you click on the Books menu item under the Book Store parent, you will be redirected to the new empty Books Page. When you click on the Books menu item under the Book Store parent, you will be redirected to the new empty Books Page.
@ -328,7 +328,7 @@ $(function () {
You can run the application! The final UI of this part is shown below: You can run the application! The final UI of this part is shown below:
![Book list](images/bookstore-book-list-3.png) ![Book list](images/bookstore-book-list-4.png)
This is a fully working, server side paged, sorted and localized table of books. This is a fully working, server side paged, sorted and localized table of books.

8
docs/en/Tutorials/Part-3.md

@ -53,7 +53,7 @@ This part is also recorded as a video tutorial and **<a href="https://www.youtub
In this section, you will learn how to create a new modal dialog form to create a new book. The modal dialog will look like the image below: In this section, you will learn how to create a new modal dialog form to create a new book. The modal dialog will look like the image below:
![bookstore-create-dialog](images/bookstore-create-dialog-2.png) ![bookstore-create-dialog](images/bookstore-create-dialog-3.png)
### Create the Modal Form ### Create the Modal Form
@ -191,7 +191,7 @@ The final content of `Index.cshtml` is shown below:
This adds a new button called **New book** to the **top-right** of the table: This adds a new button called **New book** to the **top-right** of the table:
![bookstore-new-book-button](images/bookstore-new-book-button-2.png) ![bookstore-new-book-button](images/bookstore-new-book-button-3.png)
Open the `Pages/Books/Index.js` file and add the following code right after the `Datatable` configuration: Open the `Pages/Books/Index.js` file and add the following code right after the `Datatable` configuration:
@ -465,7 +465,9 @@ You can run the application and edit any book by selecting the edit action on a
The final UI looks as below: The final UI looks as below:
![bookstore-books-table-actions](images/bookstore-edit-button-2.png) ![bookstore-books-table-actions](images/bookstore-edit-button-3.png)
> Notice that you don't see the "Actions" button in the figure below. Instead, you see an "Edit" button. ABP is smart enough to show a single simple button instead of a actions dropdown button when the dropdown has only a single item. After the next section, it will turn to a drop down button.
## Deleting a Book ## Deleting a Book

92
docs/en/Tutorials/Part-5.md

@ -130,7 +130,7 @@ Once you define the permissions, you can see them on the **permission management
Go to the *Administration -> Identity -> Roles* page, select *Permissions* action for the admin role to open the permission management modal: Go to the *Administration -> Identity -> Roles* page, select *Permissions* action for the admin role to open the permission management modal:
![bookstore-permissions-ui](images/bookstore-permissions-ui.png) ![bookstore-permissions-ui](images/bookstore-permissions-ui-2.png)
Grant the permissions you want and save the modal. Grant the permissions you want and save the modal.
@ -202,7 +202,7 @@ Now, unauthorized users are redirected to the **login page**.
The book management page has a *New Book* button that should be invisible if the current user has no *Book Creation* permission. The book management page has a *New Book* button that should be invisible if the current user has no *Book Creation* permission.
![bookstore-new-book-button-small](images/bookstore-new-book-button-small.png) ![bookstore-new-book-button-small](images/bookstore-new-book-button-small-2.png)
Open the `Pages/Books/Index.cshtml` file and change the content as shown below: Open the `Pages/Books/Index.cshtml` file and change the content as shown below:
@ -251,7 +251,7 @@ Open the `Pages/Books/Index.cshtml` file and change the content as shown below:
Books table in the book management page has an actions button for each row. The actions button includes *Edit* and *Delete* actions: Books table in the book management page has an actions button for each row. The actions button includes *Edit* and *Delete* actions:
![bookstore-edit-delete-actions](images/bookstore-edit-delete-actions.png) ![bookstore-edit-delete-actions](images/bookstore-edit-delete-actions-2.png)
We should hide an action if the current user has not granted for the related permission. Datatables row actions has a `visible` option that can be set to `false` to hide the action item. We should hide an action if the current user has not granted for the related permission. Datatables row actions has a `visible` option that can be set to `false` to hide the action item.
@ -301,82 +301,22 @@ context.Menu.AddItem(
And replace this code block with the following: And replace this code block with the following:
````csharp ````csharp
var bookStoreMenu = new ApplicationMenuItem( context.Menu.AddItem(
"BooksStore", new ApplicationMenuItem(
l["Menu:BookStore"], "BooksStore",
icon: "fa fa-book" l["Menu:BookStore"],
icon: "fa fa-book"
).AddItem(
new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/Books"
).RequirePermissions(BookStorePermissions.Books.Default) // Check the permission!
)
); );
context.Menu.AddItem(bookStoreMenu);
//CHECK the PERMISSION
if (await context.IsGrantedAsync(BookStorePermissions.Books.Default))
{
bookStoreMenu.AddItem(new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/Books"
));
}
```` ````
You also need to add `async` keyword to the `ConfigureMenuAsync` method and re-arrange the return values. The final `BookStoreMenuContributor` class should be the following: We've only added the `.RequirePermissions(BookStorePermissions.Books.Default)` extension method call for the inner menu item.
````csharp
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Acme.BookStore.Localization;
using Acme.BookStore.MultiTenancy;
using Acme.BookStore.Permissions;
using Volo.Abp.TenantManagement.Web.Navigation;
using Volo.Abp.UI.Navigation;
namespace Acme.BookStore.Web.Menus
{
public class BookStoreMenuContributor : IMenuContributor
{
public async Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if (context.Menu.Name == StandardMenus.Main)
{
await ConfigureMainMenuAsync(context);
}
}
private async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
{
if (!MultiTenancyConsts.IsEnabled)
{
var administration = context.Menu.GetAdministration();
administration.TryRemoveMenuItem(TenantManagementMenuNames.GroupName);
}
var l = context.GetLocalizer<BookStoreResource>();
context.Menu.Items.Insert(0, new ApplicationMenuItem("BookStore.Home", l["Menu:Home"], "~/"));
var bookStoreMenu = new ApplicationMenuItem(
"BooksStore",
l["Menu:BookStore"],
icon: "fa fa-book"
);
context.Menu.AddItem(bookStoreMenu);
//CHECK the PERMISSION
if (await context.IsGrantedAsync(BookStorePermissions.Books.Default))
{
bookStoreMenu.AddItem(new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/Books"
));
}
}
}
}
````
{{else if UI == "NG"}} {{else if UI == "NG"}}

2
docs/en/Tutorials/Part-6.md

@ -265,7 +265,7 @@ namespace Acme.BookStore.Authors
We will implement this repository in the next part. We will implement this repository in the next part.
> Both of these methods might **seem unnecessary** since the standard repositories already `IQueryable` and you can directly use them instead of defining such custom methods. You're right and do it like in a real application. However, for this **"learning" tutorial**, it is useful to explain how to create custom repository methods when you really need it. > Both of these methods might **seem unnecessary** since the standard repositories already provide generic querying methods and you can easily use them instead of defining such custom methods. You're right and do it like in a real application. However, for this **"learning" tutorial**, it is useful to explain how to create custom repository methods when you really need it.
## Conclusion ## Conclusion

3
docs/en/Tutorials/Part-8.md

@ -361,13 +361,10 @@ Then open the `BookStorePermissionDefinitionProvider` in the same project and ad
````csharp ````csharp
var authorsPermission = bookStoreGroup.AddPermission( var authorsPermission = bookStoreGroup.AddPermission(
BookStorePermissions.Authors.Default, L("Permission:Authors")); BookStorePermissions.Authors.Default, L("Permission:Authors"));
authorsPermission.AddChild( authorsPermission.AddChild(
BookStorePermissions.Authors.Create, L("Permission:Authors.Create")); BookStorePermissions.Authors.Create, L("Permission:Authors.Create"));
authorsPermission.AddChild( authorsPermission.AddChild(
BookStorePermissions.Authors.Edit, L("Permission:Authors.Edit")); BookStorePermissions.Authors.Edit, L("Permission:Authors.Edit"));
authorsPermission.AddChild( authorsPermission.AddChild(
BookStorePermissions.Authors.Delete, L("Permission:Authors.Delete")); BookStorePermissions.Authors.Delete, L("Permission:Authors.Delete"));
```` ````

35
docs/en/Tutorials/Part-9.md

@ -223,28 +223,39 @@ Notice that we've added more keys. They will be used in the next sections.
### Add to the Main Menu ### Add to the Main Menu
Open the `BookStoreMenuContributor.cs` in the `Menus` folder of the `Acme.BookStore.Web` project and add the following code in the end of the `ConfigureMainMenuAsync` method: Open the `BookStoreMenuContributor.cs` in the `Menus` folder of the `Acme.BookStore.Web` project and add a new *Authors* menu item under the *Book Store* menu item. The following code (in the `ConfigureMainMenuAsync` method) shows the final code part:
````csharp ````csharp
if (await context.IsGrantedAsync(BookStorePermissions.Authors.Default)) context.Menu.AddItem(
{ new ApplicationMenuItem(
bookStoreMenu.AddItem(new ApplicationMenuItem( "BooksStore",
"BooksStore.Authors", l["Menu:BookStore"],
l["Menu:Authors"], icon: "fa fa-book"
url: "/Authors" ).AddItem(
)); new ApplicationMenuItem(
} "BooksStore.Books",
l["Menu:Books"],
url: "/Books"
).RequirePermissions(BookStorePermissions.Books.Default)
).AddItem( // ADDED THE NEW "AUTHORS" MENU ITEM UNDER THE "BOOK STORE" MENU
new ApplicationMenuItem(
"BooksStore.Authors",
l["Menu:Authors"],
url: "/Authors"
).RequirePermissions(BookStorePermissions.Books.Default)
)
);
```` ````
### Run the Application ### Run the Application
Run and login to the application. **You can not see the menu item since you don't have permission yet.** Go to the `Identity/Roles` page, click to the *Actions* button and select the *Permissions* action for the **admin role**: Run and login to the application. **You can not see the menu item since you don't have permission yet.** Go to the `Identity/Roles` page, click to the *Actions* button and select the *Permissions* action for the **admin role**:
![bookstore-author-permissions](images/bookstore-author-permissions.png) ![bookstore-author-permissions](images/bookstore-author-permissions-2.png)
As you see, the admin role has no *Author Management* permissions yet. Click to the checkboxes and save the modal to grant the necessary permissions. You will see the *Authors* menu item under the *Book Store* in the main menu, after **refreshing the page**: As you see, the admin role has no *Author Management* permissions yet. Click to the checkboxes and save the modal to grant the necessary permissions. You will see the *Authors* menu item under the *Book Store* in the main menu, after **refreshing the page**:
![bookstore-authors-page](images/bookstore-authors-page.png) ![bookstore-authors-page](images/bookstore-authors-page-2.png)
The page is fully working except *New author* and *Actions/Edit* since we haven't implemented them yet. The page is fully working except *New author* and *Actions/Edit* since we haven't implemented them yet.
@ -369,7 +380,7 @@ namespace Acme.BookStore.Web
"New author" button will work as expected and open a new model when you run the application again: "New author" button will work as expected and open a new model when you run the application again:
![bookstore-new-author-modal](images/bookstore-new-author-modal.png) ![bookstore-new-author-modal](images/bookstore-new-author-modal-2.png)
## Edit Modal ## Edit Modal

BIN
docs/en/Tutorials/images/bookstore-added-author-to-book-list-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
docs/en/Tutorials/images/bookstore-added-authors-to-modals-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
docs/en/Tutorials/images/bookstore-author-permissions-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
docs/en/Tutorials/images/bookstore-authors-page-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
docs/en/Tutorials/images/bookstore-book-list-4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
docs/en/Tutorials/images/bookstore-create-dialog-3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
docs/en/Tutorials/images/bookstore-edit-button-3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
docs/en/Tutorials/images/bookstore-edit-delete-actions-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
docs/en/Tutorials/images/bookstore-new-author-modal-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
docs/en/Tutorials/images/bookstore-new-book-button-3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
docs/en/Tutorials/images/bookstore-new-book-button-small-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
docs/en/Tutorials/images/bookstore-new-menu-item-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/en/Tutorials/images/bookstore-permissions-ui-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Loading…
Cancel
Save