Browse Source

Merge pull request #19469 from abpframework/issue-19444

Use new `control flow` in angular components template.
pull/19511/head
Masum ULU 3 years ago
committed by GitHub
parent
commit
b8c5e8035d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 42
      npm/ng-packs/apps/dev-app/src/app/home/home.component.html
  2. 30
      npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.html
  3. 57
      npm/ng-packs/packages/account/src/lib/components/forgot-password/forgot-password.component.html
  4. 18
      npm/ng-packs/packages/account/src/lib/components/login/login.component.html
  5. 86
      npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.html
  6. 26
      npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings.component.html
  7. 99
      npm/ng-packs/packages/account/src/lib/components/register/register.component.html
  8. 78
      npm/ng-packs/packages/account/src/lib/components/reset-password/reset-password.component.html
  9. 291
      npm/ng-packs/packages/components/extensible/src/lib/components/extensible-form/extensible-form-prop.component.html
  10. 70
      npm/ng-packs/packages/components/page/src/page.component.html
  11. 37
      npm/ng-packs/packages/components/tree/src/lib/components/tree.component.html
  12. 7
      npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts
  13. 280
      npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.html
  14. 77
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.html
  15. 95
      npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html
  16. 10
      npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html
  17. 24
      npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html
  18. 13
      npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/account-layout.component.html
  19. 29
      npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/auth-wrapper/auth-wrapper.component.html
  20. 4
      npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/tenant-box/tenant-box.component.html
  21. 14
      npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.html
  22. 21
      npm/ng-packs/packages/theme-basic/src/lib/components/logo/logo.component.ts
  23. 123
      npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html
  24. 60
      npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/languages.component.ts
  25. 24
      npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html
  26. 32
      npm/ng-packs/packages/theme-basic/src/lib/components/page-alert-container/page-alert-container.component.html
  27. 47
      npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.html
  28. 8
      npm/ng-packs/packages/theme-basic/src/lib/components/validation-error/validation-error.component.ts
  29. 29
      npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb-items/breadcrumb-items.component.html
  30. 8
      npm/ng-packs/packages/theme-shared/src/lib/components/checkbox/checkbox.component.ts
  31. 89
      npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.html
  32. 8
      npm/ng-packs/packages/theme-shared/src/lib/components/form-input/form-input.component.ts
  33. 40
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html
  34. 11
      npm/ng-packs/packages/theme-shared/src/lib/components/toast-container/toast-container.component.html
  35. 8
      npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.html
  36. 5
      templates/app-nolayers/angular/src/app/home/home.component.html
  37. BIN
      templates/app-nolayers/angular/src/favicon.ico
  38. 68
      templates/app/angular/src/app/home/home.component.html
  39. BIN
      templates/app/angular/src/favicon.ico

42
npm/ng-packs/apps/dev-app/src/app/home/home.component.html

@ -10,17 +10,18 @@
<p class="lead px-lg-5 mx-lg-5">{{ '::LongWelcomeMessage' | abpLocalization }}</p> <p class="lead px-lg-5 mx-lg-5">{{ '::LongWelcomeMessage' | abpLocalization }}</p>
<abp-button @if (!hasLoggedIn) {
*ngIf="!hasLoggedIn" <abp-button
[loading]="loading" [loading]="loading"
(click)="login()" (click)="login()"
[disabled]="loading" [disabled]="loading"
class="px-4 ml-1" class="px-4 ml-1"
role="button" role="button"
iconClass="fa fa-sign-in" iconClass="fa fa-sign-in"
> >
{{ 'AbpAccount::Login' | abpLocalization }} {{ 'AbpAccount::Login' | abpLocalization }}
</abp-button> </abp-button>
}
</div> </div>
<div class="my-3 text-center"> <div class="my-3 text-center">
<h3>Let's improve your application!</h3> <h3>Let's improve your application!</h3>
@ -299,17 +300,14 @@
{{ context.title }} {{ context.title }}
</h5> </h5>
<p [innerHTML]="context.description"></p> <p [innerHTML]="context.description"></p>
<ng-container @if (context.customTemplate) {
*ngIf="context.customTemplate" <ng-container [ngTemplateOutlet]="context.customTemplate"></ng-container>
[ngTemplateOutlet]="context.customTemplate" }
></ng-container> @for (link of context.links; track $index) {
<a <a [href]="link.href" target="_blank" class="btn btn-link px-1"
*ngFor="let link of context.links" >{{ link.label }} <i class="fas fa-chevron-right" aria-hidden="true"></i
[href]="link.href" ></a>
target="_blank" }
class="btn btn-link px-1"
>{{ link.label }} <i class="fas fa-chevron-right" aria-hidden="true"></i
></a>
</div> </div>
</div> </div>
</ng-template> </ng-template>

30
npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.html

@ -1,18 +1,20 @@
<form [formGroup]="form" (ngSubmit)="onSubmit()" [mapErrorsFn]="mapErrorsFn" validateOnSubmit class="abp-md-form"> <form [formGroup]="form" (ngSubmit)="onSubmit()" [mapErrorsFn]="mapErrorsFn" validateOnSubmit class="abp-md-form">
<div *ngIf="!hideCurrentPassword" class="mb-3 form-group"> @if (!hideCurrentPassword) {
<label for="current-password" class="form-label">{{ <div class="mb-3 form-group">
'AbpIdentity::DisplayName:CurrentPassword' | abpLocalization <label for="current-password" class="form-label">{{
}}</label 'AbpIdentity::DisplayName:CurrentPassword' | abpLocalization
><span> * </span }}</label
><input ><span> * </span
type="password" ><input
id="current-password" type="password"
class="form-control" id="current-password"
formControlName="password" class="form-control"
autofocus formControlName="password"
autocomplete="current-password" autofocus
/> autocomplete="current-password"
</div> />
</div>
}
<div class="mb-3 form-group"> <div class="mb-3 form-group">
<label for="new-password" class="form-label">{{ <label for="new-password" class="form-label">{{
'AbpIdentity::DisplayName:NewPassword' | abpLocalization 'AbpIdentity::DisplayName:NewPassword' | abpLocalization

57
npm/ng-packs/packages/account/src/lib/components/forgot-password/forgot-password.component.html

@ -1,35 +1,30 @@
<h4>{{ 'AbpAccount::ForgotPassword' | abpLocalization }}</h4> <h4>{{ 'AbpAccount::ForgotPassword' | abpLocalization }}</h4>
<form @if (!isEmailSent) {
*ngIf="!isEmailSent; else emailSentTemplate" <form [formGroup]="form" (ngSubmit)="onSubmit()" validateOnSubmit>
[formGroup]="form" <p>{{ 'AbpAccount::SendPasswordResetLink_Information' | abpLocalization }}</p>
(ngSubmit)="onSubmit()" <div class="mb-3 form-group">
validateOnSubmit <label for="input-email-address" class="form-label">{{
> 'AbpAccount::EmailAddress' | abpLocalization
<p>{{ 'AbpAccount::SendPasswordResetLink_Information' | abpLocalization }}</p> }}</label
<div class="mb-3 form-group"> ><span> * </span>
<label for="input-email-address" class="form-label">{{ <input type="email" id="input-email-address" class="form-control" formControlName="email" />
'AbpAccount::EmailAddress' | abpLocalization </div>
}}</label <abp-button
><span> * </span> class="d-block"
<input type="email" id="input-email-address" class="form-control" formControlName="email" /> buttonClass="mt-2 mb-3 btn btn-primary btn-block"
</div> [loading]="inProgress"
<abp-button buttonType="submit"
class="d-block" [disabled]="form?.invalid"
buttonClass="mt-2 mb-3 btn btn-primary btn-block" >
[loading]="inProgress" {{ 'AbpAccount::Submit' | abpLocalization }}
buttonType="submit" </abp-button>
[disabled]="form?.invalid" <a routerLink="/account/login"
> ><i class="fa fa-long-arrow-left me-1" aria-hidden="true"></i
{{ 'AbpAccount::Submit' | abpLocalization }} >{{ 'AbpAccount::Login' | abpLocalization }}</a
</abp-button> >
<a routerLink="/account/login" </form>
><i class="fa fa-long-arrow-left me-1" aria-hidden="true"></i } @else {
>{{ 'AbpAccount::Login' | abpLocalization }}</a
>
</form>
<ng-template #emailSentTemplate>
<p> <p>
{{ 'AbpAccount::PasswordResetMailSentMessage' | abpLocalization }} {{ 'AbpAccount::PasswordResetMailSentMessage' | abpLocalization }}
</p> </p>
@ -40,4 +35,4 @@
{{ 'AbpAccount::BackToLogin' | abpLocalization }} {{ 'AbpAccount::BackToLogin' | abpLocalization }}
</button> </button>
</a> </a>
</ng-template> }

18
npm/ng-packs/packages/account/src/lib/components/login/login.component.html

@ -1,10 +1,12 @@
<h4>{{ 'AbpAccount::Login' | abpLocalization }}</h4> <h4>{{ 'AbpAccount::Login' | abpLocalization }}</h4>
<strong *ngIf="isSelfRegistrationEnabled"> @if (isSelfRegistrationEnabled) {
{{ 'AbpAccount::AreYouANewUser' | abpLocalization }} <strong>
<a class="text-decoration-none" routerLink="/account/register" queryParamsHandling="preserve">{{ {{ 'AbpAccount::AreYouANewUser' | abpLocalization }}
'AbpAccount::Register' | abpLocalization <a class="text-decoration-none" routerLink="/account/register" queryParamsHandling="preserve">{{
}}</a> 'AbpAccount::Register' | abpLocalization
</strong> }}</a>
</strong>
}
<form [formGroup]="form" (ngSubmit)="onSubmit()" validateOnSubmit class="mt-4"> <form [formGroup]="form" (ngSubmit)="onSubmit()" validateOnSubmit class="mt-4">
<div class="mb-3 form-group"> <div class="mb-3 form-group">
<label for="login-input-user-name-or-email-address" class="form-label">{{ <label for="login-input-user-name-or-email-address" class="form-label">{{
@ -20,7 +22,9 @@
/> />
</div> </div>
<div class="mb-3 form-group"> <div class="mb-3 form-group">
<label for="login-input-password" class="form-label">{{ 'AbpAccount::Password' | abpLocalization }}</label> <label for="login-input-password" class="form-label">{{
'AbpAccount::Password' | abpLocalization
}}</label>
<input <input
class="form-control" class="form-control"
type="password" type="password"

86
npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.html

@ -1,22 +1,20 @@
<div id="AbpContentToolbar"></div> <div id="AbpContentToolbar"></div>
<div class="card border-0 shadow-sm min-h-400" [abpLoading]="!(profile$ | async)?.userName" > <div class="card border-0 shadow-sm min-h-400" [abpLoading]="!(profile$ | async)?.userName">
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col-12 col-md-3"> <div class="col-12 col-md-3">
<ul class="nav flex-column nav-pills" id="nav-tab" role="tablist"> <ul class="nav flex-column nav-pills" id="nav-tab" role="tablist">
<li @if (!hideChangePasswordTab && (profile$ | async)) {
*ngIf="!hideChangePasswordTab && (profile$ | async)" <li class="nav-item" (click)="selectedTab = 0">
class="nav-item" <a
(click)="selectedTab = 0" class="nav-link"
> [ngClass]="{ active: selectedTab === 0 }"
<a role="tab"
class="nav-link" href="javascript:void(0)"
[ngClass]="{ active: selectedTab === 0 }" >{{ 'AbpUi::ChangePassword' | abpLocalization }}</a
role="tab" >
href="javascript:void(0)" </li>
>{{ 'AbpUi::ChangePassword' | abpLocalization }}</a }
>
</li>
<li class="nav-item mb-2" (click)="selectedTab = 1"> <li class="nav-item mb-2" (click)="selectedTab = 1">
<a <a
class="nav-link" class="nav-link"
@ -28,34 +26,40 @@
</li> </li>
</ul> </ul>
</div> </div>
<div *ngIf="profile$ | async" class="col-12 col-md-9"> @if (profile$ | async) {
<div class="tab-content" *ngIf="selectedTab === 0" [@fadeIn]> <div class="col-12 col-md-9">
<div class="tab-pane active" role="tabpanel"> @if (selectedTab === 0) {
<h4> <div class="tab-content" [@fadeIn]>
{{ 'AbpIdentity::ChangePassword' | abpLocalization }} <div class="tab-pane active" role="tabpanel">
<hr /> <h4>
</h4> {{ 'AbpIdentity::ChangePassword' | abpLocalization }}
<abp-change-password-form <hr />
*abpReplaceableTemplate="{ </h4>
componentKey: changePasswordKey <abp-change-password-form
}" *abpReplaceableTemplate="{
></abp-change-password-form> componentKey: changePasswordKey
</div> }"
></abp-change-password-form>
</div>
</div>
}
@if (selectedTab === 1) {
<div class="tab-content" [@fadeIn]>
<div class="tab-pane active" role="tabpanel">
<h4>
{{ 'AbpIdentity::PersonalSettings' | abpLocalization }}
<hr />
</h4>
<abp-personal-settings-form
*abpReplaceableTemplate="{
componentKey: personalSettingsKey
}"
></abp-personal-settings-form>
</div>
</div>
}
</div> </div>
<div class="tab-content" *ngIf="selectedTab === 1" [@fadeIn]> }
<div class="tab-pane active" role="tabpanel">
<h4>
{{ 'AbpIdentity::PersonalSettings' | abpLocalization }}
<hr />
</h4>
<abp-personal-settings-form
*abpReplaceableTemplate="{
componentKey: personalSettingsKey
}"
></abp-personal-settings-form>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

26
npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings.component.html

@ -1,12 +1,14 @@
<form [formGroup]="form" *ngIf="form" (ngSubmit)="submit()" validateOnSubmit class="abp-md-form"> @if (form) {
<abp-extensible-form [selectedRecord]="selected"></abp-extensible-form> <form [formGroup]="form" (ngSubmit)="submit()" validateOnSubmit class="abp-md-form">
<abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
<abp-button
buttonType="submit" <abp-button
iconClass="fa fa-check" buttonType="submit"
buttonClass="btn btn-primary color-white" iconClass="fa fa-check"
[loading]="inProgress" buttonClass="btn btn-primary color-white"
> [loading]="inProgress"
{{ 'AbpIdentity::Save' | abpLocalization }}</abp-button >
> {{ 'AbpIdentity::Save' | abpLocalization }}</abp-button
</form> >
</form>
}

99
npm/ng-packs/packages/account/src/lib/components/register/register.component.html

@ -5,53 +5,54 @@
'AbpAccount::Login' | abpLocalization 'AbpAccount::Login' | abpLocalization
}}</a> }}</a>
</strong> </strong>
<form @if (isSelfRegistrationEnabled) {
*ngIf="isSelfRegistrationEnabled" <form
[formGroup]="form" [formGroup]="form"
(ngSubmit)="onSubmit()" (ngSubmit)="onSubmit()"
validateOnSubmit validateOnSubmit
class="mt-4" class="mt-4"
>
<div class="mb-3 form-group">
<label for="input-user-name" class="form-label">{{
'AbpAccount::UserName' | abpLocalization
}}</label
><span> * </span
><input
autofocus
type="text"
id="input-user-name"
class="form-control"
formControlName="username"
autocomplete="username"
/>
</div>
<div class="mb-3 form-group">
<label for="input-email-address" class="form-label">{{
'AbpAccount::EmailAddress' | abpLocalization
}}</label
><span> * </span
><input type="email" id="input-email-address" class="form-control" formControlName="email" />
</div>
<div class="mb-3 form-group">
<label for="input-password" class="form-label">{{
'AbpAccount::Password' | abpLocalization
}}</label
><span> * </span
><input
type="password"
id="input-password"
class="form-control"
formControlName="password"
autocomplete="current-password"
/>
</div>
<abp-button
[loading]="inProgress"
buttonType="submit"
name="Action"
buttonClass="btn-block btn-lg mt-3 btn btn-primary"
> >
{{ 'AbpAccount::Register' | abpLocalization }} <div class="mb-3 form-group">
</abp-button> <label for="input-user-name" class="form-label">{{
</form> 'AbpAccount::UserName' | abpLocalization
}}</label
><span> * </span
><input
autofocus
type="text"
id="input-user-name"
class="form-control"
formControlName="username"
autocomplete="username"
/>
</div>
<div class="mb-3 form-group">
<label for="input-email-address" class="form-label">{{
'AbpAccount::EmailAddress' | abpLocalization
}}</label
><span> * </span
><input type="email" id="input-email-address" class="form-control" formControlName="email" />
</div>
<div class="mb-3 form-group">
<label for="input-password" class="form-label">{{
'AbpAccount::Password' | abpLocalization
}}</label
><span> * </span
><input
type="password"
id="input-password"
class="form-control"
formControlName="password"
autocomplete="current-password"
/>
</div>
<abp-button
[loading]="inProgress"
buttonType="submit"
name="Action"
buttonClass="btn-block btn-lg mt-3 btn btn-primary"
>
{{ 'AbpAccount::Register' | abpLocalization }}
</abp-button>
</form>
}

78
npm/ng-packs/packages/account/src/lib/components/reset-password/reset-password.component.html

@ -1,46 +1,40 @@
<h4>{{ 'AbpAccount::ResetPassword' | abpLocalization }}</h4> <h4>{{ 'AbpAccount::ResetPassword' | abpLocalization }}</h4>
<form @if (!isPasswordReset) {
*ngIf="!isPasswordReset; else passwordResetTemplate" <form [formGroup]="form" [mapErrorsFn]="mapErrorsFn" (ngSubmit)="onSubmit()" validateOnSubmit>
[formGroup]="form" <p>{{ 'AbpAccount::ResetPassword_Information' | abpLocalization }}</p>
[mapErrorsFn]="mapErrorsFn" <div class="mb-3 form-group">
(ngSubmit)="onSubmit()" <label for="input-password" class="form-label">{{
validateOnSubmit 'AbpAccount::Password' | abpLocalization
> }}</label
<p>{{ 'AbpAccount::ResetPassword_Information' | abpLocalization }}</p> ><span> * </span>
<div class="mb-3 form-group"> <input type="password" id="input-password" class="form-control" formControlName="password" />
<label for="input-password" class="form-label">{{ </div>
'AbpAccount::Password' | abpLocalization <div class="mb-3 form-group">
}}</label <label for="input-confirm-password" class="form-label">{{
><span> * </span> 'AbpAccount::ConfirmPassword' | abpLocalization
<input type="password" id="input-password" class="form-control" formControlName="password" /> }}</label
</div> ><span> * </span>
<div class="mb-3 form-group"> <input
<label for="input-confirm-password" class="form-label">{{ type="password"
'AbpAccount::ConfirmPassword' | abpLocalization id="input-confirm-password"
}}</label class="form-control"
><span> * </span> formControlName="confirmPassword"
<input />
type="password" </div>
id="input-confirm-password" <button class="me-2 btn btn-outline-primary" type="button" routerLink="/account/login">
class="form-control" {{ 'AbpAccount::Cancel' | abpLocalization }}
formControlName="confirmPassword" </button>
/> <abp-button
</div> buttonType="submit"
<button class="me-2 btn btn-outline-primary" type="button" routerLink="/account/login"> buttonClass="me-2 btn btn-primary"
{{ 'AbpAccount::Cancel' | abpLocalization }} [loading]="inProgress"
</button> (click)="onSubmit()"
<abp-button >
buttonType="submit" {{ 'AbpAccount::Submit' | abpLocalization }}
buttonClass="me-2 btn btn-primary" </abp-button>
[loading]="inProgress" </form>
(click)="onSubmit()" } @else {
>
{{ 'AbpAccount::Submit' | abpLocalization }}
</abp-button>
</form>
<ng-template #passwordResetTemplate>
<p> <p>
{{ 'AbpAccount::YourPasswordIsSuccessfullyReset' | abpLocalization }} {{ 'AbpAccount::YourPasswordIsSuccessfullyReset' | abpLocalization }}
</p> </p>
@ -50,4 +44,4 @@
{{ 'AbpAccount::BackToLogin' | abpLocalization }} {{ 'AbpAccount::BackToLogin' | abpLocalization }}
</button> </button>
</a> </a>
</ng-template> }

291
npm/ng-packs/packages/components/extensible/src/lib/components/extensible-form/extensible-form-prop.component.html

@ -1,168 +1,166 @@
<ng-container [ngSwitch]="getComponent(prop)" *abpPermission="prop.permission; runChangeDetection: false"> <ng-container *abpPermission="prop.permission; runChangeDetection: false">
<ng-template ngSwitchCase="template"> @switch (getComponent(prop)) {
<ng-container *ngComponentOutlet="prop.template; injector: injectorForCustomComponent"> @case ('template') {
</ng-container> <ng-container *ngComponentOutlet="prop.template; injector: injectorForCustomComponent">
</ng-template> </ng-container>
}
}
<div [ngClass]="containerClassName" class="mb-2"> <div [ngClass]="containerClassName" class="mb-2">
<ng-template ngSwitchCase="input"> @switch (getComponent(prop)) {
<ng-template [ngTemplateOutlet]="label"></ng-template> @case ('input') {
<input <ng-template [ngTemplateOutlet]="label"></ng-template>
#field
[id]="prop.id"
[formControlName]="prop.name"
[autocomplete]="prop.autocomplete"
[type]="getType(prop)"
[abpDisabled]="disabled"
[readonly]="readonly"
class="form-control"
/>
</ng-template>
<ng-template ngSwitchCase="hidden">
<input [formControlName]="prop.name" type="hidden" />
</ng-template>
<ng-template ngSwitchCase="checkbox">
<div class="form-check" validationTarget>
<input <input
#field #field
[id]="prop.id" [id]="prop.id"
[formControlName]="prop.name" [formControlName]="prop.name"
[autocomplete]="prop.autocomplete"
[type]="getType(prop)"
[abpDisabled]="disabled" [abpDisabled]="disabled"
type="checkbox" [readonly]="readonly"
class="form-check-input" class="form-control"
/> />
<ng-template }
[ngTemplateOutlet]="label"
[ngTemplateOutletContext]="{ $implicit: 'form-check-label' }"
></ng-template>
</div>
</ng-template>
<ng-template ngSwitchCase="select"> @case ('hidden') {
<ng-template [ngTemplateOutlet]="label"></ng-template> <input [formControlName]="prop.name" type="hidden" />
<select }
#field
[id]="prop.id"
[formControlName]="prop.name"
[abpDisabled]="disabled"
class="form-select form-control"
>
@for (option of options$ | async; track option.value) {
<option
[ngValue]="option.value"
>
{{ option.key }}
</option>
}
</select>
</ng-template>
<ng-template ngSwitchCase="multiselect"> @case ('checkbox') {
<ng-template [ngTemplateOutlet]="label"></ng-template> <div class="form-check" validationTarget>
<select <input
#field #field
[id]="prop.id" [id]="prop.id"
[formControlName]="prop.name" [formControlName]="prop.name"
[abpDisabled]="disabled" [abpDisabled]="disabled"
multiple="multiple" type="checkbox"
class="form-select form-control" class="form-check-input"
> />
<option <ng-template
*ngFor="let option of options$ | async; trackBy: track.by('value')" [ngTemplateOutlet]="label"
[ngValue]="option.value" [ngTemplateOutletContext]="{ $implicit: 'form-check-label' }"
> ></ng-template>
{{ option.key }} </div>
</option> }
</select>
</ng-template>
<ng-template ngSwitchCase="typeahead"> @case ('select') {
<ng-template [ngTemplateOutlet]="label"></ng-template> <ng-template [ngTemplateOutlet]="label"></ng-template>
<div #typeahead class="position-relative" validationStyle validationTarget> <select
<input
#field #field
[id]="prop.id" [id]="prop.id"
[autocomplete]="prop.autocomplete" [formControlName]="prop.name"
[abpDisabled]="disabled" [abpDisabled]="disabled"
[ngbTypeahead]="search" class="form-select form-control"
[editable]="false" >
[inputFormatter]="typeaheadFormatter" @for (option of options$ | async; track option.value) {
[resultFormatter]="typeaheadFormatter" <option [ngValue]="option.value">
[ngModelOptions]="{ standalone: true }" {{ option.key }}
[(ngModel)]="typeaheadModel" </option>
(selectItem)="setTypeaheadValue($event.item)" }
(blur)="setTypeaheadValue(typeaheadModel)" </select>
[class.is-invalid]="typeahead.classList.contains('is-invalid')" }
class="form-control"
/>
<input [formControlName]="prop.name" type="hidden" />
</div>
</ng-template>
<ng-template ngSwitchCase="date">
<ng-template [ngTemplateOutlet]="label"></ng-template>
<input
[id]="prop.id"
[formControlName]="prop.name"
(click)="datepicker.open()"
(keyup.space)="datepicker.open()"
ngbDatepicker
#datepicker="ngbDatepicker"
type="text"
class="form-control"
/>
</ng-template>
<ng-template ngSwitchCase="time">
<ng-template [ngTemplateOutlet]="label"></ng-template>
<ngb-timepicker [formControlName]="prop.name"></ngb-timepicker>
</ng-template>
<ng-template ngSwitchCase="dateTime"> @case ('multiselect') {
<ng-template [ngTemplateOutlet]="label"></ng-template> <ng-template [ngTemplateOutlet]="label"></ng-template>
<abp-extensible-date-time-picker [prop]="prop" [meridian]="meridian$ | async" /> <select
</ng-template> #field
[id]="prop.id"
[formControlName]="prop.name"
[abpDisabled]="disabled"
multiple="multiple"
class="form-select form-control"
>
@for (option of options$ | async; track option.value) {
<option [ngValue]="option.value">
{{ option.key }}
</option>
}
</select>
}
<ng-template ngSwitchCase="textarea"> @case ('typeahead') {
<ng-template [ngTemplateOutlet]="label"></ng-template> <ng-template [ngTemplateOutlet]="label"></ng-template>
<textarea <div #typeahead class="position-relative" validationStyle validationTarget>
#field <input
[id]="prop.id" #field
[formControlName]="prop.name" [id]="prop.id"
[abpDisabled]="disabled" [autocomplete]="prop.autocomplete"
[readonly]="readonly" [abpDisabled]="disabled"
class="form-control" [ngbTypeahead]="search"
></textarea> [editable]="false"
</ng-template> [inputFormatter]="typeaheadFormatter"
[resultFormatter]="typeaheadFormatter"
[ngModelOptions]="{ standalone: true }"
[(ngModel)]="typeaheadModel"
(selectItem)="setTypeaheadValue($event.item)"
(blur)="setTypeaheadValue(typeaheadModel)"
[class.is-invalid]="typeahead.classList.contains('is-invalid')"
class="form-control"
/>
<input [formControlName]="prop.name" type="hidden" />
</div>
}
<ng-template ngSwitchCase="passwordinputgroup"> @case ('date') {
<ng-template [ngTemplateOutlet]="label"></ng-template> <ng-template [ngTemplateOutlet]="label"></ng-template>
<div class="input-group form-group" validationTarget>
<input <input
class="form-control"
[id]="prop.id" [id]="prop.id"
[formControlName]="prop.name" [formControlName]="prop.name"
[abpShowPassword]="showPassword" (click)="datepicker.open()"
(keyup.space)="datepicker.open()"
ngbDatepicker
#datepicker="ngbDatepicker"
type="text"
class="form-control"
/> />
<button class="btn btn-secondary" type="button" (click)="showPassword = !showPassword"> }
<i @case ('time') {
class="fa" <ng-template [ngTemplateOutlet]="label"></ng-template>
aria-hidden="true" <ngb-timepicker [formControlName]="prop.name"></ngb-timepicker>
[ngClass]="{ }
'fa-eye-slash': !showPassword,
'fa-eye': showPassword @case ('dateTime') {
}" <ng-template [ngTemplateOutlet]="label"></ng-template>
></i> <abp-extensible-date-time-picker [prop]="prop" [meridian]="meridian$ | async" />
</button> }
</div>
</ng-template> @case ('textarea') {
<ng-template [ngTemplateOutlet]="label"></ng-template>
<textarea
#field
[id]="prop.id"
[formControlName]="prop.name"
[abpDisabled]="disabled"
[readonly]="readonly"
class="form-control"
></textarea>
}
@case ('passwordinputgroup') {
<ng-template [ngTemplateOutlet]="label"></ng-template>
<div class="input-group form-group" validationTarget>
<input
class="form-control"
[id]="prop.id"
[formControlName]="prop.name"
[abpShowPassword]="showPassword"
/>
<button class="btn btn-secondary" type="button" (click)="showPassword = !showPassword">
<i
class="fa"
aria-hidden="true"
[ngClass]="{
'fa-eye-slash': !showPassword,
'fa-eye': showPassword
}"
></i>
</button>
</div>
}
}
@if (prop.formText) { @if (prop.formText) {
<small class="text-muted d-block">{{ <small class="text-muted d-block">{{ prop.formText | abpLocalization }}</small>
prop.formText | abpLocalization
}}</small>
} }
</div> </div>
</ng-container> </ng-container>
@ -171,12 +169,17 @@
<label [htmlFor]="prop.id" [ngClass]="classes || 'form-label'"> <label [htmlFor]="prop.id" [ngClass]="classes || 'form-label'">
@if (prop.displayTextResolver) { @if (prop.displayTextResolver) {
{{ prop.displayTextResolver(data) | abpLocalization }} {{ prop.displayTextResolver(data) | abpLocalization }}
}@else{ } @else {
{{ prop.displayName | abpLocalization }} {{ prop.displayName | abpLocalization }}
} }
{{ asterisk }} {{ asterisk }}
@if (prop.tooltip) { @if (prop.tooltip) {
<i [ngbTooltip]="prop.tooltip.text | abpLocalization" [placement]="prop.tooltip.placement || 'auto'" container="body" class="bi bi-info-circle"></i> <i
[ngbTooltip]="prop.tooltip.text | abpLocalization"
[placement]="prop.tooltip.placement || 'auto'"
container="body"
class="bi bi-info-circle"
></i>
} }
</label> </label>
</ng-template> </ng-template>

70
npm/ng-packs/packages/components/page/src/page.component.html

@ -1,41 +1,37 @@
<div class="row entry-row" *ngIf="shouldRenderRow"> @if (shouldRenderRow) {
<ng-container *ngIf="customTitle; else defaultTitleTemplate"> <div class="row entry-row">
<ng-content select="abp-page-title-container"></ng-content> @if (customTitle) {
</ng-container> <ng-content select="abp-page-title-container"></ng-content>
} @else {
@if (title) {
<div class="col-auto" *abpPagePart="pageParts.title">
<h1 class="content-header-title">
{{ title }}
</h1>
</div>
}
}
<ng-container *ngIf="customBreadcrumb; else defaultBreadcrumbTemplate"> @if (customBreadcrumb) {
<ng-content select="abp-page-breadcrumb-container"></ng-content> <ng-content select="abp-page-breadcrumb-container"></ng-content>
</ng-container> } @else {
@if (breadcrumb) {
<div class="col-lg-auto ps-lg-0" *abpPagePart="pageParts.breadcrumb">
<abp-breadcrumb></abp-breadcrumb>
</div>
}
}
<ng-container *ngIf="customToolbar; else defaultPageToolbarTemplate"> @if (customToolbar) {
<ng-content select="abp-page-toolbar-container"></ng-content> <ng-content select="abp-page-toolbar-container"></ng-content>
</ng-container> } @else {
</div> @if (toolbarVisible) {
<div class="col" *abpPagePart="pageParts.toolbar; context: toolbarData">
<abp-page-toolbar [record]="toolbarData"></abp-page-toolbar>
</div>
}
}
</div>
}
<ng-content></ng-content> <ng-content></ng-content>
<ng-template #defaultTitleTemplate>
<ng-container *ngIf="title">
<div class="col-auto" *abpPagePart="pageParts.title">
<h1 class="content-header-title">
{{ title }}
</h1>
</div>
</ng-container>
</ng-template>
<ng-template #defaultBreadcrumbTemplate>
<ng-container *ngIf="breadcrumb">
<div class="col-lg-auto ps-lg-0" *abpPagePart="pageParts.breadcrumb">
<abp-breadcrumb></abp-breadcrumb>
</div>
</ng-container>
</ng-template>
<ng-template #defaultPageToolbarTemplate>
<ng-container *ngIf="toolbarVisible">
<div class="col" *abpPagePart="pageParts.toolbar; context: toolbarData">
<abp-page-toolbar [record]="toolbarData"></abp-page-toolbar>
</div>
</ng-container>
</ng-template>

37
npm/ng-packs/packages/components/tree/src/lib/components/tree.component.html

@ -32,25 +32,26 @@
></ng-container> ></ng-container>
</div> </div>
<div @if (menu) {
#dropdown="ngbDropdown" <div
*ngIf="menu" #dropdown="ngbDropdown"
class="d-inline-block ms-1" class="d-inline-block ms-1"
ngbDropdown ngbDropdown
placement="bottom" placement="bottom"
container="body" container="body"
(abpInit)="initDropdown(node.key, dropdown)" (abpInit)="initDropdown(node.key, dropdown)"
> >
<i <i
class="fas fa-caret-down text-muted" class="fas fa-caret-down text-muted"
ngbDropdownToggle ngbDropdownToggle
[class.dropdown-toggle]="false" [class.dropdown-toggle]="false"
aria-hidden="true" aria-hidden="true"
></i> ></i>
<div ngbDropdownMenu> <div ngbDropdownMenu>
<ng-template *ngTemplateOutlet="menu; context: { $implicit: node }"></ng-template> <ng-template *ngTemplateOutlet="menu; context: { $implicit: node }"></ng-template>
</div>
</div> </div>
</div> }
</ng-template> </ng-template>
<ng-template #defaultNodeTemplate let-node> <ng-template #defaultNodeTemplate let-node>

7
npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts

@ -15,7 +15,11 @@ import { EnvironmentService } from '../services';
@Component({ @Component({
selector: 'abp-dynamic-layout', selector: 'abp-dynamic-layout',
template: ` <ng-container *ngIf="isLayoutVisible" [ngComponentOutlet]="layout"></ng-container> `, template: `
@if (isLayoutVisible) {
<ng-container [ngComponentOutlet]="layout"></ng-container>
}
`,
providers: [SubscriptionService], providers: [SubscriptionService],
}) })
export class DynamicLayoutComponent implements OnInit { export class DynamicLayoutComponent implements OnInit {
@ -24,6 +28,7 @@ export class DynamicLayoutComponent implements OnInit {
readonly layouts = inject(DYNAMIC_LAYOUTS_TOKEN); readonly layouts = inject(DYNAMIC_LAYOUTS_TOKEN);
isLayoutVisible = true; isLayoutVisible = true;
protected readonly router = inject(Router); protected readonly router = inject(Router);
protected readonly route = inject(ActivatedRoute); protected readonly route = inject(ActivatedRoute);
protected readonly routes = inject(RoutesService); protected readonly routes = inject(RoutesService);

280
npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.html

@ -1,145 +1,161 @@
<abp-modal *ngIf="visible" [(visible)]="visible" [busy]="modalBusy" [options]="{ size: 'lg' }"> @if (visible) {
<ng-template #abpHeader> <abp-modal [(visible)]="visible" [busy]="modalBusy" [options]="{ size: 'lg' }">
<h3>{{ 'AbpFeatureManagement::Features' | abpLocalization }}</h3> <ng-template #abpHeader>
</ng-template> <h3>{{ 'AbpFeatureManagement::Features' | abpLocalization }}</h3>
</ng-template>
<ng-template #abpBody> <ng-template #abpBody>
<div class="row"> <div class="row">
<ng-container *ngIf="groups.length"> @if (groups.length) {
<div class="col-md-4"> <div class="col-md-4">
<ul <ul
ngbNav ngbNav
#nav="ngbNav" #nav="ngbNav"
[(activeId)]="selectedGroupDisplayName" [(activeId)]="selectedGroupDisplayName"
class="nav-pills" class="nav-pills"
orientation="vertical" orientation="vertical"
>
<li
*ngFor="let group of groups; trackBy: track.by('name')"
[ngbNavItem]="group.displayName"
> >
<a ngbNavLink>{{ group.displayName }}</a> @for (group of groups; track group.name) {
<ng-template ngbNavContent> <li [ngbNavItem]="group.displayName">
<h4>{{ selectedGroupDisplayName }}</h4> <a ngbNavLink>{{ group.displayName }}</a>
<hr class="mt-2 mb-3" /> <ng-template ngbNavContent>
<h4>{{ selectedGroupDisplayName }}</h4>
<hr class="mt-2 mb-3" />
<div @for (feature of features[group.name]; track feature.id; let i = $index) {
class="mt-2" <div class="mt-2" [ngStyle]="feature.style" (keyup.enter)="save()">
*ngFor=" @switch (feature.valueType?.name) {
let feature of features[group.name]; @case (valueTypes.ToggleStringValueType) {
let i = index; <div class="form-check">
trackBy: track.by('id') <input
" class="form-check-input"
[ngStyle]="feature.style" type="checkbox"
[ngSwitch]="feature.valueType?.name" [id]="feature.name"
(keyup.enter)="save()" [(ngModel)]="feature.value"
> (ngModelChange)="onCheckboxClick($event, feature)"
<ng-container *ngSwitchCase="valueTypes.ToggleStringValueType"> />
<div class="form-check">
<input
class="form-check-input"
type="checkbox"
[id]="feature.name"
[(ngModel)]="feature.value"
(ngModelChange)="onCheckboxClick($event, feature)"
/>
<label class="form-check-label" [htmlFor]="feature.name">{{ <label class="form-check-label" [htmlFor]="feature.name">{{
feature.displayName feature.displayName
}}</label> }}</label>
<ng-container <ng-container
*ngTemplateOutlet="descTmp; context: { $implicit: feature.description }" *ngTemplateOutlet="
></ng-container> descTmp;
</div> context: { $implicit: feature.description }
</ng-container> "
<ng-container *ngSwitchCase="valueTypes.FreeTextStringValueType"> ></ng-container>
<div class="mb-3 form-group"> </div>
<label [htmlFor]="feature.name" class="form-label">{{ }
feature.displayName @case (valueTypes.FreeTextStringValueType) {
}}</label> <div class="mb-3 form-group">
<input <label [htmlFor]="feature.name" class="form-label">{{
class="form-control" feature.displayName
type="text" }}</label>
[id]="feature.name" <input
[(ngModel)]="feature.value" class="form-control"
[abpFeatureManagementFreeText]="feature" type="text"
/> [id]="feature.name"
[(ngModel)]="feature.value"
[abpFeatureManagementFreeText]="feature"
/>
<ng-container <ng-container
*ngTemplateOutlet="descTmp; context: { $implicit: feature.description }" *ngTemplateOutlet="
></ng-container> descTmp;
</div> context: { $implicit: feature.description }
</ng-container> "
<ng-container *ngSwitchCase="valueTypes.SelectionStringValueType"> ></ng-container>
<ng-container *ngIf="feature.valueType.itemSource?.items?.length"> </div>
<div class="mb-3 form-group"> }
<label [htmlFor]="feature.name" class="form-label">{{ @case (valueTypes.SelectionStringValueType) {
feature.displayName @if (feature.valueType.itemSource?.items?.length) {
}}</label> <div class="mb-3 form-group">
<select class="form-select" [id]="feature.name" [(ngModel)]="feature.value"> <label [htmlFor]="feature.name" class="form-label">{{
<option feature.displayName
*ngFor=" }}</label>
let item of feature.valueType.itemSource?.items; <select
trackBy: track.by('value') class="form-select"
" [id]="feature.name"
[ngValue]="item.value" [(ngModel)]="feature.value"
> >
{{ @for (
item.displayText?.resourceName + '::' + item.displayText?.name item of feature.valueType.itemSource?.items;
| abpLocalization track item.value
}} ) {
</option> <option [ngValue]="item.value">
</select> {{
<ng-container item.displayText?.resourceName +
*ngTemplateOutlet="descTmp; context: { $implicit: feature.description }" '::' +
></ng-container> item.displayText?.name | abpLocalization
}}
</option>
}
</select>
<ng-container
*ngTemplateOutlet="
descTmp;
context: { $implicit: feature.description }
"
></ng-container>
</div>
}
}
@default {
{{ feature.displayName }}
}
}
</div> </div>
</ng-container> }
</ng-container> </ng-template>
<ng-container *ngSwitchDefault>{{ feature.displayName }}</ng-container> </li>
</div> }
</ng-template> </ul>
</li> </div>
</ul>
</div>
<ng-template #descTmp let-description> <ng-template #descTmp let-description>
<small *ngIf="description" class="d-block form-text text-muted">{{ description }}</small> @if (description) {
</ng-template> <small class="d-block form-text text-muted">{{ description }}</small>
}
</ng-template>
<div class="col-md-8"><div class="py-0" [ngbNavOutlet]="nav"></div></div> <div class="col-md-8"><div class="py-0" [ngbNavOutlet]="nav"></div></div>
</ng-container> }
<div class="col" *ngIf="!groups.length"> @if (!groups.length) {
{{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }} <div class="col">
{{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }}
</div>
}
</div> </div>
</div> </ng-template>
</ng-template>
<ng-template #abpFooter> <ng-template #abpFooter>
<button abpClose type="button" class="btn btn-link"> <button abpClose type="button" class="btn btn-link">
{{ 'AbpFeatureManagement::Cancel' | abpLocalization }} {{ 'AbpFeatureManagement::Cancel' | abpLocalization }}
</button> </button>
<abp-button @if (groups.length) {
*ngIf="groups.length" <abp-button
iconClass="fa fa-refresh" iconClass="fa fa-refresh"
buttonClass="btn btn-outline-primary" buttonClass="btn btn-outline-primary"
[disabled]="modalBusy" [disabled]="modalBusy"
(click)="resetToDefault()" (click)="resetToDefault()"
aria-hidden="true" aria-hidden="true"
> >
{{ 'AbpFeatureManagement::ResetToDefault' | abpLocalization }} {{ 'AbpFeatureManagement::ResetToDefault' | abpLocalization }}
</abp-button> </abp-button>
}
<abp-button @if (groups.length) {
*ngIf="groups.length" <abp-button
iconClass="fa fa-check" iconClass="fa fa-check"
[disabled]="modalBusy" [disabled]="modalBusy"
(click)="save()" (click)="save()"
aria-hidden="true" aria-hidden="true"
> >
{{ 'AbpFeatureManagement::Save' | abpLocalization }} {{ 'AbpFeatureManagement::Save' | abpLocalization }}
</abp-button> </abp-button>
</ng-template> }
</abp-modal> </ng-template>
</abp-modal>
}

77
npm/ng-packs/packages/identity/src/lib/components/users/users.component.html

@ -26,46 +26,45 @@
</ng-template> </ng-template>
<ng-template #abpBody> <ng-template #abpBody>
<ng-template #loaderRef> @if (form) {
<div class="text-center"><i class="fa fa-pulse fa-spinner" aria-hidden="true"></i></div> <form [formGroup]="form" (ngSubmit)="save()">
</ng-template> <ul ngbNav #nav="ngbNav" class="nav-tabs">
<li ngbNavItem>
<form *ngIf="form; else loaderRef" [formGroup]="form" (ngSubmit)="save()"> <a ngbNavLink>{{ 'AbpIdentity::UserInformations' | abpLocalization }}</a>
<ul ngbNav #nav="ngbNav" class="nav-tabs"> <ng-template ngbNavContent>
<li ngbNavItem> <abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
<a ngbNavLink>{{ 'AbpIdentity::UserInformations' | abpLocalization }}</a> </ng-template>
<ng-template ngbNavContent> </li>
<abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
</ng-template>
</li>
<li ngbNavItem> <li ngbNavItem>
<a ngbNavLink>{{ 'AbpIdentity::Roles' | abpLocalization }}</a> <a ngbNavLink>{{ 'AbpIdentity::Roles' | abpLocalization }}</a>
<ng-template ngbNavContent> <ng-template ngbNavContent>
<div @for (roleGroup of roleGroups; track $index; let i = $index) {
*ngFor="let roleGroup of roleGroups; let i = index; trackBy: trackByFn" <div class="form-check mb-2">
class="form-check mb-2" <abp-checkbox
> *abpReplaceableTemplate="{
<abp-checkbox inputs: {
*abpReplaceableTemplate="{ checkboxId: 'roles-' + i,
inputs: { label: roles[i].name,
checkboxId: 'roles-' + i, formControl: roleGroup.controls[roles[i].name]
label: roles[i].name, },
formControl: roleGroup.controls[roles[i].name] componentKey: inputKey
}, }"
componentKey: inputKey [checkboxId]="'roles-' + i"
}" [formControl]="roleGroup.controls[roles[i].name]"
[checkboxId]="'roles-' + i" [label]="roles[i].name"
[formControl]="roleGroup.controls[roles[i].name]" >
[label]="roles[i].name" </abp-checkbox>
> </div>
</abp-checkbox> }
</div> </ng-template>
</ng-template> </li>
</li> </ul>
</ul> <div class="mt-2 fade-in-top" [ngbNavOutlet]="nav"></div>
<div class="mt-2 fade-in-top" [ngbNavOutlet]="nav"></div> </form>
</form> } @else {
<div class="text-center"><i class="fa fa-pulse fa-spinner" aria-hidden="true"></i></div>
}
</ng-template> </ng-template>
<ng-template #abpFooter> <ng-template #abpFooter>

95
npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html

@ -1,5 +1,5 @@
<abp-modal [(visible)]="visible" [busy]="modalBusy" [options]="{ size: 'lg' ,scrollable:false }"> <abp-modal [(visible)]="visible" [busy]="modalBusy" [options]="{ size: 'lg', scrollable: false }">
<ng-container *ngIf="data.entityDisplayName || entityDisplayName"> @if (data.entityDisplayName || entityDisplayName) {
<ng-template #abpHeader> <ng-template #abpHeader>
<h4> <h4>
{{ 'AbpPermissionManagement::Permissions' | abpLocalization }} - {{ 'AbpPermissionManagement::Permissions' | abpLocalization }} -
@ -28,23 +28,28 @@
<hr class="mt-2 mb-2" /> <hr class="mt-2 mb-2" />
<div class="overflow-auto"> <div class="overflow-auto">
<ul class="nav nav-pills flex-column"> <ul class="nav nav-pills flex-column">
<li *ngFor="let group of data.groups; trackBy: trackByFn" class="nav-item"> @for (group of data.groups; track $index) {
<a <li class="nav-item">
*ngIf="{ assignedCount: getAssignedCount(group.name) } as count" @if ({ assignedCount: getAssignedCount(group.name) }; as count) {
class="nav-link pointer" <a
[class.active]="selectedGroup?.name === group?.name" class="nav-link pointer"
(click)="onChangeGroup(group)" [class.active]="selectedGroup?.name === group?.name"
(select)="setDisabled(group.permissions)" (click)="onChangeGroup(group)"
> (select)="setDisabled(group.permissions)"
<div [class.font-weight-bold]="count.assignedCount"> >
{{ group?.displayName }} <div [class.font-weight-bold]="count.assignedCount">
<span *ngIf="count.assignedCount > 0">({{ count.assignedCount }})</span> {{ group?.displayName }}
</div> @if (count.assignedCount > 0) {
</a> <span>({{ count.assignedCount }})</span>
</li> }
</div>
</a>
}
</li>
}
</ul> </ul>
</div> </div>
</div> </div>
<div class="col-md-8 scroll-in-modal"> <div class="col-md-8 scroll-in-modal">
<div class="ps-1"> <div class="ps-1">
@ -64,32 +69,34 @@
}}</label> }}</label>
</div> </div>
<hr class="my-2" /> <hr class="my-2" />
<div @for (permission of selectedGroupPermissions; track $index; let i = $index) {
*ngFor="let permission of selectedGroupPermissions; let i = index; trackBy: trackByFn" <div
[ngStyle]="permission.style" [ngStyle]="permission.style"
class="form-check mb-2" class="form-check mb-2"
> >
<input <input
#permissionCheckbox #permissionCheckbox
type="checkbox" type="checkbox"
[checked]="getChecked(permission.name)" [checked]="getChecked(permission.name)"
[value]="getChecked(permission.name)" [value]="getChecked(permission.name)"
[attr.id]="permission.name" [attr.id]="permission.name"
class="form-check-input" class="form-check-input"
[disabled]="isGrantedByOtherProviderName(permission.grantedProviders)" [disabled]="isGrantedByOtherProviderName(permission.grantedProviders)"
(click)="onClickCheckbox(permission, permissionCheckbox.value)" (click)="onClickCheckbox(permission, permissionCheckbox.value)"
/> />
<label class="form-check-label" [attr.for]="permission.name" <label class="form-check-label" [attr.for]="permission.name"
>{{ permission.displayName }} >{{ permission.displayName }}
<ng-container *ngIf="!hideBadges"> @if (!hideBadges) {
<span @for (provider of permission.grantedProviders; track $index) {
*ngFor="let provider of permission.grantedProviders" <span
class="badge bg-light text-dark" class="badge bg-light text-dark"
>{{ provider.providerName }}: {{ provider.providerKey }}</span >{{ provider.providerName }}: {{ provider.providerKey }}</span
> >
</ng-container> }
</label> }
</div> </label>
</div>
}
</div> </div>
</div> </div>
</div> </div>
@ -102,5 +109,5 @@
'AbpIdentity::Save' | abpLocalization 'AbpIdentity::Save' | abpLocalization
}}</abp-button> }}</abp-button>
</ng-template> </ng-template>
</ng-container> }
</abp-modal> </abp-modal>

10
npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html

@ -23,11 +23,13 @@
</ul> </ul>
</div> </div>
<div class="col-12 col-md-9"> <div class="col-12 col-md-9">
<div *ngIf="settings.length" class="tab-content"> @if (settings.length) {
<div class="tab-pane fade show active" [id]="selected.name + '-tab'" role="tabpanel"> <div class="tab-content">
<ng-container *ngComponentOutlet="selected.component"></ng-container> <div class="tab-pane fade show active" [id]="selected.name + '-tab'" role="tabpanel">
<ng-container *ngComponentOutlet="selected.component"></ng-container>
</div>
</div> </div>
</div> }
</div> </div>
</div> </div>
</div> </div>

24
npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html

@ -1,6 +1,4 @@
<abp-page [title]="'AbpTenantManagement::Tenants' | abpLocalization" [toolbar]="data.items"> <abp-page [title]="'AbpTenantManagement::Tenants' | abpLocalization" [toolbar]="data.items">
<div id="wrapper" class="card"> <div id="wrapper" class="card">
<div class="card-body"> <div class="card-body">
<div id="data-tables-table-filter" class="data-tables-filter mb-3"> <div id="data-tables-table-filter" class="data-tables-filter mb-3">
@ -26,8 +24,8 @@
<ng-template #abpHeader> <ng-template #abpHeader>
<h3> <h3>
{{ {{
(selected?.id ? 'AbpTenantManagement::Edit' : 'AbpTenantManagement::NewTenant') (selected?.id ? 'AbpTenantManagement::Edit' : 'AbpTenantManagement::NewTenant')
| abpLocalization | abpLocalization
}} }}
</h3> </h3>
</ng-template> </ng-template>
@ -44,20 +42,20 @@
</button> </button>
<abp-button iconClass="fa fa-check" (click)="save()" [disabled]="tenantForm?.invalid">{{ <abp-button iconClass="fa fa-check" (click)="save()" [disabled]="tenantForm?.invalid">{{
'AbpTenantManagement::Save' | abpLocalization 'AbpTenantManagement::Save' | abpLocalization
}}</abp-button> }}</abp-button>
</ng-template> </ng-template>
</abp-modal> </abp-modal>
<abp-feature-management <abp-feature-management
*abpReplaceableTemplate="{ *abpReplaceableTemplate="{
inputs: { inputs: {
providerName: { value: 'T' }, providerName: { value: 'T' },
providerKey: { value: providerKey }, providerKey: { value: providerKey },
visible: { value: visibleFeatures, twoWay: true } visible: { value: visibleFeatures, twoWay: true }
}, },
outputs: { visibleChange: $any(onVisibleFeaturesChange) }, outputs: { visibleChange: $any(onVisibleFeaturesChange) },
componentKey: featureManagementKey componentKey: featureManagementKey
}" }"
[(visible)]="visibleFeatures" [(visible)]="visibleFeatures"
providerName="T" providerName="T"
[providerKey]="providerKey" [providerKey]="providerKey"

13
npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/account-layout.component.html

@ -20,12 +20,13 @@
> >
<ng-container *ngTemplateOutlet="!service.smallScreen ? navigations : null"></ng-container> <ng-container *ngTemplateOutlet="!service.smallScreen ? navigations : null"></ng-container>
<div @if (service.smallScreen) {
*ngIf="service.smallScreen" <div
[@collapseWithMargin]="service.isCollapsed ? 'collapsed' : 'expanded'" [@collapseWithMargin]="service.isCollapsed ? 'collapsed' : 'expanded'"
> >
<ng-container *ngTemplateOutlet="navigations"></ng-container> <ng-container *ngTemplateOutlet="navigations"></ng-container>
</div> </div>
}
<ng-template #navigations> <ng-template #navigations>
<abp-routes <abp-routes

29
npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/auth-wrapper/auth-wrapper.component.html

@ -1,27 +1,24 @@
<div class="row"> <div class="row">
<div class="mx-auto col col-md-5"> <div class="mx-auto col col-md-5">
<ng-container *ngIf="(service.isMultiTenancyEnabled$ | async) && service.isTenantBoxVisible"> @if ((service.isMultiTenancyEnabled$ | async) && service.isTenantBoxVisible) {
<abp-tenant-box <abp-tenant-box
*abpReplaceableTemplate="{ componentKey: service.tenantBoxKey }" *abpReplaceableTemplate="{ componentKey: service.tenantBoxKey }"
></abp-tenant-box> ></abp-tenant-box>
</ng-container> }
<div class="abp-account-container"> <div class="abp-account-container">
<div @if (service.enableLocalLogin$ | async) {
*ngIf="service.enableLocalLogin$ | async; else disableLocalLoginTemplate" <div class="card mt-3 shadow-sm rounded">
class="card mt-3 shadow-sm rounded" <div class="card-body p-5">
> <ng-content></ng-content>
<div class="card-body p-5"> </div>
<ng-content></ng-content>
</div> </div>
</div> } @else {
<div class="alert alert-warning">
<strong>{{ 'AbpAccount::InvalidLoginRequest' | abpLocalization }}</strong>
{{ 'AbpAccount::ThereAreNoLoginSchemesConfiguredForThisClient' | abpLocalization }}
</div>
}
</div> </div>
</div> </div>
</div> </div>
<ng-template #disableLocalLoginTemplate>
<div class="alert alert-warning">
<strong>{{ 'AbpAccount::InvalidLoginRequest' | abpLocalization }}</strong>
{{ 'AbpAccount::ThereAreNoLoginSchemesConfiguredForThisClient' | abpLocalization }}
</div>
</ng-template>

4
npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/tenant-box/tenant-box.component.html

@ -1,4 +1,4 @@
<ng-container *ngIf="(service.currentTenant$ | async) || { name: '' } as currentTenant"> @if ((service.currentTenant$ | async) || { name: '' }; as currentTenant) {
<div class="card shadow-sm rounded mb-3"> <div class="card shadow-sm rounded mb-3">
<div class="card-body px-5"> <div class="card-body px-5">
<div class="row"> <div class="row">
@ -62,4 +62,4 @@
</abp-button> </abp-button>
</ng-template> </ng-template>
</abp-modal> </abp-modal>
</ng-container> }

14
npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.html

@ -13,12 +13,18 @@
> >
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="navbar-collapse" [class.overflow-hidden]="service.smallScreen" id="main-navbar-collapse"> <div
class="navbar-collapse"
[class.overflow-hidden]="service.smallScreen"
id="main-navbar-collapse"
>
<ng-container *ngTemplateOutlet="!service.smallScreen ? navigations : null"></ng-container> <ng-container *ngTemplateOutlet="!service.smallScreen ? navigations : null"></ng-container>
<div *ngIf="service.smallScreen" [@collapseWithMargin]="service.isCollapsed ? 'collapsed' : 'expanded'"> @if (service.smallScreen) {
<ng-container *ngTemplateOutlet="navigations"></ng-container> <div [@collapseWithMargin]="service.isCollapsed ? 'collapsed' : 'expanded'">
</div> <ng-container *ngTemplateOutlet="navigations"></ng-container>
</div>
}
<ng-template #navigations> <ng-template #navigations>
<abp-routes <abp-routes

21
npm/ng-packs/packages/theme-basic/src/lib/components/logo/logo.component.ts

@ -5,18 +5,17 @@ import { Component } from '@angular/core';
selector: 'abp-logo', selector: 'abp-logo',
template: ` template: `
<a class="navbar-brand" routerLink="/"> <a class="navbar-brand" routerLink="/">
<img @if (appInfo.logoUrl) {
*ngIf="appInfo.logoUrl; else appName" <img
[src]="appInfo.logoUrl" [src]="appInfo.logoUrl"
[alt]="appInfo.name" [alt]="appInfo.name"
width="100%" width="100%"
height="auto" height="auto"
/> />
} @else {
{{ appInfo.name }}
}
</a> </a>
<ng-template #appName>
{{ appInfo.name }}
</ng-template>
`, `,
}) })
export class LogoComponent { export class LogoComponent {

123
npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.html

@ -1,65 +1,64 @@
<ng-template #loginBtn> @if ((currentUser$ | async)?.isAuthenticated) {
<a role="button" class="nav-link pointer" (click)="navigateToLogin()">{{
'AbpAccount::Login' | abpLocalization
}}</a>
</ng-template>
<div
*ngIf="(currentUser$ | async)?.isAuthenticated; else loginBtn"
ngbDropdown
class="dropdown"
#currentUserDropdown="ngbDropdown"
display="static"
>
<a
ngbDropdownToggle
class="nav-link"
href="javascript:void(0)"
role="button"
id="dropdownMenuLink"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<small *ngIf="(selectedTenant$ | async)?.name as tenantName"
><i>{{ tenantName }}</i
>\</small
>
<strong>{{ (currentUser$ | async)?.userName }}</strong>
</a>
<div <div
class="dropdown-menu dropdown-menu-end border-0 shadow-sm" ngbDropdown
aria-labelledby="dropdownMenuLink" class="dropdown"
[class.d-block]="smallScreen && currentUserDropdown.isOpen()" #currentUserDropdown="ngbDropdown"
display="static"
> >
<ng-container *ngFor="let item of userMenu.items$ | async; trackBy: trackByFn"> <a
<ng-container *abpVisible="!item.visible || item.visible(item)"> ngbDropdownToggle
<li class="nav-item d-flex align-items-center" *abpPermission="item.requiredPolicy"> class="nav-link"
<ng-container href="javascript:void(0)"
*ngIf="item.component; else htmlTemplate" role="button"
[ngComponentOutlet]="item.component" id="dropdownMenuLink"
[ngComponentOutletInjector]="item | toInjector" data-toggle="dropdown"
></ng-container> aria-haspopup="true"
aria-expanded="false"
<ng-template #htmlTemplate> >
<div @if ((selectedTenant$ | async)?.name; as tenantName) {
*ngIf="item.html; else textTemplate" <small
[innerHTML]="item.html" ><i>{{ tenantName }}</i
(click)="item.action ? item.action() : null" >\</small
></div> >
</ng-template> }
<strong>{{ (currentUser$ | async)?.userName }}</strong>
<ng-template #textTemplate> </a>
<a <div
*ngIf="item.textTemplate" class="dropdown-menu dropdown-menu-end border-0 shadow-sm"
(click)="item.action ? item.action() : null" aria-labelledby="dropdownMenuLink"
class="dropdown-item pointer" [class.d-block]="smallScreen && currentUserDropdown.isOpen()"
> >
<i *ngIf="item.textTemplate.icon" class="me-1 {{ item.textTemplate.icon }}"></i> @for (item of userMenu.items$ | async; track $index) {
{{ item.textTemplate.text | abpLocalization }}</a <ng-container *abpVisible="!item.visible || item.visible(item)">
> <li class="nav-item d-flex align-items-center" *abpPermission="item.requiredPolicy">
</ng-template> @if (item.component) {
</li> <ng-container
</ng-container> [ngComponentOutlet]="item.component"
</ng-container> [ngComponentOutletInjector]="item | toInjector"
></ng-container>
} @else {
@if (item.html) {
<div [innerHTML]="item.html" (click)="item.action ? item.action() : null"></div>
} @else {
@if (item.textTemplate) {
<a (click)="item.action ? item.action() : null" class="dropdown-item pointer">
@if (item.textTemplate.icon) {
<i class="me-1 {{ item.textTemplate.icon }}"></i>
}
{{ item.textTemplate.text | abpLocalization }}</a
>
}
}
}
</li>
</ng-container>
}
</div>
</div> </div>
</div> } @else {
<ng-template #loginBtn>
<a role="button" class="nav-link pointer" (click)="navigateToLogin()">{{
'AbpAccount::Login' | abpLocalization
}}</a>
</ng-template>
}

60
npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/languages.component.ts

@ -6,39 +6,36 @@ import { map } from 'rxjs/operators';
@Component({ @Component({
selector: 'abp-languages', selector: 'abp-languages',
template: ` template: `
<div @if (((dropdownLanguages$ | async)?.length || 0) > 0) {
*ngIf="((dropdownLanguages$ | async)?.length || 0) > 0" <div class="dropdown" ngbDropdown #languageDropdown="ngbDropdown" display="static">
class="dropdown"
ngbDropdown
#languageDropdown="ngbDropdown"
display="static"
>
<a
ngbDropdownToggle
class="nav-link"
href="javascript:void(0)"
role="button"
id="dropdownMenuLink"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
{{ defaultLanguage$ | async }}
</a>
<div
class="dropdown-menu dropdown-menu-end border-0 shadow-sm"
aria-labelledby="dropdownMenuLink"
[class.d-block]="smallScreen && languageDropdown.isOpen()"
>
<a <a
*ngFor="let lang of dropdownLanguages$ | async" ngbDropdownToggle
class="nav-link"
href="javascript:void(0)" href="javascript:void(0)"
class="dropdown-item" role="button"
(click)="onChangeLang(lang.cultureName || '')" id="dropdownMenuLink"
>{{ lang?.displayName }}</a data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
> >
{{ defaultLanguage$ | async }}
</a>
<div
class="dropdown-menu dropdown-menu-end border-0 shadow-sm"
aria-labelledby="dropdownMenuLink"
[class.d-block]="smallScreen && languageDropdown.isOpen()"
>
@for (lang of dropdownLanguages$ | async; track $index) {
<a
href="javascript:void(0)"
class="dropdown-item"
(click)="onChangeLang(lang.cultureName || '')"
>{{ lang?.displayName }}</a
>
}
</div>
</div> </div>
</div> }
`, `,
}) })
export class LanguagesComponent { export class LanguagesComponent {
@ -69,7 +66,10 @@ export class LanguagesComponent {
return this.sessionState.getLanguage(); return this.sessionState.getLanguage();
} }
constructor(private sessionState: SessionStateService, private configState: ConfigStateService) {} constructor(
private sessionState: SessionStateService,
private configState: ConfigStateService,
) {}
onChangeLang(cultureName: string) { onChangeLang(cultureName: string) {
this.sessionState.setLanguage(cultureName); this.sessionState.setLanguage(cultureName);

24
npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html

@ -1,18 +1,16 @@
<ul class="navbar-nav"> <ul class="navbar-nav">
<ng-container *ngFor="let item of navItems.items$ | async; trackBy: trackByFn"> @for (item of navItems.items$ | async; track $index) {
<ng-container *abpVisible="!item.visible || item.visible(item)"> <ng-container *abpVisible="!item.visible || item.visible(item)">
<li class="nav-item d-flex align-items-center" *abpPermission="item.requiredPolicy"> <li class="nav-item d-flex align-items-center" *abpPermission="item.requiredPolicy">
<ng-container @if (item.component) {
<ng-container
*ngIf="item.component; else htmlTemplate" [ngComponentOutlet]="item.component"
[ngComponentOutlet]="item.component" [ngComponentOutletInjector]="item | toInjector"
[ngComponentOutletInjector]="item | toInjector" ></ng-container>
></ng-container> } @else {
<ng-template #htmlTemplate>
<div [innerHTML]="item.html" (click)="item.action ? item.action() : null"></div> <div [innerHTML]="item.html" (click)="item.action ? item.action() : null"></div>
</ng-template> }
</li> </li>
</ng-container> </ng-container>
</ng-container> }
</ul> </ul>

32
npm/ng-packs/packages/theme-basic/src/lib/components/page-alert-container/page-alert-container.component.html

@ -1,24 +1,26 @@
<ng-container *ngFor="let alert of service.alerts$ | async; let i = index"> @for (alert of service.alerts$ | async; track i; let i = $index) {
<div <div
class="alert alert-{{ alert.type }} fade show" class="alert alert-{{ alert.type }} fade show"
[ngClass]="{ 'alert-dismissible fade show': alert.dismissible }" [ngClass]="{ 'alert-dismissible fade show': alert.dismissible }"
role="alert" role="alert"
> >
<h4 @if (alert.title) {
class="alert-heading" <h4
*ngIf="alert.title" class="alert-heading"
[innerHTML]="alert.title | abpSafeHtml | abpLocalization: alert.titleLocalizationParams" [innerHTML]="alert.title | abpSafeHtml | abpLocalization: alert.titleLocalizationParams"
></h4> ></h4>
}
<span <span
[innerHTML]="alert.message | abpSafeHtml | abpLocalization: alert.messageLocalizationParams" [innerHTML]="alert.message | abpSafeHtml | abpLocalization: alert.messageLocalizationParams"
></span> ></span>
<button @if (alert.dismissible) {
*ngIf="alert.dismissible" <button
type="button" type="button"
class="btn-close" class="btn-close"
data-dismiss="alert" data-dismiss="alert"
aria-label="Close" aria-label="Close"
(click)="service.remove(i)" (click)="service.remove(i)"
></button> ></button>
}
</div> </div>
</ng-container> }

47
npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.html

@ -1,22 +1,25 @@
<ul class="navbar-nav"> <ul class="navbar-nav">
<ng-container @for (route of routesService.visible$ | async; track $index) {
*ngFor="let route of routesService.visible$ | async; trackBy: trackByFn" <ng-container
[ngTemplateOutlet]="isDropdown(route) ? dropdownLink : defaultLink" [ngTemplateOutlet]="isDropdown(route) ? dropdownLink : defaultLink"
[ngTemplateOutletContext]="{ $implicit: route }" [ngTemplateOutletContext]="{ $implicit: route }"
> >
</ng-container> </ng-container>
}
<ng-template #defaultLink let-route> <ng-template #defaultLink let-route>
<li class="nav-item" *abpPermission="route.requiredPolicy"> <li class="nav-item" *abpPermission="route.requiredPolicy">
<a class="nav-link" [routerLink]="[route.path]" <a class="nav-link" [routerLink]="[route.path]">
><i *ngIf="route.iconClass" [ngClass]="route.iconClass"></i> @if (route.iconClass) {
{{ route.name | abpLocalization }}</a <i [ngClass]="route.iconClass"></i>
> }
{{ route.name | abpLocalization }}
</a>
</li> </li>
</ng-template> </ng-template>
<ng-template #dropdownLink let-route> <ng-template #dropdownLink let-route>
<ng-container *ngIf="route.children?.length"> @if (route.children?.length) {
<li <li
class="nav-item dropdown" class="nav-item dropdown"
display="static" display="static"
@ -34,7 +37,9 @@
aria-expanded="false" aria-expanded="false"
href="javascript:void(0)" href="javascript:void(0)"
> >
<i *ngIf="route.iconClass" [ngClass]="route.iconClass"></i> @if (route.iconClass) {
<i [ngClass]="route.iconClass"></i>
}
{{ route.name | abpLocalization }} {{ route.name | abpLocalization }}
</a> </a>
<div <div
@ -48,27 +53,29 @@
></ng-container> ></ng-container>
</div> </div>
</li> </li>
</ng-container> }
</ng-template> </ng-template>
<ng-template #forTemplate let-route> <ng-template #forTemplate let-route>
<ng-container *ngFor="let child of route.children"> @for (child of route.children; track $index) {
<ng-template <ng-template
[ngTemplateOutlet]="child.children?.length ? dropdownChild : defaultChild" [ngTemplateOutlet]="child.children?.length ? dropdownChild : defaultChild"
[ngTemplateOutletContext]="{ $implicit: child }" [ngTemplateOutletContext]="{ $implicit: child }"
></ng-template> ></ng-template>
</ng-container> }
</ng-template> </ng-template>
<ng-template #defaultChild let-child> <ng-template #defaultChild let-child>
<ng-container *ngIf="child.path"> @if (child.path) {
<div class="dropdown-submenu" *abpPermission="child.requiredPolicy"> <div class="dropdown-submenu" *abpPermission="child.requiredPolicy">
<a class="dropdown-item" [routerLink]="[child.path]" (click)="closeDropdown()"> <a class="dropdown-item" [routerLink]="[child.path]" (click)="closeDropdown()">
<i *ngIf="child.iconClass" [ngClass]="child.iconClass"></i> @if (child.iconClass) {
<i [ngClass]="child.iconClass"></i>
}
{{ child.name | abpLocalization }}</a {{ child.name | abpLocalization }}</a
> >
</div> </div>
</ng-container> }
</ng-template> </ng-template>
<ng-template #dropdownChild let-child> <ng-template #dropdownChild let-child>
@ -87,7 +94,9 @@
role="button" role="button"
class="btn d-block text-start dropdown-toggle" class="btn d-block text-start dropdown-toggle"
> >
<i *ngIf="child.iconClass" [ngClass]="child.iconClass"></i> @if (child.iconClass) {
<i [ngClass]="child.iconClass"></i>
}
{{ child.name | abpLocalization }} {{ child.name | abpLocalization }}
</a> </a>
</div> </div>

8
npm/ng-packs/packages/theme-basic/src/lib/components/validation-error/validation-error.component.ts

@ -4,9 +4,11 @@ import { Validation, ValidationErrorComponent as ErrorComponent } from '@ngx-val
@Component({ @Component({
selector: 'abp-validation-error', selector: 'abp-validation-error',
template: ` template: `
<div class="invalid-feedback" *ngFor="let error of abpErrors; trackBy: trackByFn"> @for (error of abpErrors; track $index) {
{{ error.message | abpLocalization: error.interpoliteParams }} <div class="invalid-feedback" >
</div> {{ error.message | abpLocalization: error.interpoliteParams }}
</div>
}
`, `,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,

29
npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb-items/breadcrumb-items.component.html

@ -1,18 +1,17 @@
<ol class="breadcrumb" *ngIf="items.length"> @if (items.length) {
<li class="breadcrumb-item"> <ol class="breadcrumb">
<a routerLink="/"><i class="fa fa-home" aria-hidden="true"></i> </a> <li class="breadcrumb-item">
</li> <a routerLink="/"><i class="fa fa-home" aria-hidden="true"></i> </a>
<li </li>
*ngFor="let item of items; let last = last" @for (item of items; track $index; let last = $last) {
class="breadcrumb-item" <li class="breadcrumb-item" [class.active]="last" aria-current="page">
[class.active]="last" <ng-container
aria-current="page" *ngTemplateOutlet="item.path ? linkTemplate : textTemplate; context: { $implicit: item }"
> ></ng-container>
<ng-container </li>
*ngTemplateOutlet="item.path ? linkTemplate : textTemplate; context: { $implicit: item }" }
></ng-container> </ol>
</li> }
</ol>
<ng-template #linkTemplate let-item> <ng-template #linkTemplate let-item>
<a [routerLink]="item.path"> {{ item.name | abpLocalization }}</a> <a [routerLink]="item.path"> {{ item.name | abpLocalization }}</a>

8
npm/ng-packs/packages/theme-shared/src/lib/components/checkbox/checkbox.component.ts

@ -16,9 +16,11 @@ import { NG_VALUE_ACCESSOR } from '@angular/forms';
(blur)="checkboxBlur.next()" (blur)="checkboxBlur.next()"
(focus)="checkboxFocus.next()" (focus)="checkboxFocus.next()"
/> />
<label *ngIf="label" [ngClass]="labelClass" [for]="checkboxId"> @if (label) {
{{ label | abpLocalization }} <label [ngClass]="labelClass" [for]="checkboxId">
</label> {{ label | abpLocalization }}
</label>
}
</div> </div>
`, `,
providers: [ providers: [

89
npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.html

@ -1,42 +1,51 @@
<div class="confirmation" *ngIf="confirmation$ | async as data"> @if (confirmation$ | async; as data) {
<div <div class="confirmation">
class="confirmation-backdrop" <div
(click)="data.options?.dismissible ? close(dismiss) : null" class="confirmation-backdrop"
></div> (click)="data.options?.dismissible ? close(dismiss) : null"
<div class="confirmation-dialog"> ></div>
<div class="icon-container" [ngClass]="data.severity" *ngIf="data.severity || isCustomIconExists(data)"> <div class="confirmation-dialog">
<div [outerHTML]="data.options.iconTemplate" *ngIf="isIconTemplateExits(data); else iconHolder" ></div> @if (data.severity || isCustomIconExists(data)) {
<ng-template #iconHolder> <div class="icon-container" [ngClass]="data.severity">
<i class="icon" [ngClass]="getIconClass(data)"></i> @if (isIconTemplateExits(data)) {
</ng-template> <div [outerHTML]="data.options.iconTemplate"></div>
</div> } @else {
<div class="content"> <i class="icon" [ngClass]="getIconClass(data)"></i>
<h1 }
class="title" </div>
*ngIf="data.title" }
[innerHTML]="data.title | abpLocalization: data.options?.titleLocalizationParams" <div class="content">
></h1> @if (data.title) {
<p <h1
class="message" class="title"
*ngIf="data.message" [innerHTML]="data.title | abpLocalization: data.options?.titleLocalizationParams"
[innerHTML]="data.message | abpLocalization: data.options?.messageLocalizationParams" ></h1>
></p> }
</div> @if (data.message) {
<div class="footer"> <p
<button class="message"
id="cancel" [innerHTML]="data.message | abpLocalization: data.options?.messageLocalizationParams"
class="btn btn-outline-primary me-2" ></p>
[innerHTML]="data.options?.cancelText || 'AbpUi::Cancel' | abpLocalization" }
*ngIf="!data?.options?.hideCancelBtn" </div>
(click)="close(reject)" <div class="footer">
></button> @if (!data?.options?.hideCancelBtn) {
<button <button
id="confirm" id="cancel"
class="btn btn-primary" class="btn btn-outline-primary me-2"
[innerHTML]="data.options?.yesText || 'AbpUi::Yes' | abpLocalization" [innerHTML]="data.options?.cancelText || 'AbpUi::Cancel' | abpLocalization"
*ngIf="!data?.options?.hideYesBtn" (click)="close(reject)"
(click)="close(confirm)" ></button>
></button> }
@if (!data?.options?.hideYesBtn) {
<button
id="confirm"
class="btn btn-primary"
[innerHTML]="data.options?.yesText || 'AbpUi::Yes' | abpLocalization"
(click)="close(confirm)"
></button>
}
</div>
</div> </div>
</div> </div>
</div> }

8
npm/ng-packs/packages/theme-shared/src/lib/components/form-input/form-input.component.ts

@ -6,9 +6,11 @@ import { NG_VALUE_ACCESSOR } from '@angular/forms';
selector: 'abp-form-input', selector: 'abp-form-input',
template: ` template: `
<div class="mb-3"> <div class="mb-3">
<label *ngIf="label" [ngClass]="labelClass" [for]="inputId"> @if (label) {
{{ label | abpLocalization }} <label [ngClass]="labelClass" [for]="inputId">
</label> {{ label | abpLocalization }}
</label>
}
<input <input
type="text" type="text"
[id]="inputId" [id]="inputId"

40
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html

@ -1,21 +1,27 @@
<ng-content></ng-content> <ng-content></ng-content>
<ng-template #modalContent let-modal> <ng-template #modalContent let-modal>
<div *ngIf="abpHeader" id="abp-modal-header" class="modal-header abp-modal-header"> @if (abpHeader) {
<ng-container *ngTemplateOutlet="abpHeader"></ng-container> <div id="abp-modal-header" class="modal-header abp-modal-header">
​ <ng-container *ngTemplateOutlet="abpHeader"></ng-container>
<button ​
id="abp-modal-close-button" <button
type="button" id="abp-modal-close-button"
class="btn-sm btn-close" type="button"
aria-label="Close" class="btn-sm btn-close"
(click)="modal.dismiss()" aria-label="Close"
></button> (click)="modal.dismiss()"
</div> ></button>
<div *ngIf="abpBody" id="abp-modal-body" class="modal-body"> </div>
<ng-container *ngTemplateOutlet="abpBody"></ng-container> }
</div> @if (abpBody) {
<div *ngIf="abpFooter" id="abp-modal-footer" class="modal-footer"> <div id="abp-modal-body" class="modal-body">
<ng-container *ngTemplateOutlet="abpFooter"></ng-container> <ng-container *ngTemplateOutlet="abpBody"></ng-container>
</div> </div>
}
@if (abpFooter) {
<div id="abp-modal-footer" class="modal-footer">
<ng-container *ngTemplateOutlet="abpFooter"></ng-container>
</div>
}
</ng-template> </ng-template>

11
npm/ng-packs/packages/theme-shared/src/lib/components/toast-container/toast-container.component.html

@ -7,9 +7,10 @@
[style.display]="toasts.length ? 'flex' : 'none'" [style.display]="toasts.length ? 'flex' : 'none'"
[@toastInOut]="toasts.length" [@toastInOut]="toasts.length"
> >
<abp-toast @for (toast of toasts; track toast.options?.id) {
[toast]="toast" <abp-toast
*ngFor="let toast of toasts; trackBy: trackByFunc" [toast]="toast"
(remove)="remove($event)" (remove)="remove($event)"
></abp-toast> ></abp-toast>
}
</div> </div>

8
npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.html

@ -3,9 +3,11 @@
<i class="fa icon" [ngClass]="iconClass" aria-hidden="true"></i> <i class="fa icon" [ngClass]="iconClass" aria-hidden="true"></i>
</div> </div>
<div class="abp-toast-content"> <div class="abp-toast-content">
<button class="abp-toast-close-button" (click)="close()" *ngIf="toast.options?.closable"> @if (toast.options?.closable) {
<i class="fa fa-times" aria-hidden="true"></i> <button class="abp-toast-close-button" (click)="close()">
</button> <i class="fa fa-times" aria-hidden="true"></i>
</button>
}
<div class="abp-toast-title"> <div class="abp-toast-title">
{{ toast.title | abpLocalization: toast.options?.titleLocalizationParams }} {{ toast.title | abpLocalization: toast.options?.titleLocalizationParams }}
</div> </div>

5
templates/app-nolayers/angular/src/app/home/home.component.html

@ -7,9 +7,10 @@
</div> </div>
<div class="card-body"> <div class="card-body">
@if(!hasLoggedIn){ @if(!hasLoggedIn){
<button class="btn btn-primary mb-2" (click)="login()">{{ 'AbpUi::Login' | abpLocalization }}</button> <button class="btn btn-primary mb-2" (click)="login()">
{{ 'AbpUi::Login' | abpLocalization }}
</button>
} }
<p>{{ '::Welcome_Text' | abpLocalization }}</p> <p>{{ '::Welcome_Text' | abpLocalization }}</p>
</div> </div>
</div> </div>

BIN
templates/app-nolayers/angular/src/favicon.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

68
templates/app/angular/src/app/home/home.component.html

@ -2,39 +2,51 @@
<div class="p-5 text-center"> <div class="p-5 text-center">
<div class="d-inline-block bg-success text-white p-1 h5 rounded mb-4" role="alert"> <div class="d-inline-block bg-success text-white p-1 h5 rounded mb-4" role="alert">
<h5 class="m-1"> <h5 class="m-1">
<i class="fas fa-rocket" aria-hidden="true"></i> Congratulations, <strong>MyProjectName</strong> is <i class="fas fa-rocket" aria-hidden="true"></i> Congratulations,
successfully running! <strong>MyProjectName</strong> is successfully running!
</h5> </h5>
</div> </div>
<h1>{{ '::Welcome' | abpLocalization }}</h1> <h1>{{ '::Welcome' | abpLocalization }}</h1>
<p class="lead px-lg-5 mx-lg-5">{{ '::LongWelcomeMessage' | abpLocalization }}</p> <p class="lead px-lg-5 mx-lg-5">{{ '::LongWelcomeMessage' | abpLocalization }}</p>
<a *ngIf="!hasLoggedIn" (click)="login()" class="px-4 btn btn-primary ms-1" role="button" @if(!hasLoggedIn){
><i class="fa fa-sign-in" aria-hidden="true"></i> {{ 'AbpAccount::Login' | abpLocalization }}</a <a (click)="login()" class="px-4 btn btn-primary ms-1" role="button"
> ><i class="fa fa-sign-in" aria-hidden="true"></i>
{{ 'AbpAccount::Login' | abpLocalization }}</a
>
}
</div> </div>
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col-md-auto text-center"> <div class="col-md-auto text-center">
<img src="https://abp.io/assets/png/mastering-abp-framework.webp" style="max-width: 400px;" <img
class="w-100 mb-5 my-md-3"> src="https://abp.io/assets/png/mastering-abp-framework.webp"
style="max-width: 400px"
class="w-100 mb-5 my-md-3"
/>
</div> </div>
<div class="col-md d-flex align-items-center"> <div class="col-md d-flex align-items-center">
<div class="pe-0 pe-md-4"> <div class="pe-0 pe-md-4">
<small class="text-uppercase text-muted">THE OFFICIAL GUIDE</small> <small class="text-uppercase text-muted">THE OFFICIAL GUIDE</small>
<h2 class="mb-4">Mastering ABP Framework</h2> <h2 class="mb-4">Mastering ABP Framework</h2>
<p class="mb-4">Written by the creator of the ABP Framework, this book will help you gain a complete <p class="mb-4">
understanding of the framework and modern web application development techniques.</p> Written by the creator of the ABP Framework, this book will help you gain a complete
understanding of the framework and modern web application development techniques.
</p>
<div class="mb-4"> <div class="mb-4">
<a href="https://www.amazon.com/gp/product/B097Z2DM8Q/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i0" <a
class="btn btn-success mb-1"> href="https://www.amazon.com/gp/product/B097Z2DM8Q/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i0"
class="btn btn-success mb-1"
>
Buy on Amazon US Buy on Amazon US
</a> </a>
&nbsp; &nbsp;
<a href="https://www.packtpub.com/product/mastering-abp-framework/9781801079242" <a
class="btn btn-primary mb-1"> href="https://www.packtpub.com/product/mastering-abp-framework/9781801079242"
class="btn btn-primary mb-1"
>
Buy on PACKT Buy on PACKT
</a> </a>
</div> </div>
@ -297,13 +309,16 @@
<div class="mb-5 text-center"> <div class="mb-5 text-center">
<p class="align-middle"> <p class="align-middle">
<a href="https://twitter.com/abpframework" target="_blank" class="mx-2" <a href="https://twitter.com/abpframework" target="_blank" class="mx-2"
><i class="fa fa-twitter" aria-hidden="true"></i><span class="text-secondary"> Abp Framework</span></a ><i class="fa fa-twitter" aria-hidden="true"></i
><span class="text-secondary"> Abp Framework</span></a
> >
<a href="https://twitter.com/abpcommercial" target="_blank" class="mx-2" <a href="https://twitter.com/abpcommercial" target="_blank" class="mx-2"
><i class="fa fa-twitter" aria-hidden="true"></i><span class="text-secondary"> Abp Commercial</span></a ><i class="fa fa-twitter" aria-hidden="true"></i
><span class="text-secondary"> Abp Commercial</span></a
> >
<a href="https://github.com/abpframework/abp" target="_blank" class="mx-2" <a href="https://github.com/abpframework/abp" target="_blank" class="mx-2"
><i class="fa fa-github" aria-hidden="true"></i><span class="text-secondary"> abpframework</span></a ><i class="fa fa-github" aria-hidden="true"></i
><span class="text-secondary"> abpframework</span></a
> >
</p> </p>
</div> </div>
@ -313,20 +328,17 @@
<div class="col-lg-4 border-start"> <div class="col-lg-4 border-start">
<div class="p-4"> <div class="p-4">
<h5 class="mb-3"> <h5 class="mb-3">
<i class="fas fa-cubes text-secondary d-block my-3 fa-2x" aria-hidden="true"></i> {{ context.title }} <i class="fas fa-cubes text-secondary d-block my-3 fa-2x" aria-hidden="true"></i>
{{ context.title }}
</h5> </h5>
<p [innerHTML]="context.description"></p> <p [innerHTML]="context.description"></p>
<ng-container @if (context.customTemplate) {
*ngIf="context.customTemplate" <ng-container [ngTemplateOutlet]="context.customTemplate"></ng-container>
[ngTemplateOutlet]="context.customTemplate" } @for (link of context.links; track $index) {
></ng-container> <a [href]="link.href" target="_blank" class="btn btn-link px-1"
<a >{{ link.label }} <i class="fas fa-chevron-right" aria-hidden="true"></i
*ngFor="let link of context.links"
[href]="link.href"
target="_blank"
class="btn btn-link px-1"
>{{ link.label }} <i class="fas fa-chevron-right" aria-hidden="true"></i
></a> ></a>
}
</div> </div>
</div> </div>
</ng-template> </ng-template>
@ -338,7 +350,7 @@
<i class="fas fa-plus d-block mb-3 fa- 2x text-secondary" aria-hidden="true"></i> <i class="fas fa-plus d-block mb-3 fa- 2x text-secondary" aria-hidden="true"></i>
<span [innerHTML]="context.title"></span> <span [innerHTML]="context.title"></span>
<a [href]="context.href" target="_blank" class="d-block mt-2 btn btn-sm btn-link" <a [href]="context.href" target="_blank" class="d-block mt-2 btn btn-sm btn-link"
>Details <i class="fas fa-chevron-right" aria-hidden="true"></i >Details <i class="fas fa-chevron-right" aria-hidden="true"></i
></a> ></a>
</h6> </h6>
</div> </div>

BIN
templates/app/angular/src/favicon.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Loading…
Cancel
Save