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>
<abp-button
*ngIf="!hasLoggedIn"
[loading]="loading"
(click)="login()"
[disabled]="loading"
class="px-4 ml-1"
role="button"
iconClass="fa fa-sign-in"
>
{{ 'AbpAccount::Login' | abpLocalization }}
</abp-button>
@if (!hasLoggedIn) {
<abp-button
[loading]="loading"
(click)="login()"
[disabled]="loading"
class="px-4 ml-1"
role="button"
iconClass="fa fa-sign-in"
>
{{ 'AbpAccount::Login' | abpLocalization }}
</abp-button>
}
</div>
<div class="my-3 text-center">
<h3>Let's improve your application!</h3>
@ -299,17 +300,14 @@
{{ context.title }}
</h5>
<p [innerHTML]="context.description"></p>
<ng-container
*ngIf="context.customTemplate"
[ngTemplateOutlet]="context.customTemplate"
></ng-container>
<a
*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>
@if (context.customTemplate) {
<ng-container [ngTemplateOutlet]="context.customTemplate"></ng-container>
}
@for (link of context.links; track $index) {
<a [href]="link.href" target="_blank" class="btn btn-link px-1"
>{{ link.label }} <i class="fas fa-chevron-right" aria-hidden="true"></i
></a>
}
</div>
</div>
</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">
<div *ngIf="!hideCurrentPassword" class="mb-3 form-group">
<label for="current-password" class="form-label">{{
'AbpIdentity::DisplayName:CurrentPassword' | abpLocalization
}}</label
><span> * </span
><input
type="password"
id="current-password"
class="form-control"
formControlName="password"
autofocus
autocomplete="current-password"
/>
</div>
@if (!hideCurrentPassword) {
<div class="mb-3 form-group">
<label for="current-password" class="form-label">{{
'AbpIdentity::DisplayName:CurrentPassword' | abpLocalization
}}</label
><span> * </span
><input
type="password"
id="current-password"
class="form-control"
formControlName="password"
autofocus
autocomplete="current-password"
/>
</div>
}
<div class="mb-3 form-group">
<label for="new-password" class="form-label">{{
'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>
<form
*ngIf="!isEmailSent; else emailSentTemplate"
[formGroup]="form"
(ngSubmit)="onSubmit()"
validateOnSubmit
>
<p>{{ 'AbpAccount::SendPasswordResetLink_Information' | abpLocalization }}</p>
<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>
<abp-button
class="d-block"
buttonClass="mt-2 mb-3 btn btn-primary btn-block"
[loading]="inProgress"
buttonType="submit"
[disabled]="form?.invalid"
>
{{ 'AbpAccount::Submit' | abpLocalization }}
</abp-button>
<a routerLink="/account/login"
><i class="fa fa-long-arrow-left me-1" aria-hidden="true"></i
>{{ 'AbpAccount::Login' | abpLocalization }}</a
>
</form>
<ng-template #emailSentTemplate>
@if (!isEmailSent) {
<form [formGroup]="form" (ngSubmit)="onSubmit()" validateOnSubmit>
<p>{{ 'AbpAccount::SendPasswordResetLink_Information' | abpLocalization }}</p>
<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>
<abp-button
class="d-block"
buttonClass="mt-2 mb-3 btn btn-primary btn-block"
[loading]="inProgress"
buttonType="submit"
[disabled]="form?.invalid"
>
{{ 'AbpAccount::Submit' | abpLocalization }}
</abp-button>
<a routerLink="/account/login"
><i class="fa fa-long-arrow-left me-1" aria-hidden="true"></i
>{{ 'AbpAccount::Login' | abpLocalization }}</a
>
</form>
} @else {
<p>
{{ 'AbpAccount::PasswordResetMailSentMessage' | abpLocalization }}
</p>
@ -40,4 +35,4 @@
{{ 'AbpAccount::BackToLogin' | abpLocalization }}
</button>
</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>
<strong *ngIf="isSelfRegistrationEnabled">
{{ 'AbpAccount::AreYouANewUser' | abpLocalization }}
<a class="text-decoration-none" routerLink="/account/register" queryParamsHandling="preserve">{{
'AbpAccount::Register' | abpLocalization
}}</a>
</strong>
@if (isSelfRegistrationEnabled) {
<strong>
{{ 'AbpAccount::AreYouANewUser' | abpLocalization }}
<a class="text-decoration-none" routerLink="/account/register" queryParamsHandling="preserve">{{
'AbpAccount::Register' | abpLocalization
}}</a>
</strong>
}
<form [formGroup]="form" (ngSubmit)="onSubmit()" validateOnSubmit class="mt-4">
<div class="mb-3 form-group">
<label for="login-input-user-name-or-email-address" class="form-label">{{
@ -20,7 +22,9 @@
/>
</div>
<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
class="form-control"
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 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="row">
<div class="col-12 col-md-3">
<ul class="nav flex-column nav-pills" id="nav-tab" role="tablist">
<li
*ngIf="!hideChangePasswordTab && (profile$ | async)"
class="nav-item"
(click)="selectedTab = 0"
>
<a
class="nav-link"
[ngClass]="{ active: selectedTab === 0 }"
role="tab"
href="javascript:void(0)"
>{{ 'AbpUi::ChangePassword' | abpLocalization }}</a
>
</li>
@if (!hideChangePasswordTab && (profile$ | async)) {
<li class="nav-item" (click)="selectedTab = 0">
<a
class="nav-link"
[ngClass]="{ active: selectedTab === 0 }"
role="tab"
href="javascript:void(0)"
>{{ 'AbpUi::ChangePassword' | abpLocalization }}</a
>
</li>
}
<li class="nav-item mb-2" (click)="selectedTab = 1">
<a
class="nav-link"
@ -28,34 +26,40 @@
</li>
</ul>
</div>
<div *ngIf="profile$ | async" class="col-12 col-md-9">
<div class="tab-content" *ngIf="selectedTab === 0" [@fadeIn]>
<div class="tab-pane active" role="tabpanel">
<h4>
{{ 'AbpIdentity::ChangePassword' | abpLocalization }}
<hr />
</h4>
<abp-change-password-form
*abpReplaceableTemplate="{
componentKey: changePasswordKey
}"
></abp-change-password-form>
</div>
@if (profile$ | async) {
<div class="col-12 col-md-9">
@if (selectedTab === 0) {
<div class="tab-content" [@fadeIn]>
<div class="tab-pane active" role="tabpanel">
<h4>
{{ 'AbpIdentity::ChangePassword' | abpLocalization }}
<hr />
</h4>
<abp-change-password-form
*abpReplaceableTemplate="{
componentKey: changePasswordKey
}"
></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 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>

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">
<abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
<abp-button
buttonType="submit"
iconClass="fa fa-check"
buttonClass="btn btn-primary color-white"
[loading]="inProgress"
>
{{ 'AbpIdentity::Save' | abpLocalization }}</abp-button
>
</form>
@if (form) {
<form [formGroup]="form" (ngSubmit)="submit()" validateOnSubmit class="abp-md-form">
<abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
<abp-button
buttonType="submit"
iconClass="fa fa-check"
buttonClass="btn btn-primary color-white"
[loading]="inProgress"
>
{{ 'AbpIdentity::Save' | abpLocalization }}</abp-button
>
</form>
}

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

@ -5,53 +5,54 @@
'AbpAccount::Login' | abpLocalization
}}</a>
</strong>
<form
*ngIf="isSelfRegistrationEnabled"
[formGroup]="form"
(ngSubmit)="onSubmit()"
validateOnSubmit
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"
@if (isSelfRegistrationEnabled) {
<form
[formGroup]="form"
(ngSubmit)="onSubmit()"
validateOnSubmit
class="mt-4"
>
{{ 'AbpAccount::Register' | abpLocalization }}
</abp-button>
</form>
<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 }}
</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>
<form
*ngIf="!isPasswordReset; else passwordResetTemplate"
[formGroup]="form"
[mapErrorsFn]="mapErrorsFn"
(ngSubmit)="onSubmit()"
validateOnSubmit
>
<p>{{ 'AbpAccount::ResetPassword_Information' | abpLocalization }}</p>
<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" />
</div>
<div class="mb-3 form-group">
<label for="input-confirm-password" class="form-label">{{
'AbpAccount::ConfirmPassword' | abpLocalization
}}</label
><span> * </span>
<input
type="password"
id="input-confirm-password"
class="form-control"
formControlName="confirmPassword"
/>
</div>
<button class="me-2 btn btn-outline-primary" type="button" routerLink="/account/login">
{{ 'AbpAccount::Cancel' | abpLocalization }}
</button>
<abp-button
buttonType="submit"
buttonClass="me-2 btn btn-primary"
[loading]="inProgress"
(click)="onSubmit()"
>
{{ 'AbpAccount::Submit' | abpLocalization }}
</abp-button>
</form>
<ng-template #passwordResetTemplate>
@if (!isPasswordReset) {
<form [formGroup]="form" [mapErrorsFn]="mapErrorsFn" (ngSubmit)="onSubmit()" validateOnSubmit>
<p>{{ 'AbpAccount::ResetPassword_Information' | abpLocalization }}</p>
<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" />
</div>
<div class="mb-3 form-group">
<label for="input-confirm-password" class="form-label">{{
'AbpAccount::ConfirmPassword' | abpLocalization
}}</label
><span> * </span>
<input
type="password"
id="input-confirm-password"
class="form-control"
formControlName="confirmPassword"
/>
</div>
<button class="me-2 btn btn-outline-primary" type="button" routerLink="/account/login">
{{ 'AbpAccount::Cancel' | abpLocalization }}
</button>
<abp-button
buttonType="submit"
buttonClass="me-2 btn btn-primary"
[loading]="inProgress"
(click)="onSubmit()"
>
{{ 'AbpAccount::Submit' | abpLocalization }}
</abp-button>
</form>
} @else {
<p>
{{ 'AbpAccount::YourPasswordIsSuccessfullyReset' | abpLocalization }}
</p>
@ -50,4 +44,4 @@
{{ 'AbpAccount::BackToLogin' | abpLocalization }}
</button>
</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-template ngSwitchCase="template">
<ng-container *ngComponentOutlet="prop.template; injector: injectorForCustomComponent">
</ng-container>
</ng-template>
<ng-container *abpPermission="prop.permission; runChangeDetection: false">
@switch (getComponent(prop)) {
@case ('template') {
<ng-container *ngComponentOutlet="prop.template; injector: injectorForCustomComponent">
</ng-container>
}
}
<div [ngClass]="containerClassName" class="mb-2">
<ng-template ngSwitchCase="input">
<ng-template [ngTemplateOutlet]="label"></ng-template>
<input
#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>
@switch (getComponent(prop)) {
@case ('input') {
<ng-template [ngTemplateOutlet]="label"></ng-template>
<input
#field
[id]="prop.id"
[formControlName]="prop.name"
[autocomplete]="prop.autocomplete"
[type]="getType(prop)"
[abpDisabled]="disabled"
type="checkbox"
class="form-check-input"
[readonly]="readonly"
class="form-control"
/>
<ng-template
[ngTemplateOutlet]="label"
[ngTemplateOutletContext]="{ $implicit: 'form-check-label' }"
></ng-template>
</div>
</ng-template>
}
<ng-template ngSwitchCase="select">
<ng-template [ngTemplateOutlet]="label"></ng-template>
<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>
@case ('hidden') {
<input [formControlName]="prop.name" type="hidden" />
}
<ng-template ngSwitchCase="multiselect">
<ng-template [ngTemplateOutlet]="label"></ng-template>
<select
#field
[id]="prop.id"
[formControlName]="prop.name"
[abpDisabled]="disabled"
multiple="multiple"
class="form-select form-control"
>
<option
*ngFor="let option of options$ | async; trackBy: track.by('value')"
[ngValue]="option.value"
>
{{ option.key }}
</option>
</select>
</ng-template>
@case ('checkbox') {
<div class="form-check" validationTarget>
<input
#field
[id]="prop.id"
[formControlName]="prop.name"
[abpDisabled]="disabled"
type="checkbox"
class="form-check-input"
/>
<ng-template
[ngTemplateOutlet]="label"
[ngTemplateOutletContext]="{ $implicit: 'form-check-label' }"
></ng-template>
</div>
}
<ng-template ngSwitchCase="typeahead">
<ng-template [ngTemplateOutlet]="label"></ng-template>
<div #typeahead class="position-relative" validationStyle validationTarget>
<input
@case ('select') {
<ng-template [ngTemplateOutlet]="label"></ng-template>
<select
#field
[id]="prop.id"
[autocomplete]="prop.autocomplete"
[formControlName]="prop.name"
[abpDisabled]="disabled"
[ngbTypeahead]="search"
[editable]="false"
[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>
<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>
class="form-select form-control"
>
@for (option of options$ | async; track option.value) {
<option [ngValue]="option.value">
{{ option.key }}
</option>
}
</select>
}
<ng-template ngSwitchCase="dateTime">
<ng-template [ngTemplateOutlet]="label"></ng-template>
<abp-extensible-date-time-picker [prop]="prop" [meridian]="meridian$ | async" />
</ng-template>
@case ('multiselect') {
<ng-template [ngTemplateOutlet]="label"></ng-template>
<select
#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">
<ng-template [ngTemplateOutlet]="label"></ng-template>
<textarea
#field
[id]="prop.id"
[formControlName]="prop.name"
[abpDisabled]="disabled"
[readonly]="readonly"
class="form-control"
></textarea>
</ng-template>
@case ('typeahead') {
<ng-template [ngTemplateOutlet]="label"></ng-template>
<div #typeahead class="position-relative" validationStyle validationTarget>
<input
#field
[id]="prop.id"
[autocomplete]="prop.autocomplete"
[abpDisabled]="disabled"
[ngbTypeahead]="search"
[editable]="false"
[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">
<ng-template [ngTemplateOutlet]="label"></ng-template>
<div class="input-group form-group" validationTarget>
@case ('date') {
<ng-template [ngTemplateOutlet]="label"></ng-template>
<input
class="form-control"
[id]="prop.id"
[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
class="fa"
aria-hidden="true"
[ngClass]="{
'fa-eye-slash': !showPassword,
'fa-eye': showPassword
}"
></i>
</button>
</div>
</ng-template>
}
@case ('time') {
<ng-template [ngTemplateOutlet]="label"></ng-template>
<ngb-timepicker [formControlName]="prop.name"></ngb-timepicker>
}
@case ('dateTime') {
<ng-template [ngTemplateOutlet]="label"></ng-template>
<abp-extensible-date-time-picker [prop]="prop" [meridian]="meridian$ | async" />
}
@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) {
<small class="text-muted d-block">{{
prop.formText | abpLocalization
}}</small>
<small class="text-muted d-block">{{ prop.formText | abpLocalization }}</small>
}
</div>
</ng-container>
@ -171,12 +169,17 @@
<label [htmlFor]="prop.id" [ngClass]="classes || 'form-label'">
@if (prop.displayTextResolver) {
{{ prop.displayTextResolver(data) | abpLocalization }}
}@else{
} @else {
{{ prop.displayName | abpLocalization }}
}
{{ asterisk }}
@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>
</ng-template>

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

@ -1,41 +1,37 @@
<div class="row entry-row" *ngIf="shouldRenderRow">
<ng-container *ngIf="customTitle; else defaultTitleTemplate">
<ng-content select="abp-page-title-container"></ng-content>
</ng-container>
@if (shouldRenderRow) {
<div class="row entry-row">
@if (customTitle) {
<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">
<ng-content select="abp-page-breadcrumb-container"></ng-content>
</ng-container>
@if (customBreadcrumb) {
<ng-content select="abp-page-breadcrumb-container"></ng-content>
} @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">
<ng-content select="abp-page-toolbar-container"></ng-content>
</ng-container>
</div>
@if (customToolbar) {
<ng-content select="abp-page-toolbar-container"></ng-content>
} @else {
@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-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>
</div>
<div
#dropdown="ngbDropdown"
*ngIf="menu"
class="d-inline-block ms-1"
ngbDropdown
placement="bottom"
container="body"
(abpInit)="initDropdown(node.key, dropdown)"
>
<i
class="fas fa-caret-down text-muted"
ngbDropdownToggle
[class.dropdown-toggle]="false"
aria-hidden="true"
></i>
<div ngbDropdownMenu>
<ng-template *ngTemplateOutlet="menu; context: { $implicit: node }"></ng-template>
@if (menu) {
<div
#dropdown="ngbDropdown"
class="d-inline-block ms-1"
ngbDropdown
placement="bottom"
container="body"
(abpInit)="initDropdown(node.key, dropdown)"
>
<i
class="fas fa-caret-down text-muted"
ngbDropdownToggle
[class.dropdown-toggle]="false"
aria-hidden="true"
></i>
<div ngbDropdownMenu>
<ng-template *ngTemplateOutlet="menu; context: { $implicit: node }"></ng-template>
</div>
</div>
</div>
}
</ng-template>
<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({
selector: 'abp-dynamic-layout',
template: ` <ng-container *ngIf="isLayoutVisible" [ngComponentOutlet]="layout"></ng-container> `,
template: `
@if (isLayoutVisible) {
<ng-container [ngComponentOutlet]="layout"></ng-container>
}
`,
providers: [SubscriptionService],
})
export class DynamicLayoutComponent implements OnInit {
@ -24,6 +28,7 @@ export class DynamicLayoutComponent implements OnInit {
readonly layouts = inject(DYNAMIC_LAYOUTS_TOKEN);
isLayoutVisible = true;
protected readonly router = inject(Router);
protected readonly route = inject(ActivatedRoute);
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' }">
<ng-template #abpHeader>
<h3>{{ 'AbpFeatureManagement::Features' | abpLocalization }}</h3>
</ng-template>
@if (visible) {
<abp-modal [(visible)]="visible" [busy]="modalBusy" [options]="{ size: 'lg' }">
<ng-template #abpHeader>
<h3>{{ 'AbpFeatureManagement::Features' | abpLocalization }}</h3>
</ng-template>
<ng-template #abpBody>
<div class="row">
<ng-container *ngIf="groups.length">
<div class="col-md-4">
<ul
ngbNav
#nav="ngbNav"
[(activeId)]="selectedGroupDisplayName"
class="nav-pills"
orientation="vertical"
>
<li
*ngFor="let group of groups; trackBy: track.by('name')"
[ngbNavItem]="group.displayName"
<ng-template #abpBody>
<div class="row">
@if (groups.length) {
<div class="col-md-4">
<ul
ngbNav
#nav="ngbNav"
[(activeId)]="selectedGroupDisplayName"
class="nav-pills"
orientation="vertical"
>
<a ngbNavLink>{{ group.displayName }}</a>
<ng-template ngbNavContent>
<h4>{{ selectedGroupDisplayName }}</h4>
<hr class="mt-2 mb-3" />
@for (group of groups; track group.name) {
<li [ngbNavItem]="group.displayName">
<a ngbNavLink>{{ group.displayName }}</a>
<ng-template ngbNavContent>
<h4>{{ selectedGroupDisplayName }}</h4>
<hr class="mt-2 mb-3" />
<div
class="mt-2"
*ngFor="
let feature of features[group.name];
let i = index;
trackBy: track.by('id')
"
[ngStyle]="feature.style"
[ngSwitch]="feature.valueType?.name"
(keyup.enter)="save()"
>
<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)"
/>
@for (feature of features[group.name]; track feature.id; let i = $index) {
<div class="mt-2" [ngStyle]="feature.style" (keyup.enter)="save()">
@switch (feature.valueType?.name) {
@case (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">{{
feature.displayName
}}</label>
<ng-container
*ngTemplateOutlet="descTmp; context: { $implicit: feature.description }"
></ng-container>
</div>
</ng-container>
<ng-container *ngSwitchCase="valueTypes.FreeTextStringValueType">
<div class="mb-3 form-group">
<label [htmlFor]="feature.name" class="form-label">{{
feature.displayName
}}</label>
<input
class="form-control"
type="text"
[id]="feature.name"
[(ngModel)]="feature.value"
[abpFeatureManagementFreeText]="feature"
/>
<label class="form-check-label" [htmlFor]="feature.name">{{
feature.displayName
}}</label>
<ng-container
*ngTemplateOutlet="
descTmp;
context: { $implicit: feature.description }
"
></ng-container>
</div>
}
@case (valueTypes.FreeTextStringValueType) {
<div class="mb-3 form-group">
<label [htmlFor]="feature.name" class="form-label">{{
feature.displayName
}}</label>
<input
class="form-control"
type="text"
[id]="feature.name"
[(ngModel)]="feature.value"
[abpFeatureManagementFreeText]="feature"
/>
<ng-container
*ngTemplateOutlet="descTmp; context: { $implicit: feature.description }"
></ng-container>
</div>
</ng-container>
<ng-container *ngSwitchCase="valueTypes.SelectionStringValueType">
<ng-container *ngIf="feature.valueType.itemSource?.items?.length">
<div class="mb-3 form-group">
<label [htmlFor]="feature.name" class="form-label">{{
feature.displayName
}}</label>
<select class="form-select" [id]="feature.name" [(ngModel)]="feature.value">
<option
*ngFor="
let item of feature.valueType.itemSource?.items;
trackBy: track.by('value')
"
[ngValue]="item.value"
>
{{
item.displayText?.resourceName + '::' + item.displayText?.name
| abpLocalization
}}
</option>
</select>
<ng-container
*ngTemplateOutlet="descTmp; context: { $implicit: feature.description }"
></ng-container>
<ng-container
*ngTemplateOutlet="
descTmp;
context: { $implicit: feature.description }
"
></ng-container>
</div>
}
@case (valueTypes.SelectionStringValueType) {
@if (feature.valueType.itemSource?.items?.length) {
<div class="mb-3 form-group">
<label [htmlFor]="feature.name" class="form-label">{{
feature.displayName
}}</label>
<select
class="form-select"
[id]="feature.name"
[(ngModel)]="feature.value"
>
@for (
item of feature.valueType.itemSource?.items;
track item.value
) {
<option [ngValue]="item.value">
{{
item.displayText?.resourceName +
'::' +
item.displayText?.name | abpLocalization
}}
</option>
}
</select>
<ng-container
*ngTemplateOutlet="
descTmp;
context: { $implicit: feature.description }
"
></ng-container>
</div>
}
}
@default {
{{ feature.displayName }}
}
}
</div>
</ng-container>
</ng-container>
<ng-container *ngSwitchDefault>{{ feature.displayName }}</ng-container>
</div>
</ng-template>
</li>
</ul>
</div>
}
</ng-template>
</li>
}
</ul>
</div>
<ng-template #descTmp let-description>
<small *ngIf="description" class="d-block form-text text-muted">{{ description }}</small>
</ng-template>
<ng-template #descTmp let-description>
@if (description) {
<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>
</ng-container>
<div class="col-md-8"><div class="py-0" [ngbNavOutlet]="nav"></div></div>
}
<div class="col" *ngIf="!groups.length">
{{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }}
@if (!groups.length) {
<div class="col">
{{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }}
</div>
}
</div>
</div>
</ng-template>
</ng-template>
<ng-template #abpFooter>
<button abpClose type="button" class="btn btn-link">
{{ 'AbpFeatureManagement::Cancel' | abpLocalization }}
</button>
<ng-template #abpFooter>
<button abpClose type="button" class="btn btn-link">
{{ 'AbpFeatureManagement::Cancel' | abpLocalization }}
</button>
<abp-button
*ngIf="groups.length"
iconClass="fa fa-refresh"
buttonClass="btn btn-outline-primary"
[disabled]="modalBusy"
(click)="resetToDefault()"
aria-hidden="true"
>
{{ 'AbpFeatureManagement::ResetToDefault' | abpLocalization }}
</abp-button>
@if (groups.length) {
<abp-button
iconClass="fa fa-refresh"
buttonClass="btn btn-outline-primary"
[disabled]="modalBusy"
(click)="resetToDefault()"
aria-hidden="true"
>
{{ 'AbpFeatureManagement::ResetToDefault' | abpLocalization }}
</abp-button>
}
<abp-button
*ngIf="groups.length"
iconClass="fa fa-check"
[disabled]="modalBusy"
(click)="save()"
aria-hidden="true"
>
{{ 'AbpFeatureManagement::Save' | abpLocalization }}
</abp-button>
</ng-template>
</abp-modal>
@if (groups.length) {
<abp-button
iconClass="fa fa-check"
[disabled]="modalBusy"
(click)="save()"
aria-hidden="true"
>
{{ 'AbpFeatureManagement::Save' | abpLocalization }}
</abp-button>
}
</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 #abpBody>
<ng-template #loaderRef>
<div class="text-center"><i class="fa fa-pulse fa-spinner" aria-hidden="true"></i></div>
</ng-template>
<form *ngIf="form; else loaderRef" [formGroup]="form" (ngSubmit)="save()">
<ul ngbNav #nav="ngbNav" class="nav-tabs">
<li ngbNavItem>
<a ngbNavLink>{{ 'AbpIdentity::UserInformations' | abpLocalization }}</a>
<ng-template ngbNavContent>
<abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
</ng-template>
</li>
@if (form) {
<form [formGroup]="form" (ngSubmit)="save()">
<ul ngbNav #nav="ngbNav" class="nav-tabs">
<li ngbNavItem>
<a ngbNavLink>{{ 'AbpIdentity::UserInformations' | abpLocalization }}</a>
<ng-template ngbNavContent>
<abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
</ng-template>
</li>
<li ngbNavItem>
<a ngbNavLink>{{ 'AbpIdentity::Roles' | abpLocalization }}</a>
<ng-template ngbNavContent>
<div
*ngFor="let roleGroup of roleGroups; let i = index; trackBy: trackByFn"
class="form-check mb-2"
>
<abp-checkbox
*abpReplaceableTemplate="{
inputs: {
checkboxId: 'roles-' + i,
label: roles[i].name,
formControl: roleGroup.controls[roles[i].name]
},
componentKey: inputKey
}"
[checkboxId]="'roles-' + i"
[formControl]="roleGroup.controls[roles[i].name]"
[label]="roles[i].name"
>
</abp-checkbox>
</div>
</ng-template>
</li>
</ul>
<div class="mt-2 fade-in-top" [ngbNavOutlet]="nav"></div>
</form>
<li ngbNavItem>
<a ngbNavLink>{{ 'AbpIdentity::Roles' | abpLocalization }}</a>
<ng-template ngbNavContent>
@for (roleGroup of roleGroups; track $index; let i = $index) {
<div class="form-check mb-2">
<abp-checkbox
*abpReplaceableTemplate="{
inputs: {
checkboxId: 'roles-' + i,
label: roles[i].name,
formControl: roleGroup.controls[roles[i].name]
},
componentKey: inputKey
}"
[checkboxId]="'roles-' + i"
[formControl]="roleGroup.controls[roles[i].name]"
[label]="roles[i].name"
>
</abp-checkbox>
</div>
}
</ng-template>
</li>
</ul>
<div class="mt-2 fade-in-top" [ngbNavOutlet]="nav"></div>
</form>
} @else {
<div class="text-center"><i class="fa fa-pulse fa-spinner" aria-hidden="true"></i></div>
}
</ng-template>
<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 }">
<ng-container *ngIf="data.entityDisplayName || entityDisplayName">
<abp-modal [(visible)]="visible" [busy]="modalBusy" [options]="{ size: 'lg', scrollable: false }">
@if (data.entityDisplayName || entityDisplayName) {
<ng-template #abpHeader>
<h4>
{{ 'AbpPermissionManagement::Permissions' | abpLocalization }} -
@ -28,23 +28,28 @@
<hr class="mt-2 mb-2" />
<div class="overflow-auto">
<ul class="nav nav-pills flex-column">
<li *ngFor="let group of data.groups; trackBy: trackByFn" class="nav-item">
<a
*ngIf="{ assignedCount: getAssignedCount(group.name) } as count"
class="nav-link pointer"
[class.active]="selectedGroup?.name === group?.name"
(click)="onChangeGroup(group)"
(select)="setDisabled(group.permissions)"
>
<div [class.font-weight-bold]="count.assignedCount">
{{ group?.displayName }}
<span *ngIf="count.assignedCount > 0">({{ count.assignedCount }})</span>
</div>
</a>
</li>
@for (group of data.groups; track $index) {
<li class="nav-item">
@if ({ assignedCount: getAssignedCount(group.name) }; as count) {
<a
class="nav-link pointer"
[class.active]="selectedGroup?.name === group?.name"
(click)="onChangeGroup(group)"
(select)="setDisabled(group.permissions)"
>
<div [class.font-weight-bold]="count.assignedCount">
{{ group?.displayName }}
@if (count.assignedCount > 0) {
<span>({{ count.assignedCount }})</span>
}
</div>
</a>
}
</li>
}
</ul>
</div>
</div>
</div>
<div class="col-md-8 scroll-in-modal">
<div class="ps-1">
@ -64,32 +69,34 @@
}}</label>
</div>
<hr class="my-2" />
<div
*ngFor="let permission of selectedGroupPermissions; let i = index; trackBy: trackByFn"
[ngStyle]="permission.style"
class="form-check mb-2"
>
<input
#permissionCheckbox
type="checkbox"
[checked]="getChecked(permission.name)"
[value]="getChecked(permission.name)"
[attr.id]="permission.name"
class="form-check-input"
[disabled]="isGrantedByOtherProviderName(permission.grantedProviders)"
(click)="onClickCheckbox(permission, permissionCheckbox.value)"
/>
<label class="form-check-label" [attr.for]="permission.name"
>{{ permission.displayName }}
<ng-container *ngIf="!hideBadges">
<span
*ngFor="let provider of permission.grantedProviders"
class="badge bg-light text-dark"
>{{ provider.providerName }}: {{ provider.providerKey }}</span
>
</ng-container>
</label>
</div>
@for (permission of selectedGroupPermissions; track $index; let i = $index) {
<div
[ngStyle]="permission.style"
class="form-check mb-2"
>
<input
#permissionCheckbox
type="checkbox"
[checked]="getChecked(permission.name)"
[value]="getChecked(permission.name)"
[attr.id]="permission.name"
class="form-check-input"
[disabled]="isGrantedByOtherProviderName(permission.grantedProviders)"
(click)="onClickCheckbox(permission, permissionCheckbox.value)"
/>
<label class="form-check-label" [attr.for]="permission.name"
>{{ permission.displayName }}
@if (!hideBadges) {
@for (provider of permission.grantedProviders; track $index) {
<span
class="badge bg-light text-dark"
>{{ provider.providerName }}: {{ provider.providerKey }}</span
>
}
}
</label>
</div>
}
</div>
</div>
</div>
@ -102,5 +109,5 @@
'AbpIdentity::Save' | abpLocalization
}}</abp-button>
</ng-template>
</ng-container>
}
</abp-modal>

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

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

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">
<div id="wrapper" class="card">
<div class="card-body">
<div id="data-tables-table-filter" class="data-tables-filter mb-3">
@ -26,8 +24,8 @@
<ng-template #abpHeader>
<h3>
{{
(selected?.id ? 'AbpTenantManagement::Edit' : 'AbpTenantManagement::NewTenant')
| abpLocalization
(selected?.id ? 'AbpTenantManagement::Edit' : 'AbpTenantManagement::NewTenant')
| abpLocalization
}}
</h3>
</ng-template>
@ -44,20 +42,20 @@
</button>
<abp-button iconClass="fa fa-check" (click)="save()" [disabled]="tenantForm?.invalid">{{
'AbpTenantManagement::Save' | abpLocalization
}}</abp-button>
}}</abp-button>
</ng-template>
</abp-modal>
<abp-feature-management
*abpReplaceableTemplate="{
inputs: {
providerName: { value: 'T' },
providerKey: { value: providerKey },
visible: { value: visibleFeatures, twoWay: true }
},
outputs: { visibleChange: $any(onVisibleFeaturesChange) },
componentKey: featureManagementKey
}"
inputs: {
providerName: { value: 'T' },
providerKey: { value: providerKey },
visible: { value: visibleFeatures, twoWay: true }
},
outputs: { visibleChange: $any(onVisibleFeaturesChange) },
componentKey: featureManagementKey
}"
[(visible)]="visibleFeatures"
providerName="T"
[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>
<div
*ngIf="service.smallScreen"
[@collapseWithMargin]="service.isCollapsed ? 'collapsed' : 'expanded'"
>
<ng-container *ngTemplateOutlet="navigations"></ng-container>
</div>
@if (service.smallScreen) {
<div
[@collapseWithMargin]="service.isCollapsed ? 'collapsed' : 'expanded'"
>
<ng-container *ngTemplateOutlet="navigations"></ng-container>
</div>
}
<ng-template #navigations>
<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="mx-auto col col-md-5">
<ng-container *ngIf="(service.isMultiTenancyEnabled$ | async) && service.isTenantBoxVisible">
@if ((service.isMultiTenancyEnabled$ | async) && service.isTenantBoxVisible) {
<abp-tenant-box
*abpReplaceableTemplate="{ componentKey: service.tenantBoxKey }"
></abp-tenant-box>
</ng-container>
}
<div class="abp-account-container">
<div
*ngIf="service.enableLocalLogin$ | async; else disableLocalLoginTemplate"
class="card mt-3 shadow-sm rounded"
>
<div class="card-body p-5">
<ng-content></ng-content>
@if (service.enableLocalLogin$ | async) {
<div class="card mt-3 shadow-sm rounded">
<div class="card-body p-5">
<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>
<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-body px-5">
<div class="row">
@ -62,4 +62,4 @@
</abp-button>
</ng-template>
</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>
</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>
<div *ngIf="service.smallScreen" [@collapseWithMargin]="service.isCollapsed ? 'collapsed' : 'expanded'">
<ng-container *ngTemplateOutlet="navigations"></ng-container>
</div>
@if (service.smallScreen) {
<div [@collapseWithMargin]="service.isCollapsed ? 'collapsed' : 'expanded'">
<ng-container *ngTemplateOutlet="navigations"></ng-container>
</div>
}
<ng-template #navigations>
<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',
template: `
<a class="navbar-brand" routerLink="/">
<img
*ngIf="appInfo.logoUrl; else appName"
[src]="appInfo.logoUrl"
[alt]="appInfo.name"
width="100%"
height="auto"
/>
@if (appInfo.logoUrl) {
<img
[src]="appInfo.logoUrl"
[alt]="appInfo.name"
width="100%"
height="auto"
/>
} @else {
{{ appInfo.name }}
}
</a>
<ng-template #appName>
{{ appInfo.name }}
</ng-template>
`,
})
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>
<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>
@if ((currentUser$ | async)?.isAuthenticated) {
<div
class="dropdown-menu dropdown-menu-end border-0 shadow-sm"
aria-labelledby="dropdownMenuLink"
[class.d-block]="smallScreen && currentUserDropdown.isOpen()"
ngbDropdown
class="dropdown"
#currentUserDropdown="ngbDropdown"
display="static"
>
<ng-container *ngFor="let item of userMenu.items$ | async; trackBy: trackByFn">
<ng-container *abpVisible="!item.visible || item.visible(item)">
<li class="nav-item d-flex align-items-center" *abpPermission="item.requiredPolicy">
<ng-container
*ngIf="item.component; else htmlTemplate"
[ngComponentOutlet]="item.component"
[ngComponentOutletInjector]="item | toInjector"
></ng-container>
<ng-template #htmlTemplate>
<div
*ngIf="item.html; else textTemplate"
[innerHTML]="item.html"
(click)="item.action ? item.action() : null"
></div>
</ng-template>
<ng-template #textTemplate>
<a
*ngIf="item.textTemplate"
(click)="item.action ? item.action() : null"
class="dropdown-item pointer"
>
<i *ngIf="item.textTemplate.icon" class="me-1 {{ item.textTemplate.icon }}"></i>
{{ item.textTemplate.text | abpLocalization }}</a
>
</ng-template>
</li>
</ng-container>
</ng-container>
<a
ngbDropdownToggle
class="nav-link"
href="javascript:void(0)"
role="button"
id="dropdownMenuLink"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
@if ((selectedTenant$ | async)?.name; as tenantName) {
<small
><i>{{ tenantName }}</i
>\</small
>
}
<strong>{{ (currentUser$ | async)?.userName }}</strong>
</a>
<div
class="dropdown-menu dropdown-menu-end border-0 shadow-sm"
aria-labelledby="dropdownMenuLink"
[class.d-block]="smallScreen && currentUserDropdown.isOpen()"
>
@for (item of userMenu.items$ | async; track $index) {
<ng-container *abpVisible="!item.visible || item.visible(item)">
<li class="nav-item d-flex align-items-center" *abpPermission="item.requiredPolicy">
@if (item.component) {
<ng-container
[ngComponentOutlet]="item.component"
[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>
} @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({
selector: 'abp-languages',
template: `
<div
*ngIf="((dropdownLanguages$ | async)?.length || 0) > 0"
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()"
>
@if (((dropdownLanguages$ | async)?.length || 0) > 0) {
<div class="dropdown" ngbDropdown #languageDropdown="ngbDropdown" display="static">
<a
*ngFor="let lang of dropdownLanguages$ | async"
ngbDropdownToggle
class="nav-link"
href="javascript:void(0)"
class="dropdown-item"
(click)="onChangeLang(lang.cultureName || '')"
>{{ lang?.displayName }}</a
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()"
>
@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>
}
`,
})
export class LanguagesComponent {
@ -69,7 +66,10 @@ export class LanguagesComponent {
return this.sessionState.getLanguage();
}
constructor(private sessionState: SessionStateService, private configState: ConfigStateService) {}
constructor(
private sessionState: SessionStateService,
private configState: ConfigStateService,
) {}
onChangeLang(cultureName: string) {
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">
<ng-container *ngFor="let item of navItems.items$ | async; trackBy: trackByFn">
<ng-container *abpVisible="!item.visible || item.visible(item)">
@for (item of navItems.items$ | async; track $index) {
<ng-container *abpVisible="!item.visible || item.visible(item)">
<li class="nav-item d-flex align-items-center" *abpPermission="item.requiredPolicy">
<ng-container
*ngIf="item.component; else htmlTemplate"
[ngComponentOutlet]="item.component"
[ngComponentOutletInjector]="item | toInjector"
></ng-container>
<ng-template #htmlTemplate>
@if (item.component) {
<ng-container
[ngComponentOutlet]="item.component"
[ngComponentOutletInjector]="item | toInjector"
></ng-container>
} @else {
<div [innerHTML]="item.html" (click)="item.action ? item.action() : null"></div>
</ng-template>
}
</li>
</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
class="alert alert-{{ alert.type }} fade show"
[ngClass]="{ 'alert-dismissible fade show': alert.dismissible }"
role="alert"
>
<h4
class="alert-heading"
*ngIf="alert.title"
[innerHTML]="alert.title | abpSafeHtml | abpLocalization: alert.titleLocalizationParams"
></h4>
@if (alert.title) {
<h4
class="alert-heading"
[innerHTML]="alert.title | abpSafeHtml | abpLocalization: alert.titleLocalizationParams"
></h4>
}
<span
[innerHTML]="alert.message | abpSafeHtml | abpLocalization: alert.messageLocalizationParams"
></span>
<button
*ngIf="alert.dismissible"
type="button"
class="btn-close"
data-dismiss="alert"
aria-label="Close"
(click)="service.remove(i)"
></button>
@if (alert.dismissible) {
<button
type="button"
class="btn-close"
data-dismiss="alert"
aria-label="Close"
(click)="service.remove(i)"
></button>
}
</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">
<ng-container
*ngFor="let route of routesService.visible$ | async; trackBy: trackByFn"
[ngTemplateOutlet]="isDropdown(route) ? dropdownLink : defaultLink"
[ngTemplateOutletContext]="{ $implicit: route }"
>
</ng-container>
@for (route of routesService.visible$ | async; track $index) {
<ng-container
[ngTemplateOutlet]="isDropdown(route) ? dropdownLink : defaultLink"
[ngTemplateOutletContext]="{ $implicit: route }"
>
</ng-container>
}
<ng-template #defaultLink let-route>
<li class="nav-item" *abpPermission="route.requiredPolicy">
<a class="nav-link" [routerLink]="[route.path]"
><i *ngIf="route.iconClass" [ngClass]="route.iconClass"></i>
{{ route.name | abpLocalization }}</a
>
<a class="nav-link" [routerLink]="[route.path]">
@if (route.iconClass) {
<i [ngClass]="route.iconClass"></i>
}
{{ route.name | abpLocalization }}
</a>
</li>
</ng-template>
<ng-template #dropdownLink let-route>
<ng-container *ngIf="route.children?.length">
@if (route.children?.length) {
<li
class="nav-item dropdown"
display="static"
@ -34,7 +37,9 @@
aria-expanded="false"
href="javascript:void(0)"
>
<i *ngIf="route.iconClass" [ngClass]="route.iconClass"></i>
@if (route.iconClass) {
<i [ngClass]="route.iconClass"></i>
}
{{ route.name | abpLocalization }}
</a>
<div
@ -48,27 +53,29 @@
></ng-container>
</div>
</li>
</ng-container>
}
</ng-template>
<ng-template #forTemplate let-route>
<ng-container *ngFor="let child of route.children">
@for (child of route.children; track $index) {
<ng-template
[ngTemplateOutlet]="child.children?.length ? dropdownChild : defaultChild"
[ngTemplateOutletContext]="{ $implicit: child }"
></ng-template>
</ng-container>
}
</ng-template>
<ng-template #defaultChild let-child>
<ng-container *ngIf="child.path">
@if (child.path) {
<div class="dropdown-submenu" *abpPermission="child.requiredPolicy">
<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
>
</div>
</ng-container>
}
</ng-template>
<ng-template #dropdownChild let-child>
@ -87,7 +94,9 @@
role="button"
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 }}
</a>
</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({
selector: 'abp-validation-error',
template: `
<div class="invalid-feedback" *ngFor="let error of abpErrors; trackBy: trackByFn">
{{ error.message | abpLocalization: error.interpoliteParams }}
</div>
@for (error of abpErrors; track $index) {
<div class="invalid-feedback" >
{{ error.message | abpLocalization: error.interpoliteParams }}
</div>
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,
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">
<li class="breadcrumb-item">
<a routerLink="/"><i class="fa fa-home" aria-hidden="true"></i> </a>
</li>
<li
*ngFor="let item of items; let last = last"
class="breadcrumb-item"
[class.active]="last"
aria-current="page"
>
<ng-container
*ngTemplateOutlet="item.path ? linkTemplate : textTemplate; context: { $implicit: item }"
></ng-container>
</li>
</ol>
@if (items.length) {
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a routerLink="/"><i class="fa fa-home" aria-hidden="true"></i> </a>
</li>
@for (item of items; track $index; let last = $last) {
<li class="breadcrumb-item" [class.active]="last" aria-current="page">
<ng-container
*ngTemplateOutlet="item.path ? linkTemplate : textTemplate; context: { $implicit: item }"
></ng-container>
</li>
}
</ol>
}
<ng-template #linkTemplate let-item>
<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()"
(focus)="checkboxFocus.next()"
/>
<label *ngIf="label" [ngClass]="labelClass" [for]="checkboxId">
{{ label | abpLocalization }}
</label>
@if (label) {
<label [ngClass]="labelClass" [for]="checkboxId">
{{ label | abpLocalization }}
</label>
}
</div>
`,
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">
<div
class="confirmation-backdrop"
(click)="data.options?.dismissible ? close(dismiss) : null"
></div>
<div class="confirmation-dialog">
<div class="icon-container" [ngClass]="data.severity" *ngIf="data.severity || isCustomIconExists(data)">
<div [outerHTML]="data.options.iconTemplate" *ngIf="isIconTemplateExits(data); else iconHolder" ></div>
<ng-template #iconHolder>
<i class="icon" [ngClass]="getIconClass(data)"></i>
</ng-template>
</div>
<div class="content">
<h1
class="title"
*ngIf="data.title"
[innerHTML]="data.title | abpLocalization: data.options?.titleLocalizationParams"
></h1>
<p
class="message"
*ngIf="data.message"
[innerHTML]="data.message | abpLocalization: data.options?.messageLocalizationParams"
></p>
</div>
<div class="footer">
<button
id="cancel"
class="btn btn-outline-primary me-2"
[innerHTML]="data.options?.cancelText || 'AbpUi::Cancel' | abpLocalization"
*ngIf="!data?.options?.hideCancelBtn"
(click)="close(reject)"
></button>
<button
id="confirm"
class="btn btn-primary"
[innerHTML]="data.options?.yesText || 'AbpUi::Yes' | abpLocalization"
*ngIf="!data?.options?.hideYesBtn"
(click)="close(confirm)"
></button>
@if (confirmation$ | async; as data) {
<div class="confirmation">
<div
class="confirmation-backdrop"
(click)="data.options?.dismissible ? close(dismiss) : null"
></div>
<div class="confirmation-dialog">
@if (data.severity || isCustomIconExists(data)) {
<div class="icon-container" [ngClass]="data.severity">
@if (isIconTemplateExits(data)) {
<div [outerHTML]="data.options.iconTemplate"></div>
} @else {
<i class="icon" [ngClass]="getIconClass(data)"></i>
}
</div>
}
<div class="content">
@if (data.title) {
<h1
class="title"
[innerHTML]="data.title | abpLocalization: data.options?.titleLocalizationParams"
></h1>
}
@if (data.message) {
<p
class="message"
[innerHTML]="data.message | abpLocalization: data.options?.messageLocalizationParams"
></p>
}
</div>
<div class="footer">
@if (!data?.options?.hideCancelBtn) {
<button
id="cancel"
class="btn btn-outline-primary me-2"
[innerHTML]="data.options?.cancelText || 'AbpUi::Cancel' | abpLocalization"
(click)="close(reject)"
></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>
}

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',
template: `
<div class="mb-3">
<label *ngIf="label" [ngClass]="labelClass" [for]="inputId">
{{ label | abpLocalization }}
</label>
@if (label) {
<label [ngClass]="labelClass" [for]="inputId">
{{ label | abpLocalization }}
</label>
}
<input
type="text"
[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-template #modalContent let-modal>
<div *ngIf="abpHeader" id="abp-modal-header" class="modal-header abp-modal-header">
<ng-container *ngTemplateOutlet="abpHeader"></ng-container>
​
<button
id="abp-modal-close-button"
type="button"
class="btn-sm btn-close"
aria-label="Close"
(click)="modal.dismiss()"
></button>
</div>
<div *ngIf="abpBody" id="abp-modal-body" class="modal-body">
<ng-container *ngTemplateOutlet="abpBody"></ng-container>
</div>
<div *ngIf="abpFooter" id="abp-modal-footer" class="modal-footer">
<ng-container *ngTemplateOutlet="abpFooter"></ng-container>
</div>
@if (abpHeader) {
<div id="abp-modal-header" class="modal-header abp-modal-header">
<ng-container *ngTemplateOutlet="abpHeader"></ng-container>
​
<button
id="abp-modal-close-button"
type="button"
class="btn-sm btn-close"
aria-label="Close"
(click)="modal.dismiss()"
></button>
</div>
}
@if (abpBody) {
<div id="abp-modal-body" class="modal-body">
<ng-container *ngTemplateOutlet="abpBody"></ng-container>
</div>
}
@if (abpFooter) {
<div id="abp-modal-footer" class="modal-footer">
<ng-container *ngTemplateOutlet="abpFooter"></ng-container>
</div>
}
</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'"
[@toastInOut]="toasts.length"
>
<abp-toast
[toast]="toast"
*ngFor="let toast of toasts; trackBy: trackByFunc"
(remove)="remove($event)"
></abp-toast>
@for (toast of toasts; track toast.options?.id) {
<abp-toast
[toast]="toast"
(remove)="remove($event)"
></abp-toast>
}
</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>
</div>
<div class="abp-toast-content">
<button class="abp-toast-close-button" (click)="close()" *ngIf="toast.options?.closable">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
@if (toast.options?.closable) {
<button class="abp-toast-close-button" (click)="close()">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
}
<div class="abp-toast-title">
{{ toast.title | abpLocalization: toast.options?.titleLocalizationParams }}
</div>

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

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