diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json index 2bd4bc7352..a4fdf7afbd 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json @@ -47,6 +47,8 @@ "PagerInfoEmpty": "Showing 0 to 0 of 0 entries", "PagerInfoFiltered": "(filtered from _MAX_ total entries)", "NoDataAvailableInDatatable": "No data available", + "Total": "total", + "Selected": "selected", "PagerShowMenuEntries": "Show _MENU_ entries", "DatatableActionDropdownDefaultText": "Actions", "ChangePassword": "Change password", @@ -59,6 +61,6 @@ "500Message": "Internal Server Error", "GoHomePage": "Go to the homepage", "GoBack": "Go back", - "Search" : "Search" + "Search": "Search" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json index ddf8760fa9..bf558bb763 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json @@ -47,6 +47,8 @@ "PagerInfoEmpty": "0 kayıttan 0 ile 0 arası gösteriliyor.", "PagerInfoFiltered": "(_MAX_ kayıt arasından filtrelendi)", "NoDataAvailableInDatatable": "Tabloda kayıt mevcut değil.", + "Total": "toplam", + "Selected": "seçilen", "PagerShowMenuEntries": "Sayfada _MENU_ kayıt göster.", "DatatableActionDropdownDefaultText": "İşlemler", "ChangePassword": "Şifre değiştir", @@ -61,4 +63,4 @@ "GoBack": "Geri dön", "Search": "Arama" } -} \ No newline at end of file +} diff --git a/npm/ng-packs/angular.json b/npm/ng-packs/angular.json index 57fc306525..7601119eca 100644 --- a/npm/ng-packs/angular.json +++ b/npm/ng-packs/angular.json @@ -518,6 +518,21 @@ "inject": true, "bundleName": "fontawesome-v4-shims.min" }, + { + "input": "node_modules/@swimlane/ngx-datatable/index.css", + "inject": true, + "bundleName": "ngx-datatable-index" + }, + { + "input": "node_modules/@swimlane/ngx-datatable/assets/icons.css", + "inject": true, + "bundleName": "ngx-datatable-icons" + }, + { + "input": "node_modules/@swimlane/ngx-datatable/themes/material.css", + "inject": true, + "bundleName": "ngx-datatable-material" + }, "apps/dev-app/src/styles.scss" ], "scripts": [] diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index 4049f471fb..5653ef5446 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -61,6 +61,7 @@ "@ngxs/router-plugin": "^3.6.2", "@ngxs/storage-plugin": "^3.6.2", "@ngxs/store": "^3.6.2", + "@swimlane/ngx-datatable": "^16.0.0", "@types/jest": "^25.2.3", "@types/node": "^12.11.1", "angular-oauth2-oidc": "^8.0.4", diff --git a/npm/ng-packs/packages/core/src/lib/services/list.service.ts b/npm/ng-packs/packages/core/src/lib/services/list.service.ts index 944368ad88..3aff601f7a 100644 --- a/npm/ng-packs/packages/core/src/lib/services/list.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/list.service.ts @@ -7,7 +7,7 @@ import { LIST_QUERY_DEBOUNCE_TIME } from '../tokens/list.token'; import { takeUntilDestroy } from '../utils/rxjs-utils'; @Injectable() -export class ListService implements OnDestroy { +export class ListService implements OnDestroy { private _filter = ''; set filter(value: string) { this._filter = value; @@ -26,8 +26,10 @@ export class ListService implements OnDestroy { return this._maxResultCount; } - private _page = 1; + private _page = 0; set page(value: number) { + if (value === this._page) return; + this._page = value; this.get(); } @@ -53,9 +55,9 @@ export class ListService implements OnDestroy { return this._sortOrder; } - private _query$ = new ReplaySubject(1); + private _query$ = new ReplaySubject(1); - get query$(): Observable { + get query$(): Observable { return this._query$ .asObservable() .pipe(debounceTime(this.delay || 300), shareReplay({ bufferSize: 1, refCount: true })); @@ -68,12 +70,12 @@ export class ListService implements OnDestroy { } get = () => { - this._query$.next({ + this._query$.next(({ filter: this._filter || undefined, maxResultCount: this._maxResultCount, - skipCount: (this._page - 1) * this._maxResultCount, + skipCount: this._page * this._maxResultCount, sorting: this._sortOrder ? `${this._sortKey} ${this._sortOrder}` : undefined, - }); + } as any) as QueryParamsType); }; constructor(@Optional() @Inject(LIST_QUERY_DEBOUNCE_TIME) private delay: number) { @@ -81,7 +83,7 @@ export class ListService implements OnDestroy { } hookToQuery( - streamCreatorCallback: QueryStreamCreatorCallback, + streamCreatorCallback: QueryStreamCreatorCallback, ): Observable> { this._isLoading$.next(true); @@ -96,6 +98,6 @@ export class ListService implements OnDestroy { ngOnDestroy() {} } -export type QueryStreamCreatorCallback = ( - query: ABP.PageQueryParams, +export type QueryStreamCreatorCallback = ( + query: QueryParamsType, ) => Observable>; diff --git a/npm/ng-packs/packages/core/src/lib/tests/list.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/list.service.spec.ts index c2118d7f3a..f26c39d4ad 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/list.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/list.service.spec.ts @@ -49,8 +49,8 @@ describe('ListService', () => { }); describe('#page', () => { - it('should initially be 1', () => { - expect(service.page).toBe(1); + it('should initially be 0', () => { + expect(service.page).toBe(0); }); it('should be changed', () => { @@ -110,7 +110,7 @@ describe('ListService', () => { filter: 'foo', sorting: 'bar baz', maxResultCount: 20, - skipCount: 160, + skipCount: 180, }); done(); diff --git a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html index 9962d8dbb4..802e272dce 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html +++ b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html @@ -20,89 +20,54 @@
- - - - - - - - - {{ 'AbpIdentity::Actions' | abpLocalization }} - - {{ 'AbpIdentity::RoleName' | abpLocalization }} - - - - - - - -
+ + + +
+ +
+ + -
- - - -
- - - {{ data.name - }}{{ - 'AbpIdentity::DisplayName:IsDefault' | abpLocalization - }} - {{ - 'AbpIdentity::DisplayName:IsPublic' | abpLocalization - }} - - - - +
+
+
+ +
diff --git a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts index 5e0f64e811..73a9a64dfb 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts +++ b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts @@ -1,5 +1,6 @@ -import { ABP } from '@abp/ng.core'; -import { ConfirmationService, Confirmation } from '@abp/ng.theme.shared'; +import { ListService } from '@abp/ng.core'; +import { ePermissionManagementComponents } from '@abp/ng.permission-management'; +import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared'; import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { Select, Store } from '@ngxs/store'; @@ -14,11 +15,11 @@ import { } from '../../actions/identity.actions'; import { Identity } from '../../models/identity'; import { IdentityState } from '../../states/identity.state'; -import { ePermissionManagementComponents } from '@abp/ng.permission-management'; @Component({ selector: 'abp-roles', templateUrl: './roles.component.html', + providers: [ListService], }) export class RolesComponent implements OnInit { @Select(IdentityState.getRoles) @@ -37,16 +38,8 @@ export class RolesComponent implements OnInit { providerKey: string; - pageQuery: ABP.PageQueryParams = { maxResultCount: 10 }; - - loading = false; - modalBusy = false; - sortOrder = ''; - - sortKey = ''; - permissionManagementKey = ePermissionManagementComponents.PermissionManagement; @ViewChild('formRef', { static: false, read: ElementRef }) @@ -57,13 +50,14 @@ export class RolesComponent implements OnInit { }; constructor( + public readonly list: ListService, private confirmationService: ConfirmationService, private fb: FormBuilder, private store: Store, ) {} ngOnInit() { - this.get(); + this.hookToQuery(); } buildForm() { @@ -110,7 +104,7 @@ export class RolesComponent implements OnInit { .pipe(finalize(() => (this.modalBusy = false))) .subscribe(() => { this.isModalVisible = false; - this.get(); + this.list.get(); }); } @@ -121,23 +115,13 @@ export class RolesComponent implements OnInit { }) .subscribe((status: Confirmation.Status) => { if (status === Confirmation.Status.confirm) { - this.store.dispatch(new DeleteRole(id)).subscribe(() => this.get()); + this.store.dispatch(new DeleteRole(id)).subscribe(() => this.list.get()); } }); } - onPageChange(page: number) { - this.pageQuery.skipCount = (page - 1) * this.pageQuery.maxResultCount; - - this.get(); - } - - get() { - this.loading = true; - this.store - .dispatch(new GetRoles(this.pageQuery)) - .pipe(finalize(() => (this.loading = false))) - .subscribe(); + private hookToQuery() { + this.list.hookToQuery(query => this.store.dispatch(new GetRoles(query))).subscribe(); } onClickSaveButton() { @@ -152,4 +136,10 @@ export class RolesComponent implements OnInit { this.visiblePermissions = true; }, 0); } + + sort(data) { + const { prop, dir } = data.sorts[0]; + this.list.sortKey = prop; + this.list.sortOrder = dir; + } } 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 e00dbfe866..648b1024d0 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 @@ -20,108 +20,74 @@
- + [(ngModel)]="list.filter" + /> +
- - - - - - - - - {{ 'AbpIdentity::Actions' | abpLocalization }} - - {{ 'AbpIdentity::UserName' | abpLocalization }} - - - - - {{ 'AbpIdentity::EmailAddress' | abpLocalization }} - - - - {{ 'AbpIdentity::PhoneNumber' | abpLocalization }} - + + +
+ +
+ + -
- - - -
- - {{ data.userName }} - {{ data.email }} - {{ data.phoneNumber }} - - - +
+
+
+ + + + 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 8b35e9ab77..aeeb250126 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,13 +1,27 @@ -import { ABP } from '@abp/ng.core'; +import { ListService } from '@abp/ng.core'; import { ePermissionManagementComponents } from '@abp/ng.permission-management'; import { Confirmation, ConfirmationService, getPasswordValidators } from '@abp/ng.theme.shared'; import { Component, OnInit, TemplateRef, TrackByFunction, ViewChild } from '@angular/core'; -import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { + AbstractControl, + FormArray, + FormBuilder, + FormControl, + FormGroup, + Validators, +} from '@angular/forms'; import { Select, Store } from '@ngxs/store'; import { Observable } from 'rxjs'; import { finalize, pluck, switchMap, take } from 'rxjs/operators'; import snq from 'snq'; -import { CreateUser, DeleteUser, GetUserById, GetUserRoles, GetUsers, UpdateUser } from '../../actions/identity.actions'; +import { + CreateUser, + DeleteUser, + GetUserById, + GetUserRoles, + GetUsers, + UpdateUser, +} from '../../actions/identity.actions'; import { Identity } from '../../models/identity'; import { IdentityService } from '../../services/identity.service'; import { IdentityState } from '../../states/identity.state'; @@ -15,6 +29,7 @@ import { IdentityState } from '../../states/identity.state'; @Component({ selector: 'abp-users', templateUrl: './users.component.html', + providers: [ListService], }) export class UsersComponent implements OnInit { @Select(IdentityState.getUsers) @@ -23,7 +38,7 @@ export class UsersComponent implements OnInit { @Select(IdentityState.getUsersTotalCount) totalCount$: Observable; - @ViewChild('modalContent', {static: false}) + @ViewChild('modalContent', { static: false }) modalContent: TemplateRef; form: FormGroup; @@ -38,18 +53,10 @@ export class UsersComponent implements OnInit { providerKey: string; - pageQuery: ABP.PageQueryParams = { maxResultCount: 10 }; - isModalVisible: boolean; - loading = false; - modalBusy = false; - sortOrder = ''; - - sortKey = ''; - permissionManagementKey = ePermissionManagementComponents.PermissionManagement; trackByFn: TrackByFunction = (index, item) => Object.keys(item)[0] || index; @@ -63,6 +70,7 @@ export class UsersComponent implements OnInit { } constructor( + public readonly list: ListService, private confirmationService: ConfirmationService, private fb: FormBuilder, private store: Store, @@ -70,12 +78,7 @@ export class UsersComponent implements OnInit { ) {} ngOnInit() { - this.get(); - } - - onSearch(value: string) { - this.pageQuery.filter = value; - this.get(); + this.hookToQuery(); } buildForm() { @@ -170,7 +173,7 @@ export class UsersComponent implements OnInit { .pipe(finalize(() => (this.modalBusy = false))) .subscribe(() => { this.isModalVisible = false; - this.get(); + this.list.get(); }); } @@ -181,23 +184,19 @@ export class UsersComponent implements OnInit { }) .subscribe((status: Confirmation.Status) => { if (status === Confirmation.Status.confirm) { - this.store.dispatch(new DeleteUser(id)).subscribe(() => this.get()); + this.store.dispatch(new DeleteUser(id)).subscribe(() => this.list.get()); } }); } - onPageChange(page: number) { - this.pageQuery.skipCount = (page - 1) * this.pageQuery.maxResultCount; - - this.get(); + sort(data) { + const { prop, dir } = data.sorts[0]; + this.list.sortKey = prop; + this.list.sortOrder = dir; } - get() { - this.loading = true; - this.store - .dispatch(new GetUsers(this.pageQuery)) - .pipe(finalize(() => (this.loading = false))) - .subscribe(); + private hookToQuery() { + this.list.hookToQuery(query => this.store.dispatch(new GetUsers(query))).subscribe(); } openPermissionsModal(providerKey: string) { diff --git a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html index 10761a3618..c966b2c4af 100644 --- a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html +++ b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html @@ -18,99 +18,73 @@ +
- + [(ngModel)]="list.filter" + /> +
- - - - - - - - - {{ 'AbpTenantManagement::Actions' | abpLocalization }} - - {{ 'AbpTenantManagement::TenantName' | abpLocalization }} - + + +
+ +
+ + + -
- - - - -
- - {{ data.name }} - - - +
+
+
+ + @@ -128,7 +102,7 @@ {{ 'AbpTenantManagement::Cancel' | abpLocalization }} {{ - 'AbpIdentity::Save' | abpLocalization + 'AbpTenantManagement::Save' | abpLocalization }}
diff --git a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts index 2e1e5a1b5b..ec50b97c6b 100644 --- a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts +++ b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts @@ -1,4 +1,4 @@ -import { ABP } from '@abp/ng.core'; +import { ABP, ListService } from '@abp/ng.core'; import { eFeatureManagementComponents } from '@abp/ng.feature-management'; import { Confirmation, ConfirmationService, getPasswordValidators } from '@abp/ng.theme.shared'; import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; @@ -6,7 +6,13 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Select, Store } from '@ngxs/store'; import { Observable } from 'rxjs'; import { finalize, pluck, switchMap, take } from 'rxjs/operators'; -import { CreateTenant, DeleteTenant, GetTenantById, GetTenants, UpdateTenant } from '../../actions/tenant-management.actions'; +import { + CreateTenant, + DeleteTenant, + GetTenantById, + GetTenants, + UpdateTenant, +} from '../../actions/tenant-management.actions'; import { TenantManagementService } from '../../services/tenant-management.service'; import { TenantManagementState } from '../../states/tenant-management.state'; @@ -19,6 +25,7 @@ interface SelectedModalContent { @Component({ selector: 'abp-tenants', templateUrl: './tenants.component.html', + providers: [ListService], }) export class TenantsComponent implements OnInit { @Select(TenantManagementState.get) @@ -45,16 +52,8 @@ export class TenantsComponent implements OnInit { _useSharedDatabase: boolean; - pageQuery: ABP.PageQueryParams = { maxResultCount: 10 }; - - loading = false; - modalBusy = false; - sortOrder = ''; - - sortKey = ''; - featureManagementKey = eFeatureManagementComponents.FeatureManagement; get hasSelectedTenant(): boolean { @@ -100,6 +99,7 @@ export class TenantsComponent implements OnInit { }; constructor( + public readonly list: ListService, private confirmationService: ConfirmationService, private tenantService: TenantManagementService, private fb: FormBuilder, @@ -107,12 +107,7 @@ export class TenantsComponent implements OnInit { ) {} ngOnInit() { - this.get(); - } - - onSearch(value: string) { - this.pageQuery.filter = value; - this.get(); + this.hookToQuery(); } private createTenantForm() { @@ -236,7 +231,7 @@ export class TenantsComponent implements OnInit { .pipe(finalize(() => (this.modalBusy = false))) .subscribe(() => { this.isModalVisible = false; - this.get(); + this.list.get(); }); } @@ -251,23 +246,13 @@ export class TenantsComponent implements OnInit { ) .subscribe((status: Confirmation.Status) => { if (status === Confirmation.Status.confirm) { - this.store.dispatch(new DeleteTenant(id)).subscribe(() => this.get()); + this.store.dispatch(new DeleteTenant(id)).subscribe(() => this.list.get()); } }); } - onPageChange(page: number) { - this.pageQuery.skipCount = (page - 1) * this.pageQuery.maxResultCount; - - this.get(); - } - - get() { - this.loading = true; - this.store - .dispatch(new GetTenants(this.pageQuery)) - .pipe(finalize(() => (this.loading = false))) - .subscribe(); + hookToQuery() { + this.list.hookToQuery(query => this.store.dispatch(new GetTenants(query))).subscribe(); } onSharedDatabaseChange(value: boolean) { @@ -289,4 +274,10 @@ export class TenantsComponent implements OnInit { this.visibleFeatures = true; }, 0); } + + sort(data) { + const { prop, dir } = data.sorts[0]; + this.list.sortKey = prop; + this.list.sortOrder = dir; + } } diff --git a/npm/ng-packs/packages/theme-shared/ng-package.json b/npm/ng-packs/packages/theme-shared/ng-package.json index 58d74cba48..0c3b5e300f 100644 --- a/npm/ng-packs/packages/theme-shared/ng-package.json +++ b/npm/ng-packs/packages/theme-shared/ng-package.json @@ -10,6 +10,7 @@ "@fortawesome/fontawesome-free", "@ng-bootstrap/ng-bootstrap", "@ngx-validate/core", + "@swimlane/ngx-datatable", "bootstrap", "font-awesome", "chart.js" diff --git a/npm/ng-packs/packages/theme-shared/package.json b/npm/ng-packs/packages/theme-shared/package.json index b76f5df213..2eb08a7e60 100644 --- a/npm/ng-packs/packages/theme-shared/package.json +++ b/npm/ng-packs/packages/theme-shared/package.json @@ -11,6 +11,7 @@ "@fortawesome/fontawesome-free": "^5.13.0", "@ng-bootstrap/ng-bootstrap": "^6.1.0", "@ngx-validate/core": "^0.0.8", + "@swimlane/ngx-datatable": "^16.0.0", "bootstrap": "^4.5.0", "chart.js": "^2.9.3" }, diff --git a/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts b/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts index a691f96ead..f997eb6e5c 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts @@ -45,6 +45,11 @@ export default ` background: #8a8686; } +.bordered .datatable-body-row { + border-top: 1px solid #eee; + margin-top: -1px; +} + .abp-ellipsis-inline { display: inline-block; overflow: hidden; @@ -136,6 +141,9 @@ export default ` .sorting_asc:after { opacity: .3; } +.ngx-datatable.material { + box-shadow: none; +} @keyframes fadeInTop { from { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/index.ts index aa2725e328..a6b666be3b 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/directives/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/index.ts @@ -1,2 +1,4 @@ export * from './loading.directive'; +export * from './ngx-datatable-default.directive'; +export * from './ngx-datatable-list.directive'; export * from './table-sort.directive'; 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 new file mode 100644 index 0000000000..3672bde3b3 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts @@ -0,0 +1,23 @@ +import { Directive, HostBinding, Input } from '@angular/core'; +import { ColumnMode, DatatableComponent } from '@swimlane/ngx-datatable'; + +@Directive({ + // tslint:disable-next-line + selector: 'ngx-datatable[default]', + exportAs: 'ngxDatatableDefault', +}) +export class NgxDatatableDefaultDirective { + @Input() class = 'material bordered'; + + @HostBinding('class') + get classes(): string { + return `ngx-datatable ${this.class}`; + } + + constructor(private table: DatatableComponent) { + this.table.columnMode = ColumnMode.force; + this.table.footerHeight = 50; + this.table.headerHeight = 50; + this.table.rowHeight = 'auto'; + } +} 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 new file mode 100644 index 0000000000..85e574d63d --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts @@ -0,0 +1,70 @@ +import { ListService } from '@abp/ng.core'; +import { + ChangeDetectorRef, + Directive, + Input, + OnChanges, + OnDestroy, + OnInit, + SimpleChanges, +} from '@angular/core'; +import { DatatableComponent } from '@swimlane/ngx-datatable'; +import { Subscription } from 'rxjs'; + +@Directive({ + // tslint:disable-next-line + selector: 'ngx-datatable[list]', + exportAs: 'ngxDatatableList', +}) +export class NgxDatatableListDirective implements OnChanges, OnDestroy, OnInit { + private subscription = new Subscription(); + + @Input() list: ListService; + + constructor(private table: DatatableComponent, private cdRef: ChangeDetectorRef) { + this.table.externalPaging = true; + this.table.externalSorting = true; + } + + private subscribeToPage() { + const sub = this.table.page.subscribe(({ offset }) => { + this.list.page = offset; + this.table.offset = offset; + }); + this.subscription.add(sub); + } + + private subscribeToSort() { + const sub = this.table.sort.subscribe(({ sorts: [{ prop, dir }] }) => { + this.list.sortKey = prop; + this.list.sortOrder = dir; + }); + this.subscription.add(sub); + } + + private subscribeToIsLoading() { + const sub = this.list.isLoading$.subscribe(loading => { + this.table.loadingIndicator = loading; + this.cdRef.markForCheck(); + }); + this.subscription.add(sub); + } + + ngOnChanges({ list }: SimpleChanges) { + if (!list.firstChange) return; + + const { maxResultCount, page } = list.currentValue; + this.table.limit = maxResultCount; + this.table.offset = page; + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + } + + ngOnInit() { + this.subscribeToPage(); + this.subscribeToSort(); + this.subscribeToIsLoading(); + } +} 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 41d8e3706a..6afd044725 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 @@ -1,8 +1,10 @@ -import { CoreModule, LazyLoadService, noop } from '@abp/ng.core'; +import { ConfigState, CoreModule, noop } from '@abp/ng.core'; import { DatePipe } from '@angular/common'; import { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core'; import { NgbDateParserFormatter, NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap'; import { NgxValidateCoreModule } from '@ngx-validate/core'; +import { Store } from '@ngxs/store'; +import { INgxDatatableConfig, NgxDatatableModule } from '@swimlane/ngx-datatable'; import { BreadcrumbComponent } from './components/breadcrumb/breadcrumb.component'; import { ButtonComponent } from './components/button/button.component'; import { ChartComponent } from './components/chart/chart.component'; @@ -18,8 +20,9 @@ import { TableEmptyMessageComponent } from './components/table-empty-message/tab import { TableComponent } from './components/table/table.component'; import { ToastContainerComponent } from './components/toast-container/toast-container.component'; import { ToastComponent } from './components/toast/toast.component'; -import styles from './constants/styles'; import { LoadingDirective } from './directives/loading.directive'; +import { NgxDatatableDefaultDirective } from './directives/ngx-datatable-default.directive'; +import { NgxDatatableListDirective } from './directives/ngx-datatable-list.directive'; import { TableSortDirective } from './directives/table-sort.directive'; import { ErrorHandler } from './handlers/error.handler'; import { initLazyStyleHandler } from './handlers/lazy-style.handler'; @@ -27,26 +30,25 @@ import { RootParams } from './models/common'; import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token'; import { httpErrorConfigFactory, HTTP_ERROR_CONFIG } from './tokens/http-error.token'; import { DateParserFormatter } from './utils/date-parser-formatter'; -import { chartJsLoaded$ } from './utils/widget-utils'; -/** - * - * @deprecated To be deleted in v2.6 - * - */ -export function appendScript(injector: Injector) { - const fn = () => { - import('chart.js').then(() => chartJsLoaded$.next(true)); +export function ngxDatatableMessageFactory(store: Store) { + const emptyMessage = store.selectSnapshot( + ConfigState.getLocalization('AbpUi::NoDataAvailableInDatatable'), + ); + const totalMessage = store.selectSnapshot(ConfigState.getLocalization('AbpUi::Total')); + const selectedMessage = store.selectSnapshot(ConfigState.getLocalization('AbpUi::Selected')); - const lazyLoadService: LazyLoadService = injector.get(LazyLoadService); - return lazyLoadService.load(null, 'style', styles, 'head', 'beforeend').toPromise(); - }; - - return fn; + return { + messages: { + emptyMessage, + totalMessage, + selectedMessage, + }, + } as INgxDatatableConfig; } @NgModule({ - imports: [CoreModule, NgxValidateCoreModule, NgbPaginationModule], + imports: [CoreModule, NgxDatatableModule, NgxValidateCoreModule, NgbPaginationModule], declarations: [ BreadcrumbComponent, ButtonComponent, @@ -63,11 +65,14 @@ export function appendScript(injector: Injector) { ToastComponent, ToastContainerComponent, SortOrderIconComponent, + NgxDatatableDefaultDirective, + NgxDatatableListDirective, LoadingDirective, TableSortDirective, ToastContainerComponent, ], exports: [ + NgxDatatableModule, BreadcrumbComponent, ButtonComponent, ChartComponent, @@ -81,6 +86,8 @@ export function appendScript(injector: Injector) { ToastComponent, ToastContainerComponent, SortOrderIconComponent, + NgxDatatableDefaultDirective, + NgxDatatableListDirective, LoadingDirective, TableSortDirective, ToastContainerComponent, @@ -120,6 +127,11 @@ export class ThemeSharedModule { deps: [HTTP_ERROR_CONFIG], }, { provide: NgbDateParserFormatter, useClass: DateParserFormatter }, + { + provide: 'configuration', + useFactory: ngxDatatableMessageFactory, + deps: [Store], + }, ], }; } diff --git a/npm/ng-packs/scripts/prod-build.ts b/npm/ng-packs/scripts/prod-build.ts index 03a1432b99..33f2aa2c44 100644 --- a/npm/ng-packs/scripts/prod-build.ts +++ b/npm/ng-packs/scripts/prod-build.ts @@ -13,11 +13,19 @@ import fse from 'fs-extra'; }); await fse.remove('../../../templates/app/angular/node_modules/@abp'); - await fse.copy('../node_modules/@abp', '../../../templates/app/angular/node_modules/@abp', { overwrite: true, }); + // TODO: Will be removed in v3.1, it is added to fix the prod build error + await fse.copy( + '../node_modules/@swimlane', + '../../../templates/app/angular/node_modules/@swimlane', + { + overwrite: true, + }, + ); + await execa('yarn', ['ng', 'build', '--prod'], { stdout: 'inherit', cwd: '../../../templates/app/angular', diff --git a/npm/ng-packs/scripts/yarn.lock b/npm/ng-packs/scripts/yarn.lock index f2a26a3bc5..bd91324394 100644 --- a/npm/ng-packs/scripts/yarn.lock +++ b/npm/ng-packs/scripts/yarn.lock @@ -15,14 +15,14 @@ integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/node@*": - version "14.0.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.11.tgz#61d4886e2424da73b7b25547f59fdcb534c165a3" - integrity sha512-lCvvI24L21ZVeIiyIUHZ5Oflv1hhHQ5E1S25IRlKIXaRkVgmXpJMI3wUJkmym2bTbCe+WoIibQnMVAU3FguaOg== + version "14.0.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.13.tgz#ee1128e881b874c371374c1f72201893616417c9" + integrity sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA== "@types/node@^13.1.2": - version "13.13.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.10.tgz#34a9be3cbc409fd235984bd18a130006f5234396" - integrity sha512-J+FbkhLTcFstD7E5mVZDjYxa1VppwT2HALE6H3n2AnBSP8uiCQk0Pyr6BkJcP38dFV9WecoVJRJmFnl9ikIW7Q== + version "13.13.12" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.12.tgz#9c72e865380a7dc99999ea0ef20fc9635b503d20" + integrity sha512-zWz/8NEPxoXNT9YyF2osqyA9WjssZukYpgI4UYZpOjcyqwIUqWGkcCionaEb9Ki+FULyPyvNFpg/329Kd2/pbw== ansi-bgblack@^0.1.1: version "0.1.1" diff --git a/npm/ng-packs/tslint.json b/npm/ng-packs/tslint.json index d75b6a274b..5a5d15bc35 100644 --- a/npm/ng-packs/tslint.json +++ b/npm/ng-packs/tslint.json @@ -37,7 +37,7 @@ "import-blacklist": [true, "rxjs/Rx"], "interface-over-type-literal": true, "interface-name": [true, "never-prefix"], - "member-access": [true, "no-public"], + "member-access": [false], "member-ordering": [ true, { diff --git a/npm/ng-packs/yarn.lock b/npm/ng-packs/yarn.lock index afa58bc631..2193f0236c 100644 --- a/npm/ng-packs/yarn.lock +++ b/npm/ng-packs/yarn.lock @@ -110,9 +110,9 @@ tslib "^1.9.0" "@abp/ng.theme.shared@~2.9.0": - version "2.9.0" - resolved "https://registry.yarnpkg.com/@abp/ng.theme.shared/-/ng.theme.shared-2.9.0.tgz#aaf97cf94ff798b3695cbb1b0dec33d20996fbda" - integrity sha512-04xlt3aKiDVyE+6NpxA0KGHGuupJWhXTjPWwlzVtfNiPqYjx0rG2FbTGgNWMW4K1qTlRRVjPA5a/MDhZtZHZIw== + version "2.9.1" + resolved "https://registry.yarnpkg.com/@abp/ng.theme.shared/-/ng.theme.shared-2.9.1.tgz#c44064057505a5a2cdb4ca269daa6bd423a99ba6" + integrity sha512-iSlhRcjmNXYclAkSJ0vN20GBF7ART3340Mpn4V+hMRachkJSewwMNYG73G6ukVwZrF+0Sjdn2r9jJrJHhhKm3w== dependencies: "@abp/ng.core" "~2.9.0" "@fortawesome/fontawesome-free" "^5.12.1" @@ -301,9 +301,9 @@ rxjs "6.4.0" "@angular/animations@~9.1.9": - version "9.1.9" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-9.1.9.tgz#de54334ea195189402487855c9a98f5618605da4" - integrity sha512-qWVi0TxmU6HeXAgEsfpQvFFygh+a0kH2kGe6bWij4XvG6dWfV3xZjlaFwSIYGk+yK4yL0+9+PAXH+ENfxNw+Cw== + version "9.1.10" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-9.1.10.tgz#c0f0b7e30dbe95ef8edd62e5d6c2ea3224d76966" + integrity sha512-xuiL2iE8vka3IZpvwnOYDhfKKn9xKB+qyn7mcWzr6xnFP3UPfxN/1HuDJYgtwd+KXtTZmzlsm8orh+DZ3MGxbA== "@angular/cli@~9.1.7": version "9.1.7" @@ -332,14 +332,14 @@ uuid "7.0.2" "@angular/common@~9.1.9": - version "9.1.9" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-9.1.9.tgz#16e77b2db675b80e32f1788a20c538150fd09294" - integrity sha512-y/tJtkuOJhV2kcaXZyrLZH84i4uQ1r+vaaEHvXj+JZYfYfcMMd/TDqMiPcIkUb3RxqghtZ+q0ZNW5D1Nlru3Pw== + version "9.1.10" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-9.1.10.tgz#34c36f9b889ec009c5a4aa1628acb4e002a4e280" + integrity sha512-qX7ZUIwRkQi/kO6aKmpa8iGdkLXfe+80D+svC02x5PvafdQAcuBlUQQkrr1XapBqYE/Nu2GK0yYmvpa2CzxjPQ== "@angular/compiler-cli@~9.1.9": - version "9.1.9" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-9.1.9.tgz#e3c234d888074002fa5f6b7eab4f63f4ddbdb7bd" - integrity sha512-aLr2eaDlREN8XybgTbelvjtSZ8eAkxBPilnkddc700BgiC6ImyUSKaItOwa8bnjQwq4Wlz5eVG0ibsrX+5MXwg== + version "9.1.10" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-9.1.10.tgz#4ad54e9df3f0b00bc53493a2247ca4d22d67fdb0" + integrity sha512-D2JYI9GHzybG/NJ03aCd+95mSz+f4UhgDZ1c0GbYlsNLvk1B0UrDrmgGv0gOdP9yW1XxQjW3ldZAqpVurYru3Q== dependencies: canonical-path "1.0.0" chokidar "^3.0.0" @@ -355,48 +355,48 @@ yargs "15.3.0" "@angular/compiler@~9.1.9": - version "9.1.9" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.1.9.tgz#cbf678ee28a0811a8ef3ee7be565d4911ff28ec7" - integrity sha512-kjFgaTB2ckr9lgmkS1dOGRT7kmzpQueydxsxXSHWgICNVE6F/u1PHyeSOyJRpxW0GnrkLq3QM2EUFnQGGga5bg== + version "9.1.10" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.1.10.tgz#2e43cb51203e18faf3673244a78946d7a7194041" + integrity sha512-VlyTVK9elvtKGXxrkW9BWfKYRfeqXVLR3erukv03vy9u/pZppkG1xJ32SgAPKzYckGRV3kKHP6B7ZOXWMb9cog== "@angular/core@~9.1.9": - version "9.1.9" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-9.1.9.tgz#db4241f867d6e14b81ed6e7c50334813c6ebfc10" - integrity sha512-q/DERgVU6vK2LtTcdVCGGBcoO424WsEfImh3Vcuy+P/ZVmthlDUC/+q+tSKt8MMf4hLpxFDQJE8vUSkktj7QEw== + version "9.1.10" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-9.1.10.tgz#cb9c99cd99a61cc55337220cafac005332ff9fdf" + integrity sha512-pp8g0razdSi3HzSBHRzBdn5WmnVJZ5IF+sWuApvplnl4edBO0CFdZAKALmRgjctRD9y9aVPXhkEi17Spiip9aA== "@angular/forms@~9.1.9": - version "9.1.9" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-9.1.9.tgz#20c9a79d1dcb2cace45df9e2f304b658e02c1687" - integrity sha512-r675yImnb/0pY7K5W3V2ITa7YETu1I2AS+bRfII6UQ6gthyeFFOHb5noa7YneC2yqQiM6E4DQmF5ig3daPuFNg== + version "9.1.10" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-9.1.10.tgz#74da1653581bb5021015cf76fa04316a627376e6" + integrity sha512-Qp/tO3bayvP3lkpuMe2oWGBhATd39Vd9z9z/LIWtM+PkEZCZ0xCh0d6AiKrO9sc1vDATCi4SKxEnNCkmPBWOuQ== "@angular/language-service@~9.1.9": - version "9.1.9" - resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-9.1.9.tgz#332a7e54d5e553b92342b10703dc13aba474a28f" - integrity sha512-yT6HPpdAe2mD9HRoTCiWFog1MRJt+0j+CLbI/Ql7C6pH6vbjmfsJ55xMmQ7eS6trsnebpMWTUv1f2GRykv3ygw== + version "9.1.10" + resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-9.1.10.tgz#515abfaf79ae9c1ab2649c48201dcd4aae4b7c74" + integrity sha512-rj+otf/uPRhEH4L3kDX13RouKg5YT0uc/CbBlgwTbEX9kOOBGxvHxoUxPT8rysBjHuLubBd2mQozZofj/IYa8Q== "@angular/localize@~9.1.0", "@angular/localize@~9.1.9": - version "9.1.9" - resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-9.1.9.tgz#0867a82abcdeb6b88cbd4d61e1410f3c63a66ddb" - integrity sha512-U/4axUr99GO3+dRuMIEyJ1FqXauT82x/w7GulWu05qk8ML8MaIQ58RcB/LTJJY1s1qfwdcsyzX2wZrZcwBLKlA== + version "9.1.10" + resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-9.1.10.tgz#230ab75155c16d84d61eb34ccff2e3283c85b995" + integrity sha512-gAc2Xuz4clPp8+YDK+M21q+DKnLNx+J/i8L9b9Z7rj8a/gHqOQWaTun4grLgd86AbpNxp/urkr+tEFHiHaNz6Q== dependencies: "@babel/core" "7.8.3" glob "7.1.2" yargs "15.3.0" "@angular/platform-browser-dynamic@~9.1.9": - version "9.1.9" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.9.tgz#12f8b05d3c9ef0844df88f3833e29ea1e49ec5e0" - integrity sha512-b9MG5MWne+IuL3uLm8jwPhlJzqYaGBGk/qibOqb17T24j1iyrlO7T5bZ8zO6pUy5iT/TahVfHPnPJC1qTK5OmA== + version "9.1.10" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.10.tgz#a885b7903c1dcce36c327e9ca9b5f6e7ec1aa716" + integrity sha512-z8urbP03LYxiCci076SYXz+9elCukePP0ykq5RVJYe5300V6JhamGftTQgsaKszas0KlGYUz/jTULhWQ+OEv/A== "@angular/platform-browser@~9.1.9": - version "9.1.9" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-9.1.9.tgz#c2fcc50aebfdc268521b407e32dc0d967cb40411" - integrity sha512-V861X3MxJp1AlMTnkUPldpBLIJbApXF3ka0A5Dq2nVJCyOFeteGkaRWSBgqe2jxmq+LVpJbzcNvtDFXw6mQ0jA== + version "9.1.10" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-9.1.10.tgz#d014e59a2ec4722d0bb428910116c41176868d77" + integrity sha512-u8PHq92+OV0vrRKwc5bqS0SCR/VkzhuaUUXKYbjYeLsmXG+HUtg/pUCDo95ze4zPO1WFSeUvwsnRb2x1hurYAw== "@angular/router@~9.1.9": - version "9.1.9" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-9.1.9.tgz#5d79d72cb62ea1c04ea70238846653ecf9c4a73c" - integrity sha512-4u+CWMPB4hCkAsFCEzC94YEWT0wVozqGkc/Dortt2hFaqvZpIegg6iJVZlDxuyDjzFYBPnnbTDdgiTTA8ckfuA== + version "9.1.10" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-9.1.10.tgz#e0e9c5b1c35c9ab9b843c478c3cec038a0d15e19" + integrity sha512-nvMSzgmsjyj+vzw0meHpN1lea7kf106ml+g97RgxiOgHAtBUnuuedXpBKrajK2kA2m9QbwQvIaKrxkdBzyLuSw== "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.1", "@babel/code-frame@^7.8.3": version "7.10.1" @@ -2052,10 +2052,10 @@ inquirer "^6.2.0" npmlog "^4.1.2" -"@lerna/publish@3.22.0": - version "3.22.0" - resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.22.0.tgz#7a3fb61026d3b7425f3b9a1849421f67d795c55d" - integrity sha512-8LBeTLBN8NIrCrLGykRu+PKrfrCC16sGCVY0/bzq9TDioR7g6+cY0ZAw653Qt/0Kr7rg3J7XxVNdzj3fvevlwA== +"@lerna/publish@3.22.1": + version "3.22.1" + resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.22.1.tgz#b4f7ce3fba1e9afb28be4a1f3d88222269ba9519" + integrity sha512-PG9CM9HUYDreb1FbJwFg90TCBQooGjj+n/pb3gw/eH5mEDq0p8wKdLFe0qkiqUkm/Ub5C8DbVFertIo0Vd0zcw== dependencies: "@evocateur/libnpmaccess" "^3.1.2" "@evocateur/npm-registry-fetch" "^4.0.0" @@ -2078,7 +2078,7 @@ "@lerna/run-lifecycle" "3.16.2" "@lerna/run-topologically" "3.18.5" "@lerna/validation-error" "3.13.0" - "@lerna/version" "3.22.0" + "@lerna/version" "3.22.1" figgy-pudding "^3.5.1" fs-extra "^8.1.0" npm-package-arg "^6.1.0" @@ -2191,10 +2191,10 @@ dependencies: npmlog "^4.1.2" -"@lerna/version@3.22.0": - version "3.22.0" - resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.22.0.tgz#67e1340c1904e9b339becd66429f32dd8ad65a55" - integrity sha512-6uhL6RL7/FeW6u1INEgyKjd5dwO8+IsbLfkfC682QuoVLS7VG6OOB+JmTpCvnuyYWI6fqGh1bRk9ww8kPsj+EA== +"@lerna/version@3.22.1": + version "3.22.1" + resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.22.1.tgz#9805a9247a47ee62d6b81bd9fa5fb728b24b59e2" + integrity sha512-PSGt/K1hVqreAFoi3zjD0VEDupQ2WZVlVIwesrE5GbrL2BjXowjCsTDPqblahDUPy0hp6h7E2kG855yLTp62+g== dependencies: "@lerna/check-working-tree" "3.16.5" "@lerna/child-process" "3.16.5" @@ -2422,9 +2422,9 @@ "@types/node" ">= 8" "@octokit/types@^4.0.1": - version "4.1.9" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-4.1.9.tgz#a3e1ff1a15637ab830fbab0268c2d7ca824bc969" - integrity sha512-hinM/BA2c1vebN2HSR3JtVdYtrSbmvn/doUBZXXuQuh/9o60hYwitQQAGTpJu+k6pjtjURskDHQxUFvqLvYCeA== + version "4.1.10" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-4.1.10.tgz#e4029c11e2cc1335051775bc1600e7e740e4aca4" + integrity sha512-/wbFy1cUIE5eICcg0wTKGXMlKSbaAxEr00qaBXzscLXpqhcwgXeS6P8O0pkysBhRfyjkKjJaYrvR1ExMO5eOXQ== dependencies: "@types/node" ">= 8" @@ -2508,6 +2508,13 @@ dependencies: type-detect "4.0.8" +"@swimlane/ngx-datatable@^16.0.0": + version "16.1.1" + resolved "https://registry.yarnpkg.com/@swimlane/ngx-datatable/-/ngx-datatable-16.1.1.tgz#1215e81f51400314ba6899f66acdbd4e3bde2915" + integrity sha512-h2A9xC/jo314eC/CzA19aoY/YadhdTupolCwpgB9Cbw3sDRi3x/LeGsdLSV0bj3XBKQUB3DA/gPuASKYuhm8iA== + dependencies: + tslib "^1.9.0" + "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -2591,9 +2598,9 @@ "@types/node" "*" "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz#79d7a78bad4219f4c03d6557a1c72d9ca6ba62d5" - integrity sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" + integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== "@types/istanbul-lib-report@*": version "3.0.0" @@ -2624,9 +2631,9 @@ pretty-format "^25.2.1" "@types/json-schema@^7.0.4": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" - integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== + version "7.0.5" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" + integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== "@types/minimatch@*": version "3.0.3" @@ -2639,14 +2646,14 @@ integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY= "@types/node@*", "@types/node@>= 8": - version "14.0.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.11.tgz#61d4886e2424da73b7b25547f59fdcb534c165a3" - integrity sha512-lCvvI24L21ZVeIiyIUHZ5Oflv1hhHQ5E1S25IRlKIXaRkVgmXpJMI3wUJkmym2bTbCe+WoIibQnMVAU3FguaOg== + version "14.0.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.13.tgz#ee1128e881b874c371374c1f72201893616417c9" + integrity sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA== "@types/node@^12.11.1": - version "12.12.44" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.44.tgz#0d400a1453adcb359b133acceae4dd8bb0e0a159" - integrity sha512-jM6QVv0Sm5d3nW+nUD5jSzPcO6oPqboitSNcwgBay9hifVq/Rauq1PYnROnsmuw45JMBiTnsPAno0bKu2e2xrg== + version "12.12.47" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.47.tgz#5007b8866a2f9150de82335ca7e24dd1d59bdfb5" + integrity sha512-yzBInQFhdY8kaZmqoL2+3U5dSTMrKaYcb561VU+lDzAYvqt+2lojvBEy+hmpSNuXnPTx7m9+04CzWYOUqWME2A== "@types/node@^8.0.31": version "8.10.61" @@ -4005,9 +4012,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001043, caniuse-lite@^1.0.30001061: - version "1.0.30001079" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001079.tgz#ed3e5225cd9a6850984fdd88bf24ce45d69b9c22" - integrity sha512-2KaYheg0iOY+CMmDuAB3DHehrXhhb4OZU4KBVGDr/YKyYAcpudaiUQ9PJ9rxrPlKEoJ3ATasQ5AN48MqpwS43Q== + version "1.0.30001081" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001081.tgz#40615a3c416a047c5a4d45673e5257bf128eb3b5" + integrity sha512-iZdh3lu09jsUtLE6Bp8NAbJskco4Y3UDtkR3GTCJGsbMowBU5IWDFF79sV2ws7lSqTzWyKazxam2thasHymENQ== canonical-path@1.0.0: version "1.0.0" @@ -4055,9 +4062,9 @@ chalk@^3.0.0: supports-color "^7.1.0" chalk@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72" - integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A== + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" @@ -5566,9 +5573,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.413: - version "1.3.464" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.464.tgz#fe13feaa08f6f865d3c89d5d72e54c194f463aa5" - integrity sha512-Oo+0+CN9d2z6FToQW6Hwvi9ez09Y/usKwr0tsDsyg43a871zVJCi1nR0v03djLbRNcaCKjtrnVf2XJhTxEpPCg== + version "1.3.466" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.466.tgz#89f716db3afc4bb482ea2aaaa16c4808f89f762a" + integrity sha512-eieqkoM2hCkZZRhETKyCouMziDV3l4XEKHRLuzcHG+HV+P7PeODU/z9HAmBgMQkzvHg2DoyQhfIDmmeguLZT/Q== elliptic@^6.0.0, elliptic@^6.5.2: version "6.5.2" @@ -8338,9 +8345,9 @@ lcid@^2.0.0: invert-kv "^2.0.0" lerna@^3.19.0: - version "3.22.0" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.22.0.tgz#da14d08f183ffe6eec566a4ef3f0e11afa621183" - integrity sha512-xWlHdAStcqK/IjKvjsSMHPZjPkBV1lS60PmsIeObU8rLljTepc4Sg/hncw4HWfQxPIewHAUTqhrxPIsqf9L2Eg== + version "3.22.1" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.22.1.tgz#82027ac3da9c627fd8bf02ccfeff806a98e65b62" + integrity sha512-vk1lfVRFm+UuEFA7wkLKeSF7Iz13W+N/vFd48aW2yuS7Kv0RbNm2/qcDPV863056LMfkRlsEe+QYOw3palj5Lg== dependencies: "@lerna/add" "3.21.0" "@lerna/bootstrap" "3.21.0" @@ -8355,9 +8362,9 @@ lerna@^3.19.0: "@lerna/init" "3.21.0" "@lerna/link" "3.21.0" "@lerna/list" "3.21.0" - "@lerna/publish" "3.22.0" + "@lerna/publish" "3.22.1" "@lerna/run" "3.21.0" - "@lerna/version" "3.22.0" + "@lerna/version" "3.22.1" import-local "^2.0.0" npmlog "^4.1.2" @@ -13598,9 +13605,9 @@ widest-line@^3.1.0: string-width "^4.0.0" windows-release@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.3.0.tgz#dce167e9f8be733f21c849ebd4d03fe66b29b9f0" - integrity sha512-2HetyTg1Y+R+rUgrKeUEhAG/ZuOmTrI1NBb3ZyAGQMYmOJjBBPe4MTodghRkmLJZHwkuPi02anbeGP+Zf401LQ== + version "3.3.1" + resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.3.1.tgz#cb4e80385f8550f709727287bf71035e209c4ace" + integrity sha512-Pngk/RDCaI/DkuHPlGTdIkDiTAnAkyMjoQMZqRsxydNl1qGXNIoZrB7RK8g53F2tEgQBMqQJHQdYZuQEEAu54A== dependencies: execa "^1.0.0" diff --git a/templates/app/angular/angular.json b/templates/app/angular/angular.json index dfcaa5b9d3..9177a6d86c 100644 --- a/templates/app/angular/angular.json +++ b/templates/app/angular/angular.json @@ -46,6 +46,21 @@ "inject": true, "bundleName": "fontawesome-v4-shims.min" }, + { + "input": "node_modules/@swimlane/ngx-datatable/index.css", + "inject": true, + "bundleName": "ngx-datatable-index" + }, + { + "input": "node_modules/@swimlane/ngx-datatable/assets/icons.css", + "inject": true, + "bundleName": "ngx-datatable-icons" + }, + { + "input": "node_modules/@swimlane/ngx-datatable/themes/material.css", + "inject": true, + "bundleName": "ngx-datatable-material" + }, "src/styles.scss" ], "scripts": [] diff --git a/templates/module/angular/angular.json b/templates/module/angular/angular.json index 7120592c4d..642e441e81 100644 --- a/templates/module/angular/angular.json +++ b/templates/module/angular/angular.json @@ -24,27 +24,44 @@ "tsConfig": "tsconfig.app.json", "aot": true, "extractCss": true, - "assets": [ - "src/favicon.ico", - "src/assets" - ], + "assets": ["src/favicon.ico", "src/assets"], "styles": [ + { + "input": "node_modules/@abp/ng.theme.shared/styles/bootstrap-rtl.min.css", + "inject": false, + "bundleName": "bootstrap-rtl.min" + }, { "input": "node_modules/bootstrap/dist/css/bootstrap.min.css", "inject": true, - "bundleName": "bootstrap.min" + "bundleName": "bootstrap-ltr.min" }, - "src/styles.scss", { "input": "node_modules/@fortawesome/fontawesome-free/css/all.min.css", - "inject": false, + "inject": true, "bundleName": "fontawesome-all.min" }, { "input": "node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css", - "inject": false, + "inject": true, "bundleName": "fontawesome-v4-shims.min" - } + }, + { + "input": "node_modules/@swimlane/ngx-datatable/index.css", + "inject": true, + "bundleName": "ngx-datatable-index" + }, + { + "input": "node_modules/@swimlane/ngx-datatable/assets/icons.css", + "inject": true, + "bundleName": "ngx-datatable-icons" + }, + { + "input": "node_modules/@swimlane/ngx-datatable/themes/material.css", + "inject": true, + "bundleName": "ngx-datatable-material" + }, + "src/styles.scss" ], "scripts": [] }, @@ -102,10 +119,7 @@ "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js", - "assets": [ - "src/favicon.ico", - "src/assets" - ], + "assets": ["src/favicon.ico", "src/assets"], "styles": [ { "input": "node_modules/bootstrap/dist/css/bootstrap.min.css", @@ -130,14 +144,8 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "tsconfig.app.json", - "tsconfig.spec.json", - "e2e/tsconfig.json" - ], - "exclude": [ - "**/node_modules/**" - ] + "tsConfig": ["tsconfig.app.json", "tsconfig.spec.json", "e2e/tsconfig.json"], + "exclude": ["**/node_modules/**"] } }, "e2e": { @@ -187,9 +195,7 @@ "projects/my-project-name/tsconfig.lib.json", "projects/my-project-name/tsconfig.spec.json" ], - "exclude": [ - "**/node_modules/**" - ] + "exclude": ["**/node_modules/**"] } } } @@ -227,9 +233,7 @@ "projects/my-project-name-config/tsconfig.lib.json", "projects/my-project-name-config/tsconfig.spec.json" ], - "exclude": [ - "**/node_modules/**" - ] + "exclude": ["**/node_modules/**"] } } } @@ -239,4 +243,4 @@ "cli": { "analytics": false } -} \ No newline at end of file +} diff --git a/templates/module/angular/src/app/app.component.ts b/templates/module/angular/src/app/app.component.ts index 1cf17b8116..bf2a27962a 100644 --- a/templates/module/angular/src/app/app.component.ts +++ b/templates/module/angular/src/app/app.component.ts @@ -1,6 +1,4 @@ -import { LazyLoadService, LOADING_STRATEGY } from '@abp/ng.core'; -import { Component, OnInit } from '@angular/core'; -import { forkJoin } from 'rxjs'; +import { Component } from '@angular/core'; @Component({ selector: 'app-root', @@ -9,17 +7,4 @@ import { forkJoin } from 'rxjs'; `, }) -export class AppComponent implements OnInit { - constructor(private lazyLoadService: LazyLoadService) {} - - ngOnInit() { - forkJoin([ - this.lazyLoadService.load( - LOADING_STRATEGY.PrependAnonymousStyleToHead('fontawesome-v4-shims.min.css'), - ), - this.lazyLoadService.load( - LOADING_STRATEGY.PrependAnonymousStyleToHead('fontawesome-all.min.css'), - ), - ]).subscribe(); - } -} +export class AppComponent {}