mirror of https://github.com/abpframework/abp.git
81 changed files with 322 additions and 114 deletions
@ -1,12 +1,26 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace Volo.Abp.Data; |
|||
|
|||
public static class DataSeederExtensions |
|||
{ |
|||
public const string SeedInSeparateUow = "__SeedInSeparateUow"; |
|||
public const string SeedInSeparateUowOptions = "__SeedInSeparateUowOptions"; |
|||
public const string SeedInSeparateUowRequiresNew = "__SeedInSeparateUowRequiresNew"; |
|||
|
|||
public static Task SeedAsync(this IDataSeeder seeder, Guid? tenantId = null) |
|||
{ |
|||
return seeder.SeedAsync(new DataSeedContext(tenantId)); |
|||
} |
|||
|
|||
public static Task SeedInSeparateUowAsync(this IDataSeeder seeder, Guid? tenantId = null, AbpUnitOfWorkOptions options = null, bool requiresNew = false) |
|||
{ |
|||
var context = new DataSeedContext(tenantId); |
|||
context.WithProperty(SeedInSeparateUow, true); |
|||
context.WithProperty(SeedInSeparateUowOptions, options); |
|||
context.WithProperty(SeedInSeparateUowRequiresNew, requiresNew); |
|||
return seeder.SeedAsync(context); |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,43 @@ |
|||
using System; |
|||
using System.Data; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using NSubstitute; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Testing; |
|||
using Volo.Abp.Uow; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.Data; |
|||
|
|||
public class DataSeederExtensions_Tests : AbpIntegratedTest<DataSeederExtensions_Tests.TestModule> |
|||
{ |
|||
private IDataSeeder _dataSeeder; |
|||
|
|||
protected override void AfterAddApplication(IServiceCollection services) |
|||
{ |
|||
_dataSeeder = Substitute.For<IDataSeeder>(); |
|||
services.Replace(ServiceDescriptor.Singleton(_dataSeeder)); |
|||
base.AfterAddApplication(services); |
|||
} |
|||
|
|||
[Fact] |
|||
public void SeedInSeparateUowAsync() |
|||
{ |
|||
var tenantId = Guid.NewGuid(); |
|||
_dataSeeder.SeedInSeparateUowAsync(tenantId, new AbpUnitOfWorkOptions(true, IsolationLevel.Serializable, 888), true); |
|||
|
|||
_dataSeeder.Received().SeedAsync(Arg.Is<DataSeedContext>(x => x.TenantId == tenantId && |
|||
x.Properties[DataSeederExtensions.SeedInSeparateUow].To<bool>() == true && |
|||
x.Properties[DataSeederExtensions.SeedInSeparateUowOptions].As<AbpUnitOfWorkOptions>().IsTransactional == true && |
|||
x.Properties[DataSeederExtensions.SeedInSeparateUowOptions].As<AbpUnitOfWorkOptions>().IsolationLevel == IsolationLevel.Serializable && |
|||
x.Properties[DataSeederExtensions.SeedInSeparateUowOptions].As<AbpUnitOfWorkOptions>().Timeout == 888 && |
|||
x.Properties[DataSeederExtensions.SeedInSeparateUowRequiresNew].To<bool>() == true)); |
|||
} |
|||
|
|||
[DependsOn(typeof(AbpDataModule))] |
|||
public class TestModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
<button class="btn btn-primary" type="button" (click)="openFeaturesModal()"> |
|||
<i class="fa fa-cog"></i> |
|||
{{ 'FeatureManagement::ManageHostFeatures' | abpLocalization }} |
|||
</button> |
|||
<abp-feature-management |
|||
*abpReplaceableTemplate="{ |
|||
inputs: { |
|||
providerName: { value: 'T' }, |
|||
providerKey: { value: providerKey }, |
|||
visible: { value: visibleFeatures, twoWay: true } |
|||
}, |
|||
outputs: { visibleChange: onVisibleFeaturesChange }, |
|||
componentKey: 'FeatureManagement.FeatureManagementComponent' |
|||
}" |
|||
[(visible)]="visibleFeatures" |
|||
providerName="T" |
|||
[providerKey]="providerKey" |
|||
> |
|||
</abp-feature-management> |
|||
@ -0,0 +1,20 @@ |
|||
import { Component } from '@angular/core'; |
|||
|
|||
@Component({ |
|||
selector: 'abp-feature-management-tab', |
|||
templateUrl: './feature-management-tab.component.html', |
|||
}) |
|||
export class FeatureManagementTabComponent { |
|||
visibleFeatures = false; |
|||
providerKey: string; |
|||
|
|||
openFeaturesModal() { |
|||
setTimeout(() => { |
|||
this.visibleFeatures = true; |
|||
}, 0); |
|||
} |
|||
|
|||
onVisibleFeaturesChange = (value: boolean) => { |
|||
this.visibleFeatures = value; |
|||
}; |
|||
} |
|||
@ -1 +1,2 @@ |
|||
export * from './feature-management/feature-management.component'; |
|||
export * from './feature-management-tab/feature-management-tab.component'; |
|||
|
|||
@ -0,0 +1,3 @@ |
|||
export const enum eFeatureManagementTabNames { |
|||
FeatureManagement = 'AbpFeatureManagement::Permission:FeatureManagement', |
|||
} |
|||
@ -0,0 +1,2 @@ |
|||
export * from './feature-management-tab-names'; |
|||
export * from './components'; |
|||
@ -1,15 +1,28 @@ |
|||
import { CoreModule } from '@abp/ng.core'; |
|||
import { ThemeSharedModule } from '@abp/ng.theme.shared'; |
|||
import { NgModule } from '@angular/core'; |
|||
import { ModuleWithProviders, NgModule } from '@angular/core'; |
|||
import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; |
|||
import { FeatureManagementComponent } from './components/feature-management/feature-management.component'; |
|||
import { FreeTextInputDirective } from './directives/free-text-input.directive'; |
|||
import { FEATURE_MANAGEMENT_SETTINGS_PROVIDERS } from './providers'; |
|||
import { FeatureManagementTabComponent } from './components'; |
|||
|
|||
const exported = [FeatureManagementComponent, FreeTextInputDirective]; |
|||
const exported = [ |
|||
FeatureManagementComponent, |
|||
FreeTextInputDirective, |
|||
FeatureManagementTabComponent, |
|||
]; |
|||
|
|||
@NgModule({ |
|||
declarations: [...exported], |
|||
imports: [CoreModule, ThemeSharedModule, NgbNavModule], |
|||
exports: [...exported], |
|||
}) |
|||
export class FeatureManagementModule {} |
|||
export class FeatureManagementModule { |
|||
static forRoot(): ModuleWithProviders<FeatureManagementModule> { |
|||
return { |
|||
ngModule: FeatureManagementModule, |
|||
providers: [FEATURE_MANAGEMENT_SETTINGS_PROVIDERS], |
|||
}; |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,26 @@ |
|||
import { SettingTabsService } from '@abp/ng.setting-management/config'; |
|||
import { APP_INITIALIZER } from '@angular/core'; |
|||
import { eFeatureManagementTabNames } from '../enums/feature-management-tab-names'; |
|||
import { FeatureManagementTabComponent } from '../components'; |
|||
|
|||
export const FEATURE_MANAGEMENT_SETTINGS_PROVIDERS = [ |
|||
{ |
|||
provide: APP_INITIALIZER, |
|||
useFactory: configureSettingTabs, |
|||
deps: [SettingTabsService], |
|||
multi: true, |
|||
}, |
|||
]; |
|||
|
|||
export function configureSettingTabs(settingtabs: SettingTabsService) { |
|||
return () => { |
|||
settingtabs.add([ |
|||
{ |
|||
name: eFeatureManagementTabNames.FeatureManagement, |
|||
order: 104, |
|||
requiredPolicy: 'FeatureManagement.ManageHostFeatures', |
|||
component: FeatureManagementTabComponent, |
|||
}, |
|||
]); |
|||
}; |
|||
} |
|||
@ -0,0 +1 @@ |
|||
export * from './feature-management-settings.provider'; |
|||
@ -1,5 +1,6 @@ |
|||
export * from './lib/components'; |
|||
export * from './lib/directives'; |
|||
export * from './lib/providers'; |
|||
export * from './lib/enums/components'; |
|||
export * from './lib/feature-management.module'; |
|||
export * from './lib/models'; |
|||
export * from './lib/models'; |
|||
|
|||
Loading…
Reference in new issue