Browse Source

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

pull/2081/head
Yunus Emre Kalkan 7 years ago
parent
commit
a24438d042
  1. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json
  2. 8
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
  3. 2
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/zh-Hans.json
  4. 42
      npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.ts
  5. 2
      npm/ng-packs/packages/core/src/lib/core.module.ts
  6. 4
      npm/ng-packs/packages/core/src/lib/plugins/config.plugin.ts
  7. 2
      npm/ng-packs/packages/core/src/lib/plugins/index.ts
  8. 20
      npm/ng-packs/packages/core/src/lib/tests/application-configuration.service.spec.ts
  9. 124
      npm/ng-packs/packages/core/src/lib/tests/config-state.service.spec.ts
  10. 19
      npm/ng-packs/packages/core/src/lib/tests/profile-state.service.spec.ts
  11. 42
      npm/ng-packs/packages/core/src/lib/tests/profile.service.spec.ts
  12. 19
      npm/ng-packs/packages/core/src/lib/tests/session-state.service.spec.ts
  13. 20
      npm/ng-packs/packages/feature-management/src/lib/tests/feature-management-state.service.spec.ts
  14. 20
      npm/ng-packs/packages/identity/src/lib/tests/identity-state.service.spec.ts
  15. 20
      npm/ng-packs/packages/permission-management/src/lib/tests/permission-management-state.service.spec.ts
  16. 20
      npm/ng-packs/packages/tenant-management/src/lib/tests/tenant-management-state.service.spec.ts
  17. 20
      npm/ng-packs/packages/theme-basic/src/lib/tests/layout-state.service.spec.ts
  18. 4
      npm/ng-packs/packages/theme-basic/src/lib/theme-basic.module.ts
  19. 31
      npm/ng-packs/packages/theme-shared/src/lib/components/change-password/change-password.component.html
  20. 113
      npm/ng-packs/packages/theme-shared/src/lib/components/change-password/change-password.component.ts
  21. 2
      npm/ng-packs/packages/theme-shared/src/lib/components/index.ts
  22. 41
      npm/ng-packs/packages/theme-shared/src/lib/components/profile/profile.component.html
  23. 81
      npm/ng-packs/packages/theme-shared/src/lib/components/profile/profile.component.ts
  24. 6
      npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
  25. 2
      samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain.Shared/BookStoreDomainSharedModule.cs
  26. 2
      samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/BookStoreDomainModule.cs
  27. 6
      samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.HttpApi.Host/BookStoreHttpApiHostModule.cs
  28. 2
      samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.MongoDB/MongoDb/BookStoreMongoDbModule.cs
  29. 2
      samples/BookStore-Modular/application/src/Acme.BookStore.Domain.Shared/BookStoreDomainSharedModule.cs
  30. 2
      samples/BookStore-Modular/application/src/Acme.BookStore.Domain/BookStoreDomainModule.cs
  31. 2
      samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs
  32. 2
      samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs
  33. 4
      samples/BookStore-Modular/application/src/Acme.BookStore.Web/BookStoreWebModule.cs
  34. 2
      samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.HttpApi.Host/BookManagementHttpApiHostModule.cs
  35. 2
      samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.HttpApi.Host/EntityFrameworkCore/MyProjectHttpApiHostMigrationsDbContextFactory.cs
  36. 2
      samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.IdentityServer/BookManagementIdentityServerModule.cs
  37. 2
      samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.IdentityServer/EntityFrameworkCore/IdentityServerHostMigrationsDbContextFactory.cs
  38. 10
      samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.Web.Host/BookManagementWebHostModule.cs
  39. 2
      samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.Web.Unified/EntityFrameworkCore/UnifiedDbContextFactory.cs
  40. 2
      samples/BookStore/src/Acme.BookStore.Domain.Shared/BookStoreDomainSharedModule.cs
  41. 2
      samples/BookStore/src/Acme.BookStore.Domain/BookStoreDomainModule.cs
  42. 2
      samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs
  43. 4
      samples/BookStore/src/Acme.BookStore.Web/BookStoreWebModule.cs
  44. 2
      samples/DashboardDemo/src/DashboardDemo.Domain.Shared/DashboardDemoDomainSharedModule.cs
  45. 2
      samples/DashboardDemo/src/DashboardDemo.Domain/DashboardDemoDomainModule.cs
  46. 2
      samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/DashboardDemoMigrationsDbContextFactory.cs
  47. 2
      samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoEntityFrameworkCoreModule.cs
  48. 4
      samples/DashboardDemo/src/DashboardDemo.Web/DashboardDemoWebModule.cs

2
abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json

@ -26,6 +26,6 @@
"ContributionGuide": "贡献指南", "ContributionGuide": "贡献指南",
"Blog": "博客", "Blog": "博客",
"Commercial": "商业版", "Commercial": "商业版",
"SeeDocuments": "见文档" "SeeDocuments": "查看文档"
} }
} }

8
abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json

@ -42,11 +42,11 @@
"BootstrapTagHelpersDynamicFormsExplanation": "内置的后台作业系统可以集成到Hangfire,RabbitMQ或您喜欢的任何工具中.", //TODO explanation doesn't match. "BootstrapTagHelpersDynamicFormsExplanation": "内置的后台作业系统可以集成到Hangfire,RabbitMQ或您喜欢的任何工具中.", //TODO explanation doesn't match.
"HTTPAPIsDynamicProxies": "HTTP APIs和动态代理", "HTTPAPIsDynamicProxies": "HTTP APIs和动态代理",
"HTTPAPIsDynamicProxiesExplanation": "自动将应用程序服务公开为REST样式的HTTP API,并与动态JavaScript和C#代理一起使用.", "HTTPAPIsDynamicProxiesExplanation": "自动将应用程序服务公开为REST样式的HTTP API,并与动态JavaScript和C#代理一起使用.",
"CompleteArchitectureInfo": "现代构架用来创建可维护的软件解决方案.", "CompleteArchitectureInfo": "现代架构用来创建可维护的软件解决方案.",
"DomainDrivenDesignBasedLayeringModelExplanation": "帮助你实现基于DDD的分层架构并构建可维护的代码库.", "DomainDrivenDesignBasedLayeringModelExplanation": "帮助你实现基于DDD的分层架构并构建可维护的代码库.",
"DomainDrivenDesignBasedLayeringModelExplanationCont": "提供启动模板,抽象,基类,服务,文档和指南以帮助你开发基于DDD模式和准则的应用程序.", "DomainDrivenDesignBasedLayeringModelExplanationCont": "提供启动模板,抽象,基类,服务,文档和指南以帮助你开发基于DDD模式和准则的应用程序.",
"MicroserviceCompatibleModelExplanation": "核心框架和预构建模块在设计时就考虑了微服务架构.", "MicroserviceCompatibleModelExplanation": "核心框架和预构建模块在设计时就考虑了微服务架构.",
"MicroserviceCompatibleModelExplanationCont": "提供基础结构,集成,示例和文档,以更轻松地实现微服务解决方案,而如果你要使用整体应用程序,则不会带来额外的复杂性.", "MicroserviceCompatibleModelExplanationCont": "提供基础结构,集成,示例和文档,以更轻松地实现微服务解决方案,而如果你要使用整体应用程序,也不会带来额外的复杂性.",
"ModularInfo": "ABP提供了完整的模块化系统,使你能够开发可重复使用的应用程序模块.", "ModularInfo": "ABP提供了完整的模块化系统,使你能够开发可重复使用的应用程序模块.",
"PreBuiltModulesThemes": "预构建模块和主题", "PreBuiltModulesThemes": "预构建模块和主题",
"PreBuiltModulesThemesExplanation": "开源和商业模块和主题已准备好在你的业务应用程序中使用.", "PreBuiltModulesThemesExplanation": "开源和商业模块和主题已准备好在你的业务应用程序中使用.",
@ -125,7 +125,7 @@
"DatabaseConnectionTransactionManagement": "数据库连接和事务管理", "DatabaseConnectionTransactionManagement": "数据库连接和事务管理",
"CorrelationIdTracking": "关联ID跟踪", "CorrelationIdTracking": "关联ID跟踪",
"BundlingMinificationExplanation": "ABP提供了一个简单,动态,功能强大,模块化的内置Bundling & Minification系统.", "BundlingMinificationExplanation": "ABP提供了一个简单,动态,功能强大,模块化的内置Bundling & Minification系统.",
"VirtualFileSystemnExplanation": "虚拟文件系统使管理文件系统(磁盘)上不存在的文件成为可能.它主要用于将(js,css,image,cshtml...)文件嵌入到程序集中,并在运行时像物理文件一样使用它们.", "VirtualFileSystemnExplanation": "虚拟文件系统使管理文件系统(磁盘)上不存在的文件成为可能.它主要用于将(js,css,image,cshtml...)文件嵌入到程序集中,并在运行时像物理文件一样使用它们.",
"ThemingExplanation": "主题系统允许通过基于最新的Bootstrap框架定义一组通用基础库和布局来独立开发应用程序和模块主题.", "ThemingExplanation": "主题系统允许通过基于最新的Bootstrap框架定义一组通用基础库和布局来独立开发应用程序和模块主题.",
"DomainDrivenDesignInfrastructureExplanation": "基于域驱动设计模式和准则构建分层应用程序的完整基础设施;", "DomainDrivenDesignInfrastructureExplanation": "基于域驱动设计模式和准则构建分层应用程序的完整基础设施;",
"Specification": "规范", "Specification": "规范",
@ -154,7 +154,7 @@
"Result": "结果", "Result": "结果",
"SeeTheDocumentForMoreInformation": "查看<a href=\"{1}\">{0} 文档</a>获得更多信息", "SeeTheDocumentForMoreInformation": "查看<a href=\"{1}\">{0} 文档</a>获得更多信息",
"IndexPageHeroSection": "<span class=\"third-line shine2\"><strong>asp.net core的</strong></span><span class=\"first-line shine\"><strong>开源</strong></span><span class=\"second-line text-uppercase\">Web应用程序<br />框架 </span>", "IndexPageHeroSection": "<span class=\"third-line shine2\"><strong>asp.net core的</strong></span><span class=\"first-line shine\"><strong>开源</strong></span><span class=\"second-line text-uppercase\">Web应用程序<br />框架 </span>",
"UiFramework": "UI构架", "UiFramework": "UI框架",
"EmailAddress": "电子邮件地址" "EmailAddress": "电子邮件地址"
} }
} }

2
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/zh-Hans.json

@ -27,7 +27,7 @@
"DisplayName:Email": "电子邮件", "DisplayName:Email": "电子邮件",
"DisplayName:Name": "名字", "DisplayName:Name": "名字",
"DisplayName:Surname": "姓", "DisplayName:Surname": "姓",
"DisplayName:Password": "姓", "DisplayName:Password": "密码",
"DisplayName:EmailAddress": "电子邮件地址", "DisplayName:EmailAddress": "电子邮件地址",
"DisplayName:PhoneNumber": "电话号码", "DisplayName:PhoneNumber": "电话号码",
"PersonalSettings": "个人设置", "PersonalSettings": "个人设置",

42
npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.ts

@ -1,8 +1,8 @@
import { ChangePassword } from '@abp/ng.core'; import { ChangePassword, ConfigState, ABP } from '@abp/ng.core';
import { ToasterService } from '@abp/ng.theme.shared'; import { ToasterService } from '@abp/ng.theme.shared';
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { comparePasswords, Validation } from '@ngx-validate/core'; import { comparePasswords, Validation, PasswordRules, validatePassword } from '@ngx-validate/core';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
import snq from 'snq'; import snq from 'snq';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
@ -29,11 +29,45 @@ export class ChangePasswordComponent implements OnInit {
constructor(private fb: FormBuilder, private store: Store, private toasterService: ToasterService) {} constructor(private fb: FormBuilder, private store: Store, private toasterService: ToasterService) {}
ngOnInit(): void { ngOnInit(): void {
const passwordRules: ABP.Dictionary<string> = this.store.selectSnapshot(
ConfigState.getSettings('Identity.Password'),
);
const passwordRulesArr = [] as PasswordRules;
let requiredLength = 1;
if ((passwordRules['Abp.Identity.Password.RequireDigit'] || '').toLowerCase() === 'true') {
passwordRulesArr.push('number');
}
if ((passwordRules['Abp.Identity.Password.RequireLowercase'] || '').toLowerCase() === 'true') {
passwordRulesArr.push('small');
}
if ((passwordRules['Abp.Identity.Password.RequireUppercase'] || '').toLowerCase() === 'true') {
passwordRulesArr.push('capital');
}
if (+(passwordRules['Abp.Identity.Password.RequiredUniqueChars'] || 0) > 0) {
passwordRulesArr.push('special');
}
if (Number.isInteger(+passwordRules['Abp.Identity.Password.RequiredLength'])) {
requiredLength = +passwordRules['Abp.Identity.Password.RequiredLength'];
}
this.form = this.fb.group( this.form = this.fb.group(
{ {
password: ['', required], password: ['', required],
newPassword: ['', required], newPassword: [
repeatNewPassword: ['', required], '',
{
validators: [required, validatePassword(passwordRulesArr), minLength(requiredLength)],
},
],
repeatNewPassword: [
'',
{ validators: [required, validatePassword(passwordRulesArr), minLength(requiredLength)] },
],
}, },
{ {
validators: [comparePasswords(PASSWORD_FIELDS)], validators: [comparePasswords(PASSWORD_FIELDS)],

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

@ -24,7 +24,7 @@ import { ConfigState } from './states/config.state';
import { ProfileState } from './states/profile.state'; import { ProfileState } from './states/profile.state';
import { SessionState } from './states/session.state'; import { SessionState } from './states/session.state';
import { getInitialData, localeInitializer } from './utils/initial-utils'; import { getInitialData, localeInitializer } from './utils/initial-utils';
import { ConfigPlugin, NGXS_CONFIG_PLUGIN_OPTIONS } from './plugins/config/config.plugin'; import { ConfigPlugin, NGXS_CONFIG_PLUGIN_OPTIONS } from './plugins/config.plugin';
import { ForDirective } from './directives/for.directive'; import { ForDirective } from './directives/for.directive';
import { AbstractNgModelComponent } from './abstracts/ng-model.component'; import { AbstractNgModelComponent } from './abstracts/ng-model.component';
import { TableSortDirective } from './directives/table-sort.directive'; import { TableSortDirective } from './directives/table-sort.directive';

4
npm/ng-packs/packages/core/src/lib/plugins/config/config.plugin.ts → npm/ng-packs/packages/core/src/lib/plugins/config.plugin.ts

@ -2,8 +2,8 @@ import { Inject, Injectable, InjectionToken } from '@angular/core';
import { Router, Routes } from '@angular/router'; import { Router, Routes } from '@angular/router';
import { actionMatcher, InitState, NgxsNextPluginFn, NgxsPlugin, setValue, UpdateState } from '@ngxs/store'; import { actionMatcher, InitState, NgxsNextPluginFn, NgxsPlugin, setValue, UpdateState } from '@ngxs/store';
import snq from 'snq'; import snq from 'snq';
import { ABP } from '../../models'; import { ABP } from '../models';
import { organizeRoutes, getAbpRoutes } from '../../utils/route-utils'; import { organizeRoutes, getAbpRoutes } from '../utils/route-utils';
import clone from 'just-clone'; import clone from 'just-clone';
export const NGXS_CONFIG_PLUGIN_OPTIONS = new InjectionToken('NGXS_CONFIG_PLUGIN_OPTIONS'); export const NGXS_CONFIG_PLUGIN_OPTIONS = new InjectionToken('NGXS_CONFIG_PLUGIN_OPTIONS');

2
npm/ng-packs/packages/core/src/lib/plugins/index.ts

@ -1 +1 @@
export * from './config/config.plugin'; export * from './config.plugin';

20
npm/ng-packs/packages/core/src/lib/tests/application-configuration.service.spec.ts

@ -0,0 +1,20 @@
import { createHttpFactory, HttpMethod, SpectatorHttp } from '@ngneat/spectator/jest';
import { ApplicationConfigurationService, RestService } from '../services';
import { Store } from '@ngxs/store';
describe('ApplicationConfigurationService', () => {
let spectator: SpectatorHttp<ApplicationConfigurationService>;
const createHttp = createHttpFactory({
dataService: ApplicationConfigurationService,
providers: [RestService],
mocks: [Store],
});
beforeEach(() => (spectator = createHttp()));
it('should send a GET to application-configuration API', () => {
spectator.get(Store).selectSnapshot.andReturn('https://abp.io');
spectator.service.getConfiguration().subscribe();
spectator.expectOne('https://abp.io/api/abp/application-configuration', HttpMethod.GET);
});
});

124
npm/ng-packs/packages/core/src/lib/tests/config-state.service.spec.ts

@ -1,14 +1,122 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
import { ConfigStateService } from '../services/config-state.service'; import { ConfigStateService } from '../services/config-state.service';
import { ConfigState } from '../states'; import { ConfigState } from '../states';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
import { Config } from '../models/config';
const CONFIG_STATE_DATA = {
environment: {
production: false,
application: {
name: 'MyProjectName',
},
oAuthConfig: {
issuer: 'https://localhost:44305',
},
apis: {
default: {
url: 'https://localhost:44305',
},
other: {
url: 'https://localhost:44306',
},
},
localization: {
defaultResourceName: 'MyProjectName',
},
},
requirements: {
layouts: [null, null, null],
},
routes: [
{
name: '::Menu:Home',
path: '',
children: [],
url: '/',
},
{
name: 'AbpAccount::Menu:Account',
path: 'account',
invisible: true,
layout: 'application',
children: [
{
path: 'login',
name: 'AbpAccount::Login',
order: 1,
url: '/account/login',
},
],
url: '/account',
},
],
flattedRoutes: [
{
name: '::Menu:Home',
path: '',
children: [],
url: '/',
},
{
name: '::Menu:Identity',
path: 'identity',
children: [],
url: '/identity',
},
],
localization: {
values: {
MyProjectName: {
"'{0}' and '{1}' do not match.": "'{0}' and '{1}' do not match.",
},
AbpIdentity: {
Identity: 'identity',
},
},
languages: [
{
cultureName: 'cs',
uiCultureName: 'cs',
displayName: 'Čeština',
flagIcon: null,
},
],
},
auth: {
policies: {
'AbpIdentity.Roles': true,
},
grantedPolicies: {
'Abp.Identity': false,
},
},
setting: {
values: {
'Abp.Localization.DefaultLanguage': 'en',
},
},
currentUser: {
isAuthenticated: false,
id: null,
tenantId: null,
userName: null,
},
features: {
values: {},
},
} as Config.State;
describe('ConfigStateService', () => { describe('ConfigStateService', () => {
let service: ConfigStateService; let service: ConfigStateService;
let spectator: SpectatorService<ConfigStateService>; let spectator: SpectatorService<ConfigStateService>;
let store: SpyObject<Store>;
const createService = createServiceFactory({ service: ConfigStateService, mocks: [Store] }); const createService = createServiceFactory({ service: ConfigStateService, mocks: [Store] });
beforeEach(() => { beforeEach(() => {
spectator = createService(); spectator = createService();
service = spectator.service; service = spectator.service;
store = spectator.get(Store);
}); });
test('should have the all ConfigState static methods', () => { test('should have the all ConfigState static methods', () => {
const reg = /(?<=static )(.*)(?=\()/gm; const reg = /(?<=static )(.*)(?=\()/gm;
@ -16,6 +124,20 @@ describe('ConfigStateService', () => {
.match(reg) .match(reg)
.forEach(fnName => { .forEach(fnName => {
expect(service[fnName]).toBeTruthy(); expect(service[fnName]).toBeTruthy();
const spy = jest.spyOn(store, 'selectSnapshot');
spy.mockClear();
const isDynamicSelector = ConfigState[fnName].name !== 'memoized';
if (isDynamicSelector) {
ConfigState[fnName] = jest.fn((...args) => args);
service[fnName]('test', 0, {});
expect(ConfigState[fnName]).toHaveBeenCalledWith('test', 0, {});
} else {
service[fnName]();
expect(spy).toHaveBeenCalledWith(ConfigState[fnName]);
}
}); });
}); });
}); });

19
npm/ng-packs/packages/core/src/lib/tests/profile-state.service.spec.ts

@ -1,14 +1,17 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
import { ProfileStateService } from '../services/profile-state.service'; import { ProfileStateService } from '../services/profile-state.service';
import { ProfileState } from '../states/profile.state'; import { ProfileState } from '../states/profile.state';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
describe('ProfileStateService', () => { describe('ProfileStateService', () => {
let service: ProfileStateService; let service: ProfileStateService;
let spectator: SpectatorService<ProfileStateService>; let spectator: SpectatorService<ProfileStateService>;
let store: SpyObject<Store>;
const createService = createServiceFactory({ service: ProfileStateService, mocks: [Store] }); const createService = createServiceFactory({ service: ProfileStateService, mocks: [Store] });
beforeEach(() => { beforeEach(() => {
spectator = createService(); spectator = createService();
service = spectator.service; service = spectator.service;
store = spectator.get(Store);
}); });
test('should have the all ProfileState static methods', () => { test('should have the all ProfileState static methods', () => {
const reg = /(?<=static )(.*)(?=\()/gm; const reg = /(?<=static )(.*)(?=\()/gm;
@ -16,6 +19,20 @@ describe('ProfileStateService', () => {
.match(reg) .match(reg)
.forEach(fnName => { .forEach(fnName => {
expect(service[fnName]).toBeTruthy(); expect(service[fnName]).toBeTruthy();
const spy = jest.spyOn(store, 'selectSnapshot');
spy.mockClear();
const isDynamicSelector = ProfileState[fnName].name !== 'memoized';
if (isDynamicSelector) {
ProfileState[fnName] = jest.fn((...args) => args);
service[fnName]('test', 0, {});
expect(ProfileState[fnName]).toHaveBeenCalledWith('test', 0, {});
} else {
service[fnName]();
expect(spy).toHaveBeenCalledWith(ProfileState[fnName]);
}
}); });
}); });
}); });

42
npm/ng-packs/packages/core/src/lib/tests/profile.service.spec.ts

@ -0,0 +1,42 @@
import { createHttpFactory, HttpMethod, SpectatorHttp } from '@ngneat/spectator/jest';
import { ProfileService, RestService } from '../services';
import { Store } from '@ngxs/store';
describe('ProfileService', () => {
let spectator: SpectatorHttp<ProfileService>;
const createHttp = createHttpFactory({
dataService: ProfileService,
providers: [RestService],
mocks: [Store],
});
beforeEach(() => (spectator = createHttp()));
it('should send a GET to my-profile API', () => {
spectator.get(Store).selectSnapshot.andReturn('https://abp.io');
spectator.service.get().subscribe();
spectator.expectOne('https://abp.io/api/identity/my-profile', HttpMethod.GET);
});
it('should send a POST to change-password API', () => {
const mock = { currentPassword: 'test', newPassword: 'test' };
spectator.get(Store).selectSnapshot.andReturn('https://abp.io');
spectator.service.changePassword(mock).subscribe();
const req = spectator.expectOne('https://abp.io/api/identity/my-profile/change-password', HttpMethod.POST);
expect(req.request.body).toEqual(mock);
});
it('should send a PUT to my-profile API', () => {
const mock = {
email: 'info@volosoft.com',
userName: 'admin',
name: 'John',
surname: 'Doe',
phoneNumber: '+123456',
};
spectator.get(Store).selectSnapshot.andReturn('https://abp.io');
spectator.service.update(mock).subscribe();
const req = spectator.expectOne('https://abp.io/api/identity/my-profile', HttpMethod.PUT);
expect(req.request.body).toEqual(mock);
});
});

19
npm/ng-packs/packages/core/src/lib/tests/session-state.service.spec.ts

@ -1,14 +1,17 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
import { SessionStateService } from '../services/session-state.service'; import { SessionStateService } from '../services/session-state.service';
import { SessionState } from '../states/session.state'; import { SessionState } from '../states/session.state';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
describe('SessionStateService', () => { describe('SessionStateService', () => {
let service: SessionStateService; let service: SessionStateService;
let spectator: SpectatorService<SessionStateService>; let spectator: SpectatorService<SessionStateService>;
let store: SpyObject<Store>;
const createService = createServiceFactory({ service: SessionStateService, mocks: [Store] }); const createService = createServiceFactory({ service: SessionStateService, mocks: [Store] });
beforeEach(() => { beforeEach(() => {
spectator = createService(); spectator = createService();
service = spectator.service; service = spectator.service;
store = spectator.get(Store);
}); });
test('should have the all SessionState static methods', () => { test('should have the all SessionState static methods', () => {
const reg = /(?<=static )(.*)(?=\()/gm; const reg = /(?<=static )(.*)(?=\()/gm;
@ -16,6 +19,20 @@ describe('SessionStateService', () => {
.match(reg) .match(reg)
.forEach(fnName => { .forEach(fnName => {
expect(service[fnName]).toBeTruthy(); expect(service[fnName]).toBeTruthy();
const spy = jest.spyOn(store, 'selectSnapshot');
spy.mockClear();
const isDynamicSelector = SessionState[fnName].name !== 'memoized';
if (isDynamicSelector) {
SessionState[fnName] = jest.fn((...args) => args);
service[fnName]('test', 0, {});
expect(SessionState[fnName]).toHaveBeenCalledWith('test', 0, {});
} else {
service[fnName]();
expect(spy).toHaveBeenCalledWith(SessionState[fnName]);
}
}); });
}); });
}); });

20
npm/ng-packs/packages/feature-management/src/lib/tests/feature-management-state.service.spec.ts

@ -1,4 +1,4 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
import { FeatureManagementStateService } from '../services/feature-management-state.service'; import { FeatureManagementStateService } from '../services/feature-management-state.service';
import { FeatureManagementState } from '../states'; import { FeatureManagementState } from '../states';
@ -6,17 +6,35 @@ import { FeatureManagementState } from '../states';
describe('FeatureManagementStateService', () => { describe('FeatureManagementStateService', () => {
let service: FeatureManagementStateService; let service: FeatureManagementStateService;
let spectator: SpectatorService<FeatureManagementStateService>; let spectator: SpectatorService<FeatureManagementStateService>;
let store: SpyObject<Store>;
const createService = createServiceFactory({ service: FeatureManagementStateService, mocks: [Store] }); const createService = createServiceFactory({ service: FeatureManagementStateService, mocks: [Store] });
beforeEach(() => { beforeEach(() => {
spectator = createService(); spectator = createService();
service = spectator.service; service = spectator.service;
store = spectator.get(Store);
}); });
test('should have the all FeatureManagementState static methods', () => { test('should have the all FeatureManagementState static methods', () => {
const reg = /(?<=static )(.*)(?=\()/gm; const reg = /(?<=static )(.*)(?=\()/gm;
FeatureManagementState.toString() FeatureManagementState.toString()
.match(reg) .match(reg)
.forEach(fnName => { .forEach(fnName => {
expect(service[fnName]).toBeTruthy(); expect(service[fnName]).toBeTruthy();
const spy = jest.spyOn(store, 'selectSnapshot');
spy.mockClear();
const isDynamicSelector = FeatureManagementState[fnName].name !== 'memoized';
if (isDynamicSelector) {
FeatureManagementState[fnName] = jest.fn((...args) => args);
service[fnName]('test', 0, {});
expect(FeatureManagementState[fnName]).toHaveBeenCalledWith('test', 0, {});
} else {
service[fnName]();
expect(spy).toHaveBeenCalledWith(FeatureManagementState[fnName]);
}
}); });
}); });
}); });

20
npm/ng-packs/packages/identity/src/lib/tests/identity-state.service.spec.ts

@ -1,21 +1,39 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
import { IdentityStateService } from '../services/identity-state.service'; import { IdentityStateService } from '../services/identity-state.service';
import { IdentityState } from '../states/identity.state'; import { IdentityState } from '../states/identity.state';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
describe('IdentityStateService', () => { describe('IdentityStateService', () => {
let service: IdentityStateService; let service: IdentityStateService;
let spectator: SpectatorService<IdentityStateService>; let spectator: SpectatorService<IdentityStateService>;
let store: SpyObject<Store>;
const createService = createServiceFactory({ service: IdentityStateService, mocks: [Store] }); const createService = createServiceFactory({ service: IdentityStateService, mocks: [Store] });
beforeEach(() => { beforeEach(() => {
spectator = createService(); spectator = createService();
service = spectator.service; service = spectator.service;
store = spectator.get(Store);
}); });
test('should have the all IdentityState static methods', () => { test('should have the all IdentityState static methods', () => {
const reg = /(?<=static )(.*)(?=\()/gm; const reg = /(?<=static )(.*)(?=\()/gm;
IdentityState.toString() IdentityState.toString()
.match(reg) .match(reg)
.forEach(fnName => { .forEach(fnName => {
expect(service[fnName]).toBeTruthy(); expect(service[fnName]).toBeTruthy();
const spy = jest.spyOn(store, 'selectSnapshot');
spy.mockClear();
const isDynamicSelector = IdentityState[fnName].name !== 'memoized';
if (isDynamicSelector) {
IdentityState[fnName] = jest.fn((...args) => args);
service[fnName]('test', 0, {});
expect(IdentityState[fnName]).toHaveBeenCalledWith('test', 0, {});
} else {
service[fnName]();
expect(spy).toHaveBeenCalledWith(IdentityState[fnName]);
}
}); });
}); });
}); });

20
npm/ng-packs/packages/permission-management/src/lib/tests/permission-management-state.service.spec.ts

@ -1,14 +1,18 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
import { PermissionManagementStateService } from '../services/permission-management-state.service'; import { PermissionManagementStateService } from '../services/permission-management-state.service';
import { PermissionManagementState } from '../states/permission-management.state'; import { PermissionManagementState } from '../states/permission-management.state';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
describe('PermissionManagementStateService', () => { describe('PermissionManagementStateService', () => {
let service: PermissionManagementStateService; let service: PermissionManagementStateService;
let spectator: SpectatorService<PermissionManagementStateService>; let spectator: SpectatorService<PermissionManagementStateService>;
let store: SpyObject<Store>;
const createService = createServiceFactory({ service: PermissionManagementStateService, mocks: [Store] }); const createService = createServiceFactory({ service: PermissionManagementStateService, mocks: [Store] });
beforeEach(() => { beforeEach(() => {
spectator = createService(); spectator = createService();
service = spectator.service; service = spectator.service;
store = spectator.get(Store);
}); });
test('should have the all PermissionManagementState static methods', () => { test('should have the all PermissionManagementState static methods', () => {
const reg = /(?<=static )(.*)(?=\()/gm; const reg = /(?<=static )(.*)(?=\()/gm;
@ -16,6 +20,20 @@ describe('PermissionManagementStateService', () => {
.match(reg) .match(reg)
.forEach(fnName => { .forEach(fnName => {
expect(service[fnName]).toBeTruthy(); expect(service[fnName]).toBeTruthy();
const spy = jest.spyOn(store, 'selectSnapshot');
spy.mockClear();
const isDynamicSelector = PermissionManagementState[fnName].name !== 'memoized';
if (isDynamicSelector) {
PermissionManagementState[fnName] = jest.fn((...args) => args);
service[fnName]('test', 0, {});
expect(PermissionManagementState[fnName]).toHaveBeenCalledWith('test', 0, {});
} else {
service[fnName]();
expect(spy).toHaveBeenCalledWith(PermissionManagementState[fnName]);
}
}); });
}); });
}); });

20
npm/ng-packs/packages/tenant-management/src/lib/tests/tenant-management-state.service.spec.ts

@ -1,21 +1,39 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
import { TenantManagementStateService } from '../services/tenant-management-state.service'; import { TenantManagementStateService } from '../services/tenant-management-state.service';
import { TenantManagementState } from '../states/tenant-management.state'; import { TenantManagementState } from '../states/tenant-management.state';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
describe('TenantManagementStateService', () => { describe('TenantManagementStateService', () => {
let service: TenantManagementStateService; let service: TenantManagementStateService;
let spectator: SpectatorService<TenantManagementStateService>; let spectator: SpectatorService<TenantManagementStateService>;
let store: SpyObject<Store>;
const createService = createServiceFactory({ service: TenantManagementStateService, mocks: [Store] }); const createService = createServiceFactory({ service: TenantManagementStateService, mocks: [Store] });
beforeEach(() => { beforeEach(() => {
spectator = createService(); spectator = createService();
service = spectator.service; service = spectator.service;
store = spectator.get(Store);
}); });
test('should have the all TenantManagementState static methods', () => { test('should have the all TenantManagementState static methods', () => {
const reg = /(?<=static )(.*)(?=\()/gm; const reg = /(?<=static )(.*)(?=\()/gm;
TenantManagementState.toString() TenantManagementState.toString()
.match(reg) .match(reg)
.forEach(fnName => { .forEach(fnName => {
expect(service[fnName]).toBeTruthy(); expect(service[fnName]).toBeTruthy();
const spy = jest.spyOn(store, 'selectSnapshot');
spy.mockClear();
const isDynamicSelector = TenantManagementState[fnName].name !== 'memoized';
if (isDynamicSelector) {
TenantManagementState[fnName] = jest.fn((...args) => args);
service[fnName]('test', 0, {});
expect(TenantManagementState[fnName]).toHaveBeenCalledWith('test', 0, {});
} else {
service[fnName]();
expect(spy).toHaveBeenCalledWith(TenantManagementState[fnName]);
}
}); });
}); });
}); });

20
npm/ng-packs/packages/theme-basic/src/lib/tests/layout-state.service.spec.ts

@ -1,21 +1,39 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
import { LayoutStateService } from '../services/layout-state.service'; import { LayoutStateService } from '../services/layout-state.service';
import { LayoutState } from '../states/layout.state'; import { LayoutState } from '../states/layout.state';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
describe('LayoutStateService', () => { describe('LayoutStateService', () => {
let service: LayoutStateService; let service: LayoutStateService;
let spectator: SpectatorService<LayoutStateService>; let spectator: SpectatorService<LayoutStateService>;
let store: SpyObject<Store>;
const createService = createServiceFactory({ service: LayoutStateService, mocks: [Store] }); const createService = createServiceFactory({ service: LayoutStateService, mocks: [Store] });
beforeEach(() => { beforeEach(() => {
spectator = createService(); spectator = createService();
service = spectator.service; service = spectator.service;
store = spectator.get(Store);
}); });
test('should have the all LayoutState static methods', () => { test('should have the all LayoutState static methods', () => {
const reg = /(?<=static )(.*)(?=\()/gm; const reg = /(?<=static )(.*)(?=\()/gm;
LayoutState.toString() LayoutState.toString()
.match(reg) .match(reg)
.forEach(fnName => { .forEach(fnName => {
expect(service[fnName]).toBeTruthy(); expect(service[fnName]).toBeTruthy();
const spy = jest.spyOn(store, 'selectSnapshot');
spy.mockClear();
const isDynamicSelector = LayoutState[fnName].name !== 'memoized';
if (isDynamicSelector) {
LayoutState[fnName] = jest.fn((...args) => args);
service[fnName]('test', 0, {});
expect(LayoutState[fnName]).toHaveBeenCalledWith('test', 0, {});
} else {
service[fnName]();
expect(spy).toHaveBeenCalledWith(LayoutState[fnName]);
}
}); });
}); });
}); });

4
npm/ng-packs/packages/theme-basic/src/lib/theme-basic.module.ts

@ -29,9 +29,9 @@ export const LAYOUTS = [ApplicationLayoutComponent, AccountLayoutComponent, Empt
blueprints: { blueprints: {
email: 'AbpAccount::ThisFieldIsNotAValidEmailAddress.', email: 'AbpAccount::ThisFieldIsNotAValidEmailAddress.',
max: 'AbpAccount::ThisFieldMustBeBetween{0}And{1}[{{ min }},{{ max }}]', max: 'AbpAccount::ThisFieldMustBeBetween{0}And{1}[{{ min }},{{ max }}]',
maxlength: 'AbpAccount::ThisFieldMustBeAStringWithAMaximumLengthOf{1}[{{ requiredLength }}]', maxlength: 'AbpAccount::ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthoOf{0}[{{ requiredLength }}]',
min: 'AbpAccount::ThisFieldMustBeBetween{0}And{1}[{{ min }},{{ max }}]', min: 'AbpAccount::ThisFieldMustBeBetween{0}And{1}[{{ min }},{{ max }}]',
minlength: 'AbpAccount::ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf[{{ min }},{{ max }}]', minlength: 'AbpAccount::ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}[{{ requiredLength }}]',
required: 'AbpAccount::ThisFieldIsRequired.', required: 'AbpAccount::ThisFieldIsRequired.',
passwordMismatch: 'AbpIdentity::Identity.PasswordConfirmationFailed', passwordMismatch: 'AbpIdentity::Identity.PasswordConfirmationFailed',
}, },

31
npm/ng-packs/packages/theme-shared/src/lib/components/change-password/change-password.component.html

@ -1,31 +0,0 @@
<abp-modal [(visible)]="visible" [busy]="modalBusy">
<ng-template #abpHeader>
<h4>{{ 'AbpIdentity::ChangePassword' | abpLocalization }}</h4>
</ng-template>
<ng-template #abpBody>
<form [formGroup]="form" (ngSubmit)="onSubmit()" [mapErrorsFn]="mapErrorsFn">
<div class="form-group">
<label for="current-password">{{ 'AbpIdentity::DisplayName:CurrentPassword' | abpLocalization }}</label
><span> * </span
><input type="password" id="current-password" class="form-control" formControlName="password" autofocus />
</div>
<div class="form-group">
<label for="new-password">{{ 'AbpIdentity::DisplayName:NewPassword' | abpLocalization }}</label
><span> * </span><input type="password" id="new-password" class="form-control" formControlName="newPassword" />
</div>
<div class="form-group">
<label for="confirm-new-password">{{ 'AbpIdentity::DisplayName:NewPasswordConfirm' | abpLocalization }}</label
><span> * </span
><input type="password" id="confirm-new-password" class="form-control" formControlName="repeatNewPassword" />
</div>
</form>
</ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary color-white" #abpClose>
{{ 'AbpIdentity::Cancel' | abpLocalization }}
</button>
<abp-button iconClass="fa fa-check" buttonClass="btn btn-primary color-white" (click)="onSubmit()">{{
'AbpIdentity::Save' | abpLocalization
}}</abp-button>
</ng-template>
</abp-modal>

113
npm/ng-packs/packages/theme-shared/src/lib/components/change-password/change-password.component.ts

@ -1,113 +0,0 @@
import { ChangePassword } from '@abp/ng.core';
import {
Component,
EventEmitter,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
TemplateRef,
ViewChild,
} from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { comparePasswords, Validation } from '@ngx-validate/core';
import { Store } from '@ngxs/store';
import snq from 'snq';
import { finalize } from 'rxjs/operators';
import { ToasterService } from '../../services/toaster.service';
const { minLength, required } = Validators;
const PASSWORD_FIELDS = ['newPassword', 'repeatNewPassword'];
@Component({
selector: 'abp-change-password',
templateUrl: './change-password.component.html',
})
export class ChangePasswordComponent implements OnInit, OnChanges {
protected _visible;
@Input()
get visible(): boolean {
return this._visible;
}
set visible(value: boolean) {
this._visible = value;
this.visibleChange.emit(value);
}
@Output() readonly visibleChange = new EventEmitter<boolean>();
@ViewChild('modalContent', { static: false })
modalContent: TemplateRef<any>;
form: FormGroup;
modalBusy = false;
mapErrorsFn: Validation.MapErrorsFn = (errors, groupErrors, control) => {
if (PASSWORD_FIELDS.indexOf(control.name) < 0) return errors;
return errors.concat(groupErrors.filter(({ key }) => key === 'passwordMismatch'));
};
constructor(private fb: FormBuilder, private store: Store, private toasterService: ToasterService) {}
ngOnInit(): void {
this.form = this.fb.group(
{
password: ['', required],
newPassword: ['', required],
repeatNewPassword: ['', required],
},
{
validators: [comparePasswords(PASSWORD_FIELDS)],
},
);
}
onSubmit() {
if (this.form.invalid) return;
this.modalBusy = true;
this.store
.dispatch(
new ChangePassword({
currentPassword: this.form.get('password').value,
newPassword: this.form.get('newPassword').value,
}),
)
.pipe(
finalize(() => {
this.modalBusy = false;
}),
)
.subscribe({
next: () => {
this.visible = false;
this.form.reset();
},
error: err => {
this.toasterService.error(snq(() => err.error.error.message, 'AbpAccount::DefaultErrorMessage'), 'Error', {
life: 7000,
});
},
});
}
openModal() {
this.visible = true;
}
ngOnChanges({ visible }: SimpleChanges): void {
if (!visible) return;
if (visible.currentValue) {
this.openModal();
} else if (visible.currentValue === false && this.visible) {
this.visible = false;
}
}
}

2
npm/ng-packs/packages/theme-shared/src/lib/components/index.ts

@ -1,11 +1,9 @@
export * from './breadcrumb/breadcrumb.component'; export * from './breadcrumb/breadcrumb.component';
export * from './button/button.component'; export * from './button/button.component';
export * from './change-password/change-password.component';
export * from './chart/chart.component'; export * from './chart/chart.component';
export * from './confirmation/confirmation.component'; export * from './confirmation/confirmation.component';
export * from './loader-bar/loader-bar.component'; export * from './loader-bar/loader-bar.component';
export * from './modal/modal.component'; export * from './modal/modal.component';
export * from './profile/profile.component';
export * from './table-empty-message/table-empty-message.component'; export * from './table-empty-message/table-empty-message.component';
export * from './toast/toast.component'; export * from './toast/toast.component';
export * from './sort-order-icon/sort-order-icon.component'; export * from './sort-order-icon/sort-order-icon.component';

41
npm/ng-packs/packages/theme-shared/src/lib/components/profile/profile.component.html

@ -1,41 +0,0 @@
<abp-modal [(visible)]="visible" [busy]="modalBusy">
<ng-template #abpHeader>
<h4>{{ 'AbpIdentity::PersonalInfo' | abpLocalization }}</h4>
</ng-template>
<ng-template #abpBody>
<form novalidate *ngIf="form" [formGroup]="form" (ngSubmit)="submit()">
<div class="form-group">
<label for="username">{{ 'AbpIdentity::DisplayName:UserName' | abpLocalization }}</label
><span> * </span><input type="text" id="username" class="form-control" formControlName="userName" autofocus />
</div>
<div class="row">
<div class="col col-md-6">
<div class="form-group">
<label for="name">{{ 'AbpIdentity::DisplayName:Name' | abpLocalization }}</label
><input type="text" id="name" class="form-control" formControlName="name" />
</div>
</div>
<div class="col col-md-6">
<div class="form-group">
<label for="surname">{{ 'AbpIdentity::DisplayName:Surname' | abpLocalization }}</label
><input type="text" id="surname" class="form-control" formControlName="surname" />
</div>
</div>
</div>
<div class="form-group">
<label for="email-address">{{ 'AbpIdentity::DisplayName:Email' | abpLocalization }}</label
><span> * </span><input type="text" id="email-address" class="form-control" formControlName="email" />
</div>
<div class="form-group">
<label for="phone-number">{{ 'AbpIdentity::DisplayName:PhoneNumber' | abpLocalization }}</label
><input type="text" id="phone-number" class="form-control" formControlName="phoneNumber" />
</div>
</form>
</ng-template>
<ng-template #abpFooter>
<button #abpClose type="button" class="btn btn-secondary color-white">
{{ 'AbpIdentity::Cancel' | abpLocalization }}
</button>
<abp-button iconClass="fa fa-check" buttonClass="btn btn-primary color-white" (click)="submit()">{{ 'AbpIdentity::Save' | abpLocalization }}</abp-button>
</ng-template>
</abp-modal>

81
npm/ng-packs/packages/theme-shared/src/lib/components/profile/profile.component.ts

@ -1,81 +0,0 @@
import { Profile, GetProfile, ProfileState, UpdateProfile } from '@abp/ng.core';
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { take, withLatestFrom } from 'rxjs/operators';
const { maxLength, required, email } = Validators;
@Component({
selector: 'abp-profile',
templateUrl: './profile.component.html'
})
export class ProfileComponent implements OnChanges {
protected _visible;
@Input()
get visible(): boolean {
return this._visible;
}
set visible(value: boolean) {
this._visible = value;
this.visibleChange.emit(value);
}
@Output() readonly visibleChange = new EventEmitter<boolean>();
@Select(ProfileState.getProfile)
profile$: Observable<Profile.Response>;
form: FormGroup;
modalBusy = false;
constructor(private fb: FormBuilder, private store: Store) {}
buildForm() {
this.store
.dispatch(new GetProfile())
.pipe(
withLatestFrom(this.profile$),
take(1)
)
.subscribe(([, profile]) => {
this.form = this.fb.group({
userName: [profile.userName, [required, maxLength(256)]],
email: [profile.email, [required, email, maxLength(256)]],
name: [profile.name || '', [maxLength(64)]],
surname: [profile.surname || '', [maxLength(64)]],
phoneNumber: [profile.phoneNumber || '', [maxLength(16)]]
});
});
}
submit() {
if (this.form.invalid) return;
this.modalBusy = true;
this.store.dispatch(new UpdateProfile(this.form.value)).subscribe(() => {
this.modalBusy = false;
this.visible = false;
this.form.reset();
});
}
openModal() {
this.buildForm();
this.visible = true;
}
ngOnChanges({ visible }: SimpleChanges): void {
if (!visible) return;
if (visible.currentValue) {
this.openModal();
} else if (visible.currentValue === false && this.visible) {
this.visible = false;
}
}
}

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

@ -6,13 +6,11 @@ import { forkJoin } from 'rxjs';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
import { BreadcrumbComponent } from './components/breadcrumb/breadcrumb.component'; import { BreadcrumbComponent } from './components/breadcrumb/breadcrumb.component';
import { ButtonComponent } from './components/button/button.component'; import { ButtonComponent } from './components/button/button.component';
import { ChangePasswordComponent } from './components/change-password/change-password.component';
import { ChartComponent } from './components/chart/chart.component'; import { ChartComponent } from './components/chart/chart.component';
import { ConfirmationComponent } from './components/confirmation/confirmation.component'; import { ConfirmationComponent } from './components/confirmation/confirmation.component';
import { ErrorComponent } from './components/error/error.component'; import { ErrorComponent } from './components/error/error.component';
import { LoaderBarComponent } from './components/loader-bar/loader-bar.component'; import { LoaderBarComponent } from './components/loader-bar/loader-bar.component';
import { ModalComponent } from './components/modal/modal.component'; import { ModalComponent } from './components/modal/modal.component';
import { ProfileComponent } from './components/profile/profile.component';
import { ToastComponent } from './components/toast/toast.component'; import { ToastComponent } from './components/toast/toast.component';
import { SortOrderIconComponent } from './components/sort-order-icon/sort-order-icon.component'; import { SortOrderIconComponent } from './components/sort-order-icon/sort-order-icon.component';
import styles from './contants/styles'; import styles from './contants/styles';
@ -46,13 +44,11 @@ export function appendScript(injector: Injector) {
declarations: [ declarations: [
BreadcrumbComponent, BreadcrumbComponent,
ButtonComponent, ButtonComponent,
ChangePasswordComponent,
ChartComponent, ChartComponent,
ConfirmationComponent, ConfirmationComponent,
ErrorComponent, ErrorComponent,
LoaderBarComponent, LoaderBarComponent,
ModalComponent, ModalComponent,
ProfileComponent,
TableEmptyMessageComponent, TableEmptyMessageComponent,
ToastComponent, ToastComponent,
SortOrderIconComponent, SortOrderIconComponent,
@ -60,12 +56,10 @@ export function appendScript(injector: Injector) {
exports: [ exports: [
BreadcrumbComponent, BreadcrumbComponent,
ButtonComponent, ButtonComponent,
ChangePasswordComponent,
ChartComponent, ChartComponent,
ConfirmationComponent, ConfirmationComponent,
LoaderBarComponent, LoaderBarComponent,
ModalComponent, ModalComponent,
ProfileComponent,
TableEmptyMessageComponent, TableEmptyMessageComponent,
ToastComponent, ToastComponent,
SortOrderIconComponent, SortOrderIconComponent,

2
samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain.Shared/BookStoreDomainSharedModule.cs

@ -16,7 +16,7 @@ namespace Acme.BookStore
{ {
[DependsOn( [DependsOn(
typeof(AbpAuditLoggingDomainSharedModule), typeof(AbpAuditLoggingDomainSharedModule),
typeof(BackgroundJobsDomainSharedModule), typeof(AbpBackgroundJobsDomainSharedModule),
typeof(AbpFeatureManagementDomainSharedModule), typeof(AbpFeatureManagementDomainSharedModule),
typeof(AbpIdentityDomainSharedModule), typeof(AbpIdentityDomainSharedModule),
typeof(AbpIdentityServerDomainSharedModule), typeof(AbpIdentityServerDomainSharedModule),

2
samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/BookStoreDomainModule.cs

@ -16,7 +16,7 @@ namespace Acme.BookStore
[DependsOn( [DependsOn(
typeof(BookStoreDomainSharedModule), typeof(BookStoreDomainSharedModule),
typeof(AbpAuditLoggingDomainModule), typeof(AbpAuditLoggingDomainModule),
typeof(BackgroundJobsDomainModule), typeof(AbpBackgroundJobsDomainModule),
typeof(AbpFeatureManagementDomainModule), typeof(AbpFeatureManagementDomainModule),
typeof(AbpIdentityDomainModule), typeof(AbpIdentityDomainModule),
typeof(AbpPermissionManagementDomainIdentityModule), typeof(AbpPermissionManagementDomainIdentityModule),

6
samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.HttpApi.Host/BookStoreHttpApiHostModule.cs

@ -54,7 +54,7 @@ namespace Acme.BookStore
ConfigureSwaggerServices(context); ConfigureSwaggerServices(context);
} }
private void ConfigureUrls(IConfigurationRoot configuration) private void ConfigureUrls(IConfiguration configuration)
{ {
Configure<AppUrlOptions>(options => Configure<AppUrlOptions>(options =>
{ {
@ -86,7 +86,7 @@ namespace Acme.BookStore
}); });
} }
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfigurationRoot configuration) private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{ {
context.Services.AddAuthentication() context.Services.AddAuthentication()
.AddIdentityServerAuthentication(options => .AddIdentityServerAuthentication(options =>
@ -123,7 +123,7 @@ namespace Acme.BookStore
}); });
} }
private void ConfigureCors(ServiceConfigurationContext context, IConfigurationRoot configuration) private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
{ {
context.Services.AddCors(options => context.Services.AddCors(options =>
{ {

2
samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.MongoDB/MongoDb/BookStoreMongoDbModule.cs

@ -17,7 +17,7 @@ namespace Acme.BookStore.MongoDB
typeof(AbpSettingManagementMongoDbModule), typeof(AbpSettingManagementMongoDbModule),
typeof(AbpIdentityMongoDbModule), typeof(AbpIdentityMongoDbModule),
typeof(AbpIdentityServerMongoDbModule), typeof(AbpIdentityServerMongoDbModule),
typeof(BackgroundJobsMongoDbModule), typeof(AbpBackgroundJobsMongoDbModule),
typeof(AbpAuditLoggingMongoDbModule), typeof(AbpAuditLoggingMongoDbModule),
typeof(AbpTenantManagementMongoDbModule), typeof(AbpTenantManagementMongoDbModule),
typeof(AbpFeatureManagementMongoDbModule) typeof(AbpFeatureManagementMongoDbModule)

2
samples/BookStore-Modular/application/src/Acme.BookStore.Domain.Shared/BookStoreDomainSharedModule.cs

@ -17,7 +17,7 @@ namespace Acme.BookStore
{ {
[DependsOn( [DependsOn(
typeof(AbpAuditLoggingDomainSharedModule), typeof(AbpAuditLoggingDomainSharedModule),
typeof(BackgroundJobsDomainSharedModule), typeof(AbpBackgroundJobsDomainSharedModule),
typeof(AbpFeatureManagementDomainSharedModule), typeof(AbpFeatureManagementDomainSharedModule),
typeof(AbpIdentityDomainSharedModule), typeof(AbpIdentityDomainSharedModule),
typeof(AbpIdentityServerDomainSharedModule), typeof(AbpIdentityServerDomainSharedModule),

2
samples/BookStore-Modular/application/src/Acme.BookStore.Domain/BookStoreDomainModule.cs

@ -17,7 +17,7 @@ namespace Acme.BookStore
[DependsOn( [DependsOn(
typeof(BookStoreDomainSharedModule), typeof(BookStoreDomainSharedModule),
typeof(AbpAuditLoggingDomainModule), typeof(AbpAuditLoggingDomainModule),
typeof(BackgroundJobsDomainModule), typeof(AbpBackgroundJobsDomainModule),
typeof(AbpFeatureManagementDomainModule), typeof(AbpFeatureManagementDomainModule),
typeof(AbpIdentityDomainModule), typeof(AbpIdentityDomainModule),
typeof(AbpPermissionManagementDomainIdentityModule), typeof(AbpPermissionManagementDomainIdentityModule),

2
samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/BookStoreMigrationsDbContextFactory.cs

@ -19,7 +19,7 @@ namespace Acme.BookStore.EntityFrameworkCore
return new BookStoreMigrationsDbContext(builder.Options); return new BookStoreMigrationsDbContext(builder.Options);
} }
private static IConfigurationRoot BuildConfiguration() private static IConfiguration BuildConfiguration()
{ {
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) .SetBasePath(Directory.GetCurrentDirectory())

2
samples/BookStore-Modular/application/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs

@ -21,7 +21,7 @@ namespace Acme.BookStore.EntityFrameworkCore
typeof(AbpPermissionManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule), typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpEntityFrameworkCoreSqlServerModule), typeof(AbpEntityFrameworkCoreSqlServerModule),
typeof(BackgroundJobsEntityFrameworkCoreModule), typeof(AbpBackgroundJobsEntityFrameworkCoreModule),
typeof(AbpAuditLoggingEntityFrameworkCoreModule), typeof(AbpAuditLoggingEntityFrameworkCoreModule),
typeof(AbpTenantManagementEntityFrameworkCoreModule), typeof(AbpTenantManagementEntityFrameworkCoreModule),
typeof(AbpFeatureManagementEntityFrameworkCoreModule), typeof(AbpFeatureManagementEntityFrameworkCoreModule),

4
samples/BookStore-Modular/application/src/Acme.BookStore.Web/BookStoreWebModule.cs

@ -82,7 +82,7 @@ namespace Acme.BookStore.Web
ConfigureSwaggerServices(context.Services); ConfigureSwaggerServices(context.Services);
} }
private void ConfigureUrls(IConfigurationRoot configuration) private void ConfigureUrls(IConfiguration configuration)
{ {
Configure<AppUrlOptions>(options => Configure<AppUrlOptions>(options =>
{ {
@ -90,7 +90,7 @@ namespace Acme.BookStore.Web
}); });
} }
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfigurationRoot configuration) private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{ {
context.Services.AddAuthentication() context.Services.AddAuthentication()
.AddIdentityServerAuthentication(options => .AddIdentityServerAuthentication(options =>

2
samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.HttpApi.Host/BookManagementHttpApiHostModule.cs

@ -89,7 +89,7 @@ namespace Acme.BookStore.BookManagement
options.ApiName = "BookManagement"; options.ApiName = "BookManagement";
}); });
Configure<AbpCacheOptions>(options => Configure<AbpDistributedCacheOptions>(options =>
{ {
options.KeyPrefix = "BookManagement:"; options.KeyPrefix = "BookManagement:";
}); });

2
samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.HttpApi.Host/EntityFrameworkCore/MyProjectHttpApiHostMigrationsDbContextFactory.cs

@ -17,7 +17,7 @@ namespace Acme.BookStore.BookManagement.EntityFrameworkCore
return new MyProjectHttpApiHostMigrationsDbContext(builder.Options); return new MyProjectHttpApiHostMigrationsDbContext(builder.Options);
} }
private static IConfigurationRoot BuildConfiguration() private static IConfiguration BuildConfiguration()
{ {
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) .SetBasePath(Directory.GetCurrentDirectory())

2
samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.IdentityServer/BookManagementIdentityServerModule.cs

@ -108,7 +108,7 @@ namespace Acme.BookStore.BookManagement
options.ApiName = configuration["AuthServer:ApiName"]; options.ApiName = configuration["AuthServer:ApiName"];
}); });
Configure<AbpCacheOptions>(options => Configure<AbpDistributedCacheOptions>(options =>
{ {
options.KeyPrefix = "BookManagement:"; options.KeyPrefix = "BookManagement:";
}); });

2
samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.IdentityServer/EntityFrameworkCore/IdentityServerHostMigrationsDbContextFactory.cs

@ -17,7 +17,7 @@ namespace Acme.BookStore.BookManagement.EntityFrameworkCore
return new IdentityServerHostMigrationsDbContext(builder.Options); return new IdentityServerHostMigrationsDbContext(builder.Options);
} }
private static IConfigurationRoot BuildConfiguration() private static IConfiguration BuildConfiguration()
{ {
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) .SetBasePath(Directory.GetCurrentDirectory())

10
samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.Web.Host/BookManagementWebHostModule.cs

@ -85,15 +85,15 @@ namespace Acme.BookStore.BookManagement
ConfigureRedis(context, configuration, hostingEnvironment); ConfigureRedis(context, configuration, hostingEnvironment);
} }
private void ConfigureCache(IConfigurationRoot configuration) private void ConfigureCache(IConfiguration configuration)
{ {
Configure<AbpCacheOptions>(options => Configure<AbpDistributedCacheOptions>(options =>
{ {
options.KeyPrefix = "BookManagement:"; options.KeyPrefix = "BookManagement:";
}); });
} }
private void ConfigureUrls(IConfigurationRoot configuration) private void ConfigureUrls(IConfiguration configuration)
{ {
Configure<AppUrlOptions>(options => Configure<AppUrlOptions>(options =>
{ {
@ -109,7 +109,7 @@ namespace Acme.BookStore.BookManagement
}); });
} }
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfigurationRoot configuration) private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{ {
context.Services.AddAuthentication(options => context.Services.AddAuthentication(options =>
{ {
@ -177,7 +177,7 @@ namespace Acme.BookStore.BookManagement
private void ConfigureRedis( private void ConfigureRedis(
ServiceConfigurationContext context, ServiceConfigurationContext context,
IConfigurationRoot configuration, IConfiguration configuration,
IWebHostEnvironment hostingEnvironment) IWebHostEnvironment hostingEnvironment)
{ {
context.Services.AddStackExchangeRedisCache(options => context.Services.AddStackExchangeRedisCache(options =>

2
samples/BookStore-Modular/modules/book-management/host/Acme.BookStore.BookManagement.Web.Unified/EntityFrameworkCore/UnifiedDbContextFactory.cs

@ -17,7 +17,7 @@ namespace Acme.BookStore.BookManagement.EntityFrameworkCore
return new UnifiedDbContext(builder.Options); return new UnifiedDbContext(builder.Options);
} }
private static IConfigurationRoot BuildConfiguration() private static IConfiguration BuildConfiguration()
{ {
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) .SetBasePath(Directory.GetCurrentDirectory())

2
samples/BookStore/src/Acme.BookStore.Domain.Shared/BookStoreDomainSharedModule.cs

@ -16,7 +16,7 @@ namespace Acme.BookStore
{ {
[DependsOn( [DependsOn(
typeof(AbpAuditLoggingDomainSharedModule), typeof(AbpAuditLoggingDomainSharedModule),
typeof(BackgroundJobsDomainSharedModule), typeof(AbpBackgroundJobsDomainSharedModule),
typeof(AbpFeatureManagementDomainSharedModule), typeof(AbpFeatureManagementDomainSharedModule),
typeof(AbpIdentityDomainSharedModule), typeof(AbpIdentityDomainSharedModule),
typeof(AbpIdentityServerDomainSharedModule), typeof(AbpIdentityServerDomainSharedModule),

2
samples/BookStore/src/Acme.BookStore.Domain/BookStoreDomainModule.cs

@ -16,7 +16,7 @@ namespace Acme.BookStore
[DependsOn( [DependsOn(
typeof(BookStoreDomainSharedModule), typeof(BookStoreDomainSharedModule),
typeof(AbpAuditLoggingDomainModule), typeof(AbpAuditLoggingDomainModule),
typeof(BackgroundJobsDomainModule), typeof(AbpBackgroundJobsDomainModule),
typeof(AbpFeatureManagementDomainModule), typeof(AbpFeatureManagementDomainModule),
typeof(AbpIdentityDomainModule), typeof(AbpIdentityDomainModule),
typeof(AbpPermissionManagementDomainIdentityModule), typeof(AbpPermissionManagementDomainIdentityModule),

2
samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreEntityFrameworkCoreModule.cs

@ -20,7 +20,7 @@ namespace Acme.BookStore.EntityFrameworkCore
typeof(AbpPermissionManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule), typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpEntityFrameworkCoreSqlServerModule), typeof(AbpEntityFrameworkCoreSqlServerModule),
typeof(BackgroundJobsEntityFrameworkCoreModule), typeof(AbpBackgroundJobsEntityFrameworkCoreModule),
typeof(AbpAuditLoggingEntityFrameworkCoreModule), typeof(AbpAuditLoggingEntityFrameworkCoreModule),
typeof(AbpTenantManagementEntityFrameworkCoreModule), typeof(AbpTenantManagementEntityFrameworkCoreModule),
typeof(AbpFeatureManagementEntityFrameworkCoreModule) typeof(AbpFeatureManagementEntityFrameworkCoreModule)

4
samples/BookStore/src/Acme.BookStore.Web/BookStoreWebModule.cs

@ -73,7 +73,7 @@ namespace Acme.BookStore.Web
ConfigureSwaggerServices(context.Services); ConfigureSwaggerServices(context.Services);
} }
private void ConfigureUrls(IConfigurationRoot configuration) private void ConfigureUrls(IConfiguration configuration)
{ {
Configure<AppUrlOptions>(options => Configure<AppUrlOptions>(options =>
{ {
@ -81,7 +81,7 @@ namespace Acme.BookStore.Web
}); });
} }
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfigurationRoot configuration) private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{ {
context.Services.AddAuthentication() context.Services.AddAuthentication()
.AddIdentityServerAuthentication(options => .AddIdentityServerAuthentication(options =>

2
samples/DashboardDemo/src/DashboardDemo.Domain.Shared/DashboardDemoDomainSharedModule.cs

@ -16,7 +16,7 @@ namespace DashboardDemo
{ {
[DependsOn( [DependsOn(
typeof(AbpAuditLoggingDomainSharedModule), typeof(AbpAuditLoggingDomainSharedModule),
typeof(BackgroundJobsDomainSharedModule), typeof(AbpBackgroundJobsDomainSharedModule),
typeof(AbpFeatureManagementDomainSharedModule), typeof(AbpFeatureManagementDomainSharedModule),
typeof(AbpIdentityDomainSharedModule), typeof(AbpIdentityDomainSharedModule),
typeof(AbpIdentityServerDomainSharedModule), typeof(AbpIdentityServerDomainSharedModule),

2
samples/DashboardDemo/src/DashboardDemo.Domain/DashboardDemoDomainModule.cs

@ -16,7 +16,7 @@ namespace DashboardDemo
[DependsOn( [DependsOn(
typeof(DashboardDemoDomainSharedModule), typeof(DashboardDemoDomainSharedModule),
typeof(AbpAuditLoggingDomainModule), typeof(AbpAuditLoggingDomainModule),
typeof(BackgroundJobsDomainModule), typeof(AbpBackgroundJobsDomainModule),
typeof(AbpFeatureManagementDomainModule), typeof(AbpFeatureManagementDomainModule),
typeof(AbpIdentityDomainModule), typeof(AbpIdentityDomainModule),
typeof(AbpPermissionManagementDomainIdentityModule), typeof(AbpPermissionManagementDomainIdentityModule),

2
samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/DashboardDemoMigrationsDbContextFactory.cs

@ -19,7 +19,7 @@ namespace DashboardDemo.EntityFrameworkCore
return new DashboardDemoMigrationsDbContext(builder.Options); return new DashboardDemoMigrationsDbContext(builder.Options);
} }
private static IConfigurationRoot BuildConfiguration() private static IConfiguration BuildConfiguration()
{ {
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) .SetBasePath(Directory.GetCurrentDirectory())

2
samples/DashboardDemo/src/DashboardDemo.EntityFrameworkCore/EntityFrameworkCore/DashboardDemoEntityFrameworkCoreModule.cs

@ -20,7 +20,7 @@ namespace DashboardDemo.EntityFrameworkCore
typeof(AbpPermissionManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule), typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpEntityFrameworkCoreSqlServerModule), typeof(AbpEntityFrameworkCoreSqlServerModule),
typeof(BackgroundJobsEntityFrameworkCoreModule), typeof(AbpBackgroundJobsEntityFrameworkCoreModule),
typeof(AbpAuditLoggingEntityFrameworkCoreModule), typeof(AbpAuditLoggingEntityFrameworkCoreModule),
typeof(AbpTenantManagementEntityFrameworkCoreModule), typeof(AbpTenantManagementEntityFrameworkCoreModule),
typeof(AbpFeatureManagementEntityFrameworkCoreModule) typeof(AbpFeatureManagementEntityFrameworkCoreModule)

4
samples/DashboardDemo/src/DashboardDemo.Web/DashboardDemoWebModule.cs

@ -79,7 +79,7 @@ namespace DashboardDemo.Web
ConfigureSwaggerServices(context.Services); ConfigureSwaggerServices(context.Services);
} }
private void ConfigureUrls(IConfigurationRoot configuration) private void ConfigureUrls(IConfiguration configuration)
{ {
Configure<AppUrlOptions>(options => Configure<AppUrlOptions>(options =>
{ {
@ -87,7 +87,7 @@ namespace DashboardDemo.Web
}); });
} }
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfigurationRoot configuration) private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{ {
context.Services.AddAuthentication() context.Services.AddAuthentication()
.AddIdentityServerAuthentication(options => .AddIdentityServerAuthentication(options =>

Loading…
Cancel
Save