Browse Source

Merge pull request #20996 from abpframework/auto-merge/rel-8-2/3047

Merge branch rel-8.3 with rel-8.2
pull/20997/head
maliming 1 year ago
committed by GitHub
parent
commit
a77e18f41f
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 20
      docs/en/docs-nav.json
  2. 143
      docs/en/framework/ui/angular/entity-filters.md
  3. 16
      docs/en/framework/ui/angular/environment.md
  4. BIN
      docs/en/framework/ui/angular/images/angular-advanced-entity-filters-with-custom-content-above-filter.png
  5. BIN
      docs/en/framework/ui/angular/images/angular-advanced-entity-filters-with-form.png
  6. BIN
      docs/en/framework/ui/angular/images/angular-advanced-entity-filters-without-form.png
  7. BIN
      docs/en/framework/ui/angular/images/angular-advanced-entity-filters.png
  8. BIN
      docs/en/framework/ui/angular/images/angular-lookup-select.gif
  9. BIN
      docs/en/framework/ui/angular/images/angular-lookup-typeahead.gif
  10. BIN
      docs/en/framework/ui/angular/images/grouped-menu-mobile.png
  11. BIN
      docs/en/framework/ui/angular/images/grouped-menu.png
  12. BIN
      docs/en/framework/ui/angular/images/manage-profile-page-new-tab.png
  13. BIN
      docs/en/framework/ui/angular/images/manage-profile-page.png
  14. 98
      docs/en/framework/ui/angular/lookup-components.md
  15. 77
      docs/en/framework/ui/angular/manage-profile-page-tabs.md
  16. 13
      docs/en/framework/ui/angular/modifying-the-menu.md
  17. 14
      docs/en/framework/ui/angular/overview.md
  18. 2
      docs/en/framework/ui/angular/quick-start.md

20
docs/en/docs-nav.json

@ -1226,6 +1226,10 @@
{ {
"text": "Angular", "text": "Angular",
"items": [ "items": [
{
"text": "Overview",
"path": "framework/ui/angular/overview.md"
},
{ {
"text": "Quick Start", "text": "Quick Start",
"path": "framework/ui/angular/quick-start.md" "path": "framework/ui/angular/quick-start.md"
@ -1438,6 +1442,10 @@
"text": "Modifying the Menu", "text": "Modifying the Menu",
"path": "framework/ui/angular/modifying-the-menu.md" "path": "framework/ui/angular/modifying-the-menu.md"
}, },
{
"text": "Manage Profile Page Tabs",
"path": "framework/ui/angular/manage-profile-page-tabs.md"
},
{ {
"text": "Sorting Navigation Elements", "text": "Sorting Navigation Elements",
"path": "framework/ui/angular/sorting-navigation-elements.md" "path": "framework/ui/angular/sorting-navigation-elements.md"
@ -1491,6 +1499,18 @@
{ {
"text": "Card", "text": "Card",
"path": "framework/ui/angular/card-component.md" "path": "framework/ui/angular/card-component.md"
},
{
"text": "Password Complexity Indicator",
"path": "framework/ui/angular/password-complexity-indicator-component.md"
},
{
"text": "Lookup Components(Pro)",
"path": "framework/ui/angular/lookup-components.md"
},
{
"text": "Entity Filters(Pro)",
"path": "framework/ui/angular/entity-filters.md"
} }
] ]
} }

143
docs/en/framework/ui/angular/entity-filters.md

@ -0,0 +1,143 @@
# Entity Filters
Every CRUD page includes some sort of inputs to filter the listed data. Some of the inputs are common among all of the entities like the `Search` box. In addition, every entity has its own advanced filters depending on its fields. To reduce the amount of code written on every CRUD page, the Angular UI of ABP Commercial introduces a new type of component called `abp-advanced-entity-filters`
## Setup
The components are in the _@volo/abp.commercial.ng.ui_ package, which is included in the ABP templates. So, as long as your project is a product of these templates and unless you delete the package, you have access to the entity filter components.
You can either import the `CommercialUiModule` which contains other components as well as `AdvancedEntityFilters` or you can directly import the `AdvancedEntityFiltersModule` if you do not need other components. Here is how you import them in your Angular module:
```javascript
import {
CommercialUiModule,
AdvancedEntityFiltersModule,
} from "@volo/abp.commercial.ng.ui";
@NgModule({
imports: [
// other imports
CommercialUiModule,
// OR
AdvancedEntityFiltersModule,
],
// rest of the module metadata
})
export class YourModule {}
```
## Usage
Let's take a look at the `Users` page from the `Identity` module.
![ABP Angular UI Users Page with Advanced Entity Filters](./images/angular-advanced-entity-filters.png)
As shown in the screenshot, `abp-advanced-entity-filters` usually contain two parts, an entity filter (common among entities), i.e. `abp-entity-filter`, and entity-specific filters which are encapsulated within the `abp-advanced-entity-filters-form` component.
`users.component.html`
```html
<abp-advanced-entity-filters [list]="list" localizationSourceName="AbpIdentity">
<abp-advanced-entity-filters-form>
<form #filterForm (keyup.enter)="list.get()">
<div class="row">
<!-- Form elements are omitted -->
<div class="col-12 col-sm-auto align-self-end mb-3">
<div class="row">
<div class="col-6 col-sm-auto d-grid">
<button
type="button"
class="btn btn-outline-primary"
(click)="clearFilters()"
>
<span>{%{{{ 'AbpUi::Clear' | abpLocalization }}}%}</span>
</button>
</div>
<div class="col-6 col-sm-auto d-grid">
<button
type="button"
class="btn btn-primary"
(click)="list.get()"
>
<span>{%{{{ 'AbpUi::Refresh' | abpLocalization }}}%}</span>
</button>
</div>
</div>
</div>
</div>
</form>
</abp-advanced-entity-filters-form>
</abp-advanced-entity-filters>
```
The `abp-advanced-entity-filters` already contains the `abp-entity-filter` component so you do not need to pass it. However, the `abp-entity-filter` component needs an instance of `ListService` which is usually stored in the `list` field of the page. You can also change the placeholder of the component via `entityFilterPlaceholder` input which is passed into the `abpLocalization` pipe so that it uses the translated text. Default is `'AbpUi::PagerSearch'`
E.g
```html
<abp-advanced-entity-filters
[list]="list"
entityFilterPlaceholder="AbpUi::PagerSearch"
>
<!-- ... -->
</abp-advanced-entity-filters>
```
### Inputs
- `list`: an instance of `ListService`
- `entityFilterPlaceholder`: the placeholder of `abp-entity-filter` component. Default: `'AbpUi::PagerSearch'`
- `localizationSourceName`: the localization source of the current page. E.g: `AbpIdentity`
### Inner components
Some entities are simple and do not require any filter other than the `abp-entity-filter`. In this case, you can simply use the `abp-advanced-entity-filters` without anything in between.
E.g.
Let's remove `form` from the `Users` page
```html
<abp-advanced-entity-filters [list]="list" localizationSourceName="AbpIdentity">
</abp-advanced-entity-filters>
```
![ABP Angular UI Users Page with Advanced Entity Filters without form](./images/angular-advanced-entity-filters-without-form.png)
If your component needs other filters, you can pass your own `form` within the `abp-advanced-entity-filters-form` component. This will render your form as well as a toggle (`abp-advanced-entity-filters-toggle`) to show and hide the form
E.g.
```html
<abp-advanced-entity-filters [list]="list" localizationSourceName="AbpIdentity">
<abp-advanced-entity-filters-form>
<form>
<!-- Content is omitted for sake of simplicity -->
</form>
</abp-advanced-entity-filters-form>
</abp-advanced-entity-filters>
```
![ABP Angular UI Users Page with Advanced Entity Filters with form](./images/angular-advanced-entity-filters-with-form.png)
Last but not least, if you need to render some content above the `abp-entity-filter` component, you can use the `abp-advanced-entity-filters-above-search`.
E.g.
```html
<abp-advanced-entity-filters [list]="list" localizationSourceName="AbpIdentity">
<abp-advanced-entity-filters-above-search>
<h3>Custom Content above entity-filter</h3>
</abp-advanced-entity-filters-above-search>
<abp-advanced-entity-filters-form>
<form>
<!-- Content is omitted for sake of simplicity -->
</form>
</abp-advanced-entity-filters-form>
</abp-advanced-entity-filters>
```
![ABP Angular UI Users Page with Advanced Entity Filters with custom content above filter](./images/angular-advanced-entity-filters-with-custom-content-above-filter.png)

16
docs/en/framework/ui/angular/environment.md

@ -101,6 +101,22 @@ export interface RemoteEnv {
- `method`: HTTP method to be used when retrieving environment config. Default: `GET` - `method`: HTTP method to be used when retrieving environment config. Default: `GET`
- `headers`: If extra headers are needed for the request, it can be set through this field. - `headers`: If extra headers are needed for the request, it can be set through this field.
## Provide Environment Variable to Core Module
`environment` variable comes from angular host application.
```js
import { environment } from '../environments/environment';
@NgModule({
imports: [
//...other imports
CoreModule.forRoot({
environment
}),
]
})
```
## EnvironmentService ## EnvironmentService
` EnvironmentService` is a singleton service, i.e. provided in root level of your application, and keeps the environment in the internal store. ` EnvironmentService` is a singleton service, i.e. provided in root level of your application, and keeps the environment in the internal store.

BIN
docs/en/framework/ui/angular/images/angular-advanced-entity-filters-with-custom-content-above-filter.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
docs/en/framework/ui/angular/images/angular-advanced-entity-filters-with-form.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
docs/en/framework/ui/angular/images/angular-advanced-entity-filters-without-form.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
docs/en/framework/ui/angular/images/angular-advanced-entity-filters.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
docs/en/framework/ui/angular/images/angular-lookup-select.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
docs/en/framework/ui/angular/images/angular-lookup-typeahead.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

BIN
docs/en/framework/ui/angular/images/grouped-menu-mobile.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/en/framework/ui/angular/images/grouped-menu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/en/framework/ui/angular/images/manage-profile-page-new-tab.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
docs/en/framework/ui/angular/images/manage-profile-page.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

98
docs/en/framework/ui/angular/lookup-components.md

@ -0,0 +1,98 @@
# Lookup Components
The Angular UI of ABP Commercial introduces some components with `abp-lookup-...` selector prefix. These components are used for retrieving relational entity data.
## Setup
The components are in the _@volo/abp.commercial.ng.ui_ package, which is included in the ABP templates. So, as long as your project is a product of these templates and unless you delete the package, you have access to the lookup components. Here is how you import them in your Angular module:
```javascript
import { CommercialUiModule } from '@volo/abp.commercial.ng.ui';
@NgModule({
imports: [
// other imports
CommercialUiModule,
],
// rest of the module metadata
})
export class YourModule {}
```
Now you can use the lookup components in your components declared by this module.
## Lookup HTTP Requests
The lookup requests are used by all lookup components to get the related entity records. Because of lexical this, _they must be arrow functions_.
```javascript
@Injectable({
providedIn: 'root'
})
export class AuthorService {
getCountryLookup = (input: LookupRequestDto) =>
this.restService.request<any, PagedResultDto<LookupDto<string>>>({
method: 'GET',
url: '/api/app/authors/country-lookup',
params: { filter: input.filter, skipCount: input.skipCount, maxResultCount: input.maxResultCount },
},
{ apiName: this.apiName });
// rest of the service is removed for brevity
}
```
## Lookup Typeahead Component
Typeahead is a good choice when you have an unknown number of records for the related entity or you want to improve the UX with a search ability. Although not the best scenario, the country picker below shows how the lookup typeahead works:
![ABP Angular UI Typeahead Lookup](./images/angular-lookup-typeahead.gif)
Here is how it is used in the template.
```html
<abp-lookup-typeahead
cid="author-country-id"
formControlName="countryId"
displayNameProp="name"
[editingData]="selected?.country"
[getFn]="service.getCountryLookup"
></abp-lookup-typeahead>
```
The available properties are as follows:
- **cid:** The id of the form control (e.g. an input or a select element) inside the lookup component. Lets form controls respond to `<label>` events.
- **editingData:** The related entity data if a record is being updated.
- **displayNameProp:** The property of the updated record to use as a display name in the form control.
- **lookupNameProp:** The property of the entity to use as a display name in options. Should macth the lookup HTTP request interface. _(default: displayName)_
- **lookupIdProp:** The property of the entity to use as the unique key in options. Should macth the lookup HTTP request interface. _(default: id)_
- **maxResultCount:** The maximum number of options to display. _(default: 10)_
- **getFn:** A function to get the related entity records with HTTP requests. Because of lexical this, _it must be a an arrow function_.
- **disabled:** This property lets you disable/enable a lookup component. _(default: false)_.
## Lookup Select Component
Select is a good choice when you have a low (and usually fixed) number of records for the related entity and search is not necessary. The country picker below shows how the lookup select works:
![ABP Angular UI Select Lookup](./images/angular-lookup-select.gif)
Here is how it is used in the template.
```html
<abp-lookup-select
cid="author-country-id"
formControlName="countryId"
displayNameProp="name"
[getFn]="service.getCountryLookup"
></abp-lookup-select>
```
The available properties are as follows:
- **cid:** The id of the form control (e.g. an input or a select element) inside the lookup component. Lets form controls respond to `<label>` events.
- **displayNameProp:** The property of the updated record to use as a display name in the form control.
- **lookupNameProp:** The property of the entity to use as a display name in options. Should macth the lookup HTTP request interface. _(default: displayName)_
- **lookupIdProp:** The property of the entity to use as the unique key in options. Should macth the lookup HTTP request interface. _(default: id)_
- **getFn:** A function to get the related entity records with HTTP requests. Because of lexical this, _it must be a an arrow function_.
- **disabled:** This property lets you disable/enable a lookup component. _(default: false)_.

77
docs/en/framework/ui/angular/manage-profile-page-tabs.md

@ -0,0 +1,77 @@
# Manage Profile Page Tabs
![manage profile page](./images/manage-profile-page.png)
The tabs in the manage profile page can be managed via `ManageProfileTabsService` which is exposed by the `@volo/abp.ng.account/public/config` package. You can add, remove, or edit a tab with using this service.
See the example below, covers all features:
```ts
// manage-profile-tabs.provider.ts
import { APP_INITIALIZER, Component } from "@angular/core";
import { TwoFactorTabComponent } from "@volo/abp.ng.account/public";
import {
eAccountManageProfileTabNames,
ManageProfileTabsService,
} from "@volo/abp.ng.account/public/config";
import { MyAwesomeTabComponent } from "./my-awesome-tab/my-awesome-tab.component";
@Component({
standalone: true,
selector: "abp-my-awesome-tab",
template: `My Awesome Tab`,
})
class MyAwesomeTabComponent {}
export const MANAGE_PROFILE_TAB_PROVIDER = {
provide: APP_INITIALIZER,
useFactory: configureManageProfileTabs,
deps: [ManageProfileTabsService],
multi: true,
};
export function configureManageProfileTabs(tabs: ManageProfileTabsService) {
return () => {
tabs.add([
{
name: "::MyAwesomeTab", // supports localization keys
order: 5,
component: MyAwesomeTabComponent,
},
]);
tabs.patch(eAccountManageProfileTabNames.TwoFactor, {
name: "Two factor authentication",
component: TwoFactorTabComponent,
});
tabs.remove([eAccountManageProfileTabNames.ProfilePicture]);
};
}
```
```ts
//app.module.ts
import { MANAGE_PROFILE_TAB_PROVIDER } from "./manage-profile-tabs.provider";
@NgModule({
providers: [MANAGE_PROFILE_TAB_PROVIDER],
})
export class AppModule {}
```
What we have done above;
- Created the `manage-profile-page-tabs.provider.ts`.
- Determined the `configureManageProfileTabs` function to perform manage profile tabs actions.
- Added a new tab labeled "My awesome tab".
- Renamed the "Two factor" tab label.
- Removed the "Profile picture" tab.
- Determined the `MANAGE_PROFILE_TAB_PROVIDER` to be able to run the `configureManageProfileTabs` function on initialization.
- Registered the `MANAGE_PROFILE_TAB_PROVIDER` to the `AppModule` providers.
See the result:
![my awesome tab](./images/manage-profile-page-new-tab.png)

13
docs/en/framework/ui/angular/modifying-the-menu.md

@ -344,3 +344,16 @@ export class AppComponent {
* Patched the languages dropdown element with new `requiredPolicy` and new `order`. * Patched the languages dropdown element with new `requiredPolicy` and new `order`.
* Removed the current user dropdown element. * Removed the current user dropdown element.
## Grouped Menu (Pro)
**This feature is only applied for [LeptonX](https://abp.io/docs/latest/themes/lepton-x/angular) theme**
### Web
![groupped-menu](./images/grouped-menu.png)
### Mobile
![groupped-menu-mobile](./images/grouped-menu-mobile.png)

14
docs/en/framework/ui/angular/overview.md

@ -0,0 +1,14 @@
# Angular UI
[Angular](https://angular.dev/) is a framework for building interactive, client-side web UIs using [TypeScript](https://www.typescriptlang.org) and [NodeJS](https://nodejs.org).
ABP Angular provides the infrastructure to communicate with the ABP backend and offers utilities to simplify frontend development. We’ll explore and dive into the details under the following main topics:
- Development
- Core Functionality
- Utilities
- Customization
- Components
You can also make a [Quick Start](./quick-start.md)

2
docs/en/framework/ui/angular/quick-start.md

@ -1,5 +1,7 @@
# ABP Angular Quick Start # ABP Angular Quick Start
**In this version ABP uses Angular [17.3.x](https://github.com/angular/angular/tree/17.3.x) version. You don't have to install Angular CLI globally**
## How to Prepare Development Environment ## How to Prepare Development Environment
Please follow the steps below to prepare your development environment for Angular. Please follow the steps below to prepare your development environment for Angular.

Loading…
Cancel
Save