diff --git a/npm/ng-packs/angular.json b/npm/ng-packs/angular.json index 7138cb5a38..14416d1d3a 100644 --- a/npm/ng-packs/angular.json +++ b/npm/ng-packs/angular.json @@ -200,50 +200,50 @@ "bundleName": "bootstrap-dim" }, { - "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.css", - "inject": false, - "bundleName": "ng-bundle" + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.css", + "inject": false, + "bundleName": "ng-bundle" }, { - "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.css", - "inject": false, - "bundleName": "layout-bundle" + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.css", + "inject": false, + "bundleName": "layout-bundle" }, { - "input": "node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.css", - "inject": false, - "bundleName": "abp-bundle" + "input": "node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.css", + "inject": false, + "bundleName": "abp-bundle" }, { - "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.rtl.css", - "inject": false, - "bundleName": "bootstrap-dim.rtl" + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.rtl.css", + "inject": false, + "bundleName": "bootstrap-dim.rtl" }, { - "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.rtl.css", - "inject": false, - "bundleName": "ng-bundle.rtl" + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.rtl.css", + "inject": false, + "bundleName": "ng-bundle.rtl" }, { - "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.rtl.css", - "inject": false, - "bundleName": "layout-bundle.rtl" + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.rtl.css", + "inject": false, + "bundleName": "layout-bundle.rtl" }, { - "input": "node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.rtl.css", - "inject": false, - "bundleName": "abp-bundle.rtl" + "input": "node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.rtl.css", + "inject": false, + "bundleName": "abp-bundle.rtl" }, { - "input":"node_modules/@volo/ngx-lepton-x.lite/assets/css/font-bundle.rtl.css", - "inject":false, - "bundleName":"font-bundle.rtl" + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/font-bundle.rtl.css", + "inject": false, + "bundleName": "font-bundle.rtl" }, { - "input":"node_modules/@volo/ngx-lepton-x.lite/assets/css/font-bundle.css", - "inject":false, - "bundleName":"font-bundle" - }, + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/font-bundle.css", + "inject": false, + "bundleName": "font-bundle" + }, { "input": "node_modules/@fortawesome/fontawesome-free/css/all.min.css", "inject": true, @@ -756,7 +756,7 @@ } }, "tags": [], - "implicitDependencies": ["core","oauth"] + "implicitDependencies": ["core", "oauth"] } } } diff --git a/npm/ng-packs/apps/dev-app/src/app/app.module.ts b/npm/ng-packs/apps/dev-app/src/app/app.module.ts index 86e29cf0d1..56e38b40ee 100644 --- a/npm/ng-packs/apps/dev-app/src/app/app.module.ts +++ b/npm/ng-packs/apps/dev-app/src/app/app.module.ts @@ -4,8 +4,8 @@ import { registerLocale } from '@abp/ng.core/locale'; import { IdentityConfigModule } from '@abp/ng.identity/config'; import { SettingManagementConfigModule } from '@abp/ng.setting-management/config'; import { TenantManagementConfigModule } from '@abp/ng.tenant-management/config'; -import { ThemeLeptonXModule } from "@abp/ng.theme.lepton-x"; -import { SideMenuLayoutModule } from "@abp/ng.theme.lepton-x/layouts"; +import { ThemeLeptonXModule } from '@abp/ng.theme.lepton-x'; +import { SideMenuLayoutModule } from '@abp/ng.theme.lepton-x/layouts'; import { ThemeSharedModule } from '@abp/ng.theme.shared'; import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; @@ -36,7 +36,7 @@ import { AbpOAuthModule } from '@abp/ng.oauth'; FeatureManagementModule.forRoot(), SettingManagementConfigModule.forRoot(), ThemeLeptonXModule.forRoot(), - SideMenuLayoutModule.forRoot() + SideMenuLayoutModule.forRoot(), ], providers: [APP_ROUTE_PROVIDER], declarations: [AppComponent], diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html index 0b7db30ace..eaf21949f3 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html @@ -49,18 +49,24 @@ *ngFor="let roleGroup of roleGroups; let i = index; trackBy: trackByFn" class="form-check mb-2" > - - + [label]="roles[i].name" + > + -
diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts index cb0cdd9755..6dd1ab9f17 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts @@ -1,12 +1,28 @@ -import { ListService, PagedResultDto } from "@abp/ng.core"; -import { GetIdentityUsersInput, IdentityRoleDto, IdentityUserDto, IdentityUserService } from "@abp/ng.identity/proxy"; -import { ePermissionManagementComponents } from "@abp/ng.permission-management"; -import { Confirmation, ConfirmationService, ToasterService } from "@abp/ng.theme.shared"; -import { EXTENSIONS_IDENTIFIER, FormPropData, generateFormFromProps } from "@abp/ng.theme.shared/extensions"; -import { Component, Injector, OnInit, TemplateRef, TrackByFunction, ViewChild } from "@angular/core"; -import { AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; -import { finalize, switchMap, tap } from "rxjs/operators"; -import { eIdentityComponents } from "../../enums/components"; +import { ListService, PagedResultDto } from '@abp/ng.core'; +import { + GetIdentityUsersInput, + IdentityRoleDto, + IdentityUserDto, + IdentityUserService, +} from '@abp/ng.identity/proxy'; +import { ePermissionManagementComponents } from '@abp/ng.permission-management'; +import {Confirmation, ConfirmationService, eFormComponets, ToasterService} from '@abp/ng.theme.shared'; +import { + EXTENSIONS_IDENTIFIER, + FormPropData, + generateFormFromProps, +} from '@abp/ng.theme.shared/extensions'; +import { + Component, + Injector, + OnInit, + TemplateRef, + TrackByFunction, + ViewChild, +} from '@angular/core'; +import { AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { finalize, switchMap, tap } from 'rxjs/operators'; +import { eIdentityComponents } from '../../enums/components'; @Component({ selector: 'abp-users', @@ -43,7 +59,9 @@ export class UsersComponent implements OnInit { permissionManagementKey = ePermissionManagementComponents.PermissionManagement; - entityDisplayName?: string; + entityDisplayName: string; + + inputKey=eFormComponets.FormCheckboxComponent trackByFn: TrackByFunction = (index, item) => Object.keys(item)[0] || index; 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 new file mode 100644 index 0000000000..3ead2f929d --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/checkbox/checkbox.component.ts @@ -0,0 +1,45 @@ +import { AbstractNgModelComponent } from '@abp/ng.core'; +import { Component, EventEmitter, forwardRef, Injector, Input, Output } from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; + +@Component({ + selector: 'abp-checkbox', + template: ` +
+ + +
+ `, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => FormCheckboxComponent), + multi: true, + }, + ] +}) +export class FormCheckboxComponent extends AbstractNgModelComponent { + + @Input() label?: string; + @Input() labelClass = 'form-check-label'; + @Input() checkboxId!: string; + @Input() checkboxStyle = ''; + @Input() checkboxClass = 'form-check-input'; + @Input() checkboxReadonly = false; + @Output() onBlur = new EventEmitter(); + @Output() onFocus = 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 new file mode 100644 index 0000000000..d7f1f48c9d --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/form-input/form-input.component.ts @@ -0,0 +1,46 @@ +import { AbstractNgModelComponent } from '@abp/ng.core'; +import { Component, EventEmitter, forwardRef, Injector, Input, Output } from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; + +@Component({ + selector: 'abp-form-input', + template: ` +
+ + +
+ `, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => FormInputComponent), + multi: true, + }, + ] +}) +export class FormInputComponent extends AbstractNgModelComponent { + @Input() inputId!: string; + @Input() inputReadonly: boolean = false; + @Input() label: string = ''; + @Input() labelClass = 'form-label'; + @Input() inputPlaceholder: string = ''; + @Input() inputType: string = 'text'; + @Input() inputStyle: string = ''; + @Input() inputClass: string = 'form-control'; + @Output() onBlur = new EventEmitter(); + @Output() onFocus = new EventEmitter(); + + constructor(injector: Injector) { + super(injector); + } + +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/enums/form.ts b/npm/ng-packs/packages/theme-shared/src/lib/enums/form.ts new file mode 100644 index 0000000000..9ccbb93655 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/enums/form.ts @@ -0,0 +1,4 @@ +export enum eFormComponets { + FormInputComponent = 'FormInputComponent', + FormCheckboxComponent = 'FormCheckboxComponent', +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/enums/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/enums/index.ts index 3bda94b078..9e781067f7 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/enums/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/enums/index.ts @@ -1 +1,2 @@ +export * from './form'; export * from './route-names'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/checkbox.component.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/checkbox.component.spec.ts new file mode 100644 index 0000000000..e2fba6d0da --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/checkbox.component.spec.ts @@ -0,0 +1,44 @@ +import { createHostFactory, SpectatorHost } from '@ngneat/spectator/jest'; +import { FormCheckboxComponent } from '../components/checkbox/checkbox.component'; + +describe('FormCheckboxComponent', () => { + let spectator: SpectatorHost; + + const createHost = createHostFactory(FormCheckboxComponent); + + beforeEach( + () => + (spectator = createHost( + '', + { + hostProps: { attributes: { autofocus: '', name: 'abp-checkbox' } }, + }, + )), + ); + + it('should display the input', () => { + expect(spectator.query('input')).toBeTruthy(); + }); + + it('should equal the default classes to form-check-input', () => { + expect(spectator.query('input')).toHaveClass('form-check-input'); + }); + + it('should equal the default type to checkbox', () => { + expect(spectator.query('input')).toHaveAttribute('type', 'checkbox'); + }); + + it('should be readonly when checkboxReadonly is true', () => { + spectator.component.checkboxReadonly = true; + spectator.detectComponentChanges(); + expect(spectator.query('[readonly]')).toBeTruthy(); + }); + + it('should not contain readonly when checboxReadonly is false', () => { + spectator.component.checkboxReadonly = false; + spectator.detectComponentChanges(); + expect(spectator.query('[disabled]')).toBeFalsy(); + }); + +}); + diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/form-input.component.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/form-input.component.spec.ts new file mode 100644 index 0000000000..660cb72165 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/form-input.component.spec.ts @@ -0,0 +1,46 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { createHostFactory, SpectatorHost } from '@ngneat/spectator/jest'; +import { FormInputComponent } from '../components/form-input/form-input.component'; + + +describe('FormInputComponent', () => { + let spectator: SpectatorHost; + + const createHost = createHostFactory(FormInputComponent); + + beforeEach( + () => + (spectator = createHost( + '', + { + hostProps: { attributes: { autofocus: '', name: 'abp-form-input' } }, + }, + )), + ); + + it('should display the input', () => { + expect(spectator.query('input')).toBeTruthy(); + }); + + it('should equal the default classes to form-control', () => { + expect(spectator.query('input')).toHaveClass('form-control'); + }); + + it('should equal the default type to text', () => { + expect(spectator.query('input')).toHaveAttribute('type', 'text'); + }); + + it('should be readonly when inputReadonly is true', () => { + spectator.component.inputReadonly = true; + spectator.detectComponentChanges(); + expect(spectator.query('[readonly]')).toBeTruthy(); + }); + + it('should not contain readonly when inputReadonly is false', () => { + spectator.component.inputReadonly = false; + spectator.detectComponentChanges(); + expect(spectator.query('[disabled]')).toBeFalsy(); + }); + +}); + 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 35ab43177b..c7dad57f77 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 @@ -38,7 +38,8 @@ import { CONFIRMATION_ICONS, DEFAULT_CONFIRMATION_ICONS } from './tokens/confirm import { PasswordComponent } from './components/password/password.component'; import { CardModule } from './components/card/card.module'; import { AbpVisibleDirective } from './directives'; - +import { FormInputComponent } from './components/form-input/form-input.component'; +import { FormCheckboxComponent } from './components/checkbox/checkbox.component'; const declarationsWithExports = [ BreadcrumbComponent, @@ -56,6 +57,8 @@ const declarationsWithExports = [ LoadingDirective, ModalCloseDirective, AbpVisibleDirective, + FormInputComponent, + FormCheckboxComponent ]; @NgModule({ @@ -66,6 +69,7 @@ const declarationsWithExports = [ NgbPaginationModule, EllipsisModule, CardModule, + ], declarations: [...declarationsWithExports, HttpErrorWrapperComponent], exports: [ @@ -77,7 +81,7 @@ const declarationsWithExports = [ ], providers: [DatePipe], }) -export class BaseThemeSharedModule {} +export class BaseThemeSharedModule { } @NgModule({ imports: [BaseThemeSharedModule], diff --git a/npm/ng-packs/tsconfig.base.json b/npm/ng-packs/tsconfig.base.json index ac29fd53ad..71e32f80ed 100644 --- a/npm/ng-packs/tsconfig.base.json +++ b/npm/ng-packs/tsconfig.base.json @@ -30,6 +30,7 @@ "@abp/ng.identity": ["packages/identity/src/public-api.ts"], "@abp/ng.identity/config": ["packages/identity/config/src/public-api.ts"], "@abp/ng.identity/proxy": ["packages/identity/proxy/src/public-api.ts"], + "@abp/ng.oauth": ["packages/oauth/src/public-api.ts"], "@abp/ng.permission-management": ["packages/permission-management/src/public-api.ts"], "@abp/ng.permission-management/proxy": [ "packages/permission-management/proxy/src/public-api.ts" @@ -43,8 +44,7 @@ "@abp/ng.theme.basic/testing": ["packages/theme-basic/testing/src/public-api.ts"], "@abp/ng.theme.shared": ["packages/theme-shared/src/public-api.ts"], "@abp/ng.theme.shared/extensions": ["packages/theme-shared/extensions/src/public-api.ts"], - "@abp/ng.theme.shared/testing": ["packages/theme-shared/testing/src/public-api.ts"], - "@abp/ng.oauth": ["packages/oauth/src/public-api.ts"] + "@abp/ng.theme.shared/testing": ["packages/theme-shared/testing/src/public-api.ts"] } }, "exclude": ["node_modules", "tmp"]