Browse Source

Merge branch 'dev' of https://github.com/volosoft/abp into dev

pull/1746/head
Alper Ebicoglu 7 years ago
parent
commit
eb2a5880fb
  1. 6
      docs/en/Multi-Tenancy.md
  2. 6
      docs/zh-Hans/Multi-Tenancy.md
  3. 3
      modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json
  4. 87
      modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml
  5. 8
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo.Abp.IdentityServer.Domain.Shared.csproj
  6. 18
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/AbpIdentityServerDomainSharedModule.cs
  7. 7
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/en.json
  8. 5
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs
  9. 5
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs
  10. 2
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceDataSeeder.cs
  11. 5
      modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs
  12. 5
      modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceRepository.cs
  13. 5
      modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs
  14. 5
      modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs
  15. 15
      npm/ng-packs/packages/account/src/lib/account.module.ts
  16. 20
      npm/ng-packs/packages/account/src/lib/root-account.module.ts
  17. 1
      npm/ng-packs/packages/account/src/public-api.ts
  18. 32
      npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts
  19. 3
      npm/ng-packs/packages/core/src/lib/core.module.ts
  20. 174
      npm/ng-packs/packages/core/src/lib/directives/for.directive.ts
  21. 1
      npm/ng-packs/packages/core/src/lib/directives/index.ts
  22. 1
      npm/ng-packs/packages/core/src/lib/enums/common.ts
  23. 2
      npm/ng-packs/packages/core/src/lib/models/common.ts
  24. 11
      npm/ng-packs/packages/feature-management/src/lib/root-feature-management.module.ts
  25. 1
      npm/ng-packs/packages/feature-management/src/public-api.ts
  26. 168
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.html
  27. 8
      npm/ng-packs/packages/identity/src/lib/identity.module.ts
  28. 11
      npm/ng-packs/packages/identity/src/lib/root-identity.module.ts
  29. 1
      npm/ng-packs/packages/identity/src/public-api.ts
  30. 66
      npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html
  31. 3
      npm/ng-packs/packages/permission-management/src/lib/permission-management.module.ts
  32. 11
      npm/ng-packs/packages/permission-management/src/lib/root-permission-management.module.ts
  33. 1
      npm/ng-packs/packages/permission-management/src/public-api.ts
  34. 1
      npm/ng-packs/packages/setting-management/src/lib/components/index.ts
  35. 17
      npm/ng-packs/packages/setting-management/src/lib/components/services/initial.service.ts
  36. 59
      npm/ng-packs/packages/setting-management/src/lib/components/setting-layout.component.html
  37. 37
      npm/ng-packs/packages/setting-management/src/lib/components/setting-layout.component.ts
  38. 51
      npm/ng-packs/packages/setting-management/src/lib/components/setting/setting.component.html
  39. 20
      npm/ng-packs/packages/setting-management/src/lib/components/setting/setting.component.ts
  40. 1
      npm/ng-packs/packages/setting-management/src/lib/constants/routes.ts
  41. 11
      npm/ng-packs/packages/setting-management/src/lib/root-setting-management.module.ts
  42. 53
      npm/ng-packs/packages/setting-management/src/lib/services/setting-management.service.ts
  43. 8
      npm/ng-packs/packages/setting-management/src/lib/setting-management-routing.module.ts
  44. 19
      npm/ng-packs/packages/setting-management/src/lib/setting-management.module.ts
  45. 3
      npm/ng-packs/packages/setting-management/src/public-api.ts
  46. 11
      npm/ng-packs/packages/tenant-management/src/lib/root-tenant-management.module.ts
  47. 6
      npm/ng-packs/packages/tenant-management/src/lib/tenant-management.module.ts
  48. 1
      npm/ng-packs/packages/tenant-management/src/public-api.ts
  49. 7
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html
  50. 15
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts
  51. 4
      npm/ng-packs/packages/theme-shared/src/lib/models/setting-management.ts
  52. 32
      npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
  53. 9
      npm/ng-packs/tsconfig.json
  54. 11
      templates/app/angular/src/app/app.module.ts

6
docs/en/Multi-Tenancy.md

@ -114,7 +114,7 @@ namespace MyCompany.MyProject
{
Configure<TenantResolveOptions>(options =>
{
options.TenantResolvers.Add(new MyCustomTenantResolver());
options.TenantResolvers.Add(new MyCustomTenantResolveContributor());
});
//...
@ -123,14 +123,14 @@ namespace MyCompany.MyProject
}
````
MyCustomTenantResolver must implement **ITenantResolver** as shown below:
`MyCustomTenantResolveContributor` must implement **ITenantResolveContributor** as shown below:
````C#
using Volo.Abp.MultiTenancy;
namespace MyCompany.MyProject
{
public class MyCustomTenantResolver : ITenantResolver
public class MyCustomTenantResolveContributor : ITenantResolveContributor
{
public void Resolve(ITenantResolveContext context)
{

6
docs/zh-Hans/Multi-Tenancy.md

@ -115,7 +115,7 @@ namespace MyCompany.MyProject
{
Configure<TenantResolveOptions>(options =>
{
options.TenantResolvers.Add(new MyCustomTenantResolver());
options.TenantResolvers.Add(new MyCustomTenantResolveContributor());
});
//...
@ -124,14 +124,14 @@ namespace MyCompany.MyProject
}
````
MyCustomTenantResolver必须像下面这样实现**ITenantResolver**接口:
`MyCustomTenantResolveContributor`必须像下面这样实现**ITenantResolveContributor**接口:
````C#
using Volo.Abp.MultiTenancy;
namespace MyCompany.MyProject
{
public class MyCustomTenantResolver : ITenantResolver
public class MyCustomTenantResolveContributor : ITenantResolveContributor
{
public void Resolve(ITenantResolveContext context)
{

3
modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json

@ -1,6 +1,7 @@
{
"culture": "en",
"texts": {
"Features": "Features"
"Features": "Features",
"NoFeatureFoundMessage": "There is't any available feature."
}
}

87
modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml

@ -12,49 +12,58 @@
<form method="post" asp-page="/FeatureManagement/FeatureManagementModal" data-script-class="abp.modals.FeatureManagement">
<abp-modal size="Large">
<abp-modal-header title="@(L["Features"].Value)"></abp-modal-header>
<abp-modal-body class="ml-4">
<input asp-for="@Model.ProviderKey" />
<input asp-for="@Model.ProviderName" />
@for (var i = 0; i < Model.FeatureListDto.Features.Count; i++)
{
var feature = Model.FeatureListDto.Features[i];
<div class="mt-2" style="padding-left: @(feature.Depth * 20)px">
@if (Model.FeatureListDto?.Features != null && Model.FeatureListDto.Features.Any())
{
<abp-modal-body class="ml-4">
<input asp-for="@Model.ProviderKey" />
<input asp-for="@Model.ProviderName" />
@for (var i = 0; i < Model.FeatureListDto.Features.Count; i++)
{
var feature = Model.FeatureListDto.Features[i];
<div class="mt-2" style="padding-left: @(feature.Depth * 20)px">
<spam class="mr-2">@feature.Name</spam>
<spam class="mr-2">@feature.Name</spam>
<input type="text" name="Features[@i].Type" value="@feature.ValueType.Name" hidden />
@if (feature.ValueType is FreeTextStringValueType)
{
<input type="text" name="Features[@i].Name" value="@feature.Name" hidden />
<input type="text" name="Features[@i].Value" value="@feature.Value" />
}
@if (feature.ValueType is SelectionStringValueType)
{
<input type="text" name="Features[@i].Name" value="@feature.Name" hidden />
<select name="Features[@i].Value">
@foreach (var item in (feature.ValueType as SelectionStringValueType).ItemSource.Items)
{
if (item.Value == feature.Value)
<input type="text" name="Features[@i].Type" value="@feature.ValueType.Name" hidden />
@if (feature.ValueType is FreeTextStringValueType)
{
<input type="text" name="Features[@i].Name" value="@feature.Name" hidden />
<input type="text" name="Features[@i].Value" value="@feature.Value" />
}
@if (feature.ValueType is SelectionStringValueType)
{
<input type="text" name="Features[@i].Name" value="@feature.Name" hidden />
<select name="Features[@i].Value">
@foreach (var item in (feature.ValueType as SelectionStringValueType).ItemSource.Items)
{
<option value="@item.Value" selected="selected"> @L.GetString(item.DisplayText.Name) </option>
if (item.Value == feature.Value)
{
<option value="@item.Value" selected="selected"> @L.GetString(item.DisplayText.Name) </option>
}
else
{
<option value="@item.Value"> @L.GetString(item.DisplayText.Name) </option>
}
}
else
{
<option value="@item.Value"> @L.GetString(item.DisplayText.Name) </option>
}
}
</select>
}
@if (feature.ValueType is ToggleStringValueType)
{
<input type="text" name="Features[@i].Name" value="@feature.Name" hidden />
<input type="checkbox" class="FeatureValueCheckbox" name="Features[@i].BoolValue" value="@feature.Value"
@Html.Raw(feature.Value == "True" ? "checked" : "") />
}
</div>
}
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</select>
}
@if (feature.ValueType is ToggleStringValueType)
{
<input type="text" name="Features[@i].Name" value="@feature.Name" hidden />
<input type="checkbox" class="FeatureValueCheckbox" name="Features[@i].BoolValue" value="@feature.Value"
@Html.Raw(feature.Value == "True" ? "checked" : "") />
}
</div>
}
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
}
else
{
<abp-modal-body class="ml-4">
@L["NoFeatureFoundMessage"]
</abp-modal-body>
}
</abp-modal>
</form>

8
modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo.Abp.IdentityServer.Domain.Shared.csproj

@ -13,6 +13,14 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Volo\Abp\IdentityServer\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>
<None Remove="Volo\Abp\IdentityServer\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />
</ItemGroup>

18
modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/AbpIdentityServerDomainSharedModule.cs

@ -1,6 +1,9 @@
using Volo.Abp.IdentityServer.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Localization.Resources.AbpValidation;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.IdentityServer
{
@ -11,9 +14,22 @@ namespace Volo.Abp.IdentityServer
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpIdentityServerDomainSharedModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources.Add<AbpIdentityServerResource>("en");
options.Resources.Add<AbpIdentityServerResource>("en")
.AddBaseTypes(
typeof(AbpValidationResource)
).AddVirtualJson("/Volo/Abp/IdentityServer/Localization/Resources");
});
Configure<ExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace("Volo.IdentityServer", typeof(AbpIdentityServerResource));
});
}
}

7
modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/en.json

@ -0,0 +1,7 @@
{
"culture": "en",
"texts": {
"Volo.IdentityServer:DuplicateIdentityResourceName": "Identity Resource name already exist: {Name}",
"Volo.IdentityServer:DuplicateApiResourceName": "Api Resource name already exist: {Name}"
}
}

5
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs

@ -32,5 +32,10 @@ namespace Volo.Abp.IdentityServer.ApiResources
bool includeDetails = false,
CancellationToken cancellationToken = default
);
Task<bool> CheckNameExistAsync(
string name,
Guid? expectedId = null
);
}
}

5
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs

@ -27,5 +27,10 @@ namespace Volo.Abp.IdentityServer.IdentityResources
bool includeDetails = true,
CancellationToken cancellationToken = default
);
Task<bool> CheckNameExistAsync(
string name,
Guid? expectedId = null
);
}
}

2
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceDataSeeder.cs

@ -46,7 +46,7 @@ namespace Volo.Abp.IdentityServer.IdentityResources
protected virtual async Task AddIdentityResourceIfNotExistsAsync(IdentityServer4.Models.IdentityResource resource)
{
if (await IdentityResourceRepository.FindByNameAsync(resource.Name) != null)
if (await IdentityResourceRepository.CheckNameExistAsync(resource.Name))
{
return;
}

5
modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs

@ -61,6 +61,11 @@ namespace Volo.Abp.IdentityServer.ApiResources
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<bool> CheckNameExistAsync(string name, Guid? expectedId = null)
{
return await DbSet.AnyAsync(ar => ar.Id != expectedId && ar.Name == name);
}
public override async Task DeleteAsync(Guid id, bool autoSave = false, CancellationToken cancellationToken = default)
{
var scopeClaims = DbContext.Set<ApiScopeClaim>().Where(sc => sc.ApiResourceId == id);

5
modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceRepository.cs

@ -56,5 +56,10 @@ namespace Volo.Abp.IdentityServer.IdentityResources
.Where(x => x.Name == name)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
}
public async Task<bool> CheckNameExistAsync(string name, Guid? expectedId = null)
{
return await DbSet.AnyAsync(ir => ir.Id != expectedId && ir.Name == name);
}
}
}

5
modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs

@ -47,5 +47,10 @@ namespace Volo.Abp.IdentityServer.MongoDB
{
return await GetCountAsync();
}
public async Task<bool> CheckNameExistAsync(string name, Guid? expectedId = null)
{
return await GetMongoQueryable().AnyAsync(ar => ar.Id != expectedId && ar.Name == name);
}
}
}

5
modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs

@ -50,5 +50,10 @@ namespace Volo.Abp.IdentityServer.MongoDB
{
return await GetCountAsync();
}
public async Task<bool> CheckNameExistAsync(string name, Guid? expectedId = null)
{
return await GetMongoQueryable().AnyAsync(ir => ir.Id != expectedId && ir.Name == name);
}
}
}

15
npm/ng-packs/packages/account/src/lib/account.module.ts

@ -1,6 +1,6 @@
import { CoreModule } from '@abp/ng.core';
import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { NgModule } from '@angular/core';
import { NgModule, Provider } from '@angular/core';
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
import { NgxValidateCoreModule } from '@ngx-validate/core';
import { TableModule } from 'primeng/table';
@ -8,6 +8,8 @@ import { AccountRoutingModule } from './account-routing.module';
import { LoginComponent } from './components/login/login.component';
import { RegisterComponent } from './components/register/register.component';
import { TenantBoxComponent } from './components/tenant-box/tenant-box.component';
import { Options } from './models/options';
import { ACCOUNT_OPTIONS, optionsFactory } from './tokens/options.token';
@NgModule({
declarations: [LoginComponent, RegisterComponent, TenantBoxComponent],
@ -15,3 +17,14 @@ import { TenantBoxComponent } from './components/tenant-box/tenant-box.component
exports: [],
})
export class AccountModule {}
export function AccountProviders(options = {} as Options): Provider[] {
return [
{ provide: ACCOUNT_OPTIONS, useValue: options },
{
provide: 'ACCOUNT_OPTIONS',
useFactory: optionsFactory,
deps: [ACCOUNT_OPTIONS],
},
];
}

20
npm/ng-packs/packages/account/src/lib/root-account.module.ts

@ -1,20 +0,0 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
import { Options } from './models/options';
import { ACCOUNT_OPTIONS, optionsFactory } from './tokens/options.token';
@NgModule({})
export class RootAccountModule {
static forRoot(options = {} as Options): ModuleWithProviders {
return {
ngModule: RootAccountModule,
providers: [
{ provide: ACCOUNT_OPTIONS, useValue: options },
{
provide: 'ACCOUNT_OPTIONS',
useFactory: optionsFactory,
deps: [ACCOUNT_OPTIONS],
},
],
};
}
}

1
npm/ng-packs/packages/account/src/public-api.ts

@ -1,4 +1,3 @@
export * from './lib/root-account.module';
export * from './lib/account.module';
export * from './lib/components';
export * from './lib/constants/routes';

32
npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts

@ -1,12 +1,13 @@
import { Component, OnDestroy, Type } from '@angular/core';
import { NavigationEnd, Router, UrlSegment } from '@angular/router';
import { Component, Input, OnDestroy, Type } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router, UrlSegment } from '@angular/router';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { eLayoutType } from '../enums';
import { ABP, Config } from '../models';
import { ConfigState } from '../states';
import { takeUntilDestroy } from '../utils';
import snq from 'snq';
import { eLayoutType } from '../enums/common';
import { Config } from '../models/config';
import { ABP } from '../models/common';
import { ConfigState } from '../states/config.state';
import { takeUntilDestroy } from '../utils/rxjs-utils';
@Component({
selector: 'abp-dynamic-layout',
@ -23,16 +24,23 @@ export class DynamicLayoutComponent implements OnDestroy {
layout: Type<any>;
constructor(private router: Router, private store: Store) {
constructor(private router: Router, private route: ActivatedRoute, private store: Store) {
const {
requirements: { layouts },
routes,
} = this.store.selectSnapshot(ConfigState.getAll);
if ((this.route.snapshot.data || {}).layout) {
this.layout = layouts
.filter(l => !!l)
.find(l => snq(() => l.type.toLowerCase().indexOf(this.route.snapshot.data.layout), -1) > -1);
}
this.router.events.pipe(takeUntilDestroy(this)).subscribe(event => {
if (event instanceof NavigationEnd) {
const { segments } = this.router.parseUrl(event.url).root.children.primary;
const {
requirements: { layouts },
routes,
} = this.store.selectSnapshot(ConfigState.getAll);
const layout = findLayout(segments, routes);
const layout = (this.route.snapshot.data || {}).layout || findLayout(segments, routes);
this.layout = layouts.filter(l => !!l).find(l => snq(() => l.type.toLowerCase().indexOf(layout), -1) > -1);
}

3
npm/ng-packs/packages/core/src/lib/core.module.ts

@ -24,6 +24,7 @@ import { ProfileState } from './states/profile.state';
import { SessionState } from './states/session.state';
import { getInitialData, localeInitializer } from './utils/initial-utils';
import { ConfigPlugin, NGXS_CONFIG_PLUGIN_OPTIONS } from './plugins/config/config.plugin';
import { ForDirective } from './directives/for.directive';
@NgModule({
imports: [
@ -41,6 +42,7 @@ import { ConfigPlugin, NGXS_CONFIG_PLUGIN_OPTIONS } from './plugins/config/confi
DynamicLayoutComponent,
AutofocusDirective,
EllipsisDirective,
ForDirective,
FormSubmitDirective,
LocalizationPipe,
PermissionDirective,
@ -58,6 +60,7 @@ import { ConfigPlugin, NGXS_CONFIG_PLUGIN_OPTIONS } from './plugins/config/confi
DynamicLayoutComponent,
AutofocusDirective,
EllipsisDirective,
ForDirective,
FormSubmitDirective,
LocalizationPipe,
PermissionDirective,

174
npm/ng-packs/packages/core/src/lib/directives/for.directive.ts

@ -0,0 +1,174 @@
import {
Directive,
EmbeddedViewRef,
Input,
IterableChangeRecord,
IterableChanges,
IterableDiffer,
IterableDiffers,
OnChanges,
TemplateRef,
TrackByFunction,
ViewContainerRef,
} from '@angular/core';
import compare from 'just-compare';
export type CompareFn<T = any> = (value: T, comparison: T) => boolean;
class AbpForContext {
constructor(public $implicit: any, public index: number, public count: number, public list: any[]) {}
}
class RecordView {
constructor(public record: IterableChangeRecord<any>, public view: EmbeddedViewRef<AbpForContext>) {}
}
@Directive({
selector: '[abpFor]',
})
export class ForDirective implements OnChanges {
@Input('abpForOf')
items: any[];
@Input('abpForOrderBy')
orderBy: string;
@Input('abpForOrderDir')
orderDir: 'ASC' | 'DESC';
@Input('abpForFilterBy')
filterBy: string;
@Input('abpForFilterVal')
filterVal: any;
@Input('abpForTrackBy')
trackBy;
@Input('abpForCompareBy')
compareBy: CompareFn;
@Input('abpForEmptyRef')
emptyRef: TemplateRef<any>;
private differ: IterableDiffer<any>;
private isShowEmptyRef: boolean;
get compareFn(): CompareFn {
return this.compareBy || compare;
}
get trackByFn(): TrackByFunction<any> {
return this.trackBy || ((index: number, item: any) => (item as any).id || index);
}
constructor(
private tempRef: TemplateRef<AbpForContext>,
private vcRef: ViewContainerRef,
private differs: IterableDiffers,
) {}
private iterateOverAppliedOperations(changes: IterableChanges<any>) {
const rw: RecordView[] = [];
changes.forEachOperation((record: IterableChangeRecord<any>, previousIndex: number, currentIndex: number) => {
if (record.previousIndex == null) {
const view = this.vcRef.createEmbeddedView(
this.tempRef,
new AbpForContext(null, -1, -1, this.items),
currentIndex,
);
rw.push(new RecordView(record, view));
} else if (currentIndex == null) {
this.vcRef.remove(previousIndex);
} else {
const view = this.vcRef.get(previousIndex);
this.vcRef.move(view, currentIndex);
rw.push(new RecordView(record, view as EmbeddedViewRef<AbpForContext>));
}
});
for (let i = 0, l = rw.length; i < l; i++) {
rw[i].view.context.$implicit = rw[i].record.item;
}
}
private iterateOverAttachedViews(changes: IterableChanges<any>) {
for (let i = 0, l = this.vcRef.length; i < l; i++) {
const viewRef = this.vcRef.get(i) as EmbeddedViewRef<AbpForContext>;
viewRef.context.index = i;
viewRef.context.count = l;
viewRef.context.list = this.items;
}
changes.forEachIdentityChange((record: IterableChangeRecord<any>) => {
const viewRef = this.vcRef.get(record.currentIndex) as EmbeddedViewRef<AbpForContext>;
viewRef.context.$implicit = record.item;
});
}
private projectItems(items: any[]): void {
if (!items.length && this.emptyRef) {
this.vcRef.createEmbeddedView(this.emptyRef).rootNodes;
this.isShowEmptyRef = true;
return;
}
if (this.emptyRef && this.isShowEmptyRef) {
this.vcRef.clear();
this.isShowEmptyRef = false;
}
if (!this.differ && items) {
this.differ = this.differs.find(items).create(this.trackByFn);
}
if (this.differ) {
const changes = this.differ.diff(items);
if (changes) {
this.iterateOverAppliedOperations(changes);
this.iterateOverAttachedViews(changes);
}
}
}
private sortItems(items: any[]) {
if (this.orderBy) {
items.sort((a, b) => (a[this.orderBy] > b[this.orderBy] ? 1 : a[this.orderBy] < b[this.orderBy] ? -1 : 0));
} else {
items.sort();
}
}
ngOnChanges() {
let items = [...this.items] as any[];
if (!Array.isArray(items)) return;
const compareFn = this.compareFn;
if (typeof this.filterBy !== 'undefined') {
items = items.filter(item => compareFn(item[this.filterBy], this.filterVal));
}
switch (this.orderDir) {
case 'ASC':
this.sortItems(items);
this.projectItems(items);
break;
case 'DESC':
this.sortItems(items);
items.reverse();
this.projectItems(items);
break;
default:
this.projectItems(items);
}
}
}

1
npm/ng-packs/packages/core/src/lib/directives/index.ts

@ -1,5 +1,6 @@
export * from './autofocus.directive';
export * from './ellipsis.directive';
export * from './for.directive';
export * from './form-submit.directive';
export * from './permission.directive';
export * from './visibility.directive';

1
npm/ng-packs/packages/core/src/lib/enums/common.ts

@ -2,4 +2,5 @@ export const enum eLayoutType {
account = 'account',
application = 'application',
empty = 'empty',
setting = 'setting',
}

2
npm/ng-packs/packages/core/src/lib/models/common.ts

@ -1,5 +1,5 @@
import { Config } from './config';
import { eLayoutType } from '../enums';
import { eLayoutType } from '../enums/common';
export namespace ABP {
export interface Root {

11
npm/ng-packs/packages/feature-management/src/lib/root-feature-management.module.ts

@ -1,11 +0,0 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
@NgModule({})
export class RootFeatureManagementModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: RootFeatureManagementModule,
providers: [],
};
}
}

1
npm/ng-packs/packages/feature-management/src/public-api.ts

@ -1,3 +1,2 @@
export * from './lib/root-feature-management.module';
export * from './lib/feature-management.module';
export * from './lib/components';

168
npm/ng-packs/packages/identity/src/lib/components/users/users.component.html

@ -83,100 +83,98 @@
</ng-template>
<ng-template #abpBody>
<perfect-scrollbar class="ps-show-always" style="max-height: 70vh;">
<form [formGroup]="form" (ngSubmit)="save()">
<ngb-tabset>
<ngb-tab [title]="'AbpIdentity::UserInformations' | abpLocalization">
<ng-template ngbTabContent>
<div class="mt-2 fade-in-top">
<div class="form-group">
<label for="user-name">{{ 'AbpIdentity::UserName' | abpLocalization }}</label
><span> * </span>
<input type="text" id="user-name" class="form-control" formControlName="userName" autofocus />
</div>
<form [formGroup]="form" (ngSubmit)="save()">
<ngb-tabset>
<ngb-tab [title]="'AbpIdentity::UserInformations' | abpLocalization">
<ng-template ngbTabContent>
<div class="mt-2 fade-in-top">
<div class="form-group">
<label for="user-name">{{ 'AbpIdentity::UserName' | abpLocalization }}</label
><span> * </span>
<input type="text" id="user-name" class="form-control" formControlName="userName" autofocus />
</div>
<div class="form-group">
<label for="name">{{ 'AbpIdentity::DisplayName:Name' | abpLocalization }}</label>
<input type="text" id="name" class="form-control" formControlName="name" />
</div>
<div class="form-group">
<label for="name">{{ 'AbpIdentity::DisplayName:Name' | abpLocalization }}</label>
<input type="text" id="name" class="form-control" formControlName="name" />
</div>
<div class="form-group">
<label for="surname">{{ 'AbpIdentity::DisplayName:Surname' | abpLocalization }}</label>
<input type="text" id="surname" class="form-control" formControlName="surname" />
</div>
<div class="form-group">
<label for="surname">{{ 'AbpIdentity::DisplayName:Surname' | abpLocalization }}</label>
<input type="text" id="surname" class="form-control" formControlName="surname" />
</div>
<div *ngIf="!selected.userName" class="form-group">
<label for="password">{{ 'AbpIdentity::Password' | abpLocalization }}</label
><span> * </span>
<input
type="password"
id="password"
autocomplete="new-password"
class="form-control"
formControlName="password"
/>
</div>
<div *ngIf="!selected.userName" class="form-group">
<label for="password">{{ 'AbpIdentity::Password' | abpLocalization }}</label
><span> * </span>
<input
type="password"
id="password"
autocomplete="new-password"
class="form-control"
formControlName="password"
/>
</div>
<div class="form-group">
<label for="email">{{ 'AbpIdentity::EmailAddress' | abpLocalization }}</label
><span> * </span>
<input type="text" id="email" class="form-control" formControlName="email" />
</div>
<div class="form-group">
<label for="email">{{ 'AbpIdentity::EmailAddress' | abpLocalization }}</label
><span> * </span>
<input type="text" id="email" class="form-control" formControlName="email" />
</div>
<div class="form-group">
<label for="phone-number">{{ 'AbpIdentity::PhoneNumber' | abpLocalization }}</label>
<input type="text" id="phone-number" class="form-control" formControlName="phoneNumber" />
</div>
<div class="form-group">
<label for="phone-number">{{ 'AbpIdentity::PhoneNumber' | abpLocalization }}</label>
<input type="text" id="phone-number" class="form-control" formControlName="phoneNumber" />
</div>
<div class="custom-checkbox custom-control mb-2">
<input
type="checkbox"
id="lockout-checkbox"
class="custom-control-input"
formControlName="lockoutEnabled"
/>
<label class="custom-control-label" for="lockout-checkbox">{{
'AbpIdentity::DisplayName:LockoutEnabled' | abpLocalization
}}</label>
</div>
<div class="custom-checkbox custom-control mb-2">
<input
type="checkbox"
id="lockout-checkbox"
class="custom-control-input"
formControlName="lockoutEnabled"
/>
<label class="custom-control-label" for="lockout-checkbox">{{
'AbpIdentity::DisplayName:LockoutEnabled' | abpLocalization
}}</label>
</div>
<div class="custom-checkbox custom-control mb-2">
<input
type="checkbox"
id="two-factor-checkbox"
class="custom-control-input"
formControlName="twoFactorEnabled"
/>
<label class="custom-control-label" for="two-factor-checkbox">{{
'AbpIdentity::DisplayName:TwoFactorEnabled' | abpLocalization
}}</label>
</div>
<div class="custom-checkbox custom-control mb-2">
<input
type="checkbox"
id="two-factor-checkbox"
class="custom-control-input"
formControlName="twoFactorEnabled"
/>
<label class="custom-control-label" for="two-factor-checkbox">{{
'AbpIdentity::DisplayName:TwoFactorEnabled' | abpLocalization
}}</label>
</div>
</ng-template>
</ngb-tab>
<ngb-tab [title]="'AbpIdentity::Roles' | abpLocalization">
<ng-template ngbTabContent>
<div class="mt-2 fade-in-top">
<div
*ngFor="let roleGroup of roleGroups; let i = index; trackBy: trackByFn"
class="custom-checkbox custom-control mb-2"
>
<input
type="checkbox"
name="Roles[0].IsAssigned"
value="true"
class="custom-control-input"
[attr.id]="'roles-' + i"
[formControl]="roleGroup.controls[roles[i].name]"
/>
<label class="custom-control-label" [attr.for]="'roles-' + i">{{ roles[i].name }}</label>
</div>
</div>
</ng-template>
</ngb-tab>
<ngb-tab [title]="'AbpIdentity::Roles' | abpLocalization">
<ng-template ngbTabContent>
<div class="mt-2 fade-in-top">
<div
*ngFor="let roleGroup of roleGroups; let i = index; trackBy: trackByFn"
class="custom-checkbox custom-control mb-2"
>
<input
type="checkbox"
name="Roles[0].IsAssigned"
value="true"
class="custom-control-input"
[attr.id]="'roles-' + i"
[formControl]="roleGroup.controls[roles[i].name]"
/>
<label class="custom-control-label" [attr.for]="'roles-' + i">{{ roles[i].name }}</label>
</div>
</ng-template>
</ngb-tab>
</ngb-tabset>
</form>
</perfect-scrollbar>
</div>
</ng-template>
</ngb-tab>
</ngb-tabset>
</form>
</ng-template>
<ng-template #abpFooter>

8
npm/ng-packs/packages/identity/src/lib/identity.module.ts

@ -1,5 +1,5 @@
import { CoreModule } from '@abp/ng.core';
import { NgModule } from '@angular/core';
import { NgModule, Provider } from '@angular/core';
import { NgxsModule } from '@ngxs/store';
import { RolesComponent } from './components/roles/roles.component';
import { IdentityRoutingModule } from './identity-routing.module';
@ -10,7 +10,6 @@ import { UsersComponent } from './components/users/users.component';
import { PermissionManagementModule } from '@abp/ng.permission-management';
import { TableModule } from 'primeng/table';
import { NgxValidateCoreModule } from '@ngx-validate/core';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
@NgModule({
declarations: [RolesComponent, UsersComponent],
@ -24,7 +23,10 @@ import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
NgbDropdownModule,
PermissionManagementModule,
NgxValidateCoreModule,
PerfectScrollbarModule,
],
})
export class IdentityModule {}
export function IdentityProviders(): Provider[] {
return [];
}

11
npm/ng-packs/packages/identity/src/lib/root-identity.module.ts

@ -1,11 +0,0 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
@NgModule({})
export class RootIdentityModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: RootIdentityModule,
providers: [],
};
}
}

1
npm/ng-packs/packages/identity/src/public-api.ts

@ -2,7 +2,6 @@
* Public API Surface of identity
*/
export * from './lib/root-identity.module';
export * from './lib/identity.module';
export * from './lib/actions/identity.actions';
export * from './lib/components/roles/roles.component';

66
npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html

@ -22,16 +22,14 @@
<div class="row">
<div class="col-4">
<ul class="nav nav-pills flex-column">
<perfect-scrollbar class="ps-show-always" style="max-height: 70vh;">
<li *ngFor="let group of groups$ | async; trackBy: trackByFn" class="nav-item">
<a
class="nav-link pointer"
[class.active]="selectedGroup?.name === group?.name"
(click)="onChangeGroup(group)"
>{{ group?.displayName }}</a
>
</li>
</perfect-scrollbar>
<li *ngFor="let group of groups$ | async; trackBy: trackByFn" class="nav-item">
<a
class="nav-link pointer"
[class.active]="selectedGroup?.name === group?.name"
(click)="onChangeGroup(group)"
>{{ group?.displayName }}</a
>
</li>
</ul>
</div>
<div class="col-8">
@ -52,32 +50,30 @@
}}</label>
</div>
<hr class="mb-3" />
<perfect-scrollbar class="ps-show-always" style="max-height: 60vh;">
<div
*ngFor="let permission of selectedGroupPermissions$ | async; let i = index; trackBy: trackByFn"
[style.margin-left]="permission.margin + 'px'"
class="custom-checkbox custom-control mb-2"
<div
*ngFor="let permission of selectedGroupPermissions$ | async; let i = index; trackBy: trackByFn"
[style.margin-left]="permission.margin + 'px'"
class="custom-checkbox custom-control mb-2"
>
<input
#permissionCheckbox
type="checkbox"
[checked]="getChecked(permission.name)"
[value]="getChecked(permission.name)"
[attr.id]="permission.name"
class="custom-control-input"
[disabled]="isGrantedByRole(permission.grantedProviders)"
/>
<label
class="custom-control-label"
[attr.for]="permission.name"
(click)="onClickCheckbox(permission, permissionCheckbox.value)"
>{{ permission.displayName }}
<span *ngFor="let provider of permission.grantedProviders" class="badge badge-light"
>{{ provider.providerName }}: {{ provider.providerKey }}</span
></label
>
<input
#permissionCheckbox
type="checkbox"
[checked]="getChecked(permission.name)"
[value]="getChecked(permission.name)"
[attr.id]="permission.name"
class="custom-control-input"
[disabled]="isGrantedByRole(permission.grantedProviders)"
/>
<label
class="custom-control-label"
[attr.for]="permission.name"
(click)="onClickCheckbox(permission, permissionCheckbox.value)"
>{{ permission.displayName }}
<span *ngFor="let provider of permission.grantedProviders" class="badge badge-light"
>{{ provider.providerName }}: {{ provider.providerKey }}</span
></label
>
</div>
</perfect-scrollbar>
</div>
</div>
</div>
</div>

3
npm/ng-packs/packages/permission-management/src/lib/permission-management.module.ts

@ -4,11 +4,10 @@ import { NgModule } from '@angular/core';
import { NgxsModule } from '@ngxs/store';
import { PermissionManagementComponent } from './components/permission-management.component';
import { PermissionManagementState } from './states/permission-management.state';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
@NgModule({
declarations: [PermissionManagementComponent],
imports: [CoreModule, ThemeSharedModule, NgxsModule.forFeature([PermissionManagementState]), PerfectScrollbarModule],
imports: [CoreModule, ThemeSharedModule, NgxsModule.forFeature([PermissionManagementState])],
exports: [PermissionManagementComponent],
})
export class PermissionManagementModule {}

11
npm/ng-packs/packages/permission-management/src/lib/root-permission-management.module.ts

@ -1,11 +0,0 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
@NgModule({})
export class RootPermissionManagementModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: RootPermissionManagementModule,
providers: [],
};
}
}

1
npm/ng-packs/packages/permission-management/src/public-api.ts

@ -2,7 +2,6 @@
* Public API Surface of permission-management
*/
export * from './lib/root-permission-management.module';
export * from './lib/permission-management.module';
export * from './lib/actions';
export * from './lib/components';

1
npm/ng-packs/packages/setting-management/src/lib/components/index.ts

@ -1 +0,0 @@
export * from './setting/setting.component';

17
npm/ng-packs/packages/setting-management/src/lib/components/services/initial.service.ts

@ -1,17 +0,0 @@
import { SettingTab } from '@abp/ng.theme.shared';
import { Injectable, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import snq from 'snq';
@Injectable()
export class InitialService {
public settings: SettingTab[];
constructor(private router: Router) {
this.settings = this.router.config
.map(route => snq(() => route.data.routes.settings))
.filter(settings => settings && settings.length)
.reduce((acc, val) => [...acc, ...val], [])
.sort((a, b) => a.order - b.order);
}
}

59
npm/ng-packs/packages/setting-management/src/lib/components/setting-layout.component.html

@ -0,0 +1,59 @@
<div class="row entry-row">
<div class="col-auto">
<h1 class="content-header-title">{{ 'AbpSettingManagement::Settings' | abpLocalization }}</h1>
</div>
<!-- <div id="breadcrumb" class="col-md-auto pl-md-0">
<abp-breadcrumb></abp-breadcrumb>
</div> -->
<div class="col">
<div class="text-lg-right pt-2" id="AbpContentToolbar"></div>
</div>
</div>
<div id="SettingManagementWrapper">
<div class="card">
<div class="card-body">
<div *ngIf="!settingManagementService.settings.length" class="text-center">
<i class="fa fa-spinner fa-spin"></i>
</div>
<div class="row">
<div class="col-3">
<ul class="nav flex-column nav-pills" id="nav-tab" role="tablist">
<li
*abpFor="
let setting of settingManagementService.settings;
trackBy: trackByFn;
orderBy: 'order';
orderDir: 'ASC'
"
(click)="settingManagementService.setSelected(setting)"
class="nav-item"
[abpPermission]="setting.requiredPolicy"
>
<a
class="nav-link"
[id]="setting.name + '-tab'"
role="tab"
[class.active]="setting.name === settingManagementService.selected.name"
>{{ setting.name | abpLocalization }}</a
>
</li>
</ul>
</div>
<div class="col-9">
<div *ngIf="settingManagementService.settings.length" class="tab-content">
<div
class="tab-pane fade show active"
[id]="settingManagementService.selected.name + '-tab'"
role="tabpanel"
>
<h2>{{ settingManagementService.selected.name | abpLocalization }}</h2>
<hr class="my-4" />
<router-outlet></router-outlet>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

37
npm/ng-packs/packages/setting-management/src/lib/components/setting-layout.component.ts

@ -0,0 +1,37 @@
import { eLayoutType } from '@abp/ng.core';
import { SettingTab } from '@abp/ng.theme.shared';
import { Component, TrackByFunction } from '@angular/core';
import { Router } from '@angular/router';
import { timer } from 'rxjs';
import { SettingManagementService } from '../services/setting-management.service';
@Component({
selector: 'abp-setting-layout',
templateUrl: './setting-layout.component.html',
})
export class SettingLayoutComponent {
// required for dynamic component
static type = eLayoutType.setting;
trackByFn: TrackByFunction<SettingTab> = (_, item) => item.name;
constructor(public settingManagementService: SettingManagementService, private router: Router) {
if (
settingManagementService.selected &&
this.router.url !== settingManagementService.selected.url &&
settingManagementService.settings.length
) {
settingManagementService.setSelected(settingManagementService.settings[0]);
}
}
ngOnDestroy() {}
ngAfterViewInit() {
timer(250).subscribe(() => {
if (!this.settingManagementService.settings.length) {
this.settingManagementService.setSettings();
}
});
}
}

51
npm/ng-packs/packages/setting-management/src/lib/components/setting/setting.component.html

@ -1,51 +0,0 @@
<div class="row entry-row">
<div class="col-auto">
<h1 class="content-header-title">{{ 'AbpSettingManagement::Settings' | abpLocalization }}</h1>
</div>
<div id="breadcrumb" class="col-md-auto pl-md-0">
<abp-breadcrumb></abp-breadcrumb>
</div>
<div class="col">
<div class="text-lg-right pt-2" id="AbpContentToolbar"></div>
</div>
</div>
<div id="SettingManagementWrapper">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-3">
<ul class="nav flex-column nav-pills" id="T515ccf3324254f41a4a9a6b34b0dae56" role="tablist">
<li
*ngFor="let setting of settings"
(click)="selected = setting"
class="nav-item"
[abpPermission]="setting.requiredPolicy"
>
<a
class="nav-link"
[id]="setting.name + '-tab'"
role="tab"
[class.active]="setting.name === selected.name"
>{{ setting.name | abpLocalization }}</a
>
</li>
</ul>
</div>
<div class="col-9">
<div class="tab-content">
<div class="tab-pane fade show active" [id]="selected.name + '-tab'" role="tabpanel">
<h2>{{ selected.name | abpLocalization }}</h2>
<hr class="my-4" />
<ng-container
*ngComponentOutlet="selected.component"
[abpPermission]="selected.requiredPolicy"
></ng-container>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

20
npm/ng-packs/packages/setting-management/src/lib/components/setting/setting.component.ts

@ -1,20 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { SettingTab, fade } from '@abp/ng.theme.shared';
import { InitialService } from '../services/initial.service';
@Component({
selector: 'abp-setting',
templateUrl: './setting.component.html',
})
export class SettingComponent implements OnInit {
settings: SettingTab[];
selected = {} as SettingTab;
constructor(private initialService: InitialService) {}
ngOnInit() {
this.settings = this.initialService.settings;
this.selected = this.settings[0];
}
}

1
npm/ng-packs/packages/setting-management/src/lib/constants/routes.ts

@ -11,5 +11,4 @@ export const SETTING_MANAGEMENT_ROUTES = {
iconClass: 'fa fa-cog',
},
] as ABP.FullRoute[],
settings: [],
};

11
npm/ng-packs/packages/setting-management/src/lib/root-setting-management.module.ts

@ -1,11 +0,0 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
@NgModule({})
export class RootSettingManagementModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: RootSettingManagementModule,
providers: [],
};
}
}

53
npm/ng-packs/packages/setting-management/src/lib/services/setting-management.service.ts

@ -0,0 +1,53 @@
import { SettingTab } from '@abp/ng.theme.shared';
import { Injectable } from '@angular/core';
import { Router, RouteConfigLoadEnd, NavigationEnd } from '@angular/router';
import { Navigate } from '@ngxs/router-plugin';
import { Store } from '@ngxs/store';
import { filter } from 'rxjs/operators';
import { takeUntilDestroy } from '@abp/ng.core';
import { Subscription, timer } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class SettingManagementService {
settings: SettingTab[] = [];
selected = {} as SettingTab;
constructor(private router: Router, private store: Store) {
let timeout: Subscription;
this.router.events
.pipe(
filter(event => event instanceof RouteConfigLoadEnd),
takeUntilDestroy(this),
)
.subscribe(event => {
if (timeout) timeout.unsubscribe();
timeout = timer(150).subscribe(() => {
this.setSettings();
});
});
}
ngOnDestroy() {}
setSettings() {
setTimeout(() => {
const route = this.router.config.find(r => r.path === 'setting-management');
this.settings = route.data.settings.sort((a, b) => a.order - b.order);
this.checkSelected();
}, 0);
}
checkSelected() {
this.selected = this.settings.find(setting => setting.url === this.router.url) || ({} as SettingTab);
if (!this.selected.name && this.settings.length) {
this.setSelected(this.settings[0]);
}
}
setSelected(selected: SettingTab) {
this.selected = selected;
this.store.dispatch(new Navigate([selected.url]));
}
}

8
npm/ng-packs/packages/setting-management/src/lib/setting-management-routing.module.ts

@ -1,13 +1,15 @@
import { DynamicLayoutComponent } from '@abp/ng.core';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { SettingComponent } from './components/setting/setting.component';
import { SETTING_MANAGEMENT_ROUTES } from './constants/routes';
import { SettingLayoutComponent } from './components/setting-layout.component';
const routes: Routes = [
{
path: '',
path: 'setting-management',
component: DynamicLayoutComponent,
children: [{ path: '', component: SettingComponent }],
children: [{ path: '', component: SettingLayoutComponent }],
data: { routes: SETTING_MANAGEMENT_ROUTES, settings: [] },
},
];

19
npm/ng-packs/packages/setting-management/src/lib/setting-management.module.ts

@ -1,15 +1,14 @@
import { CoreModule, noop } from '@abp/ng.core';
import { NgModule, ModuleWithProviders, APP_INITIALIZER, Self } from '@angular/core';
import { SettingComponent } from './components/setting/setting.component';
import { SettingManagementRoutingModule } from './setting-management-routing.module';
import { CoreModule } from '@abp/ng.core';
import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { InitialService } from './components/services/initial.service';
import { NgModule } from '@angular/core';
import { SettingLayoutComponent } from './components/setting-layout.component';
import { SettingManagementRoutingModule } from './setting-management-routing.module';
export const SETTING_LAYOUT = SettingLayoutComponent;
@NgModule({
declarations: [SettingComponent],
declarations: [SETTING_LAYOUT],
imports: [SettingManagementRoutingModule, CoreModule, ThemeSharedModule],
providers: [InitialService],
entryComponents: [SETTING_LAYOUT],
})
export class SettingManagementModule {
constructor(@Self() initialService: InitialService) {}
}
export class SettingManagementModule {}

3
npm/ng-packs/packages/setting-management/src/public-api.ts

@ -1,4 +1,3 @@
export * from './lib/root-setting-management.module';
export * from './lib/setting-management.module';
export * from './lib/components';
export * from './lib/constants';
export * from './lib/components/setting-layout.component';

11
npm/ng-packs/packages/tenant-management/src/lib/root-tenant-management.module.ts

@ -1,11 +0,0 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
@NgModule({})
export class RootTenantManagementModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: RootTenantManagementModule,
providers: [],
};
}
}

6
npm/ng-packs/packages/tenant-management/src/lib/tenant-management.module.ts

@ -1,6 +1,6 @@
import { CoreModule } from '@abp/ng.core';
import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { NgModule } from '@angular/core';
import { NgModule, Provider } from '@angular/core';
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
import { NgxsModule } from '@ngxs/store';
import { TableModule } from 'primeng/table';
@ -24,3 +24,7 @@ import { NgxValidateCoreModule } from '@ngx-validate/core';
],
})
export class TenantManagementModule {}
export function TenantManagementProviders(): Provider[] {
return [];
}

1
npm/ng-packs/packages/tenant-management/src/public-api.ts

@ -1,4 +1,3 @@
export * from './lib/root-tenant-management.module';
export * from './lib/tenant-management.module';
export * from './lib/actions';
export * from './lib/components';

7
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html

@ -27,10 +27,9 @@
[style.minHeight]="minHeight || undefined"
>
<ng-container *ngTemplateOutlet="abpBody"></ng-container>
<div id="abp-modal-footer" class="modal-footer">
<ng-container *ngTemplateOutlet="abpFooter"></ng-container>
</div>
</div>
<div id="abp-modal-footer" class="modal-footer">
<ng-container *ngTemplateOutlet="abpFooter"></ng-container>
</div>
</div>
</div>

15
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts

@ -119,11 +119,16 @@ export class ModalComponent implements OnDestroy {
this.visibleChange.emit(value);
this.showModal = value;
value
? timer(ANIMATION_TIMEOUT + 100)
.pipe(take(1))
.subscribe(_ => (this.closable = true))
: (this.closable = false);
if (value) {
timer(ANIMATION_TIMEOUT + 100)
.pipe(take(1))
.subscribe(_ => (this.closable = true));
this.renderer.addClass(document.body, 'modal-open');
} else {
this.closable = false;
this.renderer.removeClass(document.body, 'modal-open');
}
}
listen() {

4
npm/ng-packs/packages/theme-shared/src/lib/models/setting-management.ts

@ -1,8 +1,6 @@
import { Type } from '@angular/core';
export interface SettingTab {
name: string;
order: number;
component: Type<any>;
requiredPolicy?: string;
url?: string;
}

32
npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts

@ -18,22 +18,26 @@ import { ChangePasswordComponent } from './components/change-password/change-pas
import { ProfileComponent } from './components/profile/profile.component';
import { BreadcrumbComponent } from './components/breadcrumb/breadcrumb.component';
export function appendScript(injector: Injector) {
const fn = function() {
const lazyLoadService: LazyLoadService = injector.get(LazyLoadService);
export function appendScript(styles) {
const higher = (injector: Injector) => {
const fn = function() {
const lazyLoadService: LazyLoadService = injector.get(LazyLoadService);
return forkJoin(
lazyLoadService.load(
null,
'style',
styles,
'head',
'afterbegin',
) /* lazyLoadService.load(null, 'script', scripts) */,
).pipe(take(1));
return forkJoin(
lazyLoadService.load(
null,
'style',
styles,
'head',
'afterbegin',
) /* lazyLoadService.load(null, 'script', scripts) */,
).pipe(take(1));
};
return fn;
};
return fn;
return higher;
}
@NgModule({
@ -87,7 +91,7 @@ export class ThemeSharedModule {
provide: APP_INITIALIZER,
multi: true,
deps: [Injector, ErrorHandler],
useFactory: appendScript,
useFactory: appendScript(styles),
},
{ provide: MessageService, useClass: MessageService },
],

9
npm/ng-packs/tsconfig.json

@ -11,8 +11,13 @@
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"],
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
],
"paths": {}
},
"angularCompilerOptions": {

11
templates/app/angular/src/app/app.module.ts

@ -11,9 +11,9 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SharedModule } from './shared/shared.module';
import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { RootAccountModule } from '@abp/ng.account';
import { RootIdentityModule } from '@abp/ng.identity';
import { RootTenantManagementModule } from '@abp/ng.tenant-management';
import { AccountProviders } from '@abp/ng.account';
import { IdentityProviders } from '@abp/ng.identity';
import { TenantManagementProviders } from '@abp/ng.tenant-management';
@NgModule({
declarations: [AppComponent],
@ -29,15 +29,12 @@ import { RootTenantManagementModule } from '@abp/ng.tenant-management';
layouts: LAYOUTS,
},
}),
RootAccountModule.forRoot({ redirectUrl: '/' }),
RootIdentityModule.forRoot(),
RootTenantManagementModule.forRoot(),
OAuthModule.forRoot(),
NgxsModule.forRoot([]),
NgxsReduxDevtoolsPluginModule.forRoot({ disabled: environment.production }),
],
providers: [],
providers: [...AccountProviders({ redirectUrl: '/' }), ...IdentityProviders(), ...TenantManagementProviders()],
bootstrap: [AppComponent],
})
export class AppModule {}

Loading…
Cancel
Save