diff --git a/.github/workflows/angular.yml b/.github/workflows/angular.yml index 3f576ee9c1..60051c2dc1 100644 --- a/.github/workflows/angular.yml +++ b/.github/workflows/angular.yml @@ -3,15 +3,6 @@ on: pull_request: paths: - 'npm/ng-packs/**' - branches: - #- master - - dev - push: - paths: - - 'npm/ng-packs/**' - branches: - #- master - - dev jobs: build-test-lint: runs-on: ubuntu-18.04 @@ -19,6 +10,6 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: - node-version: '10.x' + node-version: '12.x' - run: yarn && yarn ci working-directory: npm/ng-packs diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index 82c24a9def..34b80c20d5 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -16,7 +16,7 @@ "scripts:build": "cd scripts && yarn && yarn build", "prepare:workspace": "yarn scripts:build --noInstall", "ci": "yarn ng lint && yarn prepare:workspace && yarn ci:test && yarn ci:build", - "ci:test": "ng test --coverage=false", + "ci:test": "ng test --coverage=false --silent", "ci:build": "cd scripts && yarn build:prod", "lerna": "lerna", "compile:ivy": "yarn ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points --tsconfig './tsconfig.prod.json' --source node_modules --async false", @@ -51,7 +51,7 @@ "@fortawesome/fontawesome-free": "^5.13.0", "@ng-bootstrap/ng-bootstrap": "^6.1.0", "@ngneat/spectator": "^5.11.0", - "@ngx-validate/core": "^0.0.9", + "@ngx-validate/core": "^0.0.10", "@ngxs/devtools-plugin": "^3.6.2", "@ngxs/logger-plugin": "^3.6.2", "@ngxs/router-plugin": "^3.6.2", @@ -99,4 +99,4 @@ "resolutions": { "@ngx-validate/core": "^0.0.8" } -} \ No newline at end of file +} diff --git a/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts index 553fcc6d7e..9a4166e7cc 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts @@ -77,7 +77,8 @@ describe('InitialUtils', () => { const injectorSpy = jest.spyOn(injector, 'get'); const store = spectator.inject(Store); store.selectSnapshot.andCallFake(selector => selector({ SessionState: { language: 'tr' } })); - injectorSpy.mockReturnValue(store); + injectorSpy.mockReturnValueOnce(store); + injectorSpy.mockReturnValueOnce({ cultureNameToLocaleFileNameMapping: {} }); expect(typeof localeInitializer(injector)).toBe('function'); expect(await localeInitializer(injector)()).toBe('resolved'); }); diff --git a/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts index 9d6f6ba3bf..013e8c1d12 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts @@ -1,3 +1,4 @@ +import { CORE_OPTIONS } from '../tokens/options.token'; import { Router } from '@angular/router'; import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest'; import { Actions, Store } from '@ngxs/store'; @@ -13,7 +14,10 @@ describe('LocalizationService', () => { service: LocalizationService, entryComponents: [], mocks: [Store, Router], - providers: [{ provide: Actions, useValue: new Subject() }], + providers: [ + { provide: Actions, useValue: new Subject() }, + { provide: CORE_OPTIONS, useValue: { cultureNameToLocaleFileNameMapping: {} } }, + ], }); beforeEach(() => { diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html index ef1647b540..30d115216b 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html @@ -1,15 +1,13 @@
- + @@ -19,28 +17,26 @@ {{ prop.displayName | abpLocalization }} {{ asterisk }}
- + - + - + - + diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts index f796c2d5fe..4a28b14f22 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts @@ -1,14 +1,17 @@ -import { TrackByService } from '@abp/ng.core'; +import { ABP, TrackByService } from '@abp/ng.core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, Optional, + SimpleChanges, SkipSelf, + OnChanges, } from '@angular/core'; -import { ControlContainer, Validators } from '@angular/forms'; +import { ControlContainer, Validators, ValidatorFn } from '@angular/forms'; import { NgbDateAdapter, NgbTimeAdapter } from '@ng-bootstrap/ng-bootstrap'; +import { Observable, of } from 'rxjs'; import { DateAdapter } from '../../adapters/date.adapter'; import { TimeAdapter } from '../../adapters/time.adapter'; import { ePropType } from '../../enums/props.enum'; @@ -30,15 +33,23 @@ import { selfFactory } from '../../utils/factory.util'; { provide: NgbTimeAdapter, useClass: TimeAdapter }, ], }) -export class ExtensibleFormPropComponent { +export class ExtensibleFormPropComponent implements OnChanges { @Input() data: PropData; @Input() prop: FormProp; + options$: Observable[]> = of([]); + + validators: ValidatorFn[] = []; + + readonly: boolean; + + disabled: boolean; + constructor(public readonly cdRef: ChangeDetectorRef, public readonly track: TrackByService) {} - getAsterisk(prop: FormProp, data: PropData): string { - return prop.validators(data).some(validator => validator === Validators.required) ? '*' : ''; + get asterisk(): string { + return this.validators.some(validator => validator === Validators.required) ? '*' : ''; } getComponent(prop: FormProp): string { @@ -77,4 +88,16 @@ export class ExtensibleFormPropComponent { return 'hidden'; } } + + ngOnChanges({ prop }: SimpleChanges) { + const options = prop.currentValue.options; + const readonly = prop.currentValue.readonly; + const disabled = prop.currentValue.disabled; + const validators = prop.currentValue.validators; + + if (options) this.options$ = options(this.data); + if (readonly) this.readonly = readonly(this.data); + if (disabled) this.disabled = disabled(this.data); + if (validators) this.validators = validators(this.data); + } } diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form.component.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form.component.ts index 995b29b8d1..f15f173faa 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form.component.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form.component.ts @@ -1,20 +1,16 @@ import { TrackByService } from '@abp/ng.core'; import { - AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Input, - OnDestroy, Optional, QueryList, SkipSelf, ViewChildren, } from '@angular/core'; import { ControlContainer, FormGroup } from '@angular/forms'; -import { Subscription } from 'rxjs'; -import { debounceTime } from 'rxjs/operators'; import { EXTRA_PROPERTIES_KEY } from '../../constants/extra-properties'; import { FormPropList } from '../../models/form-props'; import { ExtensionsService } from '../../services/extensions.service'; @@ -35,7 +31,7 @@ import { ExtensibleFormPropComponent } from './extensible-form-prop.component'; }, ], }) -export class ExtensibleFormComponent implements AfterViewInit, OnDestroy { +export class ExtensibleFormComponent { @ViewChildren(ExtensibleFormPropComponent) formProps: QueryList; @@ -46,7 +42,6 @@ export class ExtensibleFormComponent implements AfterViewInit, OnDestro this.record = record; } - private subscription = new Subscription(); extraPropertiesKey = EXTRA_PROPERTIES_KEY; propList: FormPropList; record: R; @@ -66,17 +61,4 @@ export class ExtensibleFormComponent implements AfterViewInit, OnDestro private extensions: ExtensionsService, @Inject(EXTENSIONS_IDENTIFIER) private identifier: string, ) {} - - ngAfterViewInit() { - this.subscription.add( - this.form.statusChanges.pipe(debounceTime(0)).subscribe(() => { - this.formProps.forEach(prop => prop.cdRef.markForCheck()); - this.cdRef.detectChanges(); - }), - ); - } - - ngOnDestroy() { - this.subscription.unsubscribe(); - } } diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html index d30b005a98..dc09088430 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html @@ -27,11 +27,11 @@ [sortable]="prop.sortable" > - -
+ +
diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts index 7768d70c2c..adacc4efa8 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts @@ -9,6 +9,11 @@ import { LOCALE_ID, TemplateRef, TrackByFunction, + Type, + InjectionToken, + InjectFlags, + SimpleChanges, + OnChanges, } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -25,7 +30,7 @@ const DEFAULT_ACTIONS_COLUMN_WIDTH = 150; templateUrl: './extensible-table.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) -export class ExtensibleTableComponent { +export class ExtensibleTableComponent implements OnChanges { @Input() actionsText: string; @Input() data: R[]; @Input() list: ListService; @@ -35,6 +40,8 @@ export class ExtensibleTableComponent { } @Input() actionsTemplate: TemplateRef; + getInjected: (token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags) => T; + readonly columnWidths: number[]; readonly propList: EntityPropList; @@ -42,6 +49,8 @@ export class ExtensibleTableComponent { readonly trackByFn: TrackByFunction> = (_, item) => item.name; constructor(@Inject(LOCALE_ID) private locale: string, injector: Injector) { + // tslint:disable-next-line + this.getInjected = injector.get.bind(injector); const extensions = injector.get(ExtensionsService); const name = injector.get(EXTENSIONS_IDENTIFIER); this.propList = extensions.entityProps.get(name).props; @@ -85,4 +94,20 @@ export class ExtensibleTableComponent { }), ); } + + ngOnChanges({ data }: SimpleChanges) { + if (!data?.currentValue) return; + + this.data = data.currentValue.map((record, index) => { + this.propList.forEach(prop => { + const propData = { getInjected: this.getInjected, record, index } as any; + record[`_${prop.value.name}`] = { + visible: prop.value.visible(propData), + value: this.getContent(prop.value, propData), + }; + }); + + return record; + }); + } } diff --git a/npm/ng-packs/packages/theme-shared/package.json b/npm/ng-packs/packages/theme-shared/package.json index 542dd18d5f..d1b4be2dd7 100644 --- a/npm/ng-packs/packages/theme-shared/package.json +++ b/npm/ng-packs/packages/theme-shared/package.json @@ -10,7 +10,7 @@ "@abp/ng.core": "~3.0.4", "@fortawesome/fontawesome-free": "^5.13.1", "@ng-bootstrap/ng-bootstrap": "^6.1.0", - "@ngx-validate/core": "^0.0.9", + "@ngx-validate/core": "^0.0.10", "@swimlane/ngx-datatable": "^17.0.0", "bootstrap": "^4.5.0", "chart.js": "^2.9.3",