diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/date-time-picker/extensible-date-time-picker.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/date-time-picker/extensible-date-time-picker.component.ts
index 55b73581c9..e6f7881ca2 100644
--- a/npm/ng-packs/packages/components/extensible/src/lib/components/date-time-picker/extensible-date-time-picker.component.ts
+++ b/npm/ng-packs/packages/components/extensible/src/lib/components/date-time-picker/extensible-date-time-picker.component.ts
@@ -7,19 +7,24 @@ import {
SkipSelf,
ViewChild,
} from '@angular/core';
-import { ControlContainer } from '@angular/forms';
+import { ControlContainer, ReactiveFormsModule } from '@angular/forms';
import {
NgbDateAdapter,
+ NgbDatepickerModule,
NgbInputDatepicker,
NgbTimeAdapter,
NgbTimepicker,
+ NgbTimepickerModule,
} from '@ng-bootstrap/ng-bootstrap';
import { FormProp } from '../../models/form-props';
import { selfFactory } from '../../utils/factory.util';
import { DateTimeAdapter } from '@abp/ng.theme.shared';
+import { CommonModule } from '@angular/common';
@Component({
exportAs: 'abpExtensibleDateTimePicker',
+ standalone: true,
+ imports: [CommonModule, NgbDatepickerModule, ReactiveFormsModule, NgbTimepickerModule],
selector: 'abp-extensible-date-time-picker',
template: `
-
+
diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-form/extensible-form-prop.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-form/extensible-form-prop.component.ts
index 2689e09a33..ca32fd3e7a 100644
--- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-form/extensible-form-prop.component.ts
+++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-form/extensible-form-prop.component.ts
@@ -1,11 +1,12 @@
import { EXTENSIONS_FORM_PROP, EXTENSIONS_FORM_PROP_DATA } from './../../tokens/extensions.token';
-import { ABP, AbpValidators, ConfigStateService, TrackByService } from '@abp/ng.core';
+import { ABP, CoreModule, TrackByService } from '@abp/ng.core';
import {
AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
+ inject,
Injector,
Input,
OnChanges,
@@ -17,26 +18,53 @@ import {
import {
ControlContainer,
FormGroupDirective,
- UntypedFormGroup,
+ ReactiveFormsModule,
ValidatorFn,
- Validators,
} from '@angular/forms';
-import { NgbDateAdapter, NgbTimeAdapter } from '@ng-bootstrap/ng-bootstrap';
+import {
+ NgbDateAdapter,
+ NgbDatepickerModule,
+ NgbTimeAdapter,
+ NgbTimepickerModule,
+ NgbTypeaheadModule,
+} from '@ng-bootstrap/ng-bootstrap';
import { Observable, of } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
-import { DateAdapter, TimeAdapter } from '@abp/ng.theme.shared';
+import {
+ DateAdapter,
+ DisabledDirective,
+ PasswordComponent,
+ TimeAdapter,
+} from '@abp/ng.theme.shared';
import { EXTRA_PROPERTIES_KEY } from '../../constants/extra-properties';
-import { ePropType } from '../../enums/props.enum';
import { FormProp } from '../../models/form-props';
import { PropData } from '../../models/props';
import { selfFactory } from '../../utils/factory.util';
import { addTypeaheadTextSuffix } from '../../utils/typeahead.util';
-import { eThemeSharedComponents } from "../../enums/components";
+import { eThemeSharedComponents } from '../../enums/components';
+import { ExtensibleDateTimePickerComponent } from '../date-time-picker/extensible-date-time-picker.component';
+import { NgxValidateCoreModule } from '@ngx-validate/core';
+import { ExtensibleFormPropService } from '../../services/extensible-form-prop.service';
+import {CreateInjectorPipe} from "../../pipes/create-injector.pipe";
@Component({
selector: 'abp-extensible-form-prop',
templateUrl: './extensible-form-prop.component.html',
+ standalone: true,
+ imports: [
+ CoreModule,
+ ExtensibleDateTimePickerComponent,
+ NgbDatepickerModule,
+ NgbTimepickerModule,
+ ReactiveFormsModule,
+ DisabledDirective,
+ NgxValidateCoreModule,
+ NgbTypeaheadModule,
+ PasswordComponent,
+ CreateInjectorPipe
+ ],
changeDetection: ChangeDetectionStrategy.OnPush,
+ providers: [ExtensibleFormPropService],
viewProviders: [
{
provide: ControlContainer,
@@ -48,32 +76,27 @@ import { eThemeSharedComponents } from "../../enums/components";
],
})
export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
- @Input() data!: PropData;
+ protected service = inject(ExtensibleFormPropService);
+ public readonly cdRef = inject(ChangeDetectorRef);
+ public readonly track = inject(TrackByService);
+ #groupDirective = inject(FormGroupDirective);
+ private injector = inject(Injector);
+ private readonly form = this.#groupDirective.form;
+ @Input() data!: PropData;
@Input() prop!: FormProp;
-
@Input() first?: boolean;
-
@ViewChild('field') private fieldRef!: ElementRef;
- public injectorForCustomComponent?: Injector;
-
+ injectorForCustomComponent?: Injector;
asterisk = '';
-
containerClassName = 'mb-2';
-
options$: Observable[]> = of([]);
-
validators: ValidatorFn[] = [];
-
readonly!: boolean;
-
typeaheadModel: any;
-
passwordKey = eThemeSharedComponents.PasswordComponent;
- private readonly form: UntypedFormGroup;
-
disabledFn = (data: PropData) => false;
get disabled() {
@@ -100,27 +123,13 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
typeaheadFormatter = (option: ABP.Option) => option.key;
- get meridian() {
- return (
- this.configState.getDeep('localization.currentCulture.dateTimeFormat.shortTimePattern') || ''
- ).includes('tt');
- }
+ meridian$ = this.service.meridian$;
get isInvalid() {
const control = this.form.get(this.prop.name);
return control?.touched && control.invalid;
}
- constructor(
- public readonly cdRef: ChangeDetectorRef,
- public readonly track: TrackByService,
- protected configState: ConfigStateService,
- groupDirective: FormGroupDirective,
- private injector: Injector,
- ) {
- this.form = groupDirective.form;
- }
-
private getTypeaheadControls() {
const { name } = this.prop;
const extraPropName = `${EXTRA_PROPERTIES_KEY}.${name}`;
@@ -132,7 +141,7 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
}
private setAsterisk() {
- this.asterisk = this.validators.some(isRequired) ? '*' : '';
+ this.asterisk = this.service.calcAsterisks(this.validators);
}
ngAfterViewInit() {
@@ -143,51 +152,11 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
}
getComponent(prop: FormProp): string {
- if (prop.template) {
- return 'template';
- }
- switch (prop.type) {
- case ePropType.Boolean:
- return 'checkbox';
- case ePropType.Date:
- return 'date';
- case ePropType.DateTime:
- return 'dateTime';
- case ePropType.Hidden:
- return 'hidden';
- case ePropType.MultiSelect:
- return 'multiselect';
- case ePropType.Text:
- return 'textarea';
- case ePropType.Time:
- return 'time';
- case ePropType.Typeahead:
- return 'typeahead';
- case ePropType.PasswordInputGroup:
- return 'passwordinputgroup';
- default:
- return prop.options ? 'select' : 'input';
- }
+ return this.service.getComponent(prop);
}
getType(prop: FormProp): string {
- switch (prop.type) {
- case ePropType.Date:
- case ePropType.String:
- return 'text';
- case ePropType.Boolean:
- return 'checkbox';
- case ePropType.Number:
- return 'number';
- case ePropType.Email:
- return 'email';
- case ePropType.Password:
- return 'password';
- case ePropType.PasswordInputGroup:
- return 'passwordinputgroup';
- default:
- return 'hidden';
- }
+ return this.service.getType(prop);
}
ngOnChanges({ prop, data }: SimpleChanges) {
@@ -229,11 +198,3 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
this.typeaheadModel = { key: keyControl.value, value: valueControl.value };
}
}
-
-function isRequired(validator: ValidatorFn) {
- return (
- validator === Validators.required ||
- validator === AbpValidators.required ||
- validator.name === 'required'
- );
-}
diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-form/extensible-form.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-form/extensible-form.component.ts
index bd6f23591f..c7436d3374 100644
--- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-form/extensible-form.component.ts
+++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-form/extensible-form.component.ts
@@ -1,73 +1,76 @@
-import { TrackByService } from '@abp/ng.core';
+import {TrackByService} from '@abp/ng.core';
import {
- ChangeDetectionStrategy,
- ChangeDetectorRef,
- Component,
- Inject,
- Input,
- Optional,
- QueryList,
- SkipSelf,
- ViewChildren,
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component, inject,
+ Input,
+ Optional,
+ QueryList,
+ SkipSelf,
+ ViewChildren,
} from '@angular/core';
-import { ControlContainer, UntypedFormGroup } from '@angular/forms';
-import { EXTRA_PROPERTIES_KEY } from '../../constants/extra-properties';
-import { FormPropList, GroupedFormPropList } from '../../models/form-props';
-import { ExtensionsService } from '../../services/extensions.service';
-import { EXTENSIONS_IDENTIFIER } from '../../tokens/extensions.token';
-import { selfFactory } from '../../utils/factory.util';
-import { ExtensibleFormPropComponent } from './extensible-form-prop.component';
+import {ControlContainer, ReactiveFormsModule, UntypedFormGroup} from '@angular/forms';
+import {EXTRA_PROPERTIES_KEY} from '../../constants/extra-properties';
+import {FormPropList, GroupedFormPropList} from '../../models/form-props';
+import {ExtensionsService} from '../../services/extensions.service';
+import {EXTENSIONS_IDENTIFIER} from '../../tokens/extensions.token';
+import {selfFactory} from '../../utils/factory.util';
+import {ExtensibleFormPropComponent} from './extensible-form-prop.component';
+import {CommonModule} from "@angular/common";
+import {PropDataDirective} from "../../directives/prop-data.directive";
@Component({
- exportAs: 'abpExtensibleForm',
- selector: 'abp-extensible-form',
- templateUrl: './extensible-form.component.html',
- changeDetection: ChangeDetectionStrategy.OnPush,
- viewProviders: [
- {
- provide: ControlContainer,
- useFactory: selfFactory,
- deps: [[new Optional(), new SkipSelf(), ControlContainer]],
- },
- ],
+ exportAs: 'abpExtensibleForm',
+ selector: 'abp-extensible-form',
+ templateUrl: './extensible-form.component.html',
+ standalone:true,
+ imports:[CommonModule, PropDataDirective,ReactiveFormsModule,ExtensibleFormPropComponent],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ viewProviders: [
+ {
+ provide: ControlContainer,
+ useFactory: selfFactory,
+ deps: [[new Optional(), new SkipSelf(), ControlContainer]],
+ },
+ ],
})
export class ExtensibleFormComponent {
- @ViewChildren(ExtensibleFormPropComponent)
- formProps!: QueryList;
- @Input()
- set selectedRecord(record: R) {
- const type = !record || JSON.stringify(record) === '{}' ? 'create' : 'edit';
- const propList = this.extensions[`${type}FormProps`].get(this.identifier).props;
- this.groupedPropList = this.createGroupedList(propList);
- this.record = record;
- }
+ @ViewChildren(ExtensibleFormPropComponent)
+ formProps!: QueryList;
- extraPropertiesKey = EXTRA_PROPERTIES_KEY;
- groupedPropList!: GroupedFormPropList;
- record!: R;
+ @Input()
+ set selectedRecord(record: R) {
+ const type = !record || JSON.stringify(record) === '{}' ? 'create' : 'edit';
+ const propList = this.extensions[`${type}FormProps`].get(this.identifier).props;
+ this.groupedPropList = this.createGroupedList(propList);
+ this.record = record;
+ }
- createGroupedList(propList: FormPropList) {
- const groupedFormPropList = new GroupedFormPropList();
- propList.forEach(item => {
- groupedFormPropList.addItem(item.value);
- });
- return groupedFormPropList;
- }
+ extraPropertiesKey = EXTRA_PROPERTIES_KEY;
+ groupedPropList!: GroupedFormPropList;
+ record!: R;
- get form(): UntypedFormGroup {
- return (this.container ? this.container.control : { controls: {} }) as UntypedFormGroup;
- }
+ public readonly cdRef = inject(ChangeDetectorRef)
+ public readonly track = inject(TrackByService)
+ private container = inject(ControlContainer)
+ private extensions = inject(ExtensionsService);
+ private identifier = inject(EXTENSIONS_IDENTIFIER)
- get extraProperties(): UntypedFormGroup {
- return (this.form.controls.extraProperties || { controls: {} }) as UntypedFormGroup;
- }
+ createGroupedList(propList: FormPropList) {
+ const groupedFormPropList = new GroupedFormPropList();
+ propList.forEach(item => {
+ groupedFormPropList.addItem(item.value);
+ });
+ return groupedFormPropList;
+ }
+
+ get form(): UntypedFormGroup {
+ return (this.container ? this.container.control : {controls: {}}) as UntypedFormGroup;
+ }
+
+ get extraProperties(): UntypedFormGroup {
+ return (this.form.controls.extraProperties || {controls: {}}) as UntypedFormGroup;
+ }
- constructor(
- public readonly cdRef: ChangeDetectorRef,
- public readonly track: TrackByService,
- private container: ControlContainer,
- private extensions: ExtensionsService,
- @Inject(EXTENSIONS_IDENTIFIER) private identifier: string,
- ) {}
}
diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts
index af146e2367..697f8d36bd 100644
--- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts
+++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts
@@ -1,17 +1,19 @@
import {
ABP,
ConfigStateService,
+ CoreModule,
getShortDateFormat,
getShortDateShortTimeFormat,
getShortTimeFormat,
ListService,
PermissionService,
} from '@abp/ng.core';
-import { formatDate } from '@angular/common';
+import { CommonModule, formatDate } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
+ inject,
Inject,
Injector,
Input,
@@ -31,16 +33,28 @@ import { PropData } from '../../models/props';
import { ExtensionsService } from '../../services/extensions.service';
import {
ENTITY_PROP_TYPE_CLASSES,
- EntityPropTypeClass,
EXTENSIONS_IDENTIFIER,
PROP_DATA_STREAM,
} from '../../tokens/extensions.token';
+import { NgxDatatableModule } from '@swimlane/ngx-datatable';
+import { GridActionsComponent } from '../grid-actions/grid-actions.component';
+import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
+import { NgxDatatableDefaultDirective, NgxDatatableListDirective } from '@abp/ng.theme.shared';
const DEFAULT_ACTIONS_COLUMN_WIDTH = 150;
- @Component({
+@Component({
exportAs: 'abpExtensibleTable',
selector: 'abp-extensible-table',
+ standalone: true,
+ imports: [
+ CoreModule,
+ NgxDatatableModule,
+ GridActionsComponent,
+ NgbTooltip,
+ NgxDatatableDefaultDirective,
+ NgxDatatableListDirective,
+ ],
templateUrl: './extensible-table.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
@@ -50,6 +64,7 @@ export class ExtensibleTableComponent implements OnChanges {
set actionsText(value: string) {
this._actionsText = value;
}
+
get actionsText(): string {
return this._actionsText ?? (this.actionList.length > 1 ? 'AbpUi::Actions' : '');
}
@@ -57,19 +72,17 @@ export class ExtensibleTableComponent implements OnChanges {
@Input() data!: R[];
@Input() list!: ListService;
@Input() recordsTotal!: number;
+
@Input() set actionsColumnWidth(width: number) {
this.setColumnWidths(width ? Number(width) : undefined);
}
+
@Input() actionsTemplate?: TemplateRef;
@Output() tableActivate = new EventEmitter();
- getInjected: typeof this.injector.get
-
hasAtLeastOnePermittedAction: boolean;
- entityPropTypeClasses: EntityPropTypeClass;
-
readonly columnWidths!: number[];
readonly propList: EntityPropList;
@@ -78,20 +91,20 @@ export class ExtensibleTableComponent implements OnChanges {
readonly trackByFn: TrackByFunction> = (_, item) => item.name;
- constructor(
- @Inject(LOCALE_ID) private locale: string,
- private config: ConfigStateService,
- private injector: Injector,
- ) {
- this.entityPropTypeClasses = injector.get(ENTITY_PROP_TYPE_CLASSES);
- this.getInjected = injector.get.bind(injector);
- const extensions = injector.get(ExtensionsService);
- const name = injector.get(EXTENSIONS_IDENTIFIER);
+ locale = inject(LOCALE_ID);
+ private config = inject(ConfigStateService);
+ entityPropTypeClasses = inject(ENTITY_PROP_TYPE_CLASSES);
+ #injector = inject(Injector);
+ getInjected = this.#injector.get.bind(this.#injector);
+
+ constructor() {
+ const extensions = this.#injector.get(ExtensionsService);
+ const name = this.#injector.get(EXTENSIONS_IDENTIFIER);
this.propList = extensions.entityProps.get(name).props;
this.actionList = extensions['entityActions'].get(name)
.actions as unknown as EntityActionList;
- const permissionService = injector.get(PermissionService);
+ const permissionService = this.#injector.get(PermissionService);
this.hasAtLeastOnePermittedAction =
permissionService.filterItemsByPolicy(
this.actionList.toArray().map(action => ({ requiredPolicy: action.permission })),
@@ -149,7 +162,7 @@ export class ExtensibleTableComponent implements OnChanges {
if (!data?.currentValue) return;
if (data.currentValue.length < 1) {
- this.list.totalCount = this.recordsTotal
+ this.list.totalCount = this.recordsTotal;
}
this.data = data.currentValue.map((record: any, index: number) => {
@@ -170,7 +183,7 @@ export class ExtensibleTableComponent implements OnChanges {
useValue: value,
},
],
- parent: this.injector,
+ parent: this.#injector,
});
record[propKey].component = prop.value.component;
}
diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts
index 22b5419b55..ebccd6e163 100644
--- a/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts
+++ b/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts
@@ -8,9 +8,14 @@ import {
import { EntityAction, EntityActionList } from '../../models/entity-actions';
import { EXTENSIONS_ACTION_TYPE } from '../../tokens/extensions.token';
import { AbstractActionsComponent } from '../abstract-actions/abstract-actions.component';
+import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
+import { CoreModule } from '@abp/ng.core';
+import {EllipsisDirective} from "@abp/ng.theme.shared";
@Component({
exportAs: 'abpGridActions',
+ standalone: true,
+ imports: [ CoreModule, NgbDropdownModule, EllipsisDirective],
selector: 'abp-grid-actions',
templateUrl: './grid-actions.component.html',
providers: [
diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/page-toolbar/page-toolbar.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/page-toolbar/page-toolbar.component.ts
index afe421554b..85685cdee6 100644
--- a/npm/ng-packs/packages/components/extensible/src/lib/components/page-toolbar/page-toolbar.component.ts
+++ b/npm/ng-packs/packages/components/extensible/src/lib/components/page-toolbar/page-toolbar.component.ts
@@ -8,10 +8,14 @@ import {
} from '../../models/toolbar-actions';
import { EXTENSIONS_ACTION_TYPE } from '../../tokens/extensions.token';
import { AbstractActionsComponent } from '../abstract-actions/abstract-actions.component';
+import { CreateInjectorPipe } from '../../pipes/create-injector.pipe';
+import { CoreModule } from '@abp/ng.core';
@Component({
exportAs: 'abpPageToolbar',
selector: 'abp-page-toolbar',
+ standalone: true,
+ imports: [ CoreModule, CreateInjectorPipe],
templateUrl: './page-toolbar.component.html',
providers: [
{
@@ -31,6 +35,7 @@ export class PageToolbarComponent
readonly trackByFn: TrackByFunction> = (_, item) =>
item.action || item.component;
+
constructor(public readonly injector: Injector) {
super(injector);
}
diff --git a/npm/ng-packs/packages/components/extensible/src/lib/directives/prop-data.directive.ts b/npm/ng-packs/packages/components/extensible/src/lib/directives/prop-data.directive.ts
index 2bba45ff70..52ccd286ad 100644
--- a/npm/ng-packs/packages/components/extensible/src/lib/directives/prop-data.directive.ts
+++ b/npm/ng-packs/packages/components/extensible/src/lib/directives/prop-data.directive.ts
@@ -13,6 +13,7 @@ import { PropData, PropList } from '../models/props';
@Directive({
exportAs: 'abpPropData',
selector: '[abpPropData]',
+ standalone: true,
})
export class PropDataDirective>
extends PropData>
diff --git a/npm/ng-packs/packages/components/extensible/src/lib/extensible.module.ts b/npm/ng-packs/packages/components/extensible/src/lib/extensible.module.ts
index 334909a7e2..99bc25b6f4 100644
--- a/npm/ng-packs/packages/components/extensible/src/lib/extensible.module.ts
+++ b/npm/ng-packs/packages/components/extensible/src/lib/extensible.module.ts
@@ -15,23 +15,25 @@ import {
ExtensibleTableComponent,
GridActionsComponent,
PageToolbarComponent,
- ExtensibleDateTimePickerComponent
+ ExtensibleDateTimePickerComponent,
} from './components';
import { PropDataDirective } from './directives/prop-data.directive';
import { CreateInjectorPipe } from './pipes/create-injector.pipe';
import { DisabledDirective } from '@abp/ng.theme.shared';
+const importWithExport = [
+ DisabledDirective,
+ ExtensibleDateTimePickerComponent,
+ ExtensibleFormPropComponent,
+ GridActionsComponent,
+ PropDataDirective,
+ PageToolbarComponent,
+ CreateInjectorPipe,
+ ExtensibleFormComponent,
+ ExtensibleTableComponent,
+];
@NgModule({
- declarations: [
- ExtensibleDateTimePickerComponent,
- PageToolbarComponent,
- GridActionsComponent,
- ExtensibleFormPropComponent,
- ExtensibleFormComponent,
- ExtensibleTableComponent,
- PropDataDirective,
- CreateInjectorPipe,
- ],
+ declarations: [],
imports: [
CoreModule,
ThemeSharedModule,
@@ -41,15 +43,8 @@ import { DisabledDirective } from '@abp/ng.theme.shared';
NgbTimepickerModule,
NgbTypeaheadModule,
NgbTooltipModule,
- DisabledDirective,
- ],
- exports: [
- PageToolbarComponent,
- GridActionsComponent,
- ExtensibleFormComponent,
- ExtensibleTableComponent,
- PropDataDirective,
- CreateInjectorPipe,
+ ...importWithExport,
],
+ exports: [...importWithExport],
})
export class ExtensibleModule {}
diff --git a/npm/ng-packs/packages/components/extensible/src/lib/pipes/create-injector.pipe.ts b/npm/ng-packs/packages/components/extensible/src/lib/pipes/create-injector.pipe.ts
index 3536fa4dad..4b410fcea9 100644
--- a/npm/ng-packs/packages/components/extensible/src/lib/pipes/create-injector.pipe.ts
+++ b/npm/ng-packs/packages/components/extensible/src/lib/pipes/create-injector.pipe.ts
@@ -12,6 +12,7 @@ import { EXTENSIONS_ACTION_CALLBACK, EXTENSIONS_ACTION_DATA } from '../tokens/ex
@Pipe({
name: 'createInjector',
+ standalone: true,
})
export class CreateInjectorPipe implements PipeTransform {
public transform(
diff --git a/npm/ng-packs/packages/components/extensible/src/lib/services/extensible-form-prop.service.ts b/npm/ng-packs/packages/components/extensible/src/lib/services/extensible-form-prop.service.ts
new file mode 100644
index 0000000000..bf6de7ed05
--- /dev/null
+++ b/npm/ng-packs/packages/components/extensible/src/lib/services/extensible-form-prop.service.ts
@@ -0,0 +1,77 @@
+import { inject, Injectable } from '@angular/core';
+ import { ValidatorFn, Validators } from '@angular/forms';
+import { AbpValidators, ConfigStateService } from '@abp/ng.core';
+import { map } from 'rxjs/operators';
+import { FormProp } from '../models/form-props';
+import { ePropType } from '../enums/props.enum';
+
+@Injectable()
+export class ExtensibleFormPropService {
+ readonly #configStateService = inject(ConfigStateService);
+
+ meridian$ = this.#configStateService
+ .getDeep$('localization.currentCulture.dateTimeFormat.shortTimePattern')
+ .pipe(map((shortTimePattern: string | undefined) => (shortTimePattern || '').includes('tt')));
+
+ isRequired(validator: ValidatorFn) {
+ return (
+ validator === Validators.required ||
+ validator === AbpValidators.required ||
+ validator.name === 'required'
+ );
+ }
+
+ getComponent(prop: FormProp) {
+ if (prop.template) {
+ return 'template';
+ }
+ switch (prop.type) {
+ case ePropType.Boolean:
+ return 'checkbox';
+ case ePropType.Date:
+ return 'date';
+ case ePropType.DateTime:
+ return 'dateTime';
+ case ePropType.Hidden:
+ return 'hidden';
+ case ePropType.MultiSelect:
+ return 'multiselect';
+ case ePropType.Text:
+ return 'textarea';
+ case ePropType.Time:
+ return 'time';
+ case ePropType.Typeahead:
+ return 'typeahead';
+ case ePropType.PasswordInputGroup:
+ return 'passwordinputgroup';
+ default:
+ return prop.options ? 'select' : 'input';
+ }
+ }
+
+ getType(prop: FormProp) {
+ switch (prop.type) {
+ case ePropType.Date:
+ case ePropType.String:
+ return 'text';
+ case ePropType.Boolean:
+ return 'checkbox';
+ case ePropType.Number:
+ return 'number';
+ case ePropType.Email:
+ return 'email';
+ case ePropType.Password:
+ return 'password';
+ case ePropType.PasswordInputGroup:
+ return 'passwordinputgroup';
+ default:
+ return 'hidden';
+ }
+ }
+
+ calcAsterisks(validators: ValidatorFn[]) {
+ if (!validators) return '';
+ const required = validators.find(v => this.isRequired(v));
+ return required ? '*' : '';
+ }
+}
diff --git a/npm/ng-packs/packages/components/page/src/page.module.ts b/npm/ng-packs/packages/components/page/src/page.module.ts
index 5bb27fbc66..77ffca0951 100644
--- a/npm/ng-packs/packages/components/page/src/page.module.ts
+++ b/npm/ng-packs/packages/components/page/src/page.module.ts
@@ -1,6 +1,5 @@
import { CoreModule } from '@abp/ng.core';
import { ThemeSharedModule } from '@abp/ng.theme.shared';
- import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { PagePartDirective } from './page-part.directive';
import {
@@ -9,7 +8,7 @@ import {
PageToolbarContainerComponent,
} from './page-parts.component';
import { PageComponent } from './page.component';
-import {ExtensibleModule} from "@abp/ng.components/extensible";
+import {PageToolbarComponent} from "@abp/ng.components/extensible";
const exportedDeclarations = [
PageComponent,
@@ -21,7 +20,7 @@ const exportedDeclarations = [
@NgModule({
declarations: [...exportedDeclarations],
- imports: [CommonModule, CoreModule, ThemeSharedModule, ExtensibleModule],
+ imports: [CoreModule, ThemeSharedModule, PageToolbarComponent],
exports: [...exportedDeclarations],
})
export class PageModule {}
diff --git a/npm/ng-packs/packages/core/src/lib/abstracts/ng-model.component.ts b/npm/ng-packs/packages/core/src/lib/abstracts/ng-model.component.ts
index 0f0eaa3722..8cabb30b0d 100644
--- a/npm/ng-packs/packages/core/src/lib/abstracts/ng-model.component.ts
+++ b/npm/ng-packs/packages/core/src/lib/abstracts/ng-model.component.ts
@@ -1,11 +1,11 @@
-import { ChangeDetectorRef, Component, Injector, Input } from '@angular/core';
+import { ChangeDetectorRef, Component, inject, Input } from '@angular/core';
import { ControlValueAccessor } from '@angular/forms';
// Not an abstract class on purpose. Do not change!
@Component({ template: '' })
export class AbstractNgModelComponent implements ControlValueAccessor {
protected _value!: T;
- protected cdRef: ChangeDetectorRef;
+ protected cdRef = inject(ChangeDetectorRef);
onChange?: (value: T) => void;
onTouched?: () => void;
@@ -39,10 +39,6 @@ export class AbstractNgModelComponent implements ControlValueAcc
return this._value;
}
- constructor(public injector: Injector) {
- this.cdRef = injector.get(ChangeDetectorRef);
- }
-
notifyValueChange(): void {
if (this.onChange) {
this.onChange(this.value);
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/checkbox/checkbox.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/checkbox/checkbox.component.ts
index ee2dd5aeac..89766ce992 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/components/checkbox/checkbox.component.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/checkbox/checkbox.component.ts
@@ -43,8 +43,4 @@ export class FormCheckboxComponent extends AbstractNgModelComponent {
@Input() checkboxReadonly = false;
@Output() checkboxBlur = new EventEmitter();
@Output() checkboxFocus = new EventEmitter();
-
- constructor(injector: Injector) {
- super(injector);
- }
}
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/form-input/form-input.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/form-input/form-input.component.ts
index 8aa68a2047..d759163a0d 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/components/form-input/form-input.component.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/form-input/form-input.component.ts
@@ -45,8 +45,4 @@ export class FormInputComponent extends AbstractNgModelComponent {
@Input() inputClass = 'form-control';
@Output() formBlur = new EventEmitter();
@Output() formFocus = new EventEmitter();
-
- constructor(injector: Injector) {
- super(injector);
- }
}
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/password/password.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/password/password.component.ts
index 22fcd6e4f5..4567ef45d6 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/components/password/password.component.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/password/password.component.ts
@@ -1,9 +1,12 @@
-import { Component, forwardRef, Injector, Input } from '@angular/core';
+import { Component, forwardRef, Input } from '@angular/core';
import { AbstractNgModelComponent } from '@abp/ng.core';
-import { NG_VALUE_ACCESSOR } from '@angular/forms';
+import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
+import { CommonModule } from '@angular/common';
@Component({
selector: 'abp-password',
+ standalone: true,
+ imports: [CommonModule, FormsModule],
templateUrl: `./password.component.html`,
providers: [
{
@@ -18,10 +21,6 @@ export class PasswordComponent extends AbstractNgModelComponent {
@Input() formControlName!: string;
fieldTextType?: boolean;
- constructor(injector: Injector) {
- super(injector);
- }
-
toggleFieldTextType() {
this.fieldTextType = !this.fieldTextType;
}
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/ellipsis.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/ellipsis.directive.ts
index d7bfc999ff..2cad957942 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/directives/ellipsis.directive.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/ellipsis.directive.ts
@@ -10,6 +10,7 @@ import {
@Directive({
selector: '[abpEllipsis]',
+ standalone:true
})
export class EllipsisDirective implements AfterViewInit {
@Input('abpEllipsis')
@@ -44,9 +45,3 @@ export class EllipsisDirective implements AfterViewInit {
this.cdRef.detectChanges();
}
}
-
-@NgModule({
- exports: [EllipsisDirective],
- declarations: [EllipsisDirective],
-})
-export class EllipsisModule {}
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts
index b41be45343..eb781666c1 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts
@@ -7,6 +7,7 @@ import { debounceTime } from 'rxjs/operators';
@Directive({
// eslint-disable-next-line @angular-eslint/directive-selector
selector: 'ngx-datatable[default]',
+ standalone:true,
exportAs: 'ngxDatatableDefault',
})
export class NgxDatatableDefaultDirective implements AfterViewInit, OnDestroy {
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts
index a179669473..9ce5d1d860 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts
@@ -21,6 +21,7 @@ import {
@Directive({
// eslint-disable-next-line @angular-eslint/directive-selector
selector: 'ngx-datatable[list]',
+ standalone: true,
exportAs: 'ngxDatatableList',
})
export class NgxDatatableListDirective implements OnChanges, OnDestroy, OnInit {
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
index 71c081c9b2..44fbc85c0f 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
@@ -22,7 +22,7 @@ import { ModalComponent } from './components/modal/modal.component';
import { ToastContainerComponent } from './components/toast-container/toast-container.component';
import { ToastComponent } from './components/toast/toast.component';
import { DEFAULT_VALIDATION_BLUEPRINTS } from './constants/validation';
-import { EllipsisModule } from './directives/ellipsis.directive';
+import { EllipsisDirective } from './directives/ellipsis.directive';
import { LoadingDirective } from './directives/loading.directive';
import { NgxDatatableDefaultDirective } from './directives/ngx-datatable-default.directive';
import { NgxDatatableListDirective } from './directives/ngx-datatable-list.directive';
@@ -52,9 +52,6 @@ const declarationsWithExports = [
ModalComponent,
ToastComponent,
ToastContainerComponent,
- PasswordComponent,
- NgxDatatableDefaultDirective,
- NgxDatatableListDirective,
LoadingDirective,
ModalCloseDirective,
AbpVisibleDirective,
@@ -68,14 +65,16 @@ const declarationsWithExports = [
NgxDatatableModule,
NgxValidateCoreModule,
NgbPaginationModule,
- EllipsisModule,
+ EllipsisDirective,
CardModule,
+ PasswordComponent,
+ NgxDatatableDefaultDirective,
+ NgxDatatableListDirective,
DisabledDirective
],
declarations: [...declarationsWithExports, HttpErrorWrapperComponent],
exports: [
NgxDatatableModule,
- EllipsisModule,
NgxValidateCoreModule,
CardModule,
DisabledDirective,