Browse Source

Refactor style bindings to use [style] instead of [ngStyle]

Replaced [ngStyle] with [style] bindings in multiple components for improved Angular compatibility and performance. Removed unnecessary NgStyle imports from affected components and updated their module imports accordingly.
pull/24579/head
Fahri Gedik 4 months ago
parent
commit
dbccb4ab8b
  1. 287
      npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.html
  2. 2
      npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html
  3. 7
      npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts
  4. 6
      npm/ng-packs/packages/theme-shared/src/lib/components/card/card-body.component.ts
  5. 6
      npm/ng-packs/packages/theme-shared/src/lib/components/card/card-footer.component.ts
  6. 6
      npm/ng-packs/packages/theme-shared/src/lib/components/card/card-header.component.ts
  7. 6
      npm/ng-packs/packages/theme-shared/src/lib/components/card/card.component.ts
  8. 6
      npm/ng-packs/packages/theme-shared/src/lib/components/checkbox/checkbox.component.ts
  9. 6
      npm/ng-packs/packages/theme-shared/src/lib/components/form-input/form-input.component.ts
  10. 234
      npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts

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

@ -1,181 +1,146 @@
@if (visible) {
<abp-modal [(visible)]="visible" [busy]="modalBusy" [options]="{ size: 'lg' }">
<ng-template #abpHeader>
<h3>
{{ 'AbpFeatureManagement::Features' | abpLocalization }}
@if (providerTitle) {
- {{ providerTitle }}
}
</h3>
</ng-template>
<abp-modal [(visible)]="visible" [busy]="modalBusy" [options]="{ size: 'lg' }">
<ng-template #abpHeader>
<h3>
{{ 'AbpFeatureManagement::Features' | abpLocalization }}
@if (providerTitle) {
- {{ providerTitle }}
}
</h3>
</ng-template>
<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"
>
@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" />
<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">
@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" />
@for (feature of features[group.name]; track feature.id || i; let i = $index) {
@let provider = feature.provider.name;
@let isFeatureDisabled = !feature.parentName ? isParentDisabled(feature.name, group.name, provider) :
(provider !== providerName && provider !== defaultProviderName);
@for (feature of features[group.name]; track feature.id || i; let i = $index) {
@let provider = feature.provider.name;
@let isFeatureDisabled = !feature.parentName ? isParentDisabled(feature.name, group.name, provider) :
(provider !== providerName && provider !== defaultProviderName);
<div class="mt-2" [ngStyle]="feature.style" (keyup.enter)="save()">
@switch (feature.valueType?.name) {
@case (valueTypes.ToggleStringValueType) {
<div class="form-check" [class.px-4]="!!feature.parentName">
<input
class="form-check-input"
type="checkbox"
[id]="feature.name"
[(ngModel)]="feature.value"
(ngModelChange)="onCheckboxClick($event, feature)"
[disabled]="isFeatureDisabled"
/>
<div class="mt-2" [style]="feature.style" (keyup.enter)="save()">
@switch (feature.valueType?.name) {
@case (valueTypes.ToggleStringValueType) {
<div class="form-check" [class.px-4]="!!feature.parentName">
<input class="form-check-input" type="checkbox" [id]="feature.name" [(ngModel)]="feature.value"
(ngModelChange)="onCheckboxClick($event, feature)" [disabled]="isFeatureDisabled" />
<label class="form-check-label" [htmlFor]="feature.name">
{{ feature.displayName }}
@if (isFeatureDisabled) {
<span>({{ provider }})</span>
}
</label>
<ng-container
*ngTemplateOutlet="
<label class="form-check-label" [htmlFor]="feature.name">
{{ feature.displayName }}
@if (isFeatureDisabled) {
<span>({{ provider }})</span>
}
</label>
<ng-container *ngTemplateOutlet="
descTmp;
context: { $implicit: feature.description }
"
></ng-container>
</div>
}
@case (valueTypes.FreeTextStringValueType) {
<div class="mb-3 form-group" [class.px-2]="!!feature.parentName">
<label [htmlFor]="feature.name" class="form-label">
{{ feature.displayName }}
@if (isFeatureDisabled) {
<span>({{ provider }})</span>
}
</label>
<input
class="form-control"
type="text"
[id]="feature.name"
[(ngModel)]="feature.value"
[abpFeatureManagementFreeText]="feature"
[disabled]="isFeatureDisabled"
/>
"></ng-container>
</div>
}
@case (valueTypes.FreeTextStringValueType) {
<div class="mb-3 form-group" [class.px-2]="!!feature.parentName">
<label [htmlFor]="feature.name" class="form-label">
{{ feature.displayName }}
@if (isFeatureDisabled) {
<span>({{ provider }})</span>
}
</label>
<input class="form-control" type="text" [id]="feature.name" [(ngModel)]="feature.value"
[abpFeatureManagementFreeText]="feature" [disabled]="isFeatureDisabled" />
<ng-container
*ngTemplateOutlet="
<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" [class.px-2]="!!feature.parentName">
<label [htmlFor]="feature.name" class="form-label">
{{ feature.displayName }}
@if (isFeatureDisabled) {
<span>({{ provider }})</span>
}
</label>
<select
class="form-select"
[id]="feature.name"
[(ngModel)]="feature.value"
[disabled]="isFeatureDisabled"
>
@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="
"></ng-container>
</div>
}
@case (valueTypes.SelectionStringValueType) {
@if (feature.valueType.itemSource?.items?.length) {
<div class="mb-3 form-group" [class.px-2]="!!feature.parentName">
<label [htmlFor]="feature.name" class="form-label">
{{ feature.displayName }}
@if (isFeatureDisabled) {
<span>({{ provider }})</span>
}
</label>
<select class="form-select" [id]="feature.name" [(ngModel)]="feature.value"
[disabled]="isFeatureDisabled">
@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-template>
</li>
"></ng-container>
</div>
}
}
@default {
{{ feature.displayName }}
}
}
</div>
}
</ul>
</div>
<ng-template #descTmp let-description>
@if (description) {
<small class="d-block form-text text-muted">{{ description }}</small>
}
</ng-template>
</ng-template>
</li>
}
</ul>
</div>
<div class="col-md-8"><div class="py-0" [ngbNavOutlet]="nav"></div></div>
<ng-template #descTmp let-description>
@if (description) {
<small class="d-block form-text text-muted">{{ description }}</small>
}
</ng-template>
@if (!groups.length) {
<div class="col">
{{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }}
</div>
}
<div class="col-md-8">
<div class="py-0" [ngbNavOutlet]="nav"></div>
</div>
</ng-template>
<ng-template #abpFooter>
<button abpClose type="button" class="btn btn-link">
{{ 'AbpFeatureManagement::Cancel' | abpLocalization }}
</button>
@if (groups.length) {
<abp-button
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-check"
[disabled]="modalBusy"
(click)="save()"
aria-hidden="true"
>
{{ 'AbpFeatureManagement::Save' | abpLocalization }}
</abp-button>
@if (!groups.length) {
<div class="col">
{{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }}
</div>
}
</ng-template>
</abp-modal>
}
</div>
</ng-template>
<ng-template #abpFooter>
<button abpClose type="button" class="btn btn-link">
{{ 'AbpFeatureManagement::Cancel' | abpLocalization }}
</button>
@if (groups.length) {
<abp-button 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-check" [disabled]="modalBusy" (click)="save()" aria-hidden="true">
{{ 'AbpFeatureManagement::Save' | abpLocalization }}
</abp-button>
}
</ng-template>
</abp-modal>
}

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

@ -90,7 +90,7 @@
</div>
<hr class="my-2" />
@for (permission of selectedGroupPermissions; track $index; let i = $index) {
<div [ngStyle]="permission.style" class="form-check mb-2">
<div [style]="permission.style" class="form-check mb-2">
<input
#permissionCheckbox
type="checkbox"

7
npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts

@ -31,7 +31,7 @@ import {
import { concat, of } from 'rxjs';
import { finalize, switchMap, take, tap } from 'rxjs/operators';
import { PermissionManagement } from '../models';
import { NgStyle } from '@angular/common';
import { FormsModule } from '@angular/forms';
type PermissionWithStyle = PermissionGrantInfoDto & {
@ -95,12 +95,11 @@ type PermissionWithGroupName = PermissionGrantInfoDto & {
],
imports: [
FormsModule,
NgStyle,
ModalComponent,
LocalizationPipe,
ButtonComponent,
ModalCloseDirective,
],
ModalCloseDirective
],
})
export class PermissionManagementComponent
implements

6
npm/ng-packs/packages/theme-shared/src/lib/components/card/card-body.component.ts

@ -1,12 +1,12 @@
import { Component, HostBinding, Input } from '@angular/core';
import { NgClass, NgStyle } from '@angular/common';
import { NgClass } from '@angular/common';
@Component({
selector: 'abp-card-body',
template: ` <div [ngClass]="cardBodyClass" [ngStyle]="cardBodyStyle">
template: ` <div [ngClass]="cardBodyClass" [style]="cardBodyStyle">
<ng-content></ng-content>
</div>`,
imports: [NgClass, NgStyle],
imports: [NgClass],
})
export class CardBodyComponent {
@HostBinding('class') componentClass = 'card-body';

6
npm/ng-packs/packages/theme-shared/src/lib/components/card/card-footer.component.ts

@ -1,15 +1,15 @@
import { Component, HostBinding, Input } from '@angular/core';
import { NgClass, NgStyle } from '@angular/common';
import { NgClass } from '@angular/common';
@Component({
selector: 'abp-card-footer',
template: `
<div [ngStyle]="cardFooterStyle" [ngClass]="cardFooterClass">
<div [style]="cardFooterStyle" [ngClass]="cardFooterClass">
<ng-content></ng-content>
</div>
`,
styles: [],
imports: [NgClass, NgStyle],
imports: [NgClass],
})
export class CardFooterComponent {
@HostBinding('class') componentClass = 'card-footer';

6
npm/ng-packs/packages/theme-shared/src/lib/components/card/card-header.component.ts

@ -1,15 +1,15 @@
import { Component, HostBinding, Input } from '@angular/core';
import { NgClass, NgStyle } from '@angular/common';
import { NgClass } from '@angular/common';
@Component({
selector: 'abp-card-header',
template: `
<div [ngClass]="cardHeaderClass" [ngStyle]="cardHeaderStyle">
<div [ngClass]="cardHeaderClass" [style]="cardHeaderStyle">
<ng-content></ng-content>
</div>
`,
styles: [],
imports: [NgClass, NgStyle],
imports: [NgClass],
})
export class CardHeaderComponent {
@HostBinding('class') componentClass = 'card-header';

6
npm/ng-packs/packages/theme-shared/src/lib/components/card/card.component.ts

@ -1,12 +1,12 @@
import { Component, Input } from '@angular/core';
import { NgClass, NgStyle } from '@angular/common';
import { NgClass } from '@angular/common';
@Component({
selector: 'abp-card',
template: ` <div class="card" [ngClass]="cardClass" [ngStyle]="cardStyle">
template: ` <div class="card" [ngClass]="cardClass" [style]="cardStyle">
<ng-content></ng-content>
</div>`,
imports: [NgClass, NgStyle],
imports: [NgClass],
})
export class CardComponent {
@Input() cardClass: string;

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

@ -1,6 +1,6 @@
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
import { NgClass, NgStyle } from '@angular/common';
import { NgClass } from '@angular/common';
import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core';
@Component({
@ -13,7 +13,7 @@ import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core';
[id]="checkboxId"
[readonly]="checkboxReadonly"
[ngClass]="checkboxClass"
[ngStyle]="checkboxStyle"
[style]="checkboxStyle"
(blur)="checkboxBlur.next()"
(focus)="checkboxFocus.next()"
/>
@ -31,7 +31,7 @@ import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core';
multi: true,
},
],
imports: [NgClass, NgStyle, FormsModule, LocalizationPipe],
imports: [NgClass, FormsModule, LocalizationPipe],
})
export class FormCheckboxComponent extends AbstractNgModelComponent {
@Input() label?: string;

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

@ -1,6 +1,6 @@
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NgClass, NgStyle } from '@angular/common';
import { NgClass } from '@angular/common';
import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core';
@Component({
@ -18,7 +18,7 @@ import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core';
[placeholder]="inputPlaceholder"
[readonly]="inputReadonly"
[ngClass]="inputClass"
[ngStyle]="inputStyle"
[style]="inputStyle"
(blur)="formBlur.next()"
(focus)="formFocus.next()"
[(ngModel)]="value"
@ -32,7 +32,7 @@ import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core';
multi: true,
},
],
imports: [NgClass, NgStyle, LocalizationPipe, FormsModule],
imports: [NgClass, LocalizationPipe, FormsModule],
})
export class FormInputComponent extends AbstractNgModelComponent {
@Input() inputId!: string;

234
npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts

@ -1,118 +1,116 @@
import { NgClass, NgStyle } from '@angular/common';
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit, inject } from '@angular/core';
import { combineLatest, Subscription, timer } from 'rxjs';
import { HttpWaitService, RouterWaitService, SubscriptionService } from '@abp/ng.core';
@Component({
selector: 'abp-loader-bar',
template: `
<div id="abp-loader-bar" [ngClass]="containerClass" [class.is-loading]="isLoading">
<div
class="abp-progress"
[class.progressing]="progressLevel"
[style.width.vw]="progressLevel"
[ngStyle]="{
'background-color': color,
'box-shadow': boxShadow,
}"
></div>
</div>
`,
styleUrls: ['./loader-bar.component.scss'],
providers: [SubscriptionService],
imports: [NgClass, NgStyle],
})
export class LoaderBarComponent implements OnDestroy, OnInit {
private cdRef = inject(ChangeDetectorRef);
private subscription = inject(SubscriptionService);
private httpWaitService = inject(HttpWaitService);
private routerWaitService = inject(RouterWaitService);
protected _isLoading!: boolean;
@Input()
set isLoading(value: boolean) {
this._isLoading = value;
this.cdRef.detectChanges();
}
get isLoading(): boolean {
return this._isLoading;
}
@Input()
containerClass = 'abp-loader-bar';
@Input()
color = '#77b6ff';
progressLevel = 0;
interval = new Subscription();
timer = new Subscription();
intervalPeriod = 350;
stopDelay = 800;
private readonly clearProgress = () => {
this.progressLevel = 0;
this.cdRef.detectChanges();
};
private readonly reportProgress = () => {
if (this.progressLevel < 75) {
this.progressLevel += 1 + Math.random() * 9;
} else if (this.progressLevel < 90) {
this.progressLevel += 0.4;
} else if (this.progressLevel < 100) {
this.progressLevel += 0.1;
} else {
this.interval.unsubscribe();
}
this.cdRef.detectChanges();
};
get boxShadow(): string {
return `0 0 10px rgba(${this.color}, 0.5)`;
}
ngOnInit() {
this.subscribeLoading();
}
subscribeLoading() {
this.subscription.addOne(
combineLatest([this.httpWaitService.getLoading$(), this.routerWaitService.getLoading$()]),
([httpLoading, routerLoading]) => {
if (httpLoading || routerLoading) this.startLoading();
else this.stopLoading();
},
);
}
ngOnDestroy() {
this.interval.unsubscribe();
}
startLoading() {
if (this.isLoading || !this.interval.closed) return;
this.isLoading = true;
this.progressLevel = 0;
this.cdRef.detectChanges();
this.interval = timer(0, this.intervalPeriod).subscribe(this.reportProgress);
this.timer.unsubscribe();
}
stopLoading() {
this.interval.unsubscribe();
this.progressLevel = 100;
this.isLoading = false;
if (!this.timer.closed) return;
this.timer = timer(this.stopDelay).subscribe(this.clearProgress);
}
}
import { NgClass }ngular/common';
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit, inject } from '@angular/core';
import { combineLatest, Subscription, timer } from 'rxjs';
import { HttpWaitService, RouterWaitService, SubscriptionService } from '@abp/ng.core';
@Component({
selector: 'abp-loader-bar',
template: `
<di
<div id="abp-loader-bar" [ngClass]="containerClass" [class.is-loading]="isLoading">
<div
class="abp-progress"
[class.progressing]="progressLevel"
[style.width.vw]="progressLevel"
[style]="{
'background-color': color,
'box-shadow': boxShadow,
}"
></div>
</div>
Urls: ['./loader-bar.component.scss'],
providers: [SubscriptionService],
imports: [NgClass], [NgClass]LoaderBarComponent implements OnDestroy, OnInit {
private cdRef = inject(ChangeDetectorRef);
private subscription = inject(SubscriptionService);
private httpWaitService = inject(HttpWaitService);
private routerWaitService = inject(RouterWaitService);
protected _isLoading!: boolean;
@Input()
set isLoading(value: boolean) {
this._isLoading = value;
this.cdRef.detectChanges();
}
get isLoading(): boolean {
return this._isLoading;
}
@Input()
containerClass = 'abp-loader-bar';
@Input()
color = '#77b6ff';
progressLevel = 0;
interval = new Subscription();
timer = new Subscription();
intervalPeriod = 350;
stopDelay = 800;
private readonly clearProgress = () => {
this.progressLevel = 0;
this.cdRef.detectChanges();
};
private readonly reportProgress = () => {
if (this.progressLevel < 75) {
this.progressLevel += 1 + Math.random() * 9;
} else if (this.progressLevel < 90) {
this.progressLevel += 0.4;
} else if (this.progressLevel < 100) {
this.progressLevel += 0.1;
} else {
this.interval.unsubscribe();
}
this.cdRef.detectChanges();
};
get boxShadow(): string {
return `0 0 10px rgba(${this.color}, 0.5)`;
}
ngOnInit() {
this.subscribeLoading();
}
subscribeLoading() {
this.subscription.addOne(
combineLatest([this.httpWaitService.getLoading$(), this.routerWaitService.getLoading$()]),
([httpLoading, routerLoading]) => {
if (httpLoading || routerLoading) this.startLoading();
else this.stopLoading();
},
);
}
ngOnDestroy() {
this.interval.unsubscribe();
}
startLoading() {
if (this.isLoading || !this.interval.closed) return;
this.isLoading = true;
this.progressLevel = 0;
this.cdRef.detectChanges();
this.interval = timer(0, this.intervalPeriod).subscribe(this.reportProgress);
this.timer.unsubscribe();
}
stopLoading() {
this.interval.unsubscribe();
this.progressLevel = 100;
this.isLoading = false;
if (!this.timer.closed) return;
this.timer = timer(this.stopDelay).subscribe(this.clearProgress);
}
}

Loading…
Cancel
Save