Skip to content

Commit e23826a

Browse files
committed
Update Angular tutorial documents
1 parent a543a49 commit e23826a

35 files changed

Lines changed: 878 additions & 525 deletions

File tree

blog-posts/en/using-asp.net-zero-with-devextreme-angular-part-4.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ Update-Database
216216

217217
**It's finished**! We can test the application. Run the project, **login** as the **host admin** (click Change link and clear tenancy name) shown below:
218218

219-
<img src="/Images/Blog/login-as-host-3.png" alt="Login as host" class="img-thumbnail" style="width:100.0%" />
219+
<img src="/Images/Blog/login-as-host-7.png" alt="Login as host" class="img-thumbnail" style="width:100.0%" />
220220

221221
Default **admin** password is **123qwe**. After login, we see the **tenant list** which only contains a **default** tenant. We can create a new tenant:
222222

blog-posts/en/using-asp.net-zero-with-devextreme-mvc-part-4.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ Update-Database
180180

181181
**It's finished**! We can test the application. Run the project, **login** as the **host admin** (click Change link and clear tenancy name) shown below:
182182

183-
<img src="/Images/Blog/login-as-host-3.png" alt="Login as host" class="img-thumbnail" style="width:100.0%" />
183+
<img src="/Images/Blog/login-as-host-7.png" alt="Login as host" class="img-thumbnail" style="width:100.0%" />
184184

185185
Default **admin** password is **123qwe**. After login, we see the **tenant list** which only contains a **default** tenant. We can create a new tenant:
186186

doc-obsolete/Developing-Step-By-Step-Angular.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2034,7 +2034,7 @@ Now, we can update the database again:
20342034
**login** as the **host admin** (click Change link and clear tenancy
20352035
name) shown below:
20362036

2037-
<img src="images/login-as-host-3.png" alt="Login as host" class="img-thumbnail" style="width:100.0%" />
2037+
<img src="images/login-as-host-7.png" alt="Login as host" class="img-thumbnail" style="width:100.0%" />
20382038

20392039
After login, we see the **tenant list** which only contains a
20402040
**default** tenant. We can create a new tenant:

docs/en/Developing-Step-By-Step-Angular-Adding-AddPhone-DeletePhone-Methods.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,20 @@ Then we add configuration for AutoMapper into CustomDtoMapper.cs like below:
6868
configuration.CreateMap<AddPhoneInput, Phone>();
6969
```
7070

71+
A permission should have a unique name. We define permission names as constant strings in **AppPermissions** class. It's a simple constant string:
72+
73+
```csharp
74+
public const string Pages_Tenant_PhoneBook_DeletePhone = "Pages.Tenant.DeletePhone";
75+
public const string Pages_Tenant_PhoneBook_AddPhone = "Pages.Tenant.AddPhone";
76+
```
77+
78+
Go to **AppAuthorizationProvider** class in the server side and add a new permission as shown below (you can add just below the dashboard permission):
79+
80+
```csharp
81+
phoneBook.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook_DeletePhone, L("DeletePhone"), multiTenancySides: MultiTenancySides.Tenant);
82+
phoneBook.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook_AddPhone, L("AddPhone"), multiTenancySides: MultiTenancySides.Tenant);
83+
```
84+
7185
(Note: We injected **IRepository&lt;Phone, long&gt;** in the constructor
7286
and set to \_phoneRepository field, as similar to \_personRepository)
7387

docs/en/Developing-Step-By-Step-Angular-Adding-New-Menu-Item.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ Open PhoneBookDemo.xml (the **default**, **English** localization dictionary) an
2424

2525
```xml
2626
<text name="PhoneBook">Phone Book</text>
27+
<text name="PhoneBooksHeaderInfo">Phone Book Details</text>
2728
```
2829

2930
If we don't define "PhoneBook"s value for other localization dictionaries, default value is shown in all languages. For example, we can define it also for Turkish in `PhoneBookDmo-tr.xml` file:
3031

3132
```xml
3233
<text name="PhoneBook">Telefon Rehberi</text>
34+
<text name="PhoneBooksHeaderInfo">Telefon Rehberi Detayları</text>
3335
```
3436

3537
Note: Any change in server side (including change localization texts) requires recycle of the server application. We suggest to use Ctrl+F5 if you don't need to debugging for a faster startup. In that case, it's

docs/en/Developing-Step-By-Step-Angular-Authorization-PhoneBook.md

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ defined. We will define two permission:
1111

1212
### Define the permission
1313

14-
Go to **AppAuthorizationProvider** class in the server side and add a new permission as shown below (you can add just below the dashboard permission):
14+
A permission should have a unique name. We define permission names as constant strings in **AppPermissions** class. It's a simple constant string:
1515

1616
```csharp
17-
pages.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook, L("PhoneBook"), multiTenancySides: MultiTenancySides.Tenant);
17+
public const string Pages_Tenant_PhoneBook = "Pages.Tenant.PhoneBook";
1818
```
1919

20-
A permission should have a unique name. We define permission names as constant strings in **AppPermissions** class. It's a simple constant string:
20+
Go to **AppAuthorizationProvider** class in the server side and add a new permission as shown below (you can add just below the dashboard permission):
2121

2222
```csharp
23-
public const string Pages_Tenant_PhoneBook = "Pages.Tenant.PhoneBook";
23+
pages.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook, L("PhoneBook"), multiTenancySides: MultiTenancySides.Tenant);
2424
```
2525

2626
Unique name of this permission is "**Pages.Tenant.PhoneBook**". While you can set any string (as long as it's unique), it's suggested to use that convention. A permission can have a localizable display name: "**PhoneBook**" here. (See "Adding a New Page" section for more about localization, since it's very similar). Lastly, we set this as a **tenant** level permission.
@@ -71,7 +71,7 @@ new AppMenuItem("PhoneBook", 'Pages.Tenant.PhoneBook', "flaticon-book", "/app/ma
7171

7272
So, how we can enter the page now? Simple, go to **Role Management** page and edit **admin** role:
7373

74-
<img src="images/role-permissions-with-phonebook1.png" alt="Role permissions" class="img-thumbnail" />
74+
<img src="images/role-permissions-with-phonebook-2.png" alt="Role permissions" class="img-thumbnail" />
7575

7676
We see that a **new permission** named "**Phone book**" added to **permissions** tab. So, we can check it and save the role. After saving, we need to **refresh** the whole page to refresh permissions for the current user. We could also grant this permission to a specific user. Now, we can enter the Phone book page again.
7777

@@ -81,17 +81,17 @@ While a permission for a page is useful and probably always needed, we may want
8181

8282
### Define the Permission
8383

84-
Defining a permission is similar (in the `AppAuthorizationProvider` class):
84+
First permission was defined before. In the second line, we are creating a child permission of first one. Remember to create a constant in `AppPermissions` class:
8585

8686
```csharp
87-
var phoneBook = pages.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook, L("PhoneBook"), multiTenancySides: MultiTenancySides.Tenant);
88-
phoneBook.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook_CreatePerson, L("CreateNewPerson"), multiTenancySides: MultiTenancySides.Tenant);
87+
public const string Pages_Tenant_PhoneBook_CreatePerson = "Pages.Tenant.PhoneBook.CreatePerson";
8988
```
9089

91-
First permission was defined before. In the second line, we are creating a child permission of first one. Remember to create a constant in `AppPermissions` class:
90+
Defining a permission is similar (in the `AppAuthorizationProvider` class):
9291

9392
```csharp
94-
public const string Pages_Tenant_PhoneBook_CreatePerson = "Pages.Tenant.PhoneBook.CreatePerson";
93+
var phoneBook = pages.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook, L("PhoneBook"), multiTenancySides: MultiTenancySides.Tenant);
94+
phoneBook.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook_CreatePerson, L("CreateNewPerson"), multiTenancySides: MultiTenancySides.Tenant);
9595
```
9696

9797
### Add AbpAuthorize Attribute
@@ -113,7 +113,26 @@ If we run the application and try to create a person, we get an authorization er
113113
Open the **phonebook.component.html** view and add the permission **Pages.Tenant.PhoneBook.CreatePerson** condition as shown below:
114114

115115
```html
116-
<button *ngIf="'Pages.Tenant.PhoneBook.CreatePerson' | permission" class="btn btn-primary" (click)="createPersonModal.show()"><i class="fa fa-plus"></i> {{"CreateNewPerson" | localize}}</button>
116+
@if('Pages.Tenant.PhoneBook.CreatePerson' | permission){
117+
<button class="btn btn-primary" (click)="createPersonModal.show()"><i class="fa fa-plus"></i> {{"CreateNewPerson" | localize}}</button>
118+
}
119+
```
120+
121+
Open the **phonebook.component.ts** view and add the import **PermissionPipe** condition as shown below:
122+
123+
```typescript
124+
@Component({
125+
selector: 'app-phone-book',
126+
templateUrl: './phonebook.component.html',
127+
animations: [appModuleAnimation()],
128+
imports: [
129+
//...
130+
PermissionPipe,
131+
],
132+
})
133+
export class PhoneBookComponent extends AppComponentBase implements OnInit {
134+
//...
135+
}
117136
```
118137

119138
In this way, the "Create New Person" button is not rendered in server and user can not see this button.
@@ -122,7 +141,7 @@ In this way, the "Create New Person" button is not rendered in server and user c
122141

123142
To see the button again, we can go to role or user manager and grant related permission as shown below:
124143

125-
<img src="images/user-permissions-phonebook1.png" alt="User specific permissions" class="img-thumbnail" />
144+
<img src="images/user-permissions-phonebook-2.png" alt="User specific permissions" class="img-thumbnail" />
126145

127146
As shown above, **Create new person** permission is a child permission of the **Phone book**. Remember to refresh page to get permissions updated.
128147

docs/en/Developing-Step-By-Step-Angular-Creating-Person-Application-Service.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@ Application service interface and DTOs are located in **.Application.Shared** pr
88
using Abp.Application.Services;
99
using Abp.Application.Services.Dto;
1010

11-
namespace Acme.PhoneBookDemo.PhoneBook
11+
namespace Acme.PhoneBookDemo.PhoneBook;
12+
13+
public interface IPersonAppService : IApplicationService
1214
{
13-
public interface IPersonAppService : IApplicationService
14-
{
15-
ListResultDto<PersonListDto> GetPeople(GetPeopleInput input);
16-
}
15+
ListResultDto<PersonListDto> GetPeople(GetPeopleInput input);
1716
}
1817
```
1918

@@ -50,6 +49,14 @@ configuration.CreateMap<Person, PersonListDto>();
5049
After defining interface, we can implement it as shown below: (in **.Application** project)
5150

5251
```csharp
52+
using Abp.Application.Services.Dto;
53+
using Abp.Collections.Extensions;
54+
using Abp.Domain.Repositories;
55+
using System.Collections.Generic;
56+
using System.Linq;
57+
58+
namespace Acme.PhoneBookDemo.PhoneBook;
59+
5360
public class PersonAppService : PhoneBookDemoAppServiceBase, IPersonAppService
5461
{
5562
private readonly IRepository<Person> _personRepository;

docs/en/Developing-Step-By-Step-Angular-Creating-Person-Entity.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ using System.ComponentModel.DataAnnotations;
1010
using System.ComponentModel.DataAnnotations.Schema;
1111
using Abp.Domain.Entities.Auditing;
1212

13-
namespace Acme.PhoneBookDemo.PhoneBook
14-
{
15-
[Table("PbPersons")]
13+
namespace Acme.PhoneBookDemo.PhoneBook;
14+
15+
[Table("PbPersons")]
1616
public class Person : FullAuditedEntity
1717
{
1818
public const int MaxNameLength = 32;
@@ -30,7 +30,6 @@ namespace Acme.PhoneBookDemo.PhoneBook
3030
[MaxLength(MaxEmailAddressLength)]
3131
public virtual string EmailAddress { get; set; }
3232
}
33-
}
3433
```
3534

3635
Person's **primary key** type is **int** (as default). It inherits

docs/en/Developing-Step-By-Step-Angular-Creating-Phone-Entity.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class Person : FullAuditedEntity
3737
}
3838
```
3939

40-
We have a **PhoneType** enum as shown below: (in **.Core**
40+
We have a **PhoneType** enum as shown below: (in **.Core.Shared**
4141
project)
4242

4343
```csharp

docs/en/Developing-Step-By-Step-Angular-Creating-PhoneBook-Component.md

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ new typescript file (**phonebook.component.ts**) in the phonebook folder
55
as shown below:
66

77
```javascript
8-
import { Component, Injector } from '@angular/core';
8+
import { Component } from '@angular/core';
99
import { AppComponentBase } from '@shared/common/app-component-base';
1010
import { appModuleAnimation } from '@shared/animations/routerTransition';
11+
import { LocalizePipe } from '@shared/common/pipes/localize.pipe';
12+
import { SubHeaderComponent } from '@app/shared/common/sub-header/sub-header.component';
1113

1214
@Component({
1315
templateUrl: './phonebook.component.html',
14-
animations: [appModuleAnimation()]
16+
animations: [appModuleAnimation()],
17+
imports: [SubHeaderComponent, LocalizePipe],
1518
})
16-
1719
export class PhoneBookComponent extends AppComponentBase {
18-
constructor(
19-
injector: Injector
20-
) {
21-
super(injector);
20+
constructor() {
21+
super();
2222
}
2323
}
2424
```
@@ -32,21 +32,11 @@ As we declared in **phonebook.component.ts** we should create a
3232

3333
```html
3434
<div [@routerTransition]>
35-
<div class="kt-content kt-grid__item kt-grid__item--fluid kt-grid kt-grid--hor">
36-
<div class="kt-subheader kt-grid__item">
37-
<div [class]="containerClass">
38-
<div class="kt-subheader__main">
39-
<h3 class="kt-subheader__title">
40-
<span>{{"PhoneBook" | localize}}</span>
41-
</h3>
42-
</div>
43-
</div>
44-
</div>
45-
<div [class]="containerClass + ' kt-grid__item kt-grid__item--fluid'">
46-
<div class="kt-portlet kt-portlet--mobile">
47-
<div class="kt-portlet__body kt-portlet__body--fit">
48-
<p>PHONE BOOK CONTENT COMES HERE!</p>
49-
</div>
35+
<sub-header [title]="'PhoneBook' | localize" [description]="'PhoneBooksHeaderInfo' | localize"></sub-header>
36+
<div [class]="containerClass">
37+
<div class="card card-custom">
38+
<div class="card-body">
39+
<p>PHONE BOOK CONTENT COMES HERE!</p>
5040
</div>
5141
</div>
5242
</div>
@@ -62,15 +52,16 @@ Now we should create a **phonebook.module.ts** and **phonebook-routing.module.ts
6252
*phonebook-routing.module.ts*
6353

6454
```typescript
65-
import {NgModule} from '@angular/core';
66-
import {RouterModule, Routes} from '@angular/router';
67-
import {PhoneBookComponent} from './phonebook.component';
55+
import { NgModule } from '@angular/core';
56+
import { RouterModule, Routes } from '@angular/router';
6857

69-
const routes: Routes = [{
70-
path: '',
71-
component: PhoneBookComponent,
72-
pathMatch: 'full'
73-
}];
58+
const routes: Routes = [
59+
{
60+
path: '',
61+
loadComponent: () => import('./phonebook.component').then((m) => m.PhoneBookComponent),
62+
pathMatch: 'full',
63+
},
64+
];
7465

7566
@NgModule({
7667
imports: [RouterModule.forChild(routes)],
@@ -82,21 +73,20 @@ export class PhoneBookRoutingModule {}
8273
*phonebook.module.ts*
8374

8475
```typescript
85-
import {NgModule} from '@angular/core';
86-
import {AppSharedModule} from '@app/shared/app-shared.module';
87-
import {PhoneBookRoutingModule} from './phonebook-routing.module';
88-
import {PhoneBookComponent} from './phonebook.component';
76+
import { NgModule } from '@angular/core';
77+
import { AppSharedModule } from '@app/shared/app-shared.module';
78+
import { PhoneBookRoutingModule } from './phonebook-routing.module';
79+
import { PhoneBookComponent } from './phonebook.component';
8980

9081
@NgModule({
91-
declarations: [PhoneBookComponent],
92-
imports: [AppSharedModule, PhoneBookRoutingModule]
82+
imports: [AppSharedModule, PhoneBookRoutingModule, PhoneBookComponent],
9383
})
9484
export class PhoneBookModule {}
9585
```
9686

9787
Now, we can refresh the page to see the new added page:
9888

99-
<img src="images/phonebook-empty-ng2.png" alt="Phonebook empty" class="img-thumbnail" style="width:100.0%" />
89+
<img src="images/phonebook-empty-ng3.png" alt="Phonebook empty" class="img-thumbnail" style="width:100.0%" />
10090

10191
Note: Angular-cli automatically re-compiles and refreshes the page when
10292
any changes made to any file in the application.

0 commit comments

Comments
 (0)