From 6b47e1a866c64e9afe859e001bdc83d3f5bde176 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Wed, 14 Jun 2023 17:27:00 +0300 Subject: [PATCH 001/165] Move constant, split error handler to functions --- .../theme-shared/src/lib/constants/error.ts | 45 +++++++ .../src/lib/handlers/error.handler.ts | 110 ++---------------- .../can-create-custom-error.service.ts | 18 +++ .../create-error-component.service.ts | 89 ++++++++++++++ .../packages/theme-shared/src/public-api.ts | 1 + 5 files changed, 163 insertions(+), 100 deletions(-) create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/constants/error.ts create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts diff --git a/npm/ng-packs/packages/theme-shared/src/lib/constants/error.ts b/npm/ng-packs/packages/theme-shared/src/lib/constants/error.ts new file mode 100644 index 0000000000..9ed1c93202 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/constants/error.ts @@ -0,0 +1,45 @@ +export const DEFAULT_ERROR_MESSAGES = { + defaultError: { + title: 'An error has occurred!', + details: 'Error detail not sent by server.', + }, + defaultError401: { + title: 'You are not authenticated!', + details: 'You should be authenticated (sign in) in order to perform this operation.', + }, + defaultError403: { + title: 'You are not authorized!', + details: 'You are not allowed to perform this operation.', + }, + defaultError404: { + title: 'Resource not found!', + details: 'The resource requested could not found on the server.', + }, + defaultError500: { + title: 'Internal server error', + details: 'Error detail not sent by server.', + }, +}; + +export const DEFAULT_ERROR_LOCALIZATIONS = { + defaultError: { + title: 'AbpUi::DefaultErrorMessage', + details: 'AbpUi::DefaultErrorMessageDetail', + }, + defaultError401: { + title: 'AbpUi::DefaultErrorMessage401', + details: 'AbpUi::DefaultErrorMessage401Detail', + }, + defaultError403: { + title: 'AbpUi::DefaultErrorMessage403', + details: 'AbpUi::DefaultErrorMessage403Detail', + }, + defaultError404: { + title: 'AbpUi::DefaultErrorMessage404', + details: 'AbpUi::DefaultErrorMessage404Detail', + }, + defaultError500: { + title: 'AbpUi::500Message', + details: 'AbpUi::DefaultErrorMessage', + }, +}; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts index cc7f733798..7a2736be78 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts @@ -7,10 +7,9 @@ } from '@abp/ng.core'; import { HttpErrorResponse } from '@angular/common/http'; import { - ApplicationRef, ComponentFactoryResolver, ComponentRef, - EmbeddedViewRef, + inject, Injectable, Injector, RendererFactory2, @@ -23,57 +22,12 @@ import { ErrorScreenErrorCodes, HttpErrorConfig } from '../models/common'; import { Confirmation } from '../models/confirmation'; import { ConfirmationService } from '../services/confirmation.service'; import { HTTP_ERROR_HANDLER } from '../tokens/http-error.token'; - -export const DEFAULT_ERROR_MESSAGES = { - defaultError: { - title: 'An error has occurred!', - details: 'Error detail not sent by server.', - }, - defaultError401: { - title: 'You are not authenticated!', - details: 'You should be authenticated (sign in) in order to perform this operation.', - }, - defaultError403: { - title: 'You are not authorized!', - details: 'You are not allowed to perform this operation.', - }, - defaultError404: { - title: 'Resource not found!', - details: 'The resource requested could not found on the server.', - }, - defaultError500: { - title: 'Internal server error', - details: 'Error detail not sent by server.', - }, -}; - -export const DEFAULT_ERROR_LOCALIZATIONS = { - defaultError: { - title: 'AbpUi::DefaultErrorMessage', - details: 'AbpUi::DefaultErrorMessageDetail', - }, - defaultError401: { - title: 'AbpUi::DefaultErrorMessage401', - details: 'AbpUi::DefaultErrorMessage401Detail', - }, - defaultError403: { - title: 'AbpUi::DefaultErrorMessage403', - details: 'AbpUi::DefaultErrorMessage403Detail', - }, - defaultError404: { - title: 'AbpUi::DefaultErrorMessage404', - details: 'AbpUi::DefaultErrorMessage404Detail', - }, - defaultError500: { - title: 'AbpUi::500Message', - details: 'AbpUi::DefaultErrorMessage', - }, -}; +import { CreateErrorComponentService } from '../services/create-error-component.service'; +import { CanCreateCustomErrorService } from '../services/can-create-custom-error.service'; +import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/error'; @Injectable({ providedIn: 'root' }) export class ErrorHandler { - componentRef: ComponentRef | null = null; - protected httpErrorHandler = this.injector.get(HTTP_ERROR_HANDLER, (_, err: HttpErrorResponse) => throwError(err), ); @@ -88,6 +42,8 @@ export class ErrorHandler { private authService: AuthService; + private createErrorComponentService = inject(CreateErrorComponentService); + private canCreateCustomErrorService = inject(CanCreateCustomErrorService); constructor(protected injector: Injector) { this.httpErrorReporter = injector.get(HttpErrorReporterService); this.routerEvents = injector.get(RouterEvents); @@ -100,7 +56,6 @@ export class ErrorHandler { this.listenToRestError(); this.listenToRouterError(); - this.listenToRouterDataResolved(); } protected listenToRouterError() { @@ -110,16 +65,6 @@ export class ErrorHandler { .subscribe(() => this.show404Page()); } - protected listenToRouterDataResolved() { - this.routerEvents - .getEvents(ResolveEnd) - .pipe(filter(() => !!this.componentRef)) - .subscribe(() => { - this.componentRef?.destroy(); - this.componentRef = null; - }); - } - protected listenToRestError() { this.httpErrorReporter.reporter$ .pipe(filter(this.filterRestErrors), switchMap(this.executeErrorHandler)) @@ -151,7 +96,8 @@ export class ErrorHandler { return; } - if (err instanceof HttpErrorResponse && err.headers.get('_AbpErrorFormat')) { + const isAbpErrorFormat = err.headers.get('_AbpErrorFormat'); + if (err instanceof HttpErrorResponse && isAbpErrorFormat) { const confirmation$ = this.showErrorWithRequestBody(body); if (err.status === 401) { @@ -302,47 +248,11 @@ export class ErrorHandler { } createErrorComponent(instance: Partial) { - const renderer = this.rendererFactory.createRenderer(null, null); - const host = renderer.selectRootElement(document.body, true); - - this.componentRef = this.cfRes - .resolveComponentFactory(HttpErrorWrapperComponent) - .create(this.injector); - - for (const key in instance) { - /* istanbul ignore else */ - if (Object.prototype.hasOwnProperty.call(this.componentRef.instance, key)) { - (this.componentRef.instance as any)[key] = (instance as any)[key]; - } - } - - this.componentRef.instance.hideCloseIcon = !!this.httpErrorConfig.errorScreen?.hideCloseIcon; - const appRef = this.injector.get(ApplicationRef); - - if (this.canCreateCustomError(instance.status as ErrorScreenErrorCodes)) { - this.componentRef.instance.cfRes = this.cfRes; - this.componentRef.instance.appRef = appRef; - this.componentRef.instance.injector = this.injector; - this.componentRef.instance.customComponent = this.httpErrorConfig.errorScreen?.component; - } - - appRef.attachView(this.componentRef.hostView); - renderer.appendChild(host, (this.componentRef.hostView as EmbeddedViewRef).rootNodes[0]); - - const destroy$ = new Subject(); - this.componentRef.instance.destroy$ = destroy$; - destroy$.subscribe(() => { - this.componentRef?.destroy(); - this.componentRef = null; - }); + this.createErrorComponentService.execute(instance); } canCreateCustomError(status: ErrorScreenErrorCodes): boolean { - return !!( - this.httpErrorConfig?.errorScreen?.component && - this.httpErrorConfig?.errorScreen?.forWhichErrors && - this.httpErrorConfig?.errorScreen?.forWhichErrors.indexOf(status) > -1 - ); + return this.canCreateCustomErrorService.execute(status); } protected filterRestErrors = ({ status }: HttpErrorResponse): boolean => { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts new file mode 100644 index 0000000000..7ce1a39262 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts @@ -0,0 +1,18 @@ +import { inject, Injectable } from '@angular/core'; +import { ErrorScreenErrorCodes } from '../models/common'; +import { HTTP_ERROR_CONFIG } from '@abp/ng.theme.shared'; + +@Injectable({ + providedIn: 'root', +}) +export class CanCreateCustomErrorService { + private httpErrorConfig = inject(HTTP_ERROR_CONFIG); + + execute(status: ErrorScreenErrorCodes): boolean { + return !!( + this.httpErrorConfig?.errorScreen?.component && + this.httpErrorConfig?.errorScreen?.forWhichErrors && + this.httpErrorConfig?.errorScreen?.forWhichErrors.indexOf(status) > -1 + ); + } +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts new file mode 100644 index 0000000000..1ca37d2073 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts @@ -0,0 +1,89 @@ +import { + ApplicationRef, + ComponentFactoryResolver, + ComponentRef, + EmbeddedViewRef, + inject, + Injectable, + Injector, + RendererFactory2, +} from '@angular/core'; +import { + ErrorScreenErrorCodes, + HTTP_ERROR_CONFIG, + HttpErrorWrapperComponent, +} from '@abp/ng.theme.shared'; +import { Subject } from 'rxjs'; +import { ResolveEnd } from '@angular/router'; +import { filter } from 'rxjs/operators'; +import { RouterEvents } from '@abp/ng.core'; +import { CanCreateCustomErrorService } from './can-create-custom-error.service'; + +@Injectable({ providedIn: 'root' }) +export class CreateErrorComponentService { + protected rendererFactory = inject(RendererFactory2); + protected cfRes = inject(ComponentFactoryResolver); + private routerEvents = inject(RouterEvents); + private injector = inject(Injector); + private canCreateCustomErrorService = inject(CanCreateCustomErrorService); + private httpErrorConfig = inject(HTTP_ERROR_CONFIG); + + componentRef: ComponentRef | null = null; + + protected getErrorHostElement() { + return document.body; + } + + constructor() { + this.listenToRouterDataResolved(); + } + protected listenToRouterDataResolved() { + this.routerEvents + .getEvents(ResolveEnd) + .pipe(filter(() => !!this.componentRef)) + .subscribe(() => { + this.componentRef?.destroy(); + this.componentRef = null; + }); + } + + private isCloseIconHidden() { + return !!this.httpErrorConfig.errorScreen?.hideCloseIcon; + } + execute(instance: Partial) { + const renderer = this.rendererFactory.createRenderer(null, null); + const hostElement = this.getErrorHostElement(); + const host = renderer.selectRootElement(hostElement, true); + + this.componentRef = this.cfRes + .resolveComponentFactory(HttpErrorWrapperComponent) + .create(this.injector); + + for (const key in instance) { + /* istanbul ignore else */ + if (Object.prototype.hasOwnProperty.call(this.componentRef.instance, key)) { + (this.componentRef.instance as any)[key] = (instance as any)[key]; + } + } + + this.componentRef.instance.hideCloseIcon = this.isCloseIconHidden(); + const appRef = this.injector.get(ApplicationRef); + + if (this.canCreateCustomErrorService.execute(instance.status as ErrorScreenErrorCodes)) { + this.componentRef.instance.cfRes = this.cfRes; + this.componentRef.instance.appRef = appRef; + this.componentRef.instance.injector = this.injector; + this.componentRef.instance.customComponent = this.httpErrorConfig.errorScreen?.component; + } + + appRef.attachView(this.componentRef.hostView); + renderer.appendChild(host, (this.componentRef.hostView as EmbeddedViewRef).rootNodes[0]); + + const destroy$ = new Subject(); + this.componentRef.instance.destroy$ = destroy$; + destroy$.subscribe(() => { + this.componentRef?.destroy(); + this.componentRef = null; + }); + } +} diff --git a/npm/ng-packs/packages/theme-shared/src/public-api.ts b/npm/ng-packs/packages/theme-shared/src/public-api.ts index 56cd9936a7..840463a70f 100644 --- a/npm/ng-packs/packages/theme-shared/src/public-api.ts +++ b/npm/ng-packs/packages/theme-shared/src/public-api.ts @@ -5,6 +5,7 @@ export * from './lib/animations'; export * from './lib/components'; export * from './lib/constants/validation'; +export * from './lib/constants/error'; export * from './lib/directives'; export * from './lib/enums'; export * from './lib/handlers'; From d402ad2ea837cdceb04c7075291e1f75dc537292 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Thu, 15 Jun 2023 19:49:01 +0300 Subject: [PATCH 002/165] Move constant, split error handler to little services --- .../theme-shared/src/lib/constants/error.ts | 8 + .../src/lib/handlers/error.handler.ts | 236 +++--------------- .../theme-shared/src/lib/models/common.ts | 6 + .../lib/providers/error-handlers.provider.ts | 29 +++ .../theme-shared/src/lib/providers/index.ts | 1 + .../abp-format-error-handler.service.ts | 41 +++ .../can-create-custom-error.service.ts | 2 +- .../create-error-component.service.ts | 8 +- .../theme-shared/src/lib/services/index.ts | 7 + .../services/router-error-handler.service.ts | 41 +++ .../status-code-error-handler.service.ts | 102 ++++++++ .../tenant-resolve-error-handler.service.ts | 22 ++ ...known-status-code-error-handler.service.ts | 35 +++ .../src/lib/theme-shared.module.ts | 10 +- .../src/lib/tokens/http-error.token.ts | 6 +- .../theme-shared/src/lib/utils/error.utils.ts | 26 ++ .../theme-shared/src/lib/utils/index.ts | 1 + 17 files changed, 367 insertions(+), 214 deletions(-) create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/providers/error-handlers.provider.ts create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/services/abp-format-error-handler.service.ts create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/services/unknown-status-code-error-handler.service.ts create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/utils/error.utils.ts diff --git a/npm/ng-packs/packages/theme-shared/src/lib/constants/error.ts b/npm/ng-packs/packages/theme-shared/src/lib/constants/error.ts index 9ed1c93202..3b92ce0e7b 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/constants/error.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/constants/error.ts @@ -43,3 +43,11 @@ export const DEFAULT_ERROR_LOCALIZATIONS = { details: 'AbpUi::DefaultErrorMessage', }, }; + +export const CUSTOM_HTTP_ERROR_HANDLER_PRIORITY = Object.freeze({ + veryLow: -9, + low: -9, + normal: 0, + high: 9, + veryHigh: 99, +}); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts index 7a2736be78..721f5069a5 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts @@ -1,68 +1,40 @@ - import { - AuthService, - HttpErrorReporterService, - LocalizationParam, - RouterEvents, - SessionStateService, -} from '@abp/ng.core'; +import { AuthService, HttpErrorReporterService } from '@abp/ng.core'; import { HttpErrorResponse } from '@angular/common/http'; -import { - ComponentFactoryResolver, - ComponentRef, - inject, - Injectable, - Injector, - RendererFactory2, -} from '@angular/core'; -import { NavigationError, ResolveEnd } from '@angular/router'; -import { Observable, of, Subject, throwError } from 'rxjs'; +import { inject, Injectable, Injector } from '@angular/core'; +import { Observable, of, throwError } from 'rxjs'; import { catchError, filter, switchMap } from 'rxjs/operators'; import { HttpErrorWrapperComponent } from '../components/http-error-wrapper/http-error-wrapper.component'; -import { ErrorScreenErrorCodes, HttpErrorConfig } from '../models/common'; +import { CustomHttpErrorHandlerService, HttpErrorConfig } from '../models/common'; import { Confirmation } from '../models/confirmation'; import { ConfirmationService } from '../services/confirmation.service'; -import { HTTP_ERROR_HANDLER } from '../tokens/http-error.token'; +import { CUSTOM_ERROR_HANDLERS, HTTP_ERROR_HANDLER } from '../tokens/http-error.token'; import { CreateErrorComponentService } from '../services/create-error-component.service'; -import { CanCreateCustomErrorService } from '../services/can-create-custom-error.service'; import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/error'; +import { RouterErrorHandlerService } from '../services/router-error-handler.service'; @Injectable({ providedIn: 'root' }) export class ErrorHandler { protected httpErrorHandler = this.injector.get(HTTP_ERROR_HANDLER, (_, err: HttpErrorResponse) => throwError(err), ); - protected httpErrorReporter: HttpErrorReporterService; - protected routerEvents: RouterEvents; protected confirmationService: ConfirmationService; - protected cfRes: ComponentFactoryResolver; - protected rendererFactory: RendererFactory2; protected httpErrorConfig: HttpErrorConfig; - protected sessionStateService: SessionStateService; - private authService: AuthService; - private createErrorComponentService = inject(CreateErrorComponentService); - private canCreateCustomErrorService = inject(CanCreateCustomErrorService); + private customErrorHandlers = inject(CUSTOM_ERROR_HANDLERS); + private routerErrorHandlerService = inject(RouterErrorHandlerService); + constructor(protected injector: Injector) { this.httpErrorReporter = injector.get(HttpErrorReporterService); - this.routerEvents = injector.get(RouterEvents); this.confirmationService = injector.get(ConfirmationService); - this.cfRes = injector.get(ComponentFactoryResolver); - this.rendererFactory = injector.get(RendererFactory2); this.httpErrorConfig = injector.get('HTTP_ERROR_CONFIG'); - this.authService = this.injector.get(AuthService); - this.sessionStateService = this.injector.get(SessionStateService); - this.listenToRestError(); this.listenToRouterError(); } protected listenToRouterError() { - this.routerEvents - .getNavigationEvents('Error') - .pipe(filter(this.filterRouteErrors)) - .subscribe(() => this.show404Page()); + this.routerErrorHandlerService.listen(); } protected listenToRestError() { @@ -84,177 +56,45 @@ export class ErrorHandler { ); }; - private handleError(err: any) { - const body = err?.error?.error || { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, - }; - - if (err instanceof HttpErrorResponse && err.headers.get('Abp-Tenant-Resolve-Error')) { - this.sessionStateService.setTenant(null) - this.authService.logout().subscribe(); - return; - } - - const isAbpErrorFormat = err.headers.get('_AbpErrorFormat'); - if (err instanceof HttpErrorResponse && isAbpErrorFormat) { - const confirmation$ = this.showErrorWithRequestBody(body); - - if (err.status === 401) { - confirmation$.subscribe(() => { - this.navigateToLogin(); - }); - } - } else { - switch (err.status) { - case 401: - this.canCreateCustomError(401) - ? this.show401Page() - : this.showError( - { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError401.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError401.title, - }, - { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError401.details, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError401.details, - }, - ).subscribe(() => this.navigateToLogin()); - break; - case 403: - this.createErrorComponent({ - title: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError403.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError403.title, - }, - details: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError403.details, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError403.details, - }, - status: 403, - }); - break; - case 404: - this.canCreateCustomError(404) - ? this.show404Page() - : this.showError( - { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError404.details, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.details, - }, - { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError404.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.title, - }, - ); - break; - case 500: - this.createErrorComponent({ - title: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError500.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError500.title, - }, - details: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError500.details, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError500.details, - }, - status: 500, - }); - break; - case 0: - if (err.statusText === 'Unknown Error') { - this.createErrorComponent({ - title: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, - }, - details: err.message, - isHomeShow: false, - }); - } - break; - default: - this.showError( - { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.details, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.details, - }, - { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, - }, - ); - break; - } - } + protected sortHttpErrorHandlers( + a: CustomHttpErrorHandlerService, + b: CustomHttpErrorHandlerService, + ) { + return (b.priority || 0) - (a.priority || 0); } - protected show401Page() { - this.createErrorComponent({ - title: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError401.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError401.title, - }, - status: 401, - }); - } - - protected show404Page() { - this.createErrorComponent({ - title: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError404.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.title, - }, - status: 404, - }); - } - - protected showErrorWithRequestBody(body: any) { - let message: LocalizationParam; - let title: LocalizationParam; - - if (body.details) { - message = body.details; - title = body.message; - } else if (body.message) { - title = { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, - }; - message = body.message; - } else { - message = body.message || { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, - }; - title = ''; + private handleError(err: unknown) { + if (this.customErrorHandlers && this.customErrorHandlers.length) { + const canHandleService = this.customErrorHandlers + .sort(this.sortHttpErrorHandlers) + .find(service => service.canHandle(err)); + if (canHandleService) { + canHandleService.execute(); + return; + } } - - return this.showError(message, title); + this.showError().subscribe(); } - protected showError( - message: LocalizationParam, - title: LocalizationParam, - ): Observable { + protected showError(): Observable { + const title = { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, + }; + const message = { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.details, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.details, + }; return this.confirmationService.error(message, title, { hideCancelBtn: true, yesText: 'AbpAccount::Close', }); } - private navigateToLogin() { - this.authService.navigateToLogin(); - } - createErrorComponent(instance: Partial) { this.createErrorComponentService.execute(instance); } - canCreateCustomError(status: ErrorScreenErrorCodes): boolean { - return this.canCreateCustomErrorService.execute(status); - } - protected filterRestErrors = ({ status }: HttpErrorResponse): boolean => { if (typeof status !== 'number') return false; @@ -263,12 +103,4 @@ export class ErrorHandler { this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === status) < 0 ); }; - - protected filterRouteErrors = (navigationError: NavigationError): boolean => { - return ( - navigationError.error?.message?.indexOf('Cannot match') > -1 && - !!this.httpErrorConfig.skipHandledErrorCodes && - this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === 404) < 0 - ); - }; } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts index 9ddbe0f5be..821fe52625 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts @@ -27,3 +27,9 @@ export type HttpErrorHandler = ( ) => Observable; export type LocaleDirection = 'ltr' | 'rtl'; + +export interface CustomHttpErrorHandlerService { + readonly priority: number; + canHandle(error: unknown): boolean; + execute(); +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/providers/error-handlers.provider.ts b/npm/ng-packs/packages/theme-shared/src/lib/providers/error-handlers.provider.ts new file mode 100644 index 0000000000..9cbf6f41ab --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/providers/error-handlers.provider.ts @@ -0,0 +1,29 @@ +import { Provider } from '@angular/core'; +import { CUSTOM_ERROR_HANDLERS } from '../tokens'; +import { TenantResolveErrorHandlerService } from '../services/tenant-resolve-error-handler.service'; +import { AbpFormatErrorHandlerService } from '../services/abp-format-error-handler.service'; +import { StatusCodeErrorHandlerService } from '../services/status-code-error-handler.service'; +import { UnknownStatusCodeErrorHandlerService } from '../services/unknown-status-code-error-handler.service'; + +export const errorHandlersProviders: Provider[] = [ + { + provide: CUSTOM_ERROR_HANDLERS, + multi: true, + useClass: TenantResolveErrorHandlerService, + }, + { + provide: CUSTOM_ERROR_HANDLERS, + multi: true, + useClass: AbpFormatErrorHandlerService, + }, + { + provide: CUSTOM_ERROR_HANDLERS, + multi: true, + useClass: StatusCodeErrorHandlerService, + }, + { + provide: CUSTOM_ERROR_HANDLERS, + multi: true, + useClass: UnknownStatusCodeErrorHandlerService, + }, +]; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/providers/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/providers/index.ts index 40efb9df39..cac8aa5d94 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/providers/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/providers/index.ts @@ -1,2 +1,3 @@ export * from './ng-bootstrap-config.provider'; export * from './route.provider'; +export * from './error-handlers.provider'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/abp-format-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/abp-format-error-handler.service.ts new file mode 100644 index 0000000000..b7c6fc9d76 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/abp-format-error-handler.service.ts @@ -0,0 +1,41 @@ +import { inject, Injectable } from '@angular/core'; +import { AuthService } from '@abp/ng.core'; +import { HttpErrorResponse } from '@angular/common/http'; +import { getErrorFromRequestBody } from '../utils/error.utils'; +import { CustomHttpErrorHandlerService } from '../models/common'; +import { ConfirmationService } from '../services/confirmation.service'; +import { CUSTOM_HTTP_ERROR_HANDLER_PRIORITY } from '../constants/error'; + +@Injectable({ providedIn: 'root' }) +export class AbpFormatErrorHandlerService implements CustomHttpErrorHandlerService { + priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.high; + private confirmationService = inject(ConfirmationService); + private authService = inject(AuthService); + private error: HttpErrorResponse | undefined = undefined; + + private navigateToLogin() { + return this.authService.navigateToLogin(); + } + + canHandle(error: unknown): boolean { + if (error instanceof HttpErrorResponse && error.headers.get('_AbpErrorFormat')) { + this.error = error; + return true; + } + return false; + } + + execute() { + const { message, title } = getErrorFromRequestBody(this.error?.error?.error); + this.confirmationService + .error(message, title, { + hideCancelBtn: true, + yesText: 'AbpAccount::Close', + }) + .subscribe(() => { + if (this.error?.status === 401) { + this.navigateToLogin(); + } + }); + } +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts index 7ce1a39262..b078e2d404 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts @@ -1,6 +1,6 @@ import { inject, Injectable } from '@angular/core'; import { ErrorScreenErrorCodes } from '../models/common'; -import { HTTP_ERROR_CONFIG } from '@abp/ng.theme.shared'; +import { HTTP_ERROR_CONFIG } from '../tokens/http-error.token'; @Injectable({ providedIn: 'root', diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts index 1ca37d2073..a088ebffa2 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts @@ -8,16 +8,14 @@ import { Injector, RendererFactory2, } from '@angular/core'; -import { - ErrorScreenErrorCodes, - HTTP_ERROR_CONFIG, - HttpErrorWrapperComponent, -} from '@abp/ng.theme.shared'; import { Subject } from 'rxjs'; import { ResolveEnd } from '@angular/router'; import { filter } from 'rxjs/operators'; import { RouterEvents } from '@abp/ng.core'; import { CanCreateCustomErrorService } from './can-create-custom-error.service'; +import { HTTP_ERROR_CONFIG } from '../tokens/http-error.token'; +import { HttpErrorWrapperComponent } from '../components/http-error-wrapper/http-error-wrapper.component'; +import { ErrorScreenErrorCodes } from '../models/common'; @Injectable({ providedIn: 'root' }) export class CreateErrorComponentService { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts index 0f98819137..1985995ce1 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts @@ -3,3 +3,10 @@ export * from './nav-items.service'; export * from './page-alert.service'; export * from './toaster.service'; export * from './user-menu.service'; +export * from './can-create-custom-error.service'; +export * from './create-error-component.service'; +export * from './abp-format-error-handler.service'; +export * from './tenant-resolve-error-handler.service'; +export * from './status-code-error-handler.service'; +export * from './unknown-status-code-error-handler.service'; +export * from './router-error-handler.service'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts new file mode 100644 index 0000000000..cb201444b5 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts @@ -0,0 +1,41 @@ +import { inject, Injectable } from '@angular/core'; +import { filter } from 'rxjs/operators'; +import { RouterEvents } from '@abp/ng.core'; +import { NavigationError } from '@angular/router'; +import { HTTP_ERROR_CONFIG } from '../tokens/'; +import { CreateErrorComponentService } from '../services'; +import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/error'; + +@Injectable({ providedIn: 'root' }) +export class RouterErrorHandlerService { + private readonly routerEvents = inject(RouterEvents); + private httpErrorConfig = inject(HTTP_ERROR_CONFIG); + private createErrorComponentService = inject(CreateErrorComponentService); + + listen() { + this.routerEvents + .getNavigationEvents('Error') + .pipe(filter(this.filterRouteErrors)) + .subscribe(() => this.show404Page()); + } + + protected filterRouteErrors = (navigationError: NavigationError): boolean => { + return ( + navigationError.error?.message?.indexOf('Cannot match') > -1 && + !!this.httpErrorConfig.skipHandledErrorCodes && + this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === 404) < 0 + ); + }; + + show404Page() { + const instance = { + title: { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError404.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.title, + }, + status: 404, + }; + + this.createErrorComponentService.execute(instance); + } +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts new file mode 100644 index 0000000000..9f94769220 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts @@ -0,0 +1,102 @@ +import { Confirmation, CustomHttpErrorHandlerService } from '../models'; +import { + CUSTOM_HTTP_ERROR_HANDLER_PRIORITY, + DEFAULT_ERROR_LOCALIZATIONS, + DEFAULT_ERROR_MESSAGES, +} from '../constants/error'; +import { AuthService, LocalizationParam } from '@abp/ng.core'; +import { Observable } from 'rxjs'; +import { inject, Injectable } from '@angular/core'; +import { ConfirmationService } from './confirmation.service'; +import { CanCreateCustomErrorService } from './can-create-custom-error.service'; +import { CreateErrorComponentService } from './create-error-component.service'; + +@Injectable({ providedIn: 'root' }) +export class StatusCodeErrorHandlerService implements CustomHttpErrorHandlerService { + private readonly confirmationService = inject(ConfirmationService); + private readonly canCreateCustomErrorService = inject(CanCreateCustomErrorService); + private readonly createErrorComponentService = inject(CreateErrorComponentService); + private readonly authService = inject(AuthService); + readonly priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.normal; + private status: typeof this.handledStatusCodes[number]; + private readonly handledStatusCodes = [401, 403, 404, 500] as const; + + canHandle({ status }): boolean { + this.status = status; + return this.handledStatusCodes.indexOf(status) > -1; + } + + execute() { + const key = `defaultError${this.status}`; + const title = { + key: DEFAULT_ERROR_LOCALIZATIONS[key]?.title, + defaultValue: DEFAULT_ERROR_MESSAGES[key]?.title, + }; + const message = { + key: DEFAULT_ERROR_LOCALIZATIONS[key]?.details, + defaultValue: DEFAULT_ERROR_MESSAGES[key]?.details, + }; + + const canCreateCustomError = this.canCreateCustomErrorService.execute(this.status); + switch (this.status) { + case 401: + if (canCreateCustomError) { + this.showPage(); + } else { + this.showConfirmation(title, message).subscribe(() => this.navigateToLogin()); + } + break; + + case 403: + this.showPage(); + break; + + case 404: + if (canCreateCustomError) { + this.showPage(); + } else { + this.showConfirmation(title, message).subscribe(); + } + break; + + case 500: + this.showPage(); + break; + } + } + + private navigateToLogin() { + this.authService.navigateToLogin(); + } + + protected showConfirmation( + message: LocalizationParam, + title: LocalizationParam, + ): Observable { + return this.confirmationService.error(message, title, { + hideCancelBtn: true, + yesText: 'AbpAccount::Close', + }); + } + + protected showPage() { + const key = `defaultError${this.status}`; + + const instance = { + title: { + key: DEFAULT_ERROR_LOCALIZATIONS[key]?.title, + defaultValue: DEFAULT_ERROR_MESSAGES[key]?.title, + }, + details: { + key: DEFAULT_ERROR_LOCALIZATIONS[key]?.details, + defaultValue: DEFAULT_ERROR_MESSAGES[key]?.details, + }, + status: this.status, + }; + const shouldRemoveDetail = [401, 404].indexOf(this.status) > -1; + if (shouldRemoveDetail) { + delete instance.details; + } + this.createErrorComponentService.execute(instance); + } +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts new file mode 100644 index 0000000000..57dc7dab9b --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts @@ -0,0 +1,22 @@ +import { CustomHttpErrorHandlerService } from '../models/common'; +import { inject, Injectable } from '@angular/core'; +import { AuthService } from '@abp/ng.core'; +import { HttpErrorResponse } from '@angular/common/http'; +import { CUSTOM_HTTP_ERROR_HANDLER_PRIORITY } from '../constants/error'; + +@Injectable({ providedIn: 'root' }) +export class TenantResolveErrorHandlerService implements CustomHttpErrorHandlerService { + priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.high; + private authService = inject(AuthService); + private isTenantResolveError(error: unknown) { + return error instanceof HttpErrorResponse && !!error.headers.get('Abp-Tenant-Resolve-Error'); + } + + canHandle(error: unknown): boolean { + return this.isTenantResolveError(error); + } + + execute() { + this.authService.logout().subscribe(); + } +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/unknown-status-code-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/unknown-status-code-error-handler.service.ts new file mode 100644 index 0000000000..88de56c14d --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/unknown-status-code-error-handler.service.ts @@ -0,0 +1,35 @@ +import { CustomHttpErrorHandlerService } from '../models'; +import { + CUSTOM_HTTP_ERROR_HANDLER_PRIORITY, + DEFAULT_ERROR_LOCALIZATIONS, + DEFAULT_ERROR_MESSAGES, +} from '../constants/error'; +import { inject, Injectable } from '@angular/core'; +import { CreateErrorComponentService } from './create-error-component.service'; + +@Injectable({ providedIn: 'root' }) +export class UnknownStatusCodeErrorHandlerService implements CustomHttpErrorHandlerService { + priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.normal; + private statusText = 'Unknown Error'; + private message = ''; + private createErrorComponentService = inject(CreateErrorComponentService); + + canHandle(error: { status: number; statusText: string; message: string } | undefined): boolean { + if (error && error.status === 0 && error.statusText === this.statusText) { + this.message = error.message; + return true; + } + return false; + } + + execute() { + this.createErrorComponentService.execute({ + title: { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, + }, + details: this.message, + isHomeShow: false, + }); + } +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts index 0fea3f166c..3926069a5a 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts @@ -29,7 +29,7 @@ import { NgxDatatableListDirective } from './directives/ngx-datatable-list.direc import { DocumentDirHandlerService } from './handlers/document-dir.handler'; import { ErrorHandler } from './handlers/error.handler'; import { RootParams } from './models/common'; -import { NG_BOOTSTRAP_CONFIG_PROVIDERS } from './providers'; +import { errorHandlersProviders, NG_BOOTSTRAP_CONFIG_PROVIDERS } from './providers'; import { THEME_SHARED_ROUTE_PROVIDERS } from './providers/route.provider'; import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token'; import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/http-error.token'; @@ -58,7 +58,7 @@ const declarationsWithExports = [ ModalCloseDirective, AbpVisibleDirective, FormInputComponent, - FormCheckboxComponent + FormCheckboxComponent, ]; @NgModule({ @@ -69,7 +69,6 @@ const declarationsWithExports = [ NgbPaginationModule, EllipsisModule, CardModule, - ], declarations: [...declarationsWithExports, HttpErrorWrapperComponent], exports: [ @@ -77,11 +76,11 @@ const declarationsWithExports = [ EllipsisModule, NgxValidateCoreModule, CardModule, - ...declarationsWithExports + ...declarationsWithExports, ], providers: [DatePipe], }) -export class BaseThemeSharedModule { } +export class BaseThemeSharedModule {} @NgModule({ imports: [BaseThemeSharedModule], @@ -144,6 +143,7 @@ export class ThemeSharedModule { ...(confirmationIcons || {}), }, }, + errorHandlersProviders, ], }; } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tokens/http-error.token.ts b/npm/ng-packs/packages/theme-shared/src/lib/tokens/http-error.token.ts index 39cb43a350..a2784f4332 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/tokens/http-error.token.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/tokens/http-error.token.ts @@ -1,5 +1,5 @@ import { InjectionToken } from '@angular/core'; -import { HttpErrorConfig, HttpErrorHandler } from '../models/common'; +import { CustomHttpErrorHandlerService, HttpErrorConfig, HttpErrorHandler } from '../models/common'; export function httpErrorConfigFactory(config = {} as HttpErrorConfig) { if (config.errorScreen && config.errorScreen.component && !config.errorScreen.forWhichErrors) { @@ -16,3 +16,7 @@ export function httpErrorConfigFactory(config = {} as HttpErrorConfig) { export const HTTP_ERROR_CONFIG = new InjectionToken('HTTP_ERROR_CONFIG'); export const HTTP_ERROR_HANDLER = new InjectionToken('HTTP_ERROR_HANDLER'); + +export const CUSTOM_ERROR_HANDLERS = new InjectionToken( + 'CUSTOM_ERROR_HANDLERS', +); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/utils/error.utils.ts b/npm/ng-packs/packages/theme-shared/src/lib/utils/error.utils.ts new file mode 100644 index 0000000000..c03f16cf09 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/utils/error.utils.ts @@ -0,0 +1,26 @@ +import { LocalizationParam } from '@abp/ng.core'; +import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/error'; + +export function getErrorFromRequestBody(body: { details?: string; message?: string } | undefined) { + let message: LocalizationParam; + let title: LocalizationParam; + + if (body.details) { + message = body.details; + title = body.message; + } else if (body.message) { + title = { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, + }; + message = body.message; + } else { + message = { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, + }; + title = ''; + } + + return { message, title }; +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/utils/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/utils/index.ts index 8f159e0a49..9bf1e72a8f 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/utils/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/utils/index.ts @@ -1,2 +1,3 @@ export * from './date-parser-formatter'; export * from './validation-utils'; +export * from './error.utils'; From f6e0a1aa00dabcc3c630754a754ee6cd65d73437 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Thu, 15 Jun 2023 20:00:50 +0300 Subject: [PATCH 003/165] remove unusedCodes --- .../src/lib/handlers/error.handler.ts | 32 +++++++------------ .../status-code-error-handler.service.ts | 20 ++++-------- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts index 721f5069a5..010a09528b 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts @@ -1,34 +1,28 @@ -import { AuthService, HttpErrorReporterService } from '@abp/ng.core'; +import { HttpErrorReporterService } from '@abp/ng.core'; import { HttpErrorResponse } from '@angular/common/http'; import { inject, Injectable, Injector } from '@angular/core'; import { Observable, of, throwError } from 'rxjs'; import { catchError, filter, switchMap } from 'rxjs/operators'; -import { HttpErrorWrapperComponent } from '../components/http-error-wrapper/http-error-wrapper.component'; -import { CustomHttpErrorHandlerService, HttpErrorConfig } from '../models/common'; +import { CustomHttpErrorHandlerService } from '../models/common'; import { Confirmation } from '../models/confirmation'; import { ConfirmationService } from '../services/confirmation.service'; import { CUSTOM_ERROR_HANDLERS, HTTP_ERROR_HANDLER } from '../tokens/http-error.token'; -import { CreateErrorComponentService } from '../services/create-error-component.service'; import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/error'; import { RouterErrorHandlerService } from '../services/router-error-handler.service'; +import { HTTP_ERROR_CONFIG } from '../tokens/http-error.token'; @Injectable({ providedIn: 'root' }) export class ErrorHandler { - protected httpErrorHandler = this.injector.get(HTTP_ERROR_HANDLER, (_, err: HttpErrorResponse) => - throwError(err), - ); - protected httpErrorReporter: HttpErrorReporterService; - protected confirmationService: ConfirmationService; - protected httpErrorConfig: HttpErrorConfig; - - private createErrorComponentService = inject(CreateErrorComponentService); - private customErrorHandlers = inject(CUSTOM_ERROR_HANDLERS); + protected httpErrorReporter = inject(HttpErrorReporterService); + protected confirmationService = inject(ConfirmationService); private routerErrorHandlerService = inject(RouterErrorHandlerService); + protected httpErrorConfig = inject(HTTP_ERROR_CONFIG); + private customErrorHandlers = inject(CUSTOM_ERROR_HANDLERS); + private defaultHttpErrorHandler = (_, err: HttpErrorResponse) => throwError(() => err); + protected httpErrorHandler = + inject(HTTP_ERROR_HANDLER, { optional: true }) || this.defaultHttpErrorHandler; constructor(protected injector: Injector) { - this.httpErrorReporter = injector.get(HttpErrorReporterService); - this.confirmationService = injector.get(ConfirmationService); - this.httpErrorConfig = injector.get('HTTP_ERROR_CONFIG'); this.listenToRestError(); this.listenToRouterError(); } @@ -43,7 +37,7 @@ export class ErrorHandler { .subscribe(); } - private executeErrorHandler = (error: any) => { + private executeErrorHandler = (error: HttpErrorResponse) => { const errHandler = this.httpErrorHandler(this.injector, error); const isObservable = errHandler instanceof Observable; const response = isObservable ? errHandler : of(null); @@ -91,10 +85,6 @@ export class ErrorHandler { }); } - createErrorComponent(instance: Partial) { - this.createErrorComponentService.execute(instance); - } - protected filterRestErrors = ({ status }: HttpErrorResponse): boolean => { if (typeof status !== 'number') return false; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts index 9f94769220..65e75fedec 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts @@ -40,25 +40,19 @@ export class StatusCodeErrorHandlerService implements CustomHttpErrorHandlerServ const canCreateCustomError = this.canCreateCustomErrorService.execute(this.status); switch (this.status) { case 401: - if (canCreateCustomError) { - this.showPage(); - } else { - this.showConfirmation(title, message).subscribe(() => this.navigateToLogin()); - } - break; - - case 403: - this.showPage(); - break; - case 404: if (canCreateCustomError) { this.showPage(); - } else { - this.showConfirmation(title, message).subscribe(); + break; } + this.showConfirmation(title, message).subscribe(() => { + if (this.status === 401) { + this.navigateToLogin(); + } + }); break; + case 403: case 500: this.showPage(); break; From ca3e849597619d8c0a6efe8a79dd51990ef47874 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Fri, 16 Jun 2023 12:39:03 +0300 Subject: [PATCH 004/165] remove canCustomErrorService. Rename error constants file --- .../constants/{error.ts => default-errors.ts} | 2 +- .../src/lib/handlers/error.handler.ts | 12 +++++++----- .../theme-shared/src/lib/models/common.ts | 5 +---- .../abp-format-error-handler.service.ts | 4 ++-- .../can-create-custom-error.service.ts | 18 ------------------ .../services/create-error-component.service.ts | 16 ++++++++++++---- .../theme-shared/src/lib/services/index.ts | 1 - .../services/router-error-handler.service.ts | 2 +- .../status-code-error-handler.service.ts | 6 ++---- .../tenant-resolve-error-handler.service.ts | 4 ++-- ...nknown-status-code-error-handler.service.ts | 4 ++-- .../src/lib/tests/error.handler.spec.ts | 5 +++-- .../theme-shared/src/lib/utils/error.utils.ts | 2 +- .../packages/theme-shared/src/public-api.ts | 2 +- 14 files changed, 35 insertions(+), 48 deletions(-) rename npm/ng-packs/packages/theme-shared/src/lib/constants/{error.ts => default-errors.ts} (98%) delete mode 100644 npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts diff --git a/npm/ng-packs/packages/theme-shared/src/lib/constants/error.ts b/npm/ng-packs/packages/theme-shared/src/lib/constants/default-errors.ts similarity index 98% rename from npm/ng-packs/packages/theme-shared/src/lib/constants/error.ts rename to npm/ng-packs/packages/theme-shared/src/lib/constants/default-errors.ts index 3b92ce0e7b..46a0605b95 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/constants/error.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/constants/default-errors.ts @@ -45,7 +45,7 @@ export const DEFAULT_ERROR_LOCALIZATIONS = { }; export const CUSTOM_HTTP_ERROR_HANDLER_PRIORITY = Object.freeze({ - veryLow: -9, + veryLow: -99, low: -9, normal: 0, high: 9, diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts index 010a09528b..3ae0c25d3c 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts @@ -7,19 +7,19 @@ import { CustomHttpErrorHandlerService } from '../models/common'; import { Confirmation } from '../models/confirmation'; import { ConfirmationService } from '../services/confirmation.service'; import { CUSTOM_ERROR_HANDLERS, HTTP_ERROR_HANDLER } from '../tokens/http-error.token'; -import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/error'; +import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/default-errors'; import { RouterErrorHandlerService } from '../services/router-error-handler.service'; import { HTTP_ERROR_CONFIG } from '../tokens/http-error.token'; @Injectable({ providedIn: 'root' }) export class ErrorHandler { - protected httpErrorReporter = inject(HttpErrorReporterService); - protected confirmationService = inject(ConfirmationService); + private httpErrorReporter = inject(HttpErrorReporterService); + private confirmationService = inject(ConfirmationService); private routerErrorHandlerService = inject(RouterErrorHandlerService); protected httpErrorConfig = inject(HTTP_ERROR_CONFIG); private customErrorHandlers = inject(CUSTOM_ERROR_HANDLERS); private defaultHttpErrorHandler = (_, err: HttpErrorResponse) => throwError(() => err); - protected httpErrorHandler = + private httpErrorHandler = inject(HTTP_ERROR_HANDLER, { optional: true }) || this.defaultHttpErrorHandler; constructor(protected injector: Injector) { @@ -34,7 +34,9 @@ export class ErrorHandler { protected listenToRestError() { this.httpErrorReporter.reporter$ .pipe(filter(this.filterRestErrors), switchMap(this.executeErrorHandler)) - .subscribe(); + .subscribe(err => { + this.handleError(err); + }); } private executeErrorHandler = (error: HttpErrorResponse) => { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts index 821fe52625..f497312ff3 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts @@ -21,10 +21,7 @@ export interface HttpErrorConfig { }; } -export type HttpErrorHandler = ( - injector: Injector, - httpError: HttpErrorResponse, -) => Observable; +export type HttpErrorHandler = (httpError: HttpErrorResponse) => Observable; export type LocaleDirection = 'ltr' | 'rtl'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/abp-format-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/abp-format-error-handler.service.ts index b7c6fc9d76..a453c25226 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/abp-format-error-handler.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/abp-format-error-handler.service.ts @@ -4,11 +4,11 @@ import { HttpErrorResponse } from '@angular/common/http'; import { getErrorFromRequestBody } from '../utils/error.utils'; import { CustomHttpErrorHandlerService } from '../models/common'; import { ConfirmationService } from '../services/confirmation.service'; -import { CUSTOM_HTTP_ERROR_HANDLER_PRIORITY } from '../constants/error'; +import { CUSTOM_HTTP_ERROR_HANDLER_PRIORITY } from '../constants/default-errors'; @Injectable({ providedIn: 'root' }) export class AbpFormatErrorHandlerService implements CustomHttpErrorHandlerService { - priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.high; + readonly priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.high; private confirmationService = inject(ConfirmationService); private authService = inject(AuthService); private error: HttpErrorResponse | undefined = undefined; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts deleted file mode 100644 index b078e2d404..0000000000 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/can-create-custom-error.service.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { inject, Injectable } from '@angular/core'; -import { ErrorScreenErrorCodes } from '../models/common'; -import { HTTP_ERROR_CONFIG } from '../tokens/http-error.token'; - -@Injectable({ - providedIn: 'root', -}) -export class CanCreateCustomErrorService { - private httpErrorConfig = inject(HTTP_ERROR_CONFIG); - - execute(status: ErrorScreenErrorCodes): boolean { - return !!( - this.httpErrorConfig?.errorScreen?.component && - this.httpErrorConfig?.errorScreen?.forWhichErrors && - this.httpErrorConfig?.errorScreen?.forWhichErrors.indexOf(status) > -1 - ); - } -} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts index a088ebffa2..6972a93f34 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts @@ -12,7 +12,6 @@ import { Subject } from 'rxjs'; import { ResolveEnd } from '@angular/router'; import { filter } from 'rxjs/operators'; import { RouterEvents } from '@abp/ng.core'; -import { CanCreateCustomErrorService } from './can-create-custom-error.service'; import { HTTP_ERROR_CONFIG } from '../tokens/http-error.token'; import { HttpErrorWrapperComponent } from '../components/http-error-wrapper/http-error-wrapper.component'; import { ErrorScreenErrorCodes } from '../models/common'; @@ -23,18 +22,26 @@ export class CreateErrorComponentService { protected cfRes = inject(ComponentFactoryResolver); private routerEvents = inject(RouterEvents); private injector = inject(Injector); - private canCreateCustomErrorService = inject(CanCreateCustomErrorService); private httpErrorConfig = inject(HTTP_ERROR_CONFIG); componentRef: ComponentRef | null = null; - protected getErrorHostElement() { + private getErrorHostElement() { return document.body; } + public canCreateCustomError(status: ErrorScreenErrorCodes) { + return !!( + this.httpErrorConfig?.errorScreen?.component && + this.httpErrorConfig?.errorScreen?.forWhichErrors && + this.httpErrorConfig?.errorScreen?.forWhichErrors.indexOf(status) > -1 + ); + } + constructor() { this.listenToRouterDataResolved(); } + protected listenToRouterDataResolved() { this.routerEvents .getEvents(ResolveEnd) @@ -48,6 +55,7 @@ export class CreateErrorComponentService { private isCloseIconHidden() { return !!this.httpErrorConfig.errorScreen?.hideCloseIcon; } + execute(instance: Partial) { const renderer = this.rendererFactory.createRenderer(null, null); const hostElement = this.getErrorHostElement(); @@ -67,7 +75,7 @@ export class CreateErrorComponentService { this.componentRef.instance.hideCloseIcon = this.isCloseIconHidden(); const appRef = this.injector.get(ApplicationRef); - if (this.canCreateCustomErrorService.execute(instance.status as ErrorScreenErrorCodes)) { + if (this.canCreateCustomError(instance.status as ErrorScreenErrorCodes)) { this.componentRef.instance.cfRes = this.cfRes; this.componentRef.instance.appRef = appRef; this.componentRef.instance.injector = this.injector; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts index 1985995ce1..41f1b84039 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts @@ -3,7 +3,6 @@ export * from './nav-items.service'; export * from './page-alert.service'; export * from './toaster.service'; export * from './user-menu.service'; -export * from './can-create-custom-error.service'; export * from './create-error-component.service'; export * from './abp-format-error-handler.service'; export * from './tenant-resolve-error-handler.service'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts index cb201444b5..14a4e79266 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts @@ -4,7 +4,7 @@ import { RouterEvents } from '@abp/ng.core'; import { NavigationError } from '@angular/router'; import { HTTP_ERROR_CONFIG } from '../tokens/'; import { CreateErrorComponentService } from '../services'; -import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/error'; +import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/default-errors'; @Injectable({ providedIn: 'root' }) export class RouterErrorHandlerService { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts index 65e75fedec..e566ccb792 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/status-code-error-handler.service.ts @@ -3,18 +3,16 @@ import { CUSTOM_HTTP_ERROR_HANDLER_PRIORITY, DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES, -} from '../constants/error'; +} from '../constants/default-errors'; import { AuthService, LocalizationParam } from '@abp/ng.core'; import { Observable } from 'rxjs'; import { inject, Injectable } from '@angular/core'; import { ConfirmationService } from './confirmation.service'; -import { CanCreateCustomErrorService } from './can-create-custom-error.service'; import { CreateErrorComponentService } from './create-error-component.service'; @Injectable({ providedIn: 'root' }) export class StatusCodeErrorHandlerService implements CustomHttpErrorHandlerService { private readonly confirmationService = inject(ConfirmationService); - private readonly canCreateCustomErrorService = inject(CanCreateCustomErrorService); private readonly createErrorComponentService = inject(CreateErrorComponentService); private readonly authService = inject(AuthService); readonly priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.normal; @@ -37,7 +35,7 @@ export class StatusCodeErrorHandlerService implements CustomHttpErrorHandlerServ defaultValue: DEFAULT_ERROR_MESSAGES[key]?.details, }; - const canCreateCustomError = this.canCreateCustomErrorService.execute(this.status); + const canCreateCustomError = this.createErrorComponentService.canCreateCustomError(this.status); switch (this.status) { case 401: case 404: diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts index 57dc7dab9b..d58e0da72b 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts @@ -2,11 +2,11 @@ import { CustomHttpErrorHandlerService } from '../models/common'; import { inject, Injectable } from '@angular/core'; import { AuthService } from '@abp/ng.core'; import { HttpErrorResponse } from '@angular/common/http'; -import { CUSTOM_HTTP_ERROR_HANDLER_PRIORITY } from '../constants/error'; +import { CUSTOM_HTTP_ERROR_HANDLER_PRIORITY } from '../constants/default-errors'; @Injectable({ providedIn: 'root' }) export class TenantResolveErrorHandlerService implements CustomHttpErrorHandlerService { - priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.high; + readonly priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.high; private authService = inject(AuthService); private isTenantResolveError(error: unknown) { return error instanceof HttpErrorResponse && !!error.headers.get('Abp-Tenant-Resolve-Error'); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/unknown-status-code-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/unknown-status-code-error-handler.service.ts index 88de56c14d..129c9ed5b9 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/unknown-status-code-error-handler.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/unknown-status-code-error-handler.service.ts @@ -3,13 +3,13 @@ import { CUSTOM_HTTP_ERROR_HANDLER_PRIORITY, DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES, -} from '../constants/error'; +} from '../constants/default-errors'; import { inject, Injectable } from '@angular/core'; import { CreateErrorComponentService } from './create-error-component.service'; @Injectable({ providedIn: 'root' }) export class UnknownStatusCodeErrorHandlerService implements CustomHttpErrorHandlerService { - priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.normal; + readonly priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.normal; private statusText = 'Unknown Error'; private message = ''; private createErrorComponentService = inject(CreateErrorComponentService); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts index e6564ea99f..8688572436 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts @@ -7,7 +7,8 @@ import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; import { OAuthService } from 'angular-oauth2-oidc'; import { of, Subject } from 'rxjs'; import { HttpErrorWrapperComponent } from '../components/http-error-wrapper/http-error-wrapper.component'; -import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES, ErrorHandler } from '../handlers'; +import { ErrorHandler } from '../handlers'; +import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/default-errors'; import { ConfirmationService } from '../services'; import { httpErrorConfigFactory } from '../tokens/http-error.token'; @@ -16,7 +17,7 @@ const reporter$ = new Subject(); @NgModule({ exports: [HttpErrorWrapperComponent], declarations: [HttpErrorWrapperComponent], - entryComponents: [HttpErrorWrapperComponent], + //entryComponents: [HttpErrorWrapperComponent], imports: [CoreTestingModule], }) class MockModule {} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/utils/error.utils.ts b/npm/ng-packs/packages/theme-shared/src/lib/utils/error.utils.ts index c03f16cf09..e417b53eb8 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/utils/error.utils.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/utils/error.utils.ts @@ -1,5 +1,5 @@ import { LocalizationParam } from '@abp/ng.core'; -import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/error'; +import { DEFAULT_ERROR_LOCALIZATIONS, DEFAULT_ERROR_MESSAGES } from '../constants/default-errors'; export function getErrorFromRequestBody(body: { details?: string; message?: string } | undefined) { let message: LocalizationParam; diff --git a/npm/ng-packs/packages/theme-shared/src/public-api.ts b/npm/ng-packs/packages/theme-shared/src/public-api.ts index 840463a70f..22661e3855 100644 --- a/npm/ng-packs/packages/theme-shared/src/public-api.ts +++ b/npm/ng-packs/packages/theme-shared/src/public-api.ts @@ -5,7 +5,7 @@ export * from './lib/animations'; export * from './lib/components'; export * from './lib/constants/validation'; -export * from './lib/constants/error'; +export * from './lib/constants/default-errors'; export * from './lib/directives'; export * from './lib/enums'; export * from './lib/handlers'; From 3f3ffaf460b30d5377619dfe574aacc8e37b3fb0 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Fri, 16 Jun 2023 12:41:21 +0300 Subject: [PATCH 005/165] rename ERROR_HANDLERS_PROVIDERS --- .../theme-shared/src/lib/providers/error-handlers.provider.ts | 2 +- .../packages/theme-shared/src/lib/theme-shared.module.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/providers/error-handlers.provider.ts b/npm/ng-packs/packages/theme-shared/src/lib/providers/error-handlers.provider.ts index 9cbf6f41ab..0d177ec510 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/providers/error-handlers.provider.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/providers/error-handlers.provider.ts @@ -5,7 +5,7 @@ import { AbpFormatErrorHandlerService } from '../services/abp-format-error-handl import { StatusCodeErrorHandlerService } from '../services/status-code-error-handler.service'; import { UnknownStatusCodeErrorHandlerService } from '../services/unknown-status-code-error-handler.service'; -export const errorHandlersProviders: Provider[] = [ +export const ERROR_HANDLERS_PROVIDERS: Provider[] = [ { provide: CUSTOM_ERROR_HANDLERS, multi: true, diff --git a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts index 3926069a5a..1009d9dd60 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts @@ -29,7 +29,7 @@ import { NgxDatatableListDirective } from './directives/ngx-datatable-list.direc import { DocumentDirHandlerService } from './handlers/document-dir.handler'; import { ErrorHandler } from './handlers/error.handler'; import { RootParams } from './models/common'; -import { errorHandlersProviders, NG_BOOTSTRAP_CONFIG_PROVIDERS } from './providers'; +import { ERROR_HANDLERS_PROVIDERS, NG_BOOTSTRAP_CONFIG_PROVIDERS } from './providers'; import { THEME_SHARED_ROUTE_PROVIDERS } from './providers/route.provider'; import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token'; import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/http-error.token'; @@ -143,7 +143,7 @@ export class ThemeSharedModule { ...(confirmationIcons || {}), }, }, - errorHandlersProviders, + ERROR_HANDLERS_PROVIDERS, ], }; } From 3f57e3dc03f456f9589f9869001a97682ee82e3e Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Mon, 24 Jul 2023 18:22:23 +0300 Subject: [PATCH 006/165] Update httpService interface. Clean tenant when Abp-Tenant-Resolve-Error appeared --- npm/ng-packs/packages/theme-shared/src/lib/models/common.ts | 4 +--- .../src/lib/services/tenant-resolve-error-handler.service.ts | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts index f497312ff3..6fd9c015d3 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts @@ -20,9 +20,7 @@ export interface HttpErrorConfig { hideCloseIcon?: boolean; }; } - -export type HttpErrorHandler = (httpError: HttpErrorResponse) => Observable; - +export type HttpErrorHandler = (httpError: HttpErrorResponse) => Observable; export type LocaleDirection = 'ltr' | 'rtl'; export interface CustomHttpErrorHandlerService { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts index d58e0da72b..f772d8b518 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/tenant-resolve-error-handler.service.ts @@ -1,11 +1,12 @@ import { CustomHttpErrorHandlerService } from '../models/common'; import { inject, Injectable } from '@angular/core'; -import { AuthService } from '@abp/ng.core'; +import { AuthService, SessionStateService } from '@abp/ng.core'; import { HttpErrorResponse } from '@angular/common/http'; import { CUSTOM_HTTP_ERROR_HANDLER_PRIORITY } from '../constants/default-errors'; @Injectable({ providedIn: 'root' }) export class TenantResolveErrorHandlerService implements CustomHttpErrorHandlerService { + protected readonly sessionService = inject(SessionStateService); readonly priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.high; private authService = inject(AuthService); private isTenantResolveError(error: unknown) { @@ -17,6 +18,7 @@ export class TenantResolveErrorHandlerService implements CustomHttpErrorHandlerS } execute() { + this.sessionService.setTenant(null); this.authService.logout().subscribe(); } } From bf321afe801693142759cfa36f4d9c31dad48035 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Thu, 6 Jul 2023 14:58:10 +0300 Subject: [PATCH 007/165] connection status service was using rxjs observable now we also add signal as an alternative --- .../services/internet-connection-service.ts | 18 ++++++++++++++++-- .../internet-connection-status.component.ts | 17 ++++++++--------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts index a38f429d64..2c09eb5279 100644 --- a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts @@ -1,5 +1,5 @@ import { DOCUMENT } from '@angular/common'; -import { Injectable, inject } from '@angular/core'; +import { Injectable, inject, signal } from '@angular/core'; import { fromEvent, merge, of } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -14,5 +14,19 @@ export class InternetConnectionService{ of(navigator.onLine), fromEvent(window, 'offline'), fromEvent(window, 'online') - ).pipe(map(() => navigator.onLine)) + ).pipe(map(() => navigator.onLine)); +} + +@Injectable({ + providedIn: 'root', +}) +export class InternetConnectionSignalService{ + protected readonly window = inject(DOCUMENT).defaultView; + protected readonly navigator = this.window.navigator; + readonly networkStatus = signal(navigator.onLine); + + constructor(){ + window.addEventListener('offline', () => { this.networkStatus.set(navigator.onLine) }); + window.addEventListener('online', () => { this.networkStatus.set(navigator.onLine) }); + } } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts index c944e67ac1..a426fd2a64 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts @@ -1,14 +1,13 @@ -import { Component, inject } from '@angular/core'; -import { CommonModule } from '@angular/common' -import { map } from 'rxjs'; -import { InternetConnectionService, LocalizationModule } from '@abp/ng.core'; +import { Component, inject } from '@angular/core'; +import { NgIf, AsyncPipe } from '@angular/common' +import { InternetConnectionSignalService , LocalizationModule } from '@abp/ng.core'; @Component({ selector: 'abp-internet-status', standalone: true, - imports:[CommonModule,LocalizationModule], + imports:[NgIf, AsyncPipe, LocalizationModule], template: ` -
+
@@ -42,7 +41,7 @@ import { InternetConnectionService, LocalizationModule } from '@abp/ng.core'; } `] }) -export class InternetConnectionStatusComponent{ - internetConnectionService = inject(InternetConnectionService) - isOffline$ = this.internetConnectionService.networkStatus$.pipe(map((val) => !val)); +export class InternetConnectionStatusComponent{ + internetConnectionSignalService = inject(InternetConnectionSignalService); + isOnline = this.internetConnectionSignalService.networkStatus; } From 1624dcfafa42b72834eddb388402817c67a59f59 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Thu, 6 Jul 2023 15:40:14 +0300 Subject: [PATCH 008/165] removed unnecesarry async pipe --- .../internet-connection-status.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts index a426fd2a64..e62bc049f5 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts @@ -1,11 +1,11 @@ import { Component, inject } from '@angular/core'; -import { NgIf, AsyncPipe } from '@angular/common' +import { NgIf } from '@angular/common' import { InternetConnectionSignalService , LocalizationModule } from '@abp/ng.core'; @Component({ selector: 'abp-internet-status', standalone: true, - imports:[NgIf, AsyncPipe, LocalizationModule], + imports:[NgIf, LocalizationModule], template: `
From 515c17938edcb11127cea2e9685a08da5b4d939b Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Thu, 6 Jul 2023 16:40:02 +0300 Subject: [PATCH 009/165] this.window --- .../core/src/lib/services/internet-connection-service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts index 2c09eb5279..9fc95e4c08 100644 --- a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts @@ -26,7 +26,7 @@ export class InternetConnectionSignalService{ readonly networkStatus = signal(navigator.onLine); constructor(){ - window.addEventListener('offline', () => { this.networkStatus.set(navigator.onLine) }); - window.addEventListener('online', () => { this.networkStatus.set(navigator.onLine) }); + this.window.addEventListener('offline', () => { this.networkStatus.set(navigator.onLine) }); + this.window.addEventListener('online', () => { this.networkStatus.set(navigator.onLine) }); } } From 80928d27692a4887ca6010db9a3598971ce895c1 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Thu, 6 Jul 2023 23:37:18 +0300 Subject: [PATCH 010/165] merging observable and signal to 1 service --- .../services/internet-connection-service.ts | 41 +++++++++++-------- .../internet-connection-status.component.ts | 13 +++--- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts index 9fc95e4c08..9afcdeb166 100644 --- a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts @@ -1,7 +1,6 @@ import { DOCUMENT } from '@angular/common'; -import { Injectable, inject, signal } from '@angular/core'; -import { fromEvent, merge, of } from 'rxjs'; -import { map } from 'rxjs/operators'; +import { Injectable, computed, inject, signal } from '@angular/core'; +import { Subject } from 'rxjs'; @Injectable({ providedIn: 'root', @@ -10,23 +9,29 @@ export class InternetConnectionService{ protected readonly window = inject(DOCUMENT).defaultView; protected readonly navigator = this.window.navigator; - networkStatus$ = merge( - of(navigator.onLine), - fromEvent(window, 'offline'), - fromEvent(window, 'online') - ).pipe(map(() => navigator.onLine)); -} + /* observable */ + private status$ = new Subject() -@Injectable({ - providedIn: 'root', -}) -export class InternetConnectionSignalService{ - protected readonly window = inject(DOCUMENT).defaultView; - protected readonly navigator = this.window.navigator; - readonly networkStatus = signal(navigator.onLine); + /* creates writableSignal */ + private status = signal(navigator.onLine); constructor(){ - this.window.addEventListener('offline', () => { this.networkStatus.set(navigator.onLine) }); - this.window.addEventListener('online', () => { this.networkStatus.set(navigator.onLine) }); + this.window.addEventListener('offline', () => this.setStatus() ); + this.window.addEventListener('online', () => this.setStatus() ); + } + + private setStatus(){ + this.status.set(navigator.onLine) + this.status$.next(navigator.onLine) + } + + /* returns READONLY ANGULAR SIGNAL */ + get networkStatus(){ + return computed(this.status) + } + + /* returns OBSERVABLE */ + get networkStatus$(){ + return this.status$ } } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts index e62bc049f5..1610988a14 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts @@ -1,13 +1,14 @@ import { Component, inject } from '@angular/core'; -import { NgIf } from '@angular/common' -import { InternetConnectionSignalService , LocalizationModule } from '@abp/ng.core'; +import { AsyncPipe, NgIf } from '@angular/common' +import { InternetConnectionService , LocalizationModule } from '@abp/ng.core'; +import { map } from 'rxjs'; @Component({ selector: 'abp-internet-status', standalone: true, - imports:[NgIf, LocalizationModule], + imports:[NgIf, AsyncPipe, LocalizationModule], template: ` -
+
@@ -42,6 +43,6 @@ import { InternetConnectionSignalService , LocalizationModule } from '@abp/ng.co `] }) export class InternetConnectionStatusComponent{ - internetConnectionSignalService = inject(InternetConnectionSignalService); - isOnline = this.internetConnectionSignalService.networkStatus; + internetConnectionService = inject(InternetConnectionService); + isOffline = this.internetConnectionService.networkStatus } From f8d1ba8251fa3665af5c28f8ee6cc507e48d97e2 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Thu, 6 Jul 2023 23:37:57 +0300 Subject: [PATCH 011/165] lint clean warning --- .../internet-connection-status.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts index 1610988a14..23c7e46438 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts @@ -1,7 +1,6 @@ import { Component, inject } from '@angular/core'; import { AsyncPipe, NgIf } from '@angular/common' import { InternetConnectionService , LocalizationModule } from '@abp/ng.core'; -import { map } from 'rxjs'; @Component({ selector: 'abp-internet-status', From 63cdfecf4f5dba51e3ee6e28afe5c8e1a7ded654 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Thu, 6 Jul 2023 23:40:58 +0300 Subject: [PATCH 012/165] remove async pipe --- .../internet-connection-status.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts index 23c7e46438..c54c71c403 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts @@ -1,11 +1,11 @@ import { Component, inject } from '@angular/core'; -import { AsyncPipe, NgIf } from '@angular/common' +import { NgIf } from '@angular/common' import { InternetConnectionService , LocalizationModule } from '@abp/ng.core'; @Component({ selector: 'abp-internet-status', standalone: true, - imports:[NgIf, AsyncPipe, LocalizationModule], + imports:[NgIf, LocalizationModule], template: `
From 54bcefea119c1664d13fd0c548ddb5a5f09446e8 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 7 Jul 2023 07:58:16 +0300 Subject: [PATCH 013/165] change subject to behaviorSubject --- .../core/src/lib/services/internet-connection-service.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts index 9afcdeb166..77dc1d4b7c 100644 --- a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts @@ -1,6 +1,6 @@ import { DOCUMENT } from '@angular/common'; import { Injectable, computed, inject, signal } from '@angular/core'; -import { Subject } from 'rxjs'; +import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root', @@ -10,14 +10,14 @@ export class InternetConnectionService{ protected readonly navigator = this.window.navigator; /* observable */ - private status$ = new Subject() + private status$ = new BehaviorSubject(navigator.onLine) /* creates writableSignal */ private status = signal(navigator.onLine); constructor(){ - this.window.addEventListener('offline', () => this.setStatus() ); - this.window.addEventListener('online', () => this.setStatus() ); + this.window.addEventListener('offline', () => this.setStatus()); + this.window.addEventListener('online', () => this.setStatus()); } private setStatus(){ From 98f9f2be065c31a8b3632ad7a1ac051c81b4fa05 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 7 Jul 2023 08:03:20 +0300 Subject: [PATCH 014/165] returning observable instead of subject --- .../core/src/lib/services/internet-connection-service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts index 77dc1d4b7c..0ebdff2031 100644 --- a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts @@ -9,7 +9,7 @@ export class InternetConnectionService{ protected readonly window = inject(DOCUMENT).defaultView; protected readonly navigator = this.window.navigator; - /* observable */ + /* BehaviorSubject */ private status$ = new BehaviorSubject(navigator.onLine) /* creates writableSignal */ @@ -32,6 +32,6 @@ export class InternetConnectionService{ /* returns OBSERVABLE */ get networkStatus$(){ - return this.status$ + return this.status$.asObservable() } } From 1899fcf946156c3b4d58a91c7b13a6685a2cd92a Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 7 Jul 2023 09:55:48 +0300 Subject: [PATCH 015/165] fix computed func --- .../core/src/lib/services/internet-connection-service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts index 0ebdff2031..11d750b558 100644 --- a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts @@ -27,7 +27,7 @@ export class InternetConnectionService{ /* returns READONLY ANGULAR SIGNAL */ get networkStatus(){ - return computed(this.status) + return computed(() => this.status()) } /* returns OBSERVABLE */ From 56fa0387346f7b3ecd80f507cfa463b4f4e6dcd6 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 7 Jul 2023 10:00:55 +0300 Subject: [PATCH 016/165] return networkStatus as a variable --- .../core/src/lib/services/internet-connection-service.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts index 11d750b558..bb3338d44d 100644 --- a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts @@ -14,6 +14,9 @@ export class InternetConnectionService{ /* creates writableSignal */ private status = signal(navigator.onLine); + + /* READONLY ANGULAR SIGNAL */ + networkStatus = computed(() => this.status()) constructor(){ this.window.addEventListener('offline', () => this.setStatus()); @@ -24,11 +27,6 @@ export class InternetConnectionService{ this.status.set(navigator.onLine) this.status$.next(navigator.onLine) } - - /* returns READONLY ANGULAR SIGNAL */ - get networkStatus(){ - return computed(() => this.status()) - } /* returns OBSERVABLE */ get networkStatus$(){ From 39869c22f2a85c0b0ac3c8480f5bb4245c69c1e1 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 7 Jul 2023 14:56:52 +0300 Subject: [PATCH 017/165] adding documentation for InternetConnectionService --- .../UI/Angular/Internet-Connection-Service.md | 71 +++++++++++++++++++ .../internet-connection-status.component.ts | 4 +- 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 docs/en/UI/Angular/Internet-Connection-Service.md diff --git a/docs/en/UI/Angular/Internet-Connection-Service.md b/docs/en/UI/Angular/Internet-Connection-Service.md new file mode 100644 index 0000000000..09ba94aec1 --- /dev/null +++ b/docs/en/UI/Angular/Internet-Connection-Service.md @@ -0,0 +1,71 @@ +# Internet Connection Service +`InternetConnectionService` is a service which is exposed by `@abp/ng.core` package. **If you want to detect whether you are connected to the internet or not, you can use this service.** + + +### internet-connection-service.ts +``` +import { DOCUMENT } from '@angular/common'; +import { Injectable, computed, inject, signal } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; + +@Injectable({ + providedIn: 'root', +}) + +export class InternetConnectionService{ + protected readonly window = inject(DOCUMENT).defaultView; + protected readonly navigator = this.window.navigator; + + /* BehaviorSubject */ + private status$ = new BehaviorSubject(navigator.onLine) + + /* creates writableSignal */ + private status = signal(navigator.onLine); + + /* READONLY ANGULAR SIGNAL */ + networkStatus = computed(() => this.status()) + + constructor(){ + this.window.addEventListener('offline', () => this.setStatus()); + this.window.addEventListener('online', () => this.setStatus()); + } + + private setStatus(){ + this.status.set(navigator.onLine) + this.status$.next(navigator.onLine) + } + + /* returns OBSERVABLE */ + get networkStatus$(){ + return this.status$.asObservable() + } +} +``` + +## Getting Started +When you inject InternetConnectionService you can get the current internet status also if status changes you can catch them immediately. + +As you can see from the code above, `InternetConnectionService` is providing 2 alternatives for catching network status; +1. Signal (readonly) +2. Observable + + +# How To Use +İt's easy just inject the service and get network status + +**You can get via signal** +``` +class someComponent{ + internetConnectionService = inject(InternetConnectionService); + isOnline = this.internetConnectionService.networkStatus +} +``` +**or you can get as observable** +``` +class someComponent{ + internetConnectionService = inject(InternetConnectionService); + isOnline = this.internetConnectionService.networkStatus$ +} +``` + +That's all, feel free to try on your template \ No newline at end of file diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts index c54c71c403..4ad473141a 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts @@ -7,7 +7,7 @@ import { InternetConnectionService , LocalizationModule } from '@abp/ng.core'; standalone: true, imports:[NgIf, LocalizationModule], template: ` -
+
@@ -43,5 +43,5 @@ import { InternetConnectionService , LocalizationModule } from '@abp/ng.core'; }) export class InternetConnectionStatusComponent{ internetConnectionService = inject(InternetConnectionService); - isOffline = this.internetConnectionService.networkStatus + isOnline = this.internetConnectionService.networkStatus } From 7ae6bb6236883fe2649f07f2bb2bf72a710fe081 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 7 Jul 2023 15:09:14 +0300 Subject: [PATCH 018/165] documentation adding js editor --- docs/en/UI/Angular/Internet-Connection-Service.md | 6 +++--- .../core/src/lib/services/internet-connection-service.ts | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/en/UI/Angular/Internet-Connection-Service.md b/docs/en/UI/Angular/Internet-Connection-Service.md index 09ba94aec1..1107e64743 100644 --- a/docs/en/UI/Angular/Internet-Connection-Service.md +++ b/docs/en/UI/Angular/Internet-Connection-Service.md @@ -3,7 +3,7 @@ ### internet-connection-service.ts -``` +```js import { DOCUMENT } from '@angular/common'; import { Injectable, computed, inject, signal } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @@ -54,14 +54,14 @@ As you can see from the code above, `InternetConnectionService` is providing 2 a İt's easy just inject the service and get network status **You can get via signal** -``` +```js class someComponent{ internetConnectionService = inject(InternetConnectionService); isOnline = this.internetConnectionService.networkStatus } ``` **or you can get as observable** -``` +```js class someComponent{ internetConnectionService = inject(InternetConnectionService); isOnline = this.internetConnectionService.networkStatus$ diff --git a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts index bb3338d44d..9fc298386b 100644 --- a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts @@ -9,13 +9,10 @@ export class InternetConnectionService{ protected readonly window = inject(DOCUMENT).defaultView; protected readonly navigator = this.window.navigator; - /* BehaviorSubject */ private status$ = new BehaviorSubject(navigator.onLine) - /* creates writableSignal */ private status = signal(navigator.onLine); - /* READONLY ANGULAR SIGNAL */ networkStatus = computed(() => this.status()) constructor(){ @@ -28,7 +25,6 @@ export class InternetConnectionService{ this.status$.next(navigator.onLine) } - /* returns OBSERVABLE */ get networkStatus$(){ return this.status$.asObservable() } From 5a9a9331bfba43eca4a733e4fe3ffdfc259cc3d6 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 10 Jul 2023 08:33:17 +0300 Subject: [PATCH 019/165] adding test file --- .../tests/internet-connection.service.spec.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts diff --git a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts new file mode 100644 index 0000000000..397f362781 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts @@ -0,0 +1,28 @@ +import { TestBed } from '@angular/core/testing'; + +import { InternetConnectionService } from '../services/internet-connection-service'; + +describe('InternetConnectionService', () => { + let service: InternetConnectionService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(InternetConnectionService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('#networkStatus should return real value (true | false)', () => { + expect(typeof service.networkStatus()).toEqual('boolean') + expect(typeof !service.networkStatus()).toEqual('boolean') + }); + + it('#networkStatus$ should return real value (true | false)', () => { + service.networkStatus$.subscribe(val=>{ + expect(typeof val).toEqual('boolean') + expect(typeof !val).toEqual('boolean') + }) + }); +}); From ab664a1038c1e776a4d62dfa37352211c981b40c Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 10 Jul 2023 08:36:05 +0300 Subject: [PATCH 020/165] fix doc --- .../UI/Angular/Internet-Connection-Service.md | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/en/UI/Angular/Internet-Connection-Service.md b/docs/en/UI/Angular/Internet-Connection-Service.md index 1107e64743..2e8f23ff3b 100644 --- a/docs/en/UI/Angular/Internet-Connection-Service.md +++ b/docs/en/UI/Angular/Internet-Connection-Service.md @@ -13,32 +13,32 @@ import { BehaviorSubject } from 'rxjs'; }) export class InternetConnectionService{ - protected readonly window = inject(DOCUMENT).defaultView; - protected readonly navigator = this.window.navigator; +protected readonly window = inject(DOCUMENT).defaultView; +protected readonly navigator = this.window.navigator; - /* BehaviorSubject */ - private status$ = new BehaviorSubject(navigator.onLine) +/* BehaviorSubject */ +private status$ = new BehaviorSubject(navigator.onLine) - /* creates writableSignal */ - private status = signal(navigator.onLine); +/* creates writableSignal */ +private status = signal(navigator.onLine); - /* READONLY ANGULAR SIGNAL */ - networkStatus = computed(() => this.status()) +/* READONLY ANGULAR SIGNAL */ +networkStatus = computed(() => this.status()) - constructor(){ - this.window.addEventListener('offline', () => this.setStatus()); - this.window.addEventListener('online', () => this.setStatus()); - } +constructor(){ + this.window.addEventListener('offline', () => this.setStatus()); + this.window.addEventListener('online', () => this.setStatus()); +} - private setStatus(){ - this.status.set(navigator.onLine) - this.status$.next(navigator.onLine) - } +private setStatus(){ + this.status.set(navigator.onLine) + this.status$.next(navigator.onLine) +} - /* returns OBSERVABLE */ - get networkStatus$(){ - return this.status$.asObservable() - } +/* returns OBSERVABLE */ +get networkStatus$(){ + return this.status$.asObservable() +} } ``` @@ -56,15 +56,15 @@ As you can see from the code above, `InternetConnectionService` is providing 2 a **You can get via signal** ```js class someComponent{ - internetConnectionService = inject(InternetConnectionService); - isOnline = this.internetConnectionService.networkStatus +internetConnectionService = inject(InternetConnectionService); +isOnline = this.internetConnectionService.networkStatus } ``` **or you can get as observable** ```js class someComponent{ - internetConnectionService = inject(InternetConnectionService); - isOnline = this.internetConnectionService.networkStatus$ +internetConnectionService = inject(InternetConnectionService); +isOnline = this.internetConnectionService.networkStatus$ } ``` From 0036bbb91be8d2bc02b3e5f417be19bf74b4178a Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 10 Jul 2023 08:39:59 +0300 Subject: [PATCH 021/165] fixing space problem in doc --- .../UI/Angular/Internet-Connection-Service.md | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/en/UI/Angular/Internet-Connection-Service.md b/docs/en/UI/Angular/Internet-Connection-Service.md index 2e8f23ff3b..1107e64743 100644 --- a/docs/en/UI/Angular/Internet-Connection-Service.md +++ b/docs/en/UI/Angular/Internet-Connection-Service.md @@ -13,32 +13,32 @@ import { BehaviorSubject } from 'rxjs'; }) export class InternetConnectionService{ -protected readonly window = inject(DOCUMENT).defaultView; -protected readonly navigator = this.window.navigator; + protected readonly window = inject(DOCUMENT).defaultView; + protected readonly navigator = this.window.navigator; -/* BehaviorSubject */ -private status$ = new BehaviorSubject(navigator.onLine) + /* BehaviorSubject */ + private status$ = new BehaviorSubject(navigator.onLine) -/* creates writableSignal */ -private status = signal(navigator.onLine); + /* creates writableSignal */ + private status = signal(navigator.onLine); -/* READONLY ANGULAR SIGNAL */ -networkStatus = computed(() => this.status()) + /* READONLY ANGULAR SIGNAL */ + networkStatus = computed(() => this.status()) -constructor(){ - this.window.addEventListener('offline', () => this.setStatus()); - this.window.addEventListener('online', () => this.setStatus()); -} + constructor(){ + this.window.addEventListener('offline', () => this.setStatus()); + this.window.addEventListener('online', () => this.setStatus()); + } -private setStatus(){ - this.status.set(navigator.onLine) - this.status$.next(navigator.onLine) -} + private setStatus(){ + this.status.set(navigator.onLine) + this.status$.next(navigator.onLine) + } -/* returns OBSERVABLE */ -get networkStatus$(){ - return this.status$.asObservable() -} + /* returns OBSERVABLE */ + get networkStatus$(){ + return this.status$.asObservable() + } } ``` @@ -56,15 +56,15 @@ As you can see from the code above, `InternetConnectionService` is providing 2 a **You can get via signal** ```js class someComponent{ -internetConnectionService = inject(InternetConnectionService); -isOnline = this.internetConnectionService.networkStatus + internetConnectionService = inject(InternetConnectionService); + isOnline = this.internetConnectionService.networkStatus } ``` **or you can get as observable** ```js class someComponent{ -internetConnectionService = inject(InternetConnectionService); -isOnline = this.internetConnectionService.networkStatus$ + internetConnectionService = inject(InternetConnectionService); + isOnline = this.internetConnectionService.networkStatus$ } ``` From 55a3dbae58de19841c5bd2796ba258e96a078711 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 10 Jul 2023 08:42:08 +0300 Subject: [PATCH 022/165] fixing space problem in doc --- .../UI/Angular/Internet-Connection-Service.md | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/en/UI/Angular/Internet-Connection-Service.md b/docs/en/UI/Angular/Internet-Connection-Service.md index 1107e64743..a590b235b5 100644 --- a/docs/en/UI/Angular/Internet-Connection-Service.md +++ b/docs/en/UI/Angular/Internet-Connection-Service.md @@ -13,32 +13,32 @@ import { BehaviorSubject } from 'rxjs'; }) export class InternetConnectionService{ - protected readonly window = inject(DOCUMENT).defaultView; - protected readonly navigator = this.window.navigator; - - /* BehaviorSubject */ - private status$ = new BehaviorSubject(navigator.onLine) - - /* creates writableSignal */ - private status = signal(navigator.onLine); - - /* READONLY ANGULAR SIGNAL */ - networkStatus = computed(() => this.status()) - - constructor(){ - this.window.addEventListener('offline', () => this.setStatus()); - this.window.addEventListener('online', () => this.setStatus()); - } - - private setStatus(){ - this.status.set(navigator.onLine) - this.status$.next(navigator.onLine) - } - - /* returns OBSERVABLE */ - get networkStatus$(){ - return this.status$.asObservable() - } + protected readonly window = inject(DOCUMENT).defaultView; + protected readonly navigator = this.window.navigator; + + /* BehaviorSubject */ + private status$ = new BehaviorSubject(navigator.onLine) + + /* creates writableSignal */ +private status = signal(navigator.onLine); + + /* READONLY ANGULAR SIGNAL */ + networkStatus = computed(() => this.status()) + + constructor(){ + this.window.addEventListener('offline', () => this.setStatus()); + this.window.addEventListener('online', () => this.setStatus()); + } + + private setStatus(){ + this.status.set(navigator.onLine) + this.status$.next(navigator.onLine) + } + + /* returns OBSERVABLE */ + get networkStatus$(){ + return this.status$.asObservable() + } } ``` @@ -56,15 +56,15 @@ As you can see from the code above, `InternetConnectionService` is providing 2 a **You can get via signal** ```js class someComponent{ - internetConnectionService = inject(InternetConnectionService); - isOnline = this.internetConnectionService.networkStatus + internetConnectionService = inject(InternetConnectionService); + isOnline = this.internetConnectionService.networkStatus } ``` **or you can get as observable** ```js class someComponent{ - internetConnectionService = inject(InternetConnectionService); - isOnline = this.internetConnectionService.networkStatus$ + internetConnectionService = inject(InternetConnectionService); + isOnline = this.internetConnectionService.networkStatus$ } ``` From 1c7137ea206b6edb349cd7128995680a96c6c2a0 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 10 Jul 2023 08:45:27 +0300 Subject: [PATCH 023/165] fixing space problem in doc --- .../UI/Angular/Internet-Connection-Service.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/en/UI/Angular/Internet-Connection-Service.md b/docs/en/UI/Angular/Internet-Connection-Service.md index a590b235b5..146d43f21f 100644 --- a/docs/en/UI/Angular/Internet-Connection-Service.md +++ b/docs/en/UI/Angular/Internet-Connection-Service.md @@ -13,31 +13,31 @@ import { BehaviorSubject } from 'rxjs'; }) export class InternetConnectionService{ - protected readonly window = inject(DOCUMENT).defaultView; - protected readonly navigator = this.window.navigator; + protected readonly window = inject(DOCUMENT).defaultView; + protected readonly navigator = this.window.navigator; /* BehaviorSubject */ - private status$ = new BehaviorSubject(navigator.onLine) + private status$ = new BehaviorSubject(navigator.onLine) /* creates writableSignal */ -private status = signal(navigator.onLine); + private status = signal(navigator.onLine); /* READONLY ANGULAR SIGNAL */ - networkStatus = computed(() => this.status()) + networkStatus = computed(() => this.status()) constructor(){ this.window.addEventListener('offline', () => this.setStatus()); - this.window.addEventListener('online', () => this.setStatus()); + this.window.addEventListener('online', () => this.setStatus()); } - private setStatus(){ + private setStatus(){ this.status.set(navigator.onLine) this.status$.next(navigator.onLine) } /* returns OBSERVABLE */ - get networkStatus$(){ - return this.status$.asObservable() + get networkStatus$(){ + return this.status$.asObservable() } } ``` From 89e683f83a6210ada888907b450bbaf247f70486 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 10 Jul 2023 08:47:20 +0300 Subject: [PATCH 024/165] fixing space problem in doc --- docs/en/UI/Angular/Internet-Connection-Service.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/UI/Angular/Internet-Connection-Service.md b/docs/en/UI/Angular/Internet-Connection-Service.md index 146d43f21f..4405d6c2c2 100644 --- a/docs/en/UI/Angular/Internet-Connection-Service.md +++ b/docs/en/UI/Angular/Internet-Connection-Service.md @@ -9,7 +9,7 @@ import { Injectable, computed, inject, signal } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ - providedIn: 'root', + providedIn: 'root', }) export class InternetConnectionService{ @@ -31,13 +31,13 @@ export class InternetConnectionService{ } private setStatus(){ - this.status.set(navigator.onLine) - this.status$.next(navigator.onLine) + this.status.set(navigator.onLine) + this.status$.next(navigator.onLine) } /* returns OBSERVABLE */ get networkStatus$(){ - return this.status$.asObservable() + return this.status$.asObservable() } } ``` From 64ee7ce75038180cc6ddffb4c5ed020e31a7b300 Mon Sep 17 00:00:00 2001 From: Masum ULU <49063256+masumulu28@users.noreply.github.com> Date: Mon, 10 Jul 2023 09:28:51 +0300 Subject: [PATCH 025/165] Change sample language in docs --- docs/en/UI/Angular/Internet-Connection-Service.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/en/UI/Angular/Internet-Connection-Service.md b/docs/en/UI/Angular/Internet-Connection-Service.md index 4405d6c2c2..aa1f0d6770 100644 --- a/docs/en/UI/Angular/Internet-Connection-Service.md +++ b/docs/en/UI/Angular/Internet-Connection-Service.md @@ -3,15 +3,14 @@ ### internet-connection-service.ts -```js +```ts import { DOCUMENT } from '@angular/common'; import { Injectable, computed, inject, signal } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ - providedIn: 'root', + providedIn: 'root', }) - export class InternetConnectionService{ protected readonly window = inject(DOCUMENT).defaultView; protected readonly navigator = this.window.navigator; @@ -54,18 +53,18 @@ As you can see from the code above, `InternetConnectionService` is providing 2 a İt's easy just inject the service and get network status **You can get via signal** -```js +```ts class someComponent{ internetConnectionService = inject(InternetConnectionService); isOnline = this.internetConnectionService.networkStatus } ``` **or you can get as observable** -```js +```ts class someComponent{ internetConnectionService = inject(InternetConnectionService); isOnline = this.internetConnectionService.networkStatus$ } ``` -That's all, feel free to try on your template \ No newline at end of file +That's all, feel free to try on your template From 2c05ca21663afdf4901c38cdf969e2fd861c1fc4 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 21 Jul 2023 13:32:47 +0300 Subject: [PATCH 026/165] fixed test file --- .../lib/tests/internet-connection.service.spec.ts | 13 ++++++------- .../internet-connection-status.component.ts | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts index 397f362781..9181f430d4 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts @@ -4,7 +4,8 @@ import { InternetConnectionService } from '../services/internet-connection-servi describe('InternetConnectionService', () => { let service: InternetConnectionService; - + const internetConnectionStatus = window.navigator.onLine + beforeEach(() => { TestBed.configureTestingModule({}); service = TestBed.inject(InternetConnectionService); @@ -14,15 +15,13 @@ describe('InternetConnectionService', () => { expect(service).toBeTruthy(); }); - it('#networkStatus should return real value (true | false)', () => { - expect(typeof service.networkStatus()).toEqual('boolean') - expect(typeof !service.networkStatus()).toEqual('boolean') + it('networkStatus value should be same with current internetConnectionStatus', () => { + expect(service.networkStatus()).toEqual(internetConnectionStatus) }); - it('#networkStatus$ should return real value (true | false)', () => { + it('networkStatus$ return value should be with the current internetConnectionStatus', () => { service.networkStatus$.subscribe(val=>{ - expect(typeof val).toEqual('boolean') - expect(typeof !val).toEqual('boolean') + expect(val).toEqual(internetConnectionStatus) }) }); }); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts index 4ad473141a..5592e748a3 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, computed, inject } from '@angular/core'; import { NgIf } from '@angular/common' import { InternetConnectionService , LocalizationModule } from '@abp/ng.core'; @@ -43,5 +43,5 @@ import { InternetConnectionService , LocalizationModule } from '@abp/ng.core'; }) export class InternetConnectionStatusComponent{ internetConnectionService = inject(InternetConnectionService); - isOnline = this.internetConnectionService.networkStatus + isOnline = computed(() => this.internetConnectionService.networkStatus()) } From 23dc05911cda31355d5072097ab3c5ae9653f364 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 24 Jul 2023 16:49:10 +0300 Subject: [PATCH 027/165] updating test file --- .../services/internet-connection-service.ts | 9 +-- .../tests/internet-connection.service.spec.ts | 56 ++++++++++++++----- .../internet-connection-status.component.ts | 2 +- 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts index 9fc298386b..ebf15a9a25 100644 --- a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts @@ -6,12 +6,13 @@ import { BehaviorSubject } from 'rxjs'; providedIn: 'root', }) export class InternetConnectionService{ - protected readonly window = inject(DOCUMENT).defaultView; - protected readonly navigator = this.window.navigator; + readonly document = inject(DOCUMENT) + readonly window = this.document.defaultView; + readonly navigator = this.window.navigator; - private status$ = new BehaviorSubject(navigator.onLine) + private status$ = new BehaviorSubject(this.navigator.onLine) - private status = signal(navigator.onLine); + private status = signal(this.navigator.onLine); networkStatus = computed(() => this.status()) diff --git a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts index 9181f430d4..c5dc4bb7c5 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts @@ -1,27 +1,57 @@ -import { TestBed } from '@angular/core/testing'; +import { TestBed} from '@angular/core/testing'; +import { DOCUMENT } from '@angular/common'; import { InternetConnectionService } from '../services/internet-connection-service'; -describe('InternetConnectionService', () => { - let service: InternetConnectionService; - const internetConnectionStatus = window.navigator.onLine +let service: InternetConnectionService; + +describe('Internet connection when disconnected', () => { + let mockDocument = { defaultView: {navigator: {onLine: false}, addEventListener: jest.fn()} } beforeEach(() => { - TestBed.configureTestingModule({}); + TestBed.configureTestingModule({ + providers:[{provide:DOCUMENT, useValue: mockDocument}] + }) service = TestBed.inject(InternetConnectionService); }); - it('should be created', () => { - expect(service).toBeTruthy(); + it('document should be created', () => { + expect(service.document).toEqual(mockDocument); }); - it('networkStatus value should be same with current internetConnectionStatus', () => { - expect(service.networkStatus()).toEqual(internetConnectionStatus) + it('signal value should be false', () => { + expect(service.networkStatus()).toEqual(false); }); - it('networkStatus$ return value should be with the current internetConnectionStatus', () => { - service.networkStatus$.subscribe(val=>{ - expect(val).toEqual(internetConnectionStatus) - }) + it('observable value should be false', + (done: any) => { + service.networkStatus$.subscribe(value => { + expect(value).toBe(false) + done(); + }); }); }); + +describe('Internet connection when connected', () => { + let mockDocument = { defaultView: {navigator: {onLine: true}, addEventListener: jest.fn()} } + + beforeEach(() => { + TestBed.configureTestingModule({ + providers:[{provide:DOCUMENT, useValue: mockDocument}] + }) + service = TestBed.inject(InternetConnectionService); + }); + + + it('signal value should be true', () => { + expect(service.networkStatus()).toEqual(true); + }); + + it('observable value should be true', + (done: any) => { + service.networkStatus$.subscribe(value => { + expect(value).toBe(true) + done(); + }); + }); +}); \ No newline at end of file diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts index 5592e748a3..e649555f40 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/internet-connection-status/internet-connection-status.component.ts @@ -43,5 +43,5 @@ import { InternetConnectionService , LocalizationModule } from '@abp/ng.core'; }) export class InternetConnectionStatusComponent{ internetConnectionService = inject(InternetConnectionService); - isOnline = computed(() => this.internetConnectionService.networkStatus()) + isOnline = this.internetConnectionService.networkStatus } From 503a05cb84314f172504be362438b04462d7d68c Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 24 Jul 2023 17:08:55 +0300 Subject: [PATCH 028/165] update test --- .../src/lib/tests/internet-connection.service.spec.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts index c5dc4bb7c5..b1ad298502 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts @@ -2,6 +2,7 @@ import { TestBed} from '@angular/core/testing'; import { DOCUMENT } from '@angular/common'; import { InternetConnectionService } from '../services/internet-connection-service'; +import { first, takeLast } from 'rxjs'; let service: InternetConnectionService; @@ -25,8 +26,8 @@ describe('Internet connection when disconnected', () => { it('observable value should be false', (done: any) => { - service.networkStatus$.subscribe(value => { - expect(value).toBe(false) + service.networkStatus$.pipe(first()).subscribe(value => { + expect(value).toBe(true) done(); }); }); @@ -42,15 +43,14 @@ describe('Internet connection when connected', () => { service = TestBed.inject(InternetConnectionService); }); - it('signal value should be true', () => { expect(service.networkStatus()).toEqual(true); }); it('observable value should be true', (done: any) => { - service.networkStatus$.subscribe(value => { - expect(value).toBe(true) + service.networkStatus$.pipe(first()).subscribe(value => { + expect(value).toBe(false) done(); }); }); From 42918354ba7c50dbc6ccfafd99d3ecc94f8cb867 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 24 Jul 2023 17:10:06 +0300 Subject: [PATCH 029/165] fix test --- .../core/src/lib/tests/internet-connection.service.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts index b1ad298502..d1625c8db8 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts @@ -27,7 +27,7 @@ describe('Internet connection when disconnected', () => { it('observable value should be false', (done: any) => { service.networkStatus$.pipe(first()).subscribe(value => { - expect(value).toBe(true) + expect(value).toBe(false) done(); }); }); @@ -50,7 +50,7 @@ describe('Internet connection when connected', () => { it('observable value should be true', (done: any) => { service.networkStatus$.pipe(first()).subscribe(value => { - expect(value).toBe(false) + expect(value).toBe(true) done(); }); }); From 1255f8803451ac957624c27f488afecc3a2fad0c Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Tue, 25 Jul 2023 12:02:35 +0300 Subject: [PATCH 030/165] add test 'when internet connection value changes' --- .../services/internet-connection-service.ts | 10 ++--- .../tests/internet-connection.service.spec.ts | 41 ++++++++++++++++++- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts index ebf15a9a25..d74e65d036 100644 --- a/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/internet-connection-service.ts @@ -17,13 +17,13 @@ export class InternetConnectionService{ networkStatus = computed(() => this.status()) constructor(){ - this.window.addEventListener('offline', () => this.setStatus()); - this.window.addEventListener('online', () => this.setStatus()); + this.window.addEventListener('offline', () => this.setStatus(false)); + this.window.addEventListener('online', () => this.setStatus(true)); } - private setStatus(){ - this.status.set(navigator.onLine) - this.status$.next(navigator.onLine) + setStatus(val:boolean){ + this.status.set(val) + this.status$.next(val) } get networkStatus$(){ diff --git a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts index d1625c8db8..31a63f9006 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts @@ -2,7 +2,8 @@ import { TestBed} from '@angular/core/testing'; import { DOCUMENT } from '@angular/common'; import { InternetConnectionService } from '../services/internet-connection-service'; -import { first, takeLast } from 'rxjs'; +import { BehaviorSubject, first, of, takeLast } from 'rxjs'; +import { computed, signal } from '@angular/core'; let service: InternetConnectionService; @@ -54,4 +55,42 @@ describe('Internet connection when connected', () => { done(); }); }); +}); + +describe('when connection value changes', () => { + let mockDocument = { defaultView: {navigator: {onLine: true}, addEventListener: (eventName,cb)=>{ + window.addEventListener(eventName,cb) + }, dispatchEvent: function(event){ + this.navigator.onLine = !this.navigator.onLine + }}} + + beforeEach(() => { + TestBed.configureTestingModule({ + providers:[{provide:DOCUMENT, useValue: mockDocument}] + }) + service = TestBed.inject(InternetConnectionService); + }); + + it('check is signal value changes', () => { + expect(service.networkStatus()).toEqual(true); + const event = new Event("offline"); + service.window.dispatchEvent(event) + service.setStatus(service.window.navigator.onLine) + expect(service.networkStatus()).toEqual(false); + }); + + it('check is observable value changes',(done: any) => { + const event = new Event("online"); + service.window.dispatchEvent(event) + service.networkStatus$.pipe(first()).subscribe(value => { + expect(value).toEqual(true) + done() + }); + service.window.dispatchEvent(event) + service.setStatus(service.window.navigator.onLine) + service.networkStatus$.pipe().subscribe(value => { + expect(value).toEqual(false) + done() + }); + }); }); \ No newline at end of file From 0f9d77351a4617e41d8d554494112279b93a2d5e Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Tue, 25 Jul 2023 15:01:24 +0300 Subject: [PATCH 031/165] Add example test --- .../tests/internet-connection.service.spec.ts | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts index 31a63f9006..97f009d931 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts @@ -2,15 +2,18 @@ import { TestBed} from '@angular/core/testing'; import { DOCUMENT } from '@angular/common'; import { InternetConnectionService } from '../services/internet-connection-service'; -import { BehaviorSubject, first, of, takeLast } from 'rxjs'; -import { computed, signal } from '@angular/core'; +import { first } from 'rxjs'; let service: InternetConnectionService; describe('Internet connection when disconnected', () => { - let mockDocument = { defaultView: {navigator: {onLine: false}, addEventListener: jest.fn()} } - - beforeEach(() => { + const events = {}; + const addEventListener = jest.fn((event, callback) => { + events[event] = callback; + }); + const mockDocument = { defaultView: {navigator: {onLine: false}, addEventListener } } + + beforeAll(() => { TestBed.configureTestingModule({ providers:[{provide:DOCUMENT, useValue: mockDocument}] }) @@ -32,11 +35,21 @@ describe('Internet connection when disconnected', () => { done(); }); }); + + test.each(['offline',"online"])('should addEventListener for "%i",event',(v)=>{ + expect(events[v]).toBeTruthy() + }) + + test.each([['offline',false],["online",true]])('should called %i, then value must be %i',(eventName,value)=>{ + events[eventName]() + expect(service.networkStatus()).toEqual(value); + }) + }); describe('Internet connection when connected', () => { - let mockDocument = { defaultView: {navigator: {onLine: true}, addEventListener: jest.fn()} } - + const mockDocument = { defaultView: {navigator: {onLine: true}, addEventListener: jest.fn()} } + beforeEach(() => { TestBed.configureTestingModule({ providers:[{provide:DOCUMENT, useValue: mockDocument}] @@ -58,9 +71,9 @@ describe('Internet connection when connected', () => { }); describe('when connection value changes', () => { - let mockDocument = { defaultView: {navigator: {onLine: true}, addEventListener: (eventName,cb)=>{ + const mockDocument = { defaultView: {navigator: {onLine: true}, addEventListener: (eventName,cb)=>{ window.addEventListener(eventName,cb) - }, dispatchEvent: function(event){ + }, dispatchEvent: function(){ this.navigator.onLine = !this.navigator.onLine }}} @@ -70,7 +83,7 @@ describe('when connection value changes', () => { }) service = TestBed.inject(InternetConnectionService); }); - + it('check is signal value changes', () => { expect(service.networkStatus()).toEqual(true); const event = new Event("offline"); @@ -93,4 +106,4 @@ describe('when connection value changes', () => { done() }); }); -}); \ No newline at end of file +}); From dc04ad9757def8a3b664e66b69888210e19b380f Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Tue, 25 Jul 2023 22:44:28 +0300 Subject: [PATCH 032/165] updating test file --- .../tests/internet-connection.service.spec.ts | 85 +++++++++---------- 1 file changed, 38 insertions(+), 47 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts index 97f009d931..b4809471eb 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/internet-connection.service.spec.ts @@ -12,7 +12,6 @@ describe('Internet connection when disconnected', () => { events[event] = callback; }); const mockDocument = { defaultView: {navigator: {onLine: false}, addEventListener } } - beforeAll(() => { TestBed.configureTestingModule({ providers:[{provide:DOCUMENT, useValue: mockDocument}] @@ -36,74 +35,66 @@ describe('Internet connection when disconnected', () => { }); }); - test.each(['offline',"online"])('should addEventListener for "%i",event',(v)=>{ + test.each(['offline','online'])('should addEventListener for %p, event',(v)=>{ expect(events[v]).toBeTruthy() }) - test.each([['offline',false],["online",true]])('should called %i, then value must be %i',(eventName,value)=>{ + test.each([['offline',false],["online",true]])('when %p called ,then signal value must be %p',(eventName,value)=>{ events[eventName]() expect(service.networkStatus()).toEqual(value); }) + test.each([['offline',false],["online",true]])('when %p called,then observable must return %p',(eventName,value)=>{ + events[eventName]() + service.networkStatus$.subscribe(val=>{ + expect(val).toEqual(value) + }) + }) }); -describe('Internet connection when connected', () => { - const mockDocument = { defaultView: {navigator: {onLine: true}, addEventListener: jest.fn()} } - - beforeEach(() => { +describe('when connection value changes for signals', () => { + const events = {}; + const addEventListener = jest.fn((event, callback) => { + events[event] = callback; + }); + const mockDocument = { defaultView: {navigator: {onLine: false}, addEventListener } } + beforeAll(() => { TestBed.configureTestingModule({ providers:[{provide:DOCUMENT, useValue: mockDocument}] }) service = TestBed.inject(InternetConnectionService); }); - it('signal value should be true', () => { + it('signal value must be false when offline event is called while internet is connected', () => { + events['online']() expect(service.networkStatus()).toEqual(true); + events['offline']() + expect(service.networkStatus()).toEqual(false); }); - it('observable value should be true', - (done: any) => { - service.networkStatus$.pipe(first()).subscribe(value => { - expect(value).toBe(true) - done(); - }); + it('signal value must be true when online event is called while internet is disconnected', () => { + events['offline']() + expect(service.networkStatus()).toEqual(false); + events['online']() + expect(service.networkStatus()).toEqual(true); }); -}); - -describe('when connection value changes', () => { - const mockDocument = { defaultView: {navigator: {onLine: true}, addEventListener: (eventName,cb)=>{ - window.addEventListener(eventName,cb) - }, dispatchEvent: function(){ - this.navigator.onLine = !this.navigator.onLine - }}} - beforeEach(() => { - TestBed.configureTestingModule({ - providers:[{provide:DOCUMENT, useValue: mockDocument}] + it('observable value must be false when offline event is called while internet is connected', (done:any) => { + events['online']() + events['offline']() + service.networkStatus$.subscribe(val=>{ + expect(val).toEqual(false) + done() }) - service = TestBed.inject(InternetConnectionService); }); - it('check is signal value changes', () => { - expect(service.networkStatus()).toEqual(true); - const event = new Event("offline"); - service.window.dispatchEvent(event) - service.setStatus(service.window.navigator.onLine) - expect(service.networkStatus()).toEqual(false); - }); - - it('check is observable value changes',(done: any) => { - const event = new Event("online"); - service.window.dispatchEvent(event) - service.networkStatus$.pipe(first()).subscribe(value => { - expect(value).toEqual(true) - done() - }); - service.window.dispatchEvent(event) - service.setStatus(service.window.navigator.onLine) - service.networkStatus$.pipe().subscribe(value => { - expect(value).toEqual(false) + it('observable value must be true when online event is called while internet is disconnected', (done:any) => { + events['offline']() + events['online']() + service.networkStatus$.subscribe(val=>{ + console.log(val); + expect(val).toEqual(true) done() - }); + }) }); -}); +}); \ No newline at end of file From 333e6ffee2ebf76040f36ee8d3e5c6d5d4e2ed69 Mon Sep 17 00:00:00 2001 From: Volosoft Agent <43883821+voloagent@users.noreply.github.com> Date: Thu, 27 Jul 2023 11:15:40 +0300 Subject: [PATCH 033/165] Update latest-versions.json to version 7.3.1 --- latest-versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latest-versions.json b/latest-versions.json index 6046b25a92..63b21fe317 100644 --- a/latest-versions.json +++ b/latest-versions.json @@ -1,6 +1,6 @@ [ { - "version": "7.3.0", + "version": "7.3.1", "releaseDate": "", "type": "stable", "message": "" From 2e7d1bf8eea15f9fc1ceeacaf5a3787e5dfc66ab Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 28 Jul 2023 11:40:49 +0800 Subject: [PATCH 034/165] Add `AbpIdentityUserValidator`. --- .../AspNetCore/AbpIdentityAspNetCoreModule.cs | 3 +- .../Volo/Abp/Identity/Localization/ar.json | 1 + .../Volo/Abp/Identity/Localization/cs.json | 1 + .../Volo/Abp/Identity/Localization/de.json | 1 + .../Volo/Abp/Identity/Localization/el.json | 1 + .../Volo/Abp/Identity/Localization/en-GB.json | 1 + .../Volo/Abp/Identity/Localization/en.json | 1 + .../Volo/Abp/Identity/Localization/es.json | 1 + .../Volo/Abp/Identity/Localization/fa.json | 1 + .../Volo/Abp/Identity/Localization/fi.json | 1 + .../Volo/Abp/Identity/Localization/fr.json | 1 + .../Volo/Abp/Identity/Localization/hi.json | 1 + .../Volo/Abp/Identity/Localization/hr.json | 1 + .../Volo/Abp/Identity/Localization/hu.json | 1 + .../Volo/Abp/Identity/Localization/is.json | 1 + .../Volo/Abp/Identity/Localization/it.json | 1 + .../Volo/Abp/Identity/Localization/nl.json | 1 + .../Volo/Abp/Identity/Localization/pl-PL.json | 1 + .../Volo/Abp/Identity/Localization/pt-BR.json | 1 + .../Volo/Abp/Identity/Localization/ro-RO.json | 1 + .../Volo/Abp/Identity/Localization/ru.json | 1 + .../Volo/Abp/Identity/Localization/sk.json | 1 + .../Volo/Abp/Identity/Localization/sl.json | 1 + .../Volo/Abp/Identity/Localization/tr.json | 1 + .../Volo/Abp/Identity/Localization/vi.json | 1 + .../Abp/Identity/Localization/zh-Hans.json | 1 + .../Abp/Identity/Localization/zh-Hant.json | 1 + .../Abp/Identity/AbpIdentityUserValidator.cs | 48 +++++++++++++++++++ .../AbpIdentityUserValidator_Tests.cs | 36 ++++++++++++++ 29 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs create mode 100644 modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs index 93d8a52ee7..974f81a201 100644 --- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs @@ -16,7 +16,8 @@ public class AbpIdentityAspNetCoreModule : AbpModule builder .AddDefaultTokenProviders() .AddTokenProvider(LinkUserTokenProviderConsts.LinkUserTokenProviderName) - .AddSignInManager(); + .AddSignInManager() + .AddUserValidator(); }); } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json index 490bd611df..7985177c6e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "اسم الدور '{0}' غير صالح.", "Volo.Abp.Identity:InvalidToken": "غير صالح token.", "Volo.Abp.Identity:InvalidUserName": "اسم المستخدم '{0}' غير صالح ، يمكن أن يحتوي على أحرف أو أرقام فقط.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "لااسم المستخدم '{0}' غير صالح ، لا يمكنك استخدام البريد الإلكتروني لمستخدم آخر كاسم المستخدم الخاص بك.", "Volo.Abp.Identity:LoginAlreadyAssociated": "يوجد مستخدم لديه معلومات تسجيل الدخول هذه بالفعل.", "Volo.Abp.Identity:PasswordMismatch": "كلمة مرور غير صحيحة.", "Volo.Abp.Identity:PasswordRequiresDigit": "يجب أن تحتوي كلمات المرور على رقم واحد على الأقل ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json index 7f2ddde421..db8eef485f 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role '{0}' je neplatná.", "Volo.Abp.Identity:InvalidToken": "Neplatný token.", "Volo.Abp.Identity:InvalidUserName": "Uživatelské jméno '{0}' je neplatné, může obsahovat pouze písmena a číslice.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Uživatelské jméno '{0}' je neplatné, Nemůžete použít email jiného uživatele jako své uživatelské jméno.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Uživatel s tímto přihlášením již existuje.", "Volo.Abp.Identity:PasswordMismatch": "Chybné heslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Hesla musí obsahovat alespoň jednu číslici ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json index 69f2e9e9b2..10b056e9da 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Der Rollenname '{0}' ist ungültig.", "Volo.Abp.Identity:InvalidToken": "Ungültiger Token.", "Volo.Abp.Identity:InvalidUserName": "Der Benutzername '{0}' ist ungültig und darf nur Buchstaben oder Ziffern enthalten.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Der Benutzername '{0}' ist ungültig, Sie können nicht die E-Mail-Adresse eines anderen Benutzers als Ihren Benutzernamen verwenden.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Ein Benutzer mit diesem Login existiert bereits.", "Volo.Abp.Identity:PasswordMismatch": "Falsches Passwort.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwörter müssen mindestens eine Ziffer haben ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json index 765d85ce09..f2cf0e2d81 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json @@ -47,6 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Το όνομα ρόλου '{0}' δεν είναι έγκυρο.", "Volo.Abp.Identity:InvalidToken": "Μη έγκυρο διακριτικό.", "Volo.Abp.Identity:InvalidUserName": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο, μπορεί να περιέχει μόνο γράμματα ή ψηφία.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο, Δεν μπορείτε να χρησιμοποιήσετε το email ενός άλλου χρήστη ως όνομα χρήστη.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Ένας χρήστης με αυτήν τη σύνδεση υπάρχει ήδη.", "Volo.Abp.Identity:PasswordMismatch": "Λάθος κωδικός.", "Volo.Abp.Identity:PasswordRequiresDigit": "Οι κωδικοί πρόσβασης πρέπει να έχουν τουλάχιστον ένα ψηφίο ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json index adebfa33e8..5a94e0f816 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json @@ -47,6 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid, it should only contain letters or digits.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Username '{0}' is invalid, You cannot use another user's email as your Username.", "Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect password.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json index 724ec04300..738156140e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid, can only contain letters or digits.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Username '{0}' is invalid, You cannot use another user's email as your Username.", "Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect password.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json index 06c279ec73..3e0cbe0abc 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "El nombre de rol '{0}' no es válido.", "Volo.Abp.Identity:InvalidToken": "token no válido", "Volo.Abp.Identity:InvalidUserName": "Nombre de usuario '{0}' no es válido. Sólo puede contener letras o dígitos", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Nombre de usuario '{0}' no es válido. No puedes usar el e-mail de otro usuario como tu nombre de usuario.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Usuario con este inicio de sesión en uso.", "Volo.Abp.Identity:PasswordMismatch": "Contraseña incorrecta.", "Volo.Abp.Identity:PasswordRequiresDigit": "Contraseñas deben tener al menos un dígito ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json index 7a89cebc87..a0c1f743f9 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json @@ -47,6 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "عنوان نقش/وظیفه {0} نامعتبر است.", "Volo.Abp.Identity:InvalidToken": "گذرواژه وارد شده معتبر نیست.", "Volo.Abp.Identity:InvalidUserName": "نام کاربری '{0}' نامعتبر است، نام کاربری فقط می تواند شامل حروف یا ارقام باشد.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "شما نمی توانید از ایمیل کاربر دیگری به عنوان نام کاربری خود استفاده کنید.", "Volo.Abp.Identity:LoginAlreadyAssociated": "یک کاربر با این نام کاربری از قبل موجود می باشد.", "Volo.Abp.Identity:PasswordMismatch": "گذرواژه اشتباه است.", "Volo.Abp.Identity:PasswordRequiresDigit": "گذرواژه ها باید حداقل یک رقم داشته باشند ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json index d74257414a..ad4032eeb6 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Roolin nimi {0} on virheellinen.", "Volo.Abp.Identity:InvalidToken": "Virheellinen tunnus.", "Volo.Abp.Identity:InvalidUserName": "Käyttäjätunnus {0} on virheellinen, voi sisältää vain kirjaimia tai numeroita.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Käyttäjätunnus {0} on virheellinen, Et voi käyttää toisen käyttäjän sähköpostiosoitetta käyttäjänimenä.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Käyttäjä, jolla on tämä sisäänkirjautuminen, on jo olemassa.", "Volo.Abp.Identity:PasswordMismatch": "Väärä salasana.", "Volo.Abp.Identity:PasswordRequiresDigit": "Salasanoissa on oltava vähintään yksi numero ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json index 80a5f90a10..b4fe67f76b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Le nom de rôle '{0}' n’est pas valide.", "Volo.Abp.Identity:InvalidToken": "Jeton non valide.", "Volo.Abp.Identity:InvalidUserName": "Le nom d’utilisateur '{0}' n’est pas valide, ne peut contenir que des lettres ou des chiffres.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Le nom d’utilisateur '{0}' n’est pas valide,Vous ne pouvez pas utiliser l’e-mail d’un autre utilisateur comme nom d’utilisateur.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Un utilisateur avec cette connexion existe déjà.", "Volo.Abp.Identity:PasswordMismatch": "Mot de passe incorrect.", "Volo.Abp.Identity:PasswordRequiresDigit": "Les mots de passe doivent avoir au moins un chiffre ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json index e01e4c8e25..c6717ed5ac 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "भूमिका नाम '{0}' अमान्य है।", "Volo.Abp.Identity:InvalidToken": "अमान्य टोकन।", "Volo.Abp.Identity:InvalidUserName": "उपयोगकर्ता नाम '{0}' अमान्य है, इसमें केवल अक्षर या अंक हो सकते हैं।", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "उपयोगकर्ता नाम '{0}' अमान्य है, आप दूसरे उपयोगकर्ता का ईमेल नाम उपयोग नहीं कर सकते।", "Volo.Abp.Identity:LoginAlreadyAssociated": "इस लॉगिन वाला उपयोगकर्ता पहले से मौजूद है।", "Volo.Abp.Identity:PasswordMismatch": "गलत पासवर्ड।", "Volo.Abp.Identity:PasswordRequiresDigit": "पासवर्ड में कम से कम एक अंक ('0'-'9') होना चाहिए।", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json index a31715fc16..4890e944ea 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Naziv uloge '{0}' nije valjan.", "Volo.Abp.Identity:InvalidToken": "Pogrešan token.", "Volo.Abp.Identity:InvalidUserName": "Korisničko ime '{0}' nije važeće, može sadržavati samo slova ili znamenke.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Korisničko ime '{0}' nije važeće, Ne možete koristiti e-poštu drugog korisnika kao svoje korisničko ime.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Korisnik s ovom prijavom već postoji.", "Volo.Abp.Identity:PasswordMismatch": "Netočna lozinka.", "Volo.Abp.Identity:PasswordRequiresDigit": "Lozinke moraju imati najmanje jednu znamenku ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json index 8c658c9e89..2bbfeddcbf 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "'{0}' szerepkör név érvénytelen.", "Volo.Abp.Identity:InvalidToken": "Érvénytelen token.", "Volo.Abp.Identity:InvalidUserName": "'{0}' felhasználónév érvénytelen, csak betűket és számokat tartalmazhat.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "'{0}' felhasználónév érvénytelen, Nem használhatja más felhasználó email címét felhasználónévként.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Az ilyen bejelentkezéssel rendelkező felhasználó már létezik.", "Volo.Abp.Identity:PasswordMismatch": "Érvénytelen jelszó.", "Volo.Abp.Identity:PasswordRequiresDigit": "A jelszavaknak legalább egy számjegyet kell rendelkezniük ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json index c0bb4af19a..15a741a268 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Hlutverkanafnið '{0}' er ógilt.", "Volo.Abp.Identity:InvalidToken": "Ógilt token.", "Volo.Abp.Identity:InvalidUserName": "Notandanafnið '{0}' er ógilt, getur aðeins innihaldið bókstafi eða tölustafi.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Notandanafnið '{0}' er ógilt, Þú getur ekki notað netfang annars notanda sem notendanafn.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Notandi með þessa innskráningu er þegar til.", "Volo.Abp.Identity:PasswordMismatch": "Rangt lykilorð.", "Volo.Abp.Identity:PasswordRequiresDigit": "Lykilorð verða að hafa að minnsta kosti einn staf ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json index 513def4b52..eaf566930b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Il nome del ruolo '{0}' non è valido.", "Volo.Abp.Identity:InvalidToken": "Token non valido.", "Volo.Abp.Identity:InvalidUserName": "Il nome utente '{0}' non è valido, può contenere solo lettere o cifre.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Il nome utente '{0}' non è valido, Non puoi utilizzare l'email di un altro utente come nome utente.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Esiste già un utente con questo account.", "Volo.Abp.Identity:PasswordMismatch": "Password errata.", "Volo.Abp.Identity:PasswordRequiresDigit": "La password deve contenere almeno una cifra ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json index 472935418b..79ee163cd2 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Rol naam '{0}' is ongeldig.", "Volo.Abp.Identity:InvalidToken": "Ongeldig token.", "Volo.Abp.Identity:InvalidUserName": "Gebruikersnaam '{0}' is ongeldig, mag alleen letters of cijfers bevatten.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Gebruikersnaam '{0}' is ongeldig, U kunt het e-mailadres van een andere gebruiker niet als uw gebruikersnaam gebruiken.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Er bestaat al een gebruiker met deze login.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect wachtwoord.", "Volo.Abp.Identity:PasswordRequiresDigit": "Wachtwoorden moeten minimaal één cijfer bevatten ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json index 377c792ddf..36297c453a 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Rola '{0}' jest niepoprawna.", "Volo.Abp.Identity:InvalidToken": "Niepoprawny token.", "Volo.Abp.Identity:InvalidUserName": "Nazwa użytkownika '{0}' jest niepoprawna, może zawierać tylko litery i cyfry.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Nazwa użytkownika '{0}' jest niepoprawna, Nie możesz użyć adresu e-mail innego użytkownika jako swojej nazwy użytkownika.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Użytkownik o tym loginie już istnieje.", "Volo.Abp.Identity:PasswordMismatch": "Niepoprawne hasło.", "Volo.Abp.Identity:PasswordRequiresDigit": "Hasło musi zawierać przynajmniej jedną cyfrę ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json index c8807d2792..22936d80b1 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Perfil '{0}' inválido.", "Volo.Abp.Identity:InvalidToken": "Token inválido.", "Volo.Abp.Identity:InvalidUserName": "Usuário '{0}' é inválido, somente pode conter letras ou números.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Usuário '{0}' é inválido, Você não pode usar o e-mail de outro usuário como seu nome de usuário.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Um usuário com este login já existe.", "Volo.Abp.Identity:PasswordMismatch": "Senha incorreta.", "Volo.Abp.Identity:PasswordRequiresDigit": "Senhas devem possuir pelo menos um dígito ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json index d86eb4f1fa..ec0e22eb39 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Numele de rol '{0}' este invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Numele de utilizator '{0}' este invalid, poate conţine doar litere şi cifre.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Numele de utilizator '{0}' este invalid, Nu puteţi folosi adresa de email a altui utilizator ca nume de utilizator.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Un utilizator cu această autentificare există deja.", "Volo.Abp.Identity:PasswordMismatch": "Parolă incorectă.", "Volo.Abp.Identity:PasswordRequiresDigit": "Parolele trebuie să conţină cel puţin o cifră ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json index 73fd937af0..d584a5ac3d 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Имя роли '{0}' недопустимо.", "Volo.Abp.Identity:InvalidToken": "Недопустимый маркер.", "Volo.Abp.Identity:InvalidUserName": "Имя пользователя '{0}' недопустимо и может содержать только буквы или цифры.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Имя пользователя '{0}' недопустимо Вы не можете использовать электронную почту другого пользователя в качестве своего имени пользователя.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Пользователь с таким логином уже существует.", "Volo.Abp.Identity:PasswordMismatch": "Неверный пароль.", "Volo.Abp.Identity:PasswordRequiresDigit": "Пароль должен содержать по крайней мере одну цифру.", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json index 83eb3850ad..7083f2f494 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Názov roly '{0}' je neplatný.", "Volo.Abp.Identity:InvalidToken": "Neplatný token.", "Volo.Abp.Identity:InvalidUserName": "Používateľské meno '{0}' je neplatné, môže obsahovať len písmená alebo číslice.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Používateľské meno '{0}' je neplatné, Nemôžete použiť email iného používateľa ako svoje používateľské meno.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Používateľ s týmto prihlasovacím menom už existuje.", "Volo.Abp.Identity:PasswordMismatch": "Nesprávne heslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Heslá musia obsahovať aspoň jednu číslicu ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json index caa60a2d71..ce58ebdcf6 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Naziv vloge '{0}' ni veljaven.", "Volo.Abp.Identity:InvalidToken": "Neveljaven žeton.", "Volo.Abp.Identity:InvalidUserName": "Uporabniško ime '{0}' ni veljavno, vsebuje lahko le črke in številke.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Uporabniško ime '{0}' ni veljavno, Ne morete uporabiti e-poštnega naslova drugega uporabnika kot svojega uporabniškega imena.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Uporabnik s to prijavo že obstaja.", "Volo.Abp.Identity:PasswordMismatch": "Nepravilno geslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Gesla morajo imeti vsaj eno številko ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json index c8957dc3e7..83e21f3c58 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "'{0}' rol ismi geçersizdir.", "Volo.Abp.Identity:InvalidToken": "Geçersiz token.", "Volo.Abp.Identity:InvalidUserName": "'{0}' kullanıcı adı geçersiz, sadece harf ve rakamlardan oluşmalı.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "'{0}' kullanıcı adı geçersiz, Başka bir kullanıcının e-posta adresini kullanıcı adı olarak kullanamazsınız.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Bu giriş bilgilerine sahip bir kullanıcı zaten var.", "Volo.Abp.Identity:PasswordMismatch": "Hatalı şifre.", "Volo.Abp.Identity:PasswordRequiresDigit": "Şifre en az bir sayı içermeli ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json index 05dbe248a0..f17fcbfe0d 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Tên người dùng '{0}' Không hợp lệ.", "Volo.Abp.Identity:InvalidToken": "Token không hợp lệ.", "Volo.Abp.Identity:InvalidUserName": "Tên người dùng '{0}' không hợp lệ, chỉ có thể chứa chữ cái hoặc chữ số.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Tên người dùng '{0}' không hợp lệ, Bạn không thể sử dụng email của người dùng khác làm tên người dùng của mình.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Một người dùng có thông tin đăng nhập này đã tồn tại.", "Volo.Abp.Identity:PasswordMismatch": "Mật khẩu không đúng.", "Volo.Abp.Identity:PasswordRequiresDigit": "Mật khẩu phải có ít nhất một chữ số ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json index 095f5cef2f..df0183aa3f 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 无效.", "Volo.Abp.Identity:InvalidToken": "token无效.", "Volo.Abp.Identity:InvalidUserName": "用户名 '{0}' 无效, 只能包含字母或数字.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "用户名 '{0}' 无效, 不能使用其他用户的邮箱作为你的用户名.", "Volo.Abp.Identity:LoginAlreadyAssociated": "此登录名的用户已存在.", "Volo.Abp.Identity:PasswordMismatch": "密码错误.", "Volo.Abp.Identity:PasswordRequiresDigit": "密码至少包含一位数字 ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json index 936ad985f6..1a88eb9c37 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json @@ -48,6 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 無效.", "Volo.Abp.Identity:InvalidToken": "token無效.", "Volo.Abp.Identity:InvalidUserName": "使用者名稱 '{0}' 無效, 只能包含字母或數字.", + "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "使用者名稱 '{0}' 無效, 不能使用其他使用者的電子信箱作為你的使用者名稱.", "Volo.Abp.Identity:LoginAlreadyAssociated": "此登入名的使用者已存在.", "Volo.Abp.Identity:PasswordMismatch": "密碼錯誤.", "Volo.Abp.Identity:PasswordRequiresDigit": "密碼至少包含一位數字 ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs new file mode 100644 index 0000000000..e4b7217037 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Localization; +using Volo.Abp.Identity.Localization; + +namespace Volo.Abp.Identity +{ + public class AbpIdentityUserValidator : IUserValidator + { + protected IStringLocalizer Localizer { get; } + + public AbpIdentityUserValidator(IStringLocalizer localizer) + { + Localizer = localizer; + } + + public virtual async Task ValidateAsync(UserManager manager, IdentityUser user) + { + var describer = new IdentityErrorDescriber(); + + Check.NotNull(manager, nameof(manager)); + Check.NotNull(user, nameof(user)); + + var errors = new List(); + + var userName = await manager.GetUserNameAsync(user); + if (userName == null) + { + errors.Add(describer.InvalidUserName(null)); + } + else + { + var owner = await manager.FindByEmailAsync(userName); + if (owner != null && !string.Equals(await manager.GetUserIdAsync(owner), await manager.GetUserIdAsync(user))) + { + errors.Add(new IdentityError + { + Code = "InvalidUserName", + Description = Localizer["Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername", userName] + }); + } + } + + return errors.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success; + } + } +} diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs new file mode 100644 index 0000000000..105ce166d8 --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs @@ -0,0 +1,36 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Localization; +using Shouldly; +using Volo.Abp.Identity.Localization; +using Xunit; + +namespace Volo.Abp.Identity.AspNetCore; + +public class AbpIdentityUserValidator_Tests : AbpIdentityAspNetCoreTestBase +{ + private readonly IdentityUserManager _identityUserManager; + private readonly IStringLocalizer Localizer; + + public AbpIdentityUserValidator_Tests() + { + _identityUserManager = GetRequiredService(); + Localizer = GetRequiredService>(); + } + + [Fact] + public async Task Test() + { + var user1 = new IdentityUser(Guid.NewGuid(), "user1", "user1@volosoft.com"); + var identityResult = await _identityUserManager.CreateAsync(user1); + identityResult.Succeeded.ShouldBeTrue(); + + var user2 = new IdentityUser(Guid.NewGuid(), "user1@volosoft.com", "user2@volosoft.com"); + identityResult = await _identityUserManager.CreateAsync(user2); + identityResult.Succeeded.ShouldBeFalse(); + identityResult.Errors.Count().ShouldBe(1); + identityResult.Errors.First().Code.ShouldBe("InvalidUserName"); + identityResult.Errors.First().Description.ShouldBe(Localizer["Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername", "user1@volosoft.com"]); + } +} From 1420b53e262b7b7e80007952c9714c9e384cbe99 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 28 Jul 2023 11:42:25 +0800 Subject: [PATCH 035/165] Update AbpIdentityUserValidator_Tests.cs --- .../Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs index 105ce166d8..ac20b4894c 100644 --- a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs @@ -20,7 +20,7 @@ public class AbpIdentityUserValidator_Tests : AbpIdentityAspNetCoreTestBase } [Fact] - public async Task Test() + public async Task Can_Not_Use_Another_Users_Email_As_Your_Username_Test() { var user1 = new IdentityUser(Guid.NewGuid(), "user1", "user1@volosoft.com"); var identityResult = await _identityUserManager.CreateAsync(user1); From aa2a6020089f7d04a21da302a3fb46cc9245de5c Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 28 Jul 2023 12:55:44 +0800 Subject: [PATCH 036/165] Update localization texts. --- .../Volo/Abp/Identity/Localization/ar.json | 2 +- .../Volo/Abp/Identity/Localization/cs.json | 2 +- .../Volo/Abp/Identity/Localization/de.json | 2 +- .../Volo/Abp/Identity/Localization/el.json | 2 +- .../Volo/Abp/Identity/Localization/en-GB.json | 2 +- .../Volo/Abp/Identity/Localization/en.json | 2 +- .../Volo/Abp/Identity/Localization/es.json | 2 +- .../Volo/Abp/Identity/Localization/fa.json | 2 +- .../Volo/Abp/Identity/Localization/fi.json | 2 +- .../Volo/Abp/Identity/Localization/fr.json | 2 +- .../Volo/Abp/Identity/Localization/hi.json | 2 +- .../Volo/Abp/Identity/Localization/hr.json | 2 +- .../Volo/Abp/Identity/Localization/hu.json | 2 +- .../Volo/Abp/Identity/Localization/is.json | 2 +- .../Volo/Abp/Identity/Localization/it.json | 2 +- .../Volo/Abp/Identity/Localization/nl.json | 2 +- .../Volo/Abp/Identity/Localization/pl-PL.json | 2 +- .../Volo/Abp/Identity/Localization/pt-BR.json | 2 +- .../Volo/Abp/Identity/Localization/ro-RO.json | 2 +- .../Volo/Abp/Identity/Localization/ru.json | 2 +- .../Volo/Abp/Identity/Localization/sk.json | 2 +- .../Volo/Abp/Identity/Localization/sl.json | 2 +- .../Volo/Abp/Identity/Localization/tr.json | 2 +- .../Volo/Abp/Identity/Localization/vi.json | 2 +- .../Volo/Abp/Identity/Localization/zh-Hans.json | 2 +- .../Volo/Abp/Identity/Localization/zh-Hant.json | 2 +- .../Volo/Abp/Identity/AbpIdentityUserValidator.cs | 2 +- 27 files changed, 27 insertions(+), 27 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json index 7985177c6e..39c55dfb7c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "اسم الدور '{0}' غير صالح.", "Volo.Abp.Identity:InvalidToken": "غير صالح token.", "Volo.Abp.Identity:InvalidUserName": "اسم المستخدم '{0}' غير صالح ، يمكن أن يحتوي على أحرف أو أرقام فقط.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "لااسم المستخدم '{0}' غير صالح ، لا يمكنك استخدام البريد الإلكتروني لمستخدم آخر كاسم المستخدم الخاص بك.", + "InvalidUserName": "لااسم المستخدم '{0}' غير صالح .", "Volo.Abp.Identity:LoginAlreadyAssociated": "يوجد مستخدم لديه معلومات تسجيل الدخول هذه بالفعل.", "Volo.Abp.Identity:PasswordMismatch": "كلمة مرور غير صحيحة.", "Volo.Abp.Identity:PasswordRequiresDigit": "يجب أن تحتوي كلمات المرور على رقم واحد على الأقل ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json index db8eef485f..87d0b79066 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role '{0}' je neplatná.", "Volo.Abp.Identity:InvalidToken": "Neplatný token.", "Volo.Abp.Identity:InvalidUserName": "Uživatelské jméno '{0}' je neplatné, může obsahovat pouze písmena a číslice.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Uživatelské jméno '{0}' je neplatné, Nemůžete použít email jiného uživatele jako své uživatelské jméno.", + "InvalidUserName": "Uživatelské jméno '{0}' je neplatné.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Uživatel s tímto přihlášením již existuje.", "Volo.Abp.Identity:PasswordMismatch": "Chybné heslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Hesla musí obsahovat alespoň jednu číslici ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json index 10b056e9da..841752f211 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Der Rollenname '{0}' ist ungültig.", "Volo.Abp.Identity:InvalidToken": "Ungültiger Token.", "Volo.Abp.Identity:InvalidUserName": "Der Benutzername '{0}' ist ungültig und darf nur Buchstaben oder Ziffern enthalten.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Der Benutzername '{0}' ist ungültig, Sie können nicht die E-Mail-Adresse eines anderen Benutzers als Ihren Benutzernamen verwenden.", + "InvalidUserName": "Der Benutzername '{0}' ist ungültig.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Ein Benutzer mit diesem Login existiert bereits.", "Volo.Abp.Identity:PasswordMismatch": "Falsches Passwort.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwörter müssen mindestens eine Ziffer haben ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json index f2cf0e2d81..9316a29d39 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json @@ -47,7 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Το όνομα ρόλου '{0}' δεν είναι έγκυρο.", "Volo.Abp.Identity:InvalidToken": "Μη έγκυρο διακριτικό.", "Volo.Abp.Identity:InvalidUserName": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο, μπορεί να περιέχει μόνο γράμματα ή ψηφία.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο, Δεν μπορείτε να χρησιμοποιήσετε το email ενός άλλου χρήστη ως όνομα χρήστη.", + "InvalidUserName": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Ένας χρήστης με αυτήν τη σύνδεση υπάρχει ήδη.", "Volo.Abp.Identity:PasswordMismatch": "Λάθος κωδικός.", "Volo.Abp.Identity:PasswordRequiresDigit": "Οι κωδικοί πρόσβασης πρέπει να έχουν τουλάχιστον ένα ψηφίο ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json index 5a94e0f816..15e534ea67 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json @@ -47,7 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid, it should only contain letters or digits.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Username '{0}' is invalid, You cannot use another user's email as your Username.", + "InvalidUserName": "Username '{0}' is invalid.", "Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect password.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json index 738156140e..6de7c220e2 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid, can only contain letters or digits.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Username '{0}' is invalid, You cannot use another user's email as your Username.", + "InvalidUserName": "Username '{0}' is invalid.", "Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect password.", "Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json index 3e0cbe0abc..c70078845c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "El nombre de rol '{0}' no es válido.", "Volo.Abp.Identity:InvalidToken": "token no válido", "Volo.Abp.Identity:InvalidUserName": "Nombre de usuario '{0}' no es válido. Sólo puede contener letras o dígitos", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Nombre de usuario '{0}' no es válido. No puedes usar el e-mail de otro usuario como tu nombre de usuario.", + "InvalidUserName": "Nombre de usuario '{0}' no es válido.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Usuario con este inicio de sesión en uso.", "Volo.Abp.Identity:PasswordMismatch": "Contraseña incorrecta.", "Volo.Abp.Identity:PasswordRequiresDigit": "Contraseñas deben tener al menos un dígito ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json index a0c1f743f9..f349f080af 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json @@ -47,7 +47,7 @@ "Volo.Abp.Identity:InvalidRoleName": "عنوان نقش/وظیفه {0} نامعتبر است.", "Volo.Abp.Identity:InvalidToken": "گذرواژه وارد شده معتبر نیست.", "Volo.Abp.Identity:InvalidUserName": "نام کاربری '{0}' نامعتبر است، نام کاربری فقط می تواند شامل حروف یا ارقام باشد.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "شما نمی توانید از ایمیل کاربر دیگری به عنوان نام کاربری خود استفاده کنید.", + "InvalidUserName": "ام کاربری '{0}' نامعتبر است", "Volo.Abp.Identity:LoginAlreadyAssociated": "یک کاربر با این نام کاربری از قبل موجود می باشد.", "Volo.Abp.Identity:PasswordMismatch": "گذرواژه اشتباه است.", "Volo.Abp.Identity:PasswordRequiresDigit": "گذرواژه ها باید حداقل یک رقم داشته باشند ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json index ad4032eeb6..6b133481e7 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Roolin nimi {0} on virheellinen.", "Volo.Abp.Identity:InvalidToken": "Virheellinen tunnus.", "Volo.Abp.Identity:InvalidUserName": "Käyttäjätunnus {0} on virheellinen, voi sisältää vain kirjaimia tai numeroita.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Käyttäjätunnus {0} on virheellinen, Et voi käyttää toisen käyttäjän sähköpostiosoitetta käyttäjänimenä.", + "InvalidUserName": "Käyttäjätunnus {0} on virheellinen.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Käyttäjä, jolla on tämä sisäänkirjautuminen, on jo olemassa.", "Volo.Abp.Identity:PasswordMismatch": "Väärä salasana.", "Volo.Abp.Identity:PasswordRequiresDigit": "Salasanoissa on oltava vähintään yksi numero ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json index b4fe67f76b..c9d1bfba7b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Le nom de rôle '{0}' n’est pas valide.", "Volo.Abp.Identity:InvalidToken": "Jeton non valide.", "Volo.Abp.Identity:InvalidUserName": "Le nom d’utilisateur '{0}' n’est pas valide, ne peut contenir que des lettres ou des chiffres.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Le nom d’utilisateur '{0}' n’est pas valide,Vous ne pouvez pas utiliser l’e-mail d’un autre utilisateur comme nom d’utilisateur.", + "InvalidUserName": "Le nom d’utilisateur '{0}' n’est pas valide.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Un utilisateur avec cette connexion existe déjà.", "Volo.Abp.Identity:PasswordMismatch": "Mot de passe incorrect.", "Volo.Abp.Identity:PasswordRequiresDigit": "Les mots de passe doivent avoir au moins un chiffre ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json index c6717ed5ac..7155c3bf58 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "भूमिका नाम '{0}' अमान्य है।", "Volo.Abp.Identity:InvalidToken": "अमान्य टोकन।", "Volo.Abp.Identity:InvalidUserName": "उपयोगकर्ता नाम '{0}' अमान्य है, इसमें केवल अक्षर या अंक हो सकते हैं।", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "उपयोगकर्ता नाम '{0}' अमान्य है, आप दूसरे उपयोगकर्ता का ईमेल नाम उपयोग नहीं कर सकते।", + "InvalidUserName": "उपयोगकर्ता नाम '{0}' अमान्य है", "Volo.Abp.Identity:LoginAlreadyAssociated": "इस लॉगिन वाला उपयोगकर्ता पहले से मौजूद है।", "Volo.Abp.Identity:PasswordMismatch": "गलत पासवर्ड।", "Volo.Abp.Identity:PasswordRequiresDigit": "पासवर्ड में कम से कम एक अंक ('0'-'9') होना चाहिए।", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json index 4890e944ea..cdea4c02f5 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Naziv uloge '{0}' nije valjan.", "Volo.Abp.Identity:InvalidToken": "Pogrešan token.", "Volo.Abp.Identity:InvalidUserName": "Korisničko ime '{0}' nije važeće, može sadržavati samo slova ili znamenke.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Korisničko ime '{0}' nije važeće, Ne možete koristiti e-poštu drugog korisnika kao svoje korisničko ime.", + "InvalidUserName": "Korisničko ime '{0}' nije važeće.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Korisnik s ovom prijavom već postoji.", "Volo.Abp.Identity:PasswordMismatch": "Netočna lozinka.", "Volo.Abp.Identity:PasswordRequiresDigit": "Lozinke moraju imati najmanje jednu znamenku ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json index 2bbfeddcbf..fc72ed1e0f 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "'{0}' szerepkör név érvénytelen.", "Volo.Abp.Identity:InvalidToken": "Érvénytelen token.", "Volo.Abp.Identity:InvalidUserName": "'{0}' felhasználónév érvénytelen, csak betűket és számokat tartalmazhat.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "'{0}' felhasználónév érvénytelen, Nem használhatja más felhasználó email címét felhasználónévként.", + "InvalidUserName": "'{0}' felhasználónév érvénytelen.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Az ilyen bejelentkezéssel rendelkező felhasználó már létezik.", "Volo.Abp.Identity:PasswordMismatch": "Érvénytelen jelszó.", "Volo.Abp.Identity:PasswordRequiresDigit": "A jelszavaknak legalább egy számjegyet kell rendelkezniük ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json index 15a741a268..a30d47f4c0 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Hlutverkanafnið '{0}' er ógilt.", "Volo.Abp.Identity:InvalidToken": "Ógilt token.", "Volo.Abp.Identity:InvalidUserName": "Notandanafnið '{0}' er ógilt, getur aðeins innihaldið bókstafi eða tölustafi.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Notandanafnið '{0}' er ógilt, Þú getur ekki notað netfang annars notanda sem notendanafn.", + "InvalidUserName": "Notandanafnið '{0}' er ógilt.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Notandi með þessa innskráningu er þegar til.", "Volo.Abp.Identity:PasswordMismatch": "Rangt lykilorð.", "Volo.Abp.Identity:PasswordRequiresDigit": "Lykilorð verða að hafa að minnsta kosti einn staf ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json index eaf566930b..67a0cbeb36 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Il nome del ruolo '{0}' non è valido.", "Volo.Abp.Identity:InvalidToken": "Token non valido.", "Volo.Abp.Identity:InvalidUserName": "Il nome utente '{0}' non è valido, può contenere solo lettere o cifre.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Il nome utente '{0}' non è valido, Non puoi utilizzare l'email di un altro utente come nome utente.", + "InvalidUserName": "Il nome utente '{0}' non è valido.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Esiste già un utente con questo account.", "Volo.Abp.Identity:PasswordMismatch": "Password errata.", "Volo.Abp.Identity:PasswordRequiresDigit": "La password deve contenere almeno una cifra ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json index 79ee163cd2..139fa50107 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Rol naam '{0}' is ongeldig.", "Volo.Abp.Identity:InvalidToken": "Ongeldig token.", "Volo.Abp.Identity:InvalidUserName": "Gebruikersnaam '{0}' is ongeldig, mag alleen letters of cijfers bevatten.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Gebruikersnaam '{0}' is ongeldig, U kunt het e-mailadres van een andere gebruiker niet als uw gebruikersnaam gebruiken.", + "InvalidUserName": "Gebruikersnaam '{0}' is ongeldig.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Er bestaat al een gebruiker met deze login.", "Volo.Abp.Identity:PasswordMismatch": "Incorrect wachtwoord.", "Volo.Abp.Identity:PasswordRequiresDigit": "Wachtwoorden moeten minimaal één cijfer bevatten ('0' - '9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json index 36297c453a..dabf2655c4 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Rola '{0}' jest niepoprawna.", "Volo.Abp.Identity:InvalidToken": "Niepoprawny token.", "Volo.Abp.Identity:InvalidUserName": "Nazwa użytkownika '{0}' jest niepoprawna, może zawierać tylko litery i cyfry.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Nazwa użytkownika '{0}' jest niepoprawna, Nie możesz użyć adresu e-mail innego użytkownika jako swojej nazwy użytkownika.", + "InvalidUserName": "Nazwa użytkownika '{0}' jest niepoprawna.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Użytkownik o tym loginie już istnieje.", "Volo.Abp.Identity:PasswordMismatch": "Niepoprawne hasło.", "Volo.Abp.Identity:PasswordRequiresDigit": "Hasło musi zawierać przynajmniej jedną cyfrę ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json index 22936d80b1..999a9f19bd 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Perfil '{0}' inválido.", "Volo.Abp.Identity:InvalidToken": "Token inválido.", "Volo.Abp.Identity:InvalidUserName": "Usuário '{0}' é inválido, somente pode conter letras ou números.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Usuário '{0}' é inválido, Você não pode usar o e-mail de outro usuário como seu nome de usuário.", + "InvalidUserName": "Usuário '{0}' é inválido.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Um usuário com este login já existe.", "Volo.Abp.Identity:PasswordMismatch": "Senha incorreta.", "Volo.Abp.Identity:PasswordRequiresDigit": "Senhas devem possuir pelo menos um dígito ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json index ec0e22eb39..573331d4f3 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Numele de rol '{0}' este invalid.", "Volo.Abp.Identity:InvalidToken": "Invalid token.", "Volo.Abp.Identity:InvalidUserName": "Numele de utilizator '{0}' este invalid, poate conţine doar litere şi cifre.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Numele de utilizator '{0}' este invalid, Nu puteţi folosi adresa de email a altui utilizator ca nume de utilizator.", + "InvalidUserName": "Numele de utilizator '{0}' este invalid.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Un utilizator cu această autentificare există deja.", "Volo.Abp.Identity:PasswordMismatch": "Parolă incorectă.", "Volo.Abp.Identity:PasswordRequiresDigit": "Parolele trebuie să conţină cel puţin o cifră ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json index d584a5ac3d..7bd8da5955 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Имя роли '{0}' недопустимо.", "Volo.Abp.Identity:InvalidToken": "Недопустимый маркер.", "Volo.Abp.Identity:InvalidUserName": "Имя пользователя '{0}' недопустимо и может содержать только буквы или цифры.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Имя пользователя '{0}' недопустимо Вы не можете использовать электронную почту другого пользователя в качестве своего имени пользователя.", + "InvalidUserName": "Имя пользователя '{0}' недопустимо.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Пользователь с таким логином уже существует.", "Volo.Abp.Identity:PasswordMismatch": "Неверный пароль.", "Volo.Abp.Identity:PasswordRequiresDigit": "Пароль должен содержать по крайней мере одну цифру.", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json index 7083f2f494..520377210d 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Názov roly '{0}' je neplatný.", "Volo.Abp.Identity:InvalidToken": "Neplatný token.", "Volo.Abp.Identity:InvalidUserName": "Používateľské meno '{0}' je neplatné, môže obsahovať len písmená alebo číslice.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Používateľské meno '{0}' je neplatné, Nemôžete použiť email iného používateľa ako svoje používateľské meno.", + "InvalidUserName": "Používateľské meno '{0}' je neplatné.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Používateľ s týmto prihlasovacím menom už existuje.", "Volo.Abp.Identity:PasswordMismatch": "Nesprávne heslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Heslá musia obsahovať aspoň jednu číslicu ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json index ce58ebdcf6..0fec5bbd4d 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Naziv vloge '{0}' ni veljaven.", "Volo.Abp.Identity:InvalidToken": "Neveljaven žeton.", "Volo.Abp.Identity:InvalidUserName": "Uporabniško ime '{0}' ni veljavno, vsebuje lahko le črke in številke.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Uporabniško ime '{0}' ni veljavno, Ne morete uporabiti e-poštnega naslova drugega uporabnika kot svojega uporabniškega imena.", + "InvalidUserName": "Uporabniško ime '{0}' ni veljavno.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Uporabnik s to prijavo že obstaja.", "Volo.Abp.Identity:PasswordMismatch": "Nepravilno geslo.", "Volo.Abp.Identity:PasswordRequiresDigit": "Gesla morajo imeti vsaj eno številko ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json index 83e21f3c58..6a8b5f04c7 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "'{0}' rol ismi geçersizdir.", "Volo.Abp.Identity:InvalidToken": "Geçersiz token.", "Volo.Abp.Identity:InvalidUserName": "'{0}' kullanıcı adı geçersiz, sadece harf ve rakamlardan oluşmalı.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "'{0}' kullanıcı adı geçersiz, Başka bir kullanıcının e-posta adresini kullanıcı adı olarak kullanamazsınız.", + "InvalidUserName": "'{0}' kullanıcı adı geçersiz.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Bu giriş bilgilerine sahip bir kullanıcı zaten var.", "Volo.Abp.Identity:PasswordMismatch": "Hatalı şifre.", "Volo.Abp.Identity:PasswordRequiresDigit": "Şifre en az bir sayı içermeli ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json index f17fcbfe0d..c649637b4d 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "Tên người dùng '{0}' Không hợp lệ.", "Volo.Abp.Identity:InvalidToken": "Token không hợp lệ.", "Volo.Abp.Identity:InvalidUserName": "Tên người dùng '{0}' không hợp lệ, chỉ có thể chứa chữ cái hoặc chữ số.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "Tên người dùng '{0}' không hợp lệ, Bạn không thể sử dụng email của người dùng khác làm tên người dùng của mình.", + "InvalidUserName": "Tên người dùng '{0}' không hợp lệ.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Một người dùng có thông tin đăng nhập này đã tồn tại.", "Volo.Abp.Identity:PasswordMismatch": "Mật khẩu không đúng.", "Volo.Abp.Identity:PasswordRequiresDigit": "Mật khẩu phải có ít nhất một chữ số ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json index df0183aa3f..165ba09b41 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 无效.", "Volo.Abp.Identity:InvalidToken": "token无效.", "Volo.Abp.Identity:InvalidUserName": "用户名 '{0}' 无效, 只能包含字母或数字.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "用户名 '{0}' 无效, 不能使用其他用户的邮箱作为你的用户名.", + "InvalidUserName": "用户名 '{0}' 无效.", "Volo.Abp.Identity:LoginAlreadyAssociated": "此登录名的用户已存在.", "Volo.Abp.Identity:PasswordMismatch": "密码错误.", "Volo.Abp.Identity:PasswordRequiresDigit": "密码至少包含一位数字 ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json index 1a88eb9c37..d12c44890a 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json @@ -48,7 +48,7 @@ "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 無效.", "Volo.Abp.Identity:InvalidToken": "token無效.", "Volo.Abp.Identity:InvalidUserName": "使用者名稱 '{0}' 無效, 只能包含字母或數字.", - "Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername": "使用者名稱 '{0}' 無效, 不能使用其他使用者的電子信箱作為你的使用者名稱.", + "InvalidUserName": "使用者名稱 '{0}' 無效.", "Volo.Abp.Identity:LoginAlreadyAssociated": "此登入名的使用者已存在.", "Volo.Abp.Identity:PasswordMismatch": "密碼錯誤.", "Volo.Abp.Identity:PasswordRequiresDigit": "密碼至少包含一位數字 ('0'-'9').", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs index e4b7217037..c7507c6e36 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs @@ -37,7 +37,7 @@ namespace Volo.Abp.Identity errors.Add(new IdentityError { Code = "InvalidUserName", - Description = Localizer["Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername", userName] + Description = Localizer["InvalidUserName", userName] }); } } From f231792aefa6ec785686e79cb8cf00f8f3093b06 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 28 Jul 2023 14:02:12 +0800 Subject: [PATCH 037/165] Update AbpIdentityUserValidator_Tests.cs --- .../Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs index ac20b4894c..ef9cfb53d3 100644 --- a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs @@ -31,6 +31,6 @@ public class AbpIdentityUserValidator_Tests : AbpIdentityAspNetCoreTestBase identityResult.Succeeded.ShouldBeFalse(); identityResult.Errors.Count().ShouldBe(1); identityResult.Errors.First().Code.ShouldBe("InvalidUserName"); - identityResult.Errors.First().Description.ShouldBe(Localizer["Volo.Abp.Identity:YouCanNotUseAnotherUsersEmailAsYourUsername", "user1@volosoft.com"]); + identityResult.Errors.First().Description.ShouldBe(Localizer["InvalidUserName", "user1@volosoft.com"]); } } From 9c6529e93f0e11e4a555264cb21f8ed694949456 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 28 Jul 2023 14:59:40 +0300 Subject: [PATCH 038/165] show password directive test and document --- docs/en/UI/Angular/Show-Password-Directive.md | 52 +++++++++++++++ .../Angular/images/showPasswordDirective1.png | Bin 0 -> 3707 bytes .../Angular/images/showPasswordDirective2.png | Bin 0 -> 3932 bytes .../lib/tests/show-password-directive.spec.ts | 59 ++++++++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 docs/en/UI/Angular/Show-Password-Directive.md create mode 100644 docs/en/UI/Angular/images/showPasswordDirective1.png create mode 100644 docs/en/UI/Angular/images/showPasswordDirective2.png create mode 100644 npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md new file mode 100644 index 0000000000..db54bcdd76 --- /dev/null +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -0,0 +1,52 @@ +# Show Password Directive + +In password input, text can be shown easily via changing input type attribute to `text`. To make this even easier, you can use the `ShowPasswordDirective` which has been exposed by the `@abp/ng.core` package. + + +## Getting Started + +In order to use the `ShowPasswordDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: + +```ts +// ... +import { CoreModule } from '@abp/ng.core'; + +@NgModule({ + //... + imports: [..., CoreModule], +}) +export class MyFeatureModule {} +``` + +## Usage + +The `ShowPasswordDirective` is very easy to use. The directive's selector is **`abpShowPassword`**. By adding the `abpShowPassword` attribute to an input element, you can activate the `ShowPasswordDirective` for the input element. + +See an example usage: + +```ts +@Component({ + selector: 'test-component', + standalone: true, + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + showPassword = false; +} +``` + +The `abpShowPassword` attribute has been added to the `` element. Click icon to activate the `ShowPasswordDirective`. + +See the result: + +![Show Password directive](./images/showPasswordDirective1.png) + +To see password input click icon. + +![Show Password directive](./images/showPasswordDirective2.png) \ No newline at end of file diff --git a/docs/en/UI/Angular/images/showPasswordDirective1.png b/docs/en/UI/Angular/images/showPasswordDirective1.png new file mode 100644 index 0000000000000000000000000000000000000000..7b64be2b5f14c8e8affb7849331f0f5398188193 GIT binary patch literal 3707 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 YNubRLytJp=IDz)l)k46FG%?Tr1J+;SK>z>% literal 0 HcmV?d00001 diff --git a/docs/en/UI/Angular/images/showPasswordDirective2.png b/docs/en/UI/Angular/images/showPasswordDirective2.png new file mode 100644 index 0000000000000000000000000000000000000000..43199ffeaa2b1a813743599a1f74137404254ee0 GIT binary patch literal 3932 zcma)9c{r5c+aIzg+4mt!mWYsb)W|+)rYPB$3`(|;ol(-*X~w=Q5h457cP4u=XzW`m zG)N5D-pBWP|NOr1?{}{2dCqyx@|^qr-1j;6{fW8**So;L%K!p_F2MA)jX@wv7|^~; zM+3ZjGvwDnpo{b{?OXT!vwqE@JPEtm_-*kf;t{K<#)AlHnHH)73MMRNmwXoN`BRSd zjJid*^c_*jD+F7X50*?Z{x&|tx+PTL>je5@AKtn zGBQ$M)L5St=%BwP1k={m7Nv?1JsW0b#{gg2ns@$n@QqAiWrtn&qv&3{$cKry0t|tv ze<#!J674F&hczG_cHecZKa2?Vv9qB&xOIXorJnD}(os#xmi)7IjHA4cLv*~5no^FP zGc5(`N$y9*_p;L%ZM=<+v$MGEKK#!?uP{(j$Lw~l#p;UuavKV95!~ZWmlT6joJlD> z$JNT_Qlrke4 z#)_Yn70TN^TyvmC)^Pk@KXSX~BQOx^mjCC0>|NzR0Yg&e?H6)keas6B6XUK|$es1H z{=daJ<1bd)L#*K^D0g9*9Ue}2H8Tg}=X>`f>W(>BSPp!n+7pqTDe^S%4az0h{@i_j ziRN4|n$pvOa{#rt(nvn9a?;h5HoC9Y7SKXzZDi-UN;|hn!)uFZ^X?TkIHZ$&C8IrcW zR?Nk_`s>2G5Ap2E5#{1fY3=lTy-T}iKO)YIC{qT22E(=Xk5yBI(_=qIcRpx*HN`s@ zgw^PGEj(T4?j^c1$`R}-_v@ceOq1-1OL7~k_u${0l))NZMHKR(zZpeIOP@(@uBY|X zVc}@Lr!z=&3Q||8wTHISPtKmdJDvx2obSb*0W-eG;jy`%L-+0Kq6c0+J&_U;Pf-?E z-(rnkGR8CeA;*ZSCPf1!o(P^m>f98-;8yM|Y?$F8*jiuj)dZ-Hg`w&+`PajNI$e3e zY9DaP)rAHQrQX{JhfY^69$ZTGDpcvq7MeC-O&3x;R=D7Qi4C7Kenc8^w}6)B|J=?@ zUlY_Cd;LI#8=7e;rV>@9WZZNU^uYS3hcs}OUQ2hTg1EbWJmDke*nTR%NFKdDp{q%L zy;v=5!|+K`t5T$yQzY*!I2_0<|-C>kG;c(dcVp z(TqlO0p`9T7PYBDKjUd*PHU5Y?Ld_j)EcHin{~53wNYwU|Ll0j`m;J6XF=T4jYhZT z`rf}Sj_(I&1_T9N03Y9*Rpv=bO!QpUM8vnOxxj-@ets(zuTeSQwVd(T#pR$s|NWwf zT()~b?PP|*He(YHibn`imrdOG;giQhV3BhLQk*Zq=qe;m_y9knGb%Xxn^Fb;b;VdQ(E z3FPY^w5EYng2pI+XyEiv))ZOkupf7q0|Itl&1O7C^3~$QQ{R==?|1l69og4LZADE3 zz9nyGmL+YDME9qDnm49R(@*!~qQ@&$I}M4sB-B4vGw#?^lp+QX>h?AhHNuuHO{?=+ z3uV3J#z*IEm-zpQHw{$MMz#cw$luDQ&rm77-Crn}Qj$FzCmU?843yBt<_uDSDC?EW zNeu9qEXIb;&t}31c14H%>|vWQFV9HZp>?`F-jn{DGy# zlfE&7#9Ytk2z$TGyy}rPzfM32J1^~Z`(%xsrn3|#s06AH)+s^a1BlX@SjH0vLQpW5 zc`V1_ubsZuQzp!Ee#4%`oDF^ymhH)=9JhX~5ctUZV~}N$YK7%-YM#JZ)XDoMvZpxL z9@`W;SdhlMM+hA*LZK^hj`9%Il;u;uj0MF$Bint6VXBL$&|UKNnzVYEWl7Rus@WcU zDe~~kr}TO-g(1l7Y5Av~X9-|KMuG>tb9*HM2S>e0o9U4>i?t11!tdM?*hyty_-UxB zV9gHA)G-)|a+qV7xX~KcoDDK}o!RVkKXEacCs`SP=W6dpVlGbD$xe;P|AuAT-um6m z>%z46?h+vE^Ka8tR2psQf_JDH#PABYI=aQI*JAr68^%?}V6IP?XxU#vn|gP}d�Y zx-=@ZKc@!UqB`SJS~_LXdsHc4kZavv)ya!NHN1YKx6!>ZL-8~2tgiLj$XwO;4d2+Ksk1Ka;xH8ZN3$6e-$NX3jNU>tlZ zQ4zb%Z~F#Oi;t_uFmlS1clM@ox8~DtyNp??q?Cu(Xb)zGy7Z^s^et7LP>40(j182Xjlu#7K|v}%u{U_&hCCOuTzgM(&s4_1Dys#{!414iZG}UF zRtzUsc~Bwr2Tv%xid7ipPLnh_+eL~+d5`xk2Sth5AnE!(hE}yJ!+aT;ZLP6uYij*D zbzLN3D@5sfNarK*@l%u8<)YY0E=vA9q@SeD0C;6`e`|bY+04es{Pt$PDj?TpQoAHP zXy$qVjjqNEx*xE=Xm>@vuh~?0_nhxW{%~$XG=^&x^VRqkiIvN7R?wrg zTzvfy_EjOQFRI&LO2WND!LRfj1XeKBj@k!(CvOurCEpU9JLJE_hfD=qAyAzsIyc0^ z4@3L|TWVLk)(@+Ot-L6{*95L@FA*&?Nbmf`fV;x0N84Rro^t8dk#JgaWlUxwaV%;fdRt0cIzjw`v++JMTNJ4&gZ?)2xP51m8SQ0zHm4)Tx?@- z0(r*{RmS0|)%iX4&dH^HY$4bhpC!NdSN23hRBMzJQjZRIB#sHu%eQD-=1|qZ2G!>e zuLZ}vf)=KGlM*lus(N3Guv5)=>zrJfd8@U2sSm% zKB@rOC=pkc*ftja%s}aUVOoc!?#~nfvXb~~vgW41dv7xPnU~3UX|Yn*hh`ddurcuu z?0ACavM=9b^v=n|URTK8?g9;p4*OufzOD7}+a+uZvA*ryo#!$cL-8U#v6~u_93+pM)@PVZhFKZ?&J1|(k3;aqTJif) zzhlq?Y(8)P8uAn(3JuK_L>c zjJq2d-D*_}tcU$l1>Wa%dN{rM+>Wqk(j~bD8R|G1jnw z`MCDZ@=)!+hCZ(R+0XZYB}6O%R#6?^v1)HWf0l`?81T6Y=mI@<6$%@5_J|p#eM>ps zI0gei1J*AznP~g#y!88)hlExH-%K4&(IGm@;fLbnm$?apyjeuv#aT08qHrpvk3CLO z?bVO3Dlf9ZH8@4`fkg-d?DP0r + + + `, + imports:[ShowPasswordDirective] +}) +class TestComponent { + showPassword:boolean = false +} + +describe('ShowPasswordDirective',()=>{ + let fixture: ComponentFixture;; + let des : DebugElement[]; + let desAll : DebugElement[]; + let bareInput; + + beforeEach(()=>{ + fixture = TestBed.configureTestingModule({ + imports: [ TestComponent ] + }).createComponent(TestComponent) + + fixture.detectChanges(); // initial binding + + // all elements with an attached HighlightDirective + des = fixture.debugElement.queryAll(By.directive(ShowPasswordDirective)); + + // all inputs includes nondirective + desAll = fixture.debugElement.queryAll(By.all()); + + // the input without the ShowPasswordDirective + bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); + }) + + // color tests + it('should have three input has ShowPasswordDirective elements', () => { + expect(des.length).toBe(3); + }); + + test.each([[0,'text'],[1,'password'],[2,'text'],[3,'password']])('%p. input type must be %p)', (index,inpType) => { + const inputType = desAll[index].nativeElement.type; + expect(inputType).toBe(inpType); + }); + + it('should have three input has ShowPasswordDirective elements', () => { + let input = des[2].nativeElement + expect(input.type).toBe('password') + fixture.componentInstance.showPassword = true + fixture.detectChanges() + expect(input.type).toBe('text') + }); + }); \ No newline at end of file From da4a3594fb9d0bb0bb172f71ebd89d04d962770e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Sun, 30 Jul 2023 13:53:02 +0300 Subject: [PATCH 039/165] Update Internet-Connection-Service.md --- .../UI/Angular/Internet-Connection-Service.md | 48 ++----------------- 1 file changed, 4 insertions(+), 44 deletions(-) diff --git a/docs/en/UI/Angular/Internet-Connection-Service.md b/docs/en/UI/Angular/Internet-Connection-Service.md index aa1f0d6770..0a8aca69f4 100644 --- a/docs/en/UI/Angular/Internet-Connection-Service.md +++ b/docs/en/UI/Angular/Internet-Connection-Service.md @@ -1,61 +1,21 @@ # Internet Connection Service `InternetConnectionService` is a service which is exposed by `@abp/ng.core` package. **If you want to detect whether you are connected to the internet or not, you can use this service.** - -### internet-connection-service.ts -```ts -import { DOCUMENT } from '@angular/common'; -import { Injectable, computed, inject, signal } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; - -@Injectable({ - providedIn: 'root', -}) -export class InternetConnectionService{ - protected readonly window = inject(DOCUMENT).defaultView; - protected readonly navigator = this.window.navigator; - - /* BehaviorSubject */ - private status$ = new BehaviorSubject(navigator.onLine) - - /* creates writableSignal */ - private status = signal(navigator.onLine); - - /* READONLY ANGULAR SIGNAL */ - networkStatus = computed(() => this.status()) - - constructor(){ - this.window.addEventListener('offline', () => this.setStatus()); - this.window.addEventListener('online', () => this.setStatus()); - } - - private setStatus(){ - this.status.set(navigator.onLine) - this.status$.next(navigator.onLine) - } - - /* returns OBSERVABLE */ - get networkStatus$(){ - return this.status$.asObservable() - } -} -``` - ## Getting Started When you inject InternetConnectionService you can get the current internet status also if status changes you can catch them immediately. -As you can see from the code above, `InternetConnectionService` is providing 2 alternatives for catching network status; +`InternetConnectionService` is providing 2 alternatives for catching network status; 1. Signal (readonly) 2. Observable # How To Use -İt's easy just inject the service and get network status +İt's easy just inject the service and get network status. **You can get via signal** ```ts class someComponent{ - internetConnectionService = inject(InternetConnectionService); + internetConnectionService = inject(InternetConnectionService); isOnline = this.internetConnectionService.networkStatus } ``` @@ -67,4 +27,4 @@ class someComponent{ } ``` -That's all, feel free to try on your template +To see how we implement to template, check `InternetConnectionStatusComponent` From 11f03b26ed02e28850e3e14081a37e607ec3ee1d Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Sun, 30 Jul 2023 23:48:51 +0300 Subject: [PATCH 040/165] capsLock doc and test --- .../src/lib/tests/capsLock.directive.spec.ts | 58 +++++++++++++++++++ .../lib/tests/show-password-directive.spec.ts | 2 +- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts diff --git a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts new file mode 100644 index 0000000000..17d50ba697 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts @@ -0,0 +1,58 @@ +import { Component, DebugElement } from '@angular/core' +import { ComponentFixture, TestBed } from '@angular/core/testing' +import { TrackCapsLockDirective } from '../directives'; +import { By } from '@angular/platform-browser'; + +@Component({ + standalone:true, + template: ` + + `, + imports:[TrackCapsLockDirective] +}) +class TestComponent { + capsLock:boolean = false +} + +describe('TrackCapsLockDirective',()=>{ + let fixture: ComponentFixture;; + let des : DebugElement[]; + + beforeEach(()=>{ + fixture = TestBed.configureTestingModule({ + imports: [ TestComponent ] + }).createComponent(TestComponent); + + fixture.detectChanges(); + + des = fixture.debugElement.queryAll(By.directive(TrackCapsLockDirective)); + }); + + // tests + test.each(['keydown','keyup'])('is %p works when press capslock and is emit status', (eventName) => { + const event = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: true + }); + window.dispatchEvent(event); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(true) + }); + + test.each(['keydown','keyup'])('is %p detect the change capslock is emit status', (eventName) => { + const trueEvent = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: true + }); + window.dispatchEvent(trueEvent); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(true) + const falseEvent = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: false + }); + window.dispatchEvent(falseEvent); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(false) + }); + }); \ No newline at end of file diff --git a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts index 6b07997bc9..e1e9750995 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts @@ -39,7 +39,7 @@ describe('ShowPasswordDirective',()=>{ bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); }) - // color tests + // tests it('should have three input has ShowPasswordDirective elements', () => { expect(des.length).toBe(3); }); From 3257c24d74186ebf1d62452b5b8e752c0201c726 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Sun, 30 Jul 2023 23:49:52 +0300 Subject: [PATCH 041/165] capsLock doc and test --- docs/en/UI/Angular/CapsLock.directive.md | 52 ++++++++++++++++++ .../UI/Angular/images/CapsLockDirective1.png | Bin 0 -> 2224 bytes .../UI/Angular/images/CapsLockDirective2.png | Bin 0 -> 4274 bytes 3 files changed, 52 insertions(+) create mode 100644 docs/en/UI/Angular/CapsLock.directive.md create mode 100644 docs/en/UI/Angular/images/CapsLockDirective1.png create mode 100644 docs/en/UI/Angular/images/CapsLockDirective2.png diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md new file mode 100644 index 0000000000..4b92d61124 --- /dev/null +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -0,0 +1,52 @@ +# Show Password Directive + +In password inputs,You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. + + +## Getting Started + +In order to use the `TrackCapsLockDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: + +```ts +// ... +import { CoreModule } from '@abp/ng.core'; + +@NgModule({ + //... + imports: [..., CoreModule], +}) +export class MyFeatureModule {} +``` + +## Usage + +The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. U can use this to warn user + +See an example usage: + +```ts +@Component({ + selector: 'test-component', + standalone: true, + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + capsLock = false; +} +``` + +The `abpCapsLock` event has been added to the `` element. Press Caps Lock to activate the `TrackCapsLockDirective`. + +See the result: + +![Show Password directive](./images/CapsLockDirective1.png) + +To see Caps Lock icon press Caps Lock. + +![Show Password directive](./images/CapsLockDirective2.png) \ No newline at end of file diff --git a/docs/en/UI/Angular/images/CapsLockDirective1.png b/docs/en/UI/Angular/images/CapsLockDirective1.png new file mode 100644 index 0000000000000000000000000000000000000000..2f143d755fd2d331beed42c8ce9c361cb8aeaa0b GIT binary patch literal 2224 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 U>BitD2Pwepw$-gl!+XE~7Z`*$lmGw# literal 0 HcmV?d00001 From 45a544b0108d8aa8f0083dc092083c669f5e9a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:48:56 +0300 Subject: [PATCH 042/165] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 4b92d61124..a21057490c 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -5,15 +5,17 @@ In password inputs,You may want to show if Caps Lock is on. To make this even ea ## Getting Started -In order to use the `TrackCapsLockDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: +`TrackCapsLockDirective` is standalone. In order to use the `TrackCapsLockDirective` in an HTML template, import it to related module or your standalone component: ```ts -// ... -import { CoreModule } from '@abp/ng.core'; +import { TrackCapsLockDirective } from '@abp/ng.core'; @NgModule({ //... - imports: [..., CoreModule], + imports: [ + ..., + TrackCapsLockDirective + ], }) export class MyFeatureModule {} ``` @@ -25,6 +27,8 @@ The `TrackCapsLockDirective` is very easy to use. The directive's selector is ** See an example usage: ```ts +import { TrackCapsLockDirective } from '@abp/ng.core' + @Component({ selector: 'test-component', standalone: true, @@ -34,7 +38,8 @@ See an example usage: icon
- ` + `, + imports: [ TrackCapsLockDirective ] }) export class TestComponent{ capsLock = false; @@ -49,4 +54,4 @@ See the result: To see Caps Lock icon press Caps Lock. -![Show Password directive](./images/CapsLockDirective2.png) \ No newline at end of file +![Show Password directive](./images/CapsLockDirective2.png) From 383222a9ee7b6e9699228e9b71ffa16044ef309b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:51:53 +0300 Subject: [PATCH 043/165] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index a21057490c..24bef39cdc 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -1,6 +1,6 @@ -# Show Password Directive +# Caps Lock Directive -In password inputs,You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. +In password inputs, You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. ## Getting Started From f96f71576b4318b4a58bf85b2355432d8819d55b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:58:53 +0300 Subject: [PATCH 044/165] Update Show-Password-Directive.md --- docs/en/UI/Angular/Show-Password-Directive.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md index db54bcdd76..6c3cbe4f45 100644 --- a/docs/en/UI/Angular/Show-Password-Directive.md +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -4,16 +4,17 @@ In password input, text can be shown easily via changing input type attribute to ## Getting Started - -In order to use the `ShowPasswordDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: +`ShowPasswordDirective` is standalone. In order to use the `ShowPasswordDirective` in an HTML template, import it to related module or your standalone component: ```ts -// ... -import { CoreModule } from '@abp/ng.core'; +import { ShowPasswordDirective } from '@abp/ng.core'; @NgModule({ //... - imports: [..., CoreModule], + imports: [ + ..., + ShowPasswordDirective + ], }) export class MyFeatureModule {} ``` @@ -25,6 +26,7 @@ The `ShowPasswordDirective` is very easy to use. The directive's selector is **` See an example usage: ```ts +import { ShowPasswordDirective } from '@abp/ng.core'; @Component({ selector: 'test-component', standalone: true, @@ -34,7 +36,8 @@ See an example usage: icon
- ` + `, + imports: [ShowPasswordDirective] }) export class TestComponent{ showPassword = false; @@ -49,4 +52,4 @@ See the result: To see password input click icon. -![Show Password directive](./images/showPasswordDirective2.png) \ No newline at end of file +![Show Password directive](./images/showPasswordDirective2.png) From 6e4cd54f2a675685511d4a4fb4c213e0c75db37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 11:21:13 +0300 Subject: [PATCH 045/165] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 29 +++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 24bef39cdc..1e1021bdd4 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -7,11 +7,16 @@ In password inputs, You may want to show if Caps Lock is on. To make this even e `TrackCapsLockDirective` is standalone. In order to use the `TrackCapsLockDirective` in an HTML template, import it to related module or your standalone component: +**Importing to NgModule** ```ts import { TrackCapsLockDirective } from '@abp/ng.core'; @NgModule({ //... + declarations: [ + ..., + TestComponent + ], imports: [ ..., TrackCapsLockDirective @@ -22,15 +27,33 @@ export class MyFeatureModule {} ## Usage -The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. U can use this to warn user +The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. You can use this to warn user. See an example usage: +**NgModule Component usage** +```ts +@Component({ + selector: 'test-component', + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + capsLock = false; +} +``` + +**Standalone Component usage** ```ts import { TrackCapsLockDirective } from '@abp/ng.core' @Component({ - selector: 'test-component', + selector: 'standalone-component', standalone: true, template: `
@@ -41,7 +64,7 @@ import { TrackCapsLockDirective } from '@abp/ng.core' `, imports: [ TrackCapsLockDirective ] }) -export class TestComponent{ +export class StandaloneComponent{ capsLock = false; } ``` From 14b103668b267e96160cac8a7cd831f743a35efa Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 31 Jul 2023 16:38:00 +0800 Subject: [PATCH 046/165] Add `IAbpAccessTokenProvider`. --- .../MauiBlazor/IAbpMauiAccessTokenProvider.cs | 8 ----- .../MauiBlazorAbpAccessTokenProvider.cs | 14 ++++++++ ...delRemoteServiceHttpClientAuthenticator.cs | 24 +++---------- .../NullAbpMauiAccessTokenProvider.cs | 13 ------- .../AbpHttpClientIdentityModelWebModule.cs | 8 +++-- .../Web/HttpContextAbpAccessTokenProvider.cs | 29 ++++++++++++++++ ...delRemoteServiceHttpClientAuthenticator.cs | 23 ++++--------- ...delRemoteServiceHttpClientAuthenticator.cs | 34 ++++--------------- .../WebAssemblyAbpAccessTokenProvider.cs | 34 +++++++++++++++++++ .../Authentication/IAbpAccessTokenProvider.cs | 8 +++++ .../NullAbpAccessTokenProvider.cs | 12 +++++++ 11 files changed, 120 insertions(+), 87 deletions(-) delete mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/IAbpMauiAccessTokenProvider.cs create mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiBlazorAbpAccessTokenProvider.cs delete mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/NullAbpMauiAccessTokenProvider.cs create mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextAbpAccessTokenProvider.cs create mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/WebAssemblyAbpAccessTokenProvider.cs create mode 100644 framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAbpAccessTokenProvider.cs create mode 100644 framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullAbpAccessTokenProvider.cs diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/IAbpMauiAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/IAbpMauiAccessTokenProvider.cs deleted file mode 100644 index 0c257b090c..0000000000 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/IAbpMauiAccessTokenProvider.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor; - -public interface IAbpMauiAccessTokenProvider -{ - Task GetAccessTokenAsync(); -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiBlazorAbpAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiBlazorAbpAccessTokenProvider.cs new file mode 100644 index 0000000000..8afbcbafed --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiBlazorAbpAccessTokenProvider.cs @@ -0,0 +1,14 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.Authentication; + +namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor; + +[Dependency(ReplaceServices = true)] +public class MauiBlazorAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency +{ + public virtual Task GetTokenAsync() + { + return Task.FromResult(null as string); + } +} diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiIBlazorIdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiIBlazorIdentityModelRemoteServiceHttpClientAuthenticator.cs index ba36de1d77..b1277373fa 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiIBlazorIdentityModelRemoteServiceHttpClientAuthenticator.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiIBlazorIdentityModelRemoteServiceHttpClientAuthenticator.cs @@ -1,8 +1,5 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; using IdentityModel.Client; -using JetBrains.Annotations; -using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; using Volo.Abp.Http.Client.Authentication; using Volo.Abp.IdentityModel; @@ -12,22 +9,21 @@ namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor; [Dependency(ReplaceServices = true)] public class MauiBlazorIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator { - [CanBeNull] - protected IAbpMauiAccessTokenProvider AbpMauiAccessTokenProvider { get; } + protected IAbpAccessTokenProvider AccessTokenProvider { get; } public MauiBlazorIdentityModelRemoteServiceHttpClientAuthenticator( IIdentityModelAuthenticationService identityModelAuthenticationService, - IServiceProvider serviceProvider) + IAbpAccessTokenProvider abpAccessTokenProvider) : base(identityModelAuthenticationService) { - AbpMauiAccessTokenProvider = serviceProvider.GetService(); + AccessTokenProvider = abpAccessTokenProvider; } public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) { if (context.RemoteService.GetUseCurrentAccessToken() != false) { - var accessToken = await GetAccessTokenFromAccessTokenProviderOrNullAsync(); + var accessToken = await AccessTokenProvider.GetTokenAsync(); if (accessToken != null) { context.Request.SetBearerToken(accessToken); @@ -37,14 +33,4 @@ public class MauiBlazorIdentityModelRemoteServiceHttpClientAuthenticator : Ident await base.Authenticate(context); } - - protected virtual async Task GetAccessTokenFromAccessTokenProviderOrNullAsync() - { - if (AbpMauiAccessTokenProvider == null) - { - return null; - } - - return await AbpMauiAccessTokenProvider.GetAccessTokenAsync(); - } } diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/NullAbpMauiAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/NullAbpMauiAccessTokenProvider.cs deleted file mode 100644 index ae6ecd949f..0000000000 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/NullAbpMauiAccessTokenProvider.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Threading.Tasks; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor; - -[Dependency(TryRegister = true)] -public class NullAbpMauiAccessTokenProvider : IAbpMauiAccessTokenProvider -{ - public Task GetAccessTokenAsync() - { - return Task.FromResult(null as string); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/AbpHttpClientIdentityModelWebModule.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/AbpHttpClientIdentityModelWebModule.cs index 44959fbb82..1478193bf6 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/AbpHttpClientIdentityModelWebModule.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/AbpHttpClientIdentityModelWebModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Modularity; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; namespace Volo.Abp.Http.Client.IdentityModel.Web; @@ -7,5 +8,8 @@ namespace Volo.Abp.Http.Client.IdentityModel.Web; )] public class AbpHttpClientIdentityModelWebModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddHttpContextAccessor(); + } } diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextAbpAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextAbpAccessTokenProvider.cs new file mode 100644 index 0000000000..97d88bd3b0 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextAbpAccessTokenProvider.cs @@ -0,0 +1,29 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.Authentication; + +namespace Volo.Abp.Http.Client.IdentityModel.Web; + +[Dependency(ReplaceServices = true)] +public class HttpContextAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency +{ + protected IHttpContextAccessor HttpContextAccessor { get; } + + public HttpContextAbpAccessTokenProvider(IHttpContextAccessor httpContextAccessor) + { + HttpContextAccessor = httpContextAccessor; + } + + public virtual async Task GetTokenAsync() + { + var httpContext = HttpContextAccessor?.HttpContext; + if (httpContext == null) + { + return null; + } + + return await httpContext.GetTokenAsync("access_token"); + } +} diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs index 6ae44a0943..364134348b 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs @@ -1,7 +1,5 @@ using System.Threading.Tasks; using IdentityModel.Client; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Http; using Volo.Abp.DependencyInjection; using Volo.Abp.Http.Client.Authentication; using Volo.Abp.IdentityModel; @@ -11,19 +9,21 @@ namespace Volo.Abp.Http.Client.IdentityModel.Web; [Dependency(ReplaceServices = true)] public class HttpContextIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator { - public IHttpContextAccessor HttpContextAccessor { get; set; } + protected IAbpAccessTokenProvider AccessTokenProvider { get; } public HttpContextIdentityModelRemoteServiceHttpClientAuthenticator( - IIdentityModelAuthenticationService identityModelAuthenticationService) + IIdentityModelAuthenticationService identityModelAuthenticationService, + IAbpAccessTokenProvider accessTokenProvider) : base(identityModelAuthenticationService) { + AccessTokenProvider = accessTokenProvider; } - public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) + public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) { if (context.RemoteService.GetUseCurrentAccessToken() != false) { - var accessToken = await GetAccessTokenFromHttpContextOrNullAsync(); + var accessToken = await AccessTokenProvider.GetTokenAsync(); if (accessToken != null) { context.Request.SetBearerToken(accessToken); @@ -33,15 +33,4 @@ public class HttpContextIdentityModelRemoteServiceHttpClientAuthenticator : Iden await base.Authenticate(context); } - - protected virtual async Task GetAccessTokenFromHttpContextOrNullAsync() - { - var httpContext = HttpContextAccessor?.HttpContext; - if (httpContext == null) - { - return null; - } - - return await httpContext.GetTokenAsync("access_token"); - } } diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs index 846cc6f3a3..c16317e376 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs @@ -1,9 +1,5 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; using IdentityModel.Client; -using JetBrains.Annotations; -using Microsoft.AspNetCore.Components.WebAssembly.Authentication; -using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; using Volo.Abp.Http.Client.Authentication; using Volo.Abp.IdentityModel; @@ -14,22 +10,21 @@ namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly; public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator { - [CanBeNull] - protected IAccessTokenProvider AccessTokenProvider { get; } + protected IAbpAccessTokenProvider AccessTokenProvider { get; } public AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator( IIdentityModelAuthenticationService identityModelAuthenticationService, - IServiceProvider serviceProvider) + IAbpAccessTokenProvider accessTokenProvider) : base(identityModelAuthenticationService) { - AccessTokenProvider = serviceProvider.GetService(); + AccessTokenProvider = accessTokenProvider; } - public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) + public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) { if (context.RemoteService.GetUseCurrentAccessToken() != false) { - var accessToken = await GetAccessTokenFromAccessTokenProviderOrNullAsync(); + var accessToken = await AccessTokenProvider.GetTokenAsync(); if (accessToken != null) { context.Request.SetBearerToken(accessToken); @@ -39,21 +34,4 @@ public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticato await base.Authenticate(context); } - - protected virtual async Task GetAccessTokenFromAccessTokenProviderOrNullAsync() - { - if (AccessTokenProvider == null) - { - return null; - } - - var result = await AccessTokenProvider.RequestAccessToken(); - if (result.Status != AccessTokenResultStatus.Success) - { - return null; - } - - result.TryGetToken(out var token); - return token.Value; - } } diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/WebAssemblyAbpAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/WebAssemblyAbpAccessTokenProvider.cs new file mode 100644 index 0000000000..d0a68cdb7c --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/WebAssemblyAbpAccessTokenProvider.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components.WebAssembly.Authentication; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.Authentication; + +namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly; + +[Dependency(ReplaceServices = true)] +public class WebAssemblyAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency +{ + protected IAccessTokenProvider AccessTokenProvider { get; } + + public WebAssemblyAbpAccessTokenProvider(IAccessTokenProvider accessTokenProvider) + { + AccessTokenProvider = accessTokenProvider; + } + + public virtual async Task GetTokenAsync() + { + if (AccessTokenProvider == null) + { + return null; + } + + var result = await AccessTokenProvider.RequestAccessToken(); + if (result.Status != AccessTokenResultStatus.Success) + { + return null; + } + + result.TryGetToken(out var token); + return token.Value; + } +} diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAbpAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAbpAccessTokenProvider.cs new file mode 100644 index 0000000000..a4e9e650e3 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAbpAccessTokenProvider.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Http.Client.Authentication; + +public interface IAbpAccessTokenProvider +{ + Task GetTokenAsync(); +} diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullAbpAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullAbpAccessTokenProvider.cs new file mode 100644 index 0000000000..6bd7e6344b --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullAbpAccessTokenProvider.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Http.Client.Authentication; + +public class NullAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency +{ + public Task GetTokenAsync() + { + return Task.FromResult(null as string); + } +} From 3daec5dd224a7169027b402b2d0613e49e64c021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 12:22:36 +0300 Subject: [PATCH 047/165] Update Show-Password-Directive.md --- docs/en/UI/Angular/Show-Password-Directive.md | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md index 6c3cbe4f45..c19c8073bd 100644 --- a/docs/en/UI/Angular/Show-Password-Directive.md +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -6,11 +6,16 @@ In password input, text can be shown easily via changing input type attribute to ## Getting Started `ShowPasswordDirective` is standalone. In order to use the `ShowPasswordDirective` in an HTML template, import it to related module or your standalone component: +**Importing to NgModule** ```ts import { ShowPasswordDirective } from '@abp/ng.core'; @NgModule({ //... + declarations: [ + ..., + TestComponent + ], imports: [ ..., ShowPasswordDirective @@ -25,10 +30,27 @@ The `ShowPasswordDirective` is very easy to use. The directive's selector is **` See an example usage: +**NgModule Component usage** ```ts -import { ShowPasswordDirective } from '@abp/ng.core'; @Component({ selector: 'test-component', + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + showPassword = false; +} +``` +**Standalone Component usage** +```ts +import { ShowPasswordDirective } from '@abp/ng.core'; +@Component({ + selector: 'standalone-component', standalone: true, template: `
@@ -39,7 +61,7 @@ import { ShowPasswordDirective } from '@abp/ng.core'; `, imports: [ShowPasswordDirective] }) -export class TestComponent{ +export class StandaloneComponent{ showPassword = false; } ``` From 8197eb1289a1c935c5e32b5f0fcf481e0c420293 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 31 Jul 2023 12:57:37 +0300 Subject: [PATCH 048/165] settings tab re-order --- .../src/lib/providers/feature-management-settings.provider.ts | 2 +- .../config/src/lib/providers/setting-tab.provider.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts b/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts index 2d7664bb46..30d6701d4b 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts @@ -17,7 +17,7 @@ export function configureSettingTabs(settingtabs: SettingTabsService) { settingtabs.add([ { name: eFeatureManagementTabNames.FeatureManagement, - order: 104, + order: 120, requiredPolicy: 'FeatureManagement.ManageHostFeatures', component: FeatureManagementTabComponent, }, diff --git a/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts b/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts index f05104c177..91a31f70cc 100644 --- a/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts +++ b/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts @@ -17,7 +17,7 @@ export function configureSettingTabs(settingTabs: SettingTabsService) { settingTabs.add([ { name: eSettingManamagementSettingTabNames.EmailSettingGroup, - order: 100, + order: 110, requiredPolicy: 'SettingManagement.Emailing', component: EmailSettingGroupComponent, }, From 9b778069fdcc7e1079d40ddcba55b3758ca028ab Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Mon, 31 Jul 2023 17:50:39 +0300 Subject: [PATCH 049/165] re-setting order to default value and new sorting compare function --- .../core/src/lib/services/routes.service.ts | 22 +++++++++++++++---- .../feature-management-settings.provider.ts | 2 +- .../src/lib/providers/setting-tab.provider.ts | 2 +- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts index 329d2a370c..ec8ee4c4e5 100644 --- a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts @@ -12,6 +12,7 @@ import { } from '../utils/tree-utils'; import { ConfigStateService } from './config-state.service'; import { PermissionService } from './permission.service'; +import { LocalizationService } from './localization.service'; // eslint-disable-next-line @typescript-eslint/ban-types export abstract class AbstractTreeService { @@ -158,14 +159,26 @@ export abstract class AbstractNavTreeService { private subscription: Subscription; private permissionService: PermissionService; + private localizationService: LocalizationService readonly id = 'name'; readonly parentId = 'parentName'; readonly hide = (item: T) => item.invisible || !this.isGranted(item); readonly sort = (a: T, b: T) => { - if (!Number.isInteger(a.order)) return 1; - if (!Number.isInteger(b.order)) return -1; - - return (a.order as number) - (b.order as number); + const aName = this.localizationService.instant(a.name); + const bName = this.localizationService.instant(b.name); + const aNumber = a.order; + const bNumber = b.order; + + if (!Number.isInteger(aNumber)) return 1; + if (!Number.isInteger(bNumber)) return -1; + + if (aNumber > bNumber) return 1 + if (aNumber < bNumber) return -1 + + if ( aName > bName ) return 1; + if ( aName < bName ) return -1; + + return 0 }; constructor(protected injector: Injector) { @@ -175,6 +188,7 @@ export abstract class AbstractNavTreeService .createOnUpdateStream(state => state) .subscribe(() => this.refresh()); this.permissionService = injector.get(PermissionService); + this.localizationService = injector.get(LocalizationService); this.othersGroup = injector.get(OTHERS_GROUP); } diff --git a/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts b/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts index 30d6701d4b..64bbfb9932 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/providers/feature-management-settings.provider.ts @@ -17,7 +17,7 @@ export function configureSettingTabs(settingtabs: SettingTabsService) { settingtabs.add([ { name: eFeatureManagementTabNames.FeatureManagement, - order: 120, + order: 100, requiredPolicy: 'FeatureManagement.ManageHostFeatures', component: FeatureManagementTabComponent, }, diff --git a/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts b/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts index 91a31f70cc..f05104c177 100644 --- a/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts +++ b/npm/ng-packs/packages/setting-management/config/src/lib/providers/setting-tab.provider.ts @@ -17,7 +17,7 @@ export function configureSettingTabs(settingTabs: SettingTabsService) { settingTabs.add([ { name: eSettingManamagementSettingTabNames.EmailSettingGroup, - order: 110, + order: 100, requiredPolicy: 'SettingManagement.Emailing', component: EmailSettingGroupComponent, }, From 939f116ebcfe01dc2e2fb90ddaefbb783d2fb30a Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Tue, 1 Aug 2023 12:14:00 +0300 Subject: [PATCH 050/165] moving logic to compare func --- .../packages/core/src/lib/services/routes.service.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts index ec8ee4c4e5..5f05eaa8ab 100644 --- a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts @@ -164,6 +164,10 @@ export abstract class AbstractNavTreeService readonly parentId = 'parentName'; readonly hide = (item: T) => item.invisible || !this.isGranted(item); readonly sort = (a: T, b: T) => { + return this.compareFunc(a,b) + }; + + readonly compareFunc = (a: T, b: T) => { const aName = this.localizationService.instant(a.name); const bName = this.localizationService.instant(b.name); const aNumber = a.order; @@ -179,7 +183,7 @@ export abstract class AbstractNavTreeService if ( aName < bName ) return -1; return 0 - }; + } constructor(protected injector: Injector) { super(); From b2008832025e0dd742f42e493dea9f6988322ea2 Mon Sep 17 00:00:00 2001 From: Masum ULU Date: Tue, 1 Aug 2023 14:30:13 +0300 Subject: [PATCH 051/165] Update NavItem model for toolbar --- .../packages/theme-shared/src/lib/models/nav-item.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts index 706eb1cb6c..c673bc74e2 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts @@ -1,8 +1,17 @@ import { Injector, Type } from '@angular/core'; import { Observable, of } from 'rxjs'; +export interface Badge { + count?: number | Observable; + color?: string; + icon?: string; +} + export class NavItem { id?: string | number; + name?: string; + description?: string; + badge?: Badge; component?: Type; html?: string; action?: () => void; From b84412409633c1d29454953e4f821a18423a172c Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Tue, 1 Aug 2023 17:02:46 -0400 Subject: [PATCH 052/165] Added Distributed Events section --- docs/en/Modules/Tenant-Management.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/en/Modules/Tenant-Management.md b/docs/en/Modules/Tenant-Management.md index e12b6fc7a6..0d43c5e31e 100644 --- a/docs/en/Modules/Tenant-Management.md +++ b/docs/en/Modules/Tenant-Management.md @@ -48,6 +48,33 @@ The Features action opens a modal to enable/disable/set [features](../Features.m *Manage Host features* button is used to set features for the host side, if you use the features of your application also in the host side. +## Distributed Events + +This module defines the following ETOs (Event Transfer Objects) to allow you to subscribe to changes on the entities of the module; + +- `TenantEto` is published on changes done on an `Tenant` entity. + +**Example: Get notified when a new tenant has been created** + +``` +public class MyHandler : + IDistributedEventHandler>, + ITransientDependency +{ + public async Task HandleEventAsync(EntityCreatedEto eventData) + { + TenantEto tenant = eventData.Entity; + // TODO: ... + } +} +``` + + + +`TenantEto` is configured to automatically publish the events. You should configure yourself for the others. See the [Distributed Event Bus document](https://github.com/abpframework/abp/blob/rel-7.3/docs/en/Distributed-Event-Bus.md) to learn details of the pre-defined events. + +> Subscribing to the distributed events is especially useful for distributed scenarios (like microservice architecture). If you are building a monolithic application, or listening events in the same process that runs the Tenant Management Module, then subscribing to the [local events](https://github.com/abpframework/abp/blob/rel-7.3/docs/en/Local-Event-Bus.md) can be more efficient and easier. + ## Internals This section can be used as a reference if you want to [customize](../Customizing-Application-Modules-Guide.md) this module without changing [its source code](https://github.com/abpframework/abp/tree/dev/modules/tenant-management). From 2302230e56b1ef92171cd3512f7b7d446c7af61b Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 2 Aug 2023 09:18:27 +0800 Subject: [PATCH 053/165] Depends on `AbpBackgroundJobsModule` in the `DemoAppSharedModule`. Resolve #17250 --- .../DemoAppSharedModule.cs | 2 +- .../Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs index 193e87b528..ad002a5e18 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs @@ -5,7 +5,7 @@ using Volo.Abp.Modularity; namespace Volo.Abp.BackgroundJobs.DemoApp.Shared { [DependsOn( - typeof(AbpBackgroundJobsAbstractionsModule) + typeof(AbpBackgroundJobsModule) )] public class DemoAppSharedModule : AbpModule { diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj index e6a08dbd02..d8ff12e3f8 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj @@ -8,7 +8,7 @@ - + From 71a61a895d7d1f9c1fcaee390c4ceee1d20f5157 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 2 Aug 2023 11:27:39 +0800 Subject: [PATCH 054/165] Order setting tabs --- .../SettingManagement/SettingManagement.razor.cs | 2 +- .../SettingComponentCreationContext.cs | 13 +++++++++++++ .../SettingComponentGroup.cs | 7 ++++++- .../Settings/EmailingPageContributor.cs | 3 ++- .../Settings/TimeZonePageContributor.cs | 3 ++- .../SettingPageContributorManager.cs | 1 + .../SettingManagement/SettingPageCreationContext.cs | 13 +++++++++++++ .../Pages/SettingManagement/SettingPageGroup.cs | 7 ++++++- .../Settings/EmailingPageContributor.cs | 3 ++- .../Settings/TimeZonePageContributor.cs | 3 ++- 10 files changed, 48 insertions(+), 7 deletions(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs index 1422d67873..47a956a028 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs @@ -39,7 +39,7 @@ public partial class SettingManagement { await contributor.ConfigureAsync(SettingComponentCreationContext); } - + SettingComponentCreationContext.Normalize(); SettingItemRenders.Clear(); SelectedGroup = GetNormalizedString(SettingComponentCreationContext.Groups.First().Id); diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs index dfba0564f2..d016fb66ce 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Volo.Abp.DependencyInjection; namespace Volo.Abp.SettingManagement.Blazor; @@ -16,4 +17,16 @@ public class SettingComponentCreationContext : IServiceProviderAccessor Groups = new List(); } + + public void Normalize() + { + Order(); + } + + private void Order() + { + var orderedItems = Groups.OrderBy(item => item.Order).ToArray(); + Groups.Clear(); + Groups.AddRange(orderedItems); + } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs index bf4bbf2a22..0577f38b76 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs @@ -5,6 +5,8 @@ namespace Volo.Abp.SettingManagement.Blazor; public class SettingComponentGroup { + public const int DefaultOrder = 1000; + public string Id { get => _id; set => _id = Check.NotNullOrWhiteSpace(value, nameof(Id)); @@ -24,12 +26,15 @@ public class SettingComponentGroup private Type _componentType; public object Parameter { get; set; } + + public int Order { get; set; } - public SettingComponentGroup([NotNull] string id, [NotNull] string displayName, [NotNull] Type componentType, object parameter = null) + public SettingComponentGroup([NotNull] string id, [NotNull] string displayName, [NotNull] Type componentType, object parameter = null, int order = DefaultOrder) { Id = id; DisplayName = displayName; ComponentType = componentType; Parameter = parameter; + Order = order; } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs index aec58c8ca8..13cdc2acde 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs @@ -23,7 +23,8 @@ public class EmailingPageContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.SettingManagement", l["Menu:Emailing"], - typeof(EmailSettingGroupViewComponent) + typeof(EmailSettingGroupViewComponent), + order : 3 ) ); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs index 6effd64494..a23a32cb53 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs @@ -20,7 +20,8 @@ public class TimeZonePageContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.TimeZone", l["Menu:TimeZone"], - typeof(TimeZoneSettingGroupViewComponent) + typeof(TimeZoneSettingGroupViewComponent), + order : 4 ) ); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorManager.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorManager.cs index 9b08236cae..83f5d53fa5 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorManager.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorManager.cs @@ -37,6 +37,7 @@ public class SettingPageContributorManager : IScopedDependency { await contributor.ConfigureAsync(context); } + context.Normalize(); return context; } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs index c929fef16d..51490e4e63 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Volo.Abp.DependencyInjection; namespace Volo.Abp.SettingManagement.Web.Pages.SettingManagement; @@ -16,4 +17,16 @@ public class SettingPageCreationContext : IServiceProviderAccessor Groups = new List(); } + + public void Normalize() + { + Order(); + } + + private void Order() + { + var orderedItems = Groups.OrderBy(item => item.Order).ToArray(); + Groups.Clear(); + Groups.AddRange(orderedItems); + } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageGroup.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageGroup.cs index 2dbc6eb4de..65aceb554c 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageGroup.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageGroup.cs @@ -5,6 +5,8 @@ namespace Volo.Abp.SettingManagement.Web.Pages.SettingManagement; public class SettingPageGroup { + public const int DefaultOrder = 1000; + public string Id { get => _id; set => _id = Check.NotNullOrWhiteSpace(value, nameof(Id)); @@ -24,12 +26,15 @@ public class SettingPageGroup private Type _componentType; public object Parameter { get; set; } + + public int Order { get; set; } - public SettingPageGroup([NotNull] string id, [NotNull] string displayName, [NotNull] Type componentType, object parameter = null) + public SettingPageGroup([NotNull] string id, [NotNull] string displayName, [NotNull] Type componentType, object parameter = null, int order = DefaultOrder) { Id = id; DisplayName = displayName; ComponentType = componentType; Parameter = parameter; + Order = order; } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs index 5096404a11..0c369f12ff 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs @@ -23,7 +23,8 @@ public class EmailingPageContributor : SettingPageContributorBase new SettingPageGroup( "Volo.Abp.EmailSetting", l["Menu:Emailing"], - typeof(EmailSettingGroupViewComponent) + typeof(EmailSettingGroupViewComponent), + order : 3 ) ); return Task.CompletedTask; diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs index 696d1204da..21c35baccc 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs @@ -25,7 +25,8 @@ public class TimeZonePageContributor : SettingPageContributorBase new SettingPageGroup( "Volo.Abp.TimeZone", l["Menu:TimeZone"], - typeof(TimeZoneSettingGroupViewComponent) + typeof(TimeZoneSettingGroupViewComponent), + order : 4 ) ); } From 0d107364be1c0c8066b14fef2da0a0b499438578 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 2 Aug 2023 11:58:25 +0800 Subject: [PATCH 055/165] Update document --- docs/en/Modules/Setting-Management.md | 6 ++++-- docs/zh-Hans/Modules/Setting-Management.md | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/en/Modules/Setting-Management.md b/docs/en/Modules/Setting-Management.md index 354fbdd539..e26c7c806e 100644 --- a/docs/en/Modules/Setting-Management.md +++ b/docs/en/Modules/Setting-Management.md @@ -177,7 +177,8 @@ public class BookStoreSettingPageContributor : ISettingPageContributor new SettingPageGroup( "Volo.Abp.MySettingGroup", "MySettingGroup", - typeof(MySettingGroupViewComponent) + typeof(MySettingGroupViewComponent), + order : 1 ) ); @@ -240,7 +241,8 @@ public class BookStoreSettingComponentContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.MySettingGroup", "MySettingGroup", - typeof(MySettingGroupComponent) + typeof(MySettingGroupComponent), + order : 1 ) ); diff --git a/docs/zh-Hans/Modules/Setting-Management.md b/docs/zh-Hans/Modules/Setting-Management.md index 242553c2c9..cf52d588a2 100644 --- a/docs/zh-Hans/Modules/Setting-Management.md +++ b/docs/zh-Hans/Modules/Setting-Management.md @@ -146,7 +146,8 @@ public class BookStoreSettingPageContributor : ISettingPageContributor new SettingPageGroup( "Volo.Abp.MySettingGroup", "MySettingGroup", - typeof(MySettingGroupViewComponent) + typeof(MySettingGroupViewComponent), + order : 1 ) ); @@ -209,7 +210,8 @@ public class BookStoreSettingComponentContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.MySettingGroup", "MySettingGroup", - typeof(MySettingGroupComponent) + typeof(MySettingGroupComponent), + order : 1 ) ); From b5b2cfb07ed2954d4211c9e9fa1c53733a096c72 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 2 Aug 2023 12:45:41 +0800 Subject: [PATCH 056/165] improve --- .../SettingComponentCreationContext.cs | 2 +- .../Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs | 2 +- .../Settings/EmailingPageContributor.cs | 3 +-- .../Settings/TimeZonePageContributor.cs | 3 +-- .../Pages/SettingManagement/SettingPageCreationContext.cs | 2 +- .../Settings/EmailingPageContributor.cs | 3 +-- .../Settings/TimeZonePageContributor.cs | 3 +-- 7 files changed, 7 insertions(+), 11 deletions(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs index d016fb66ce..ff386cc260 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs @@ -25,7 +25,7 @@ public class SettingComponentCreationContext : IServiceProviderAccessor private void Order() { - var orderedItems = Groups.OrderBy(item => item.Order).ToArray(); + var orderedItems = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToArray(); Groups.Clear(); Groups.AddRange(orderedItems); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs index 0577f38b76..7b1aca36aa 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs @@ -5,7 +5,7 @@ namespace Volo.Abp.SettingManagement.Blazor; public class SettingComponentGroup { - public const int DefaultOrder = 1000; + public const int DefaultOrder = 1; public string Id { get => _id; diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs index 13cdc2acde..aec58c8ca8 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/EmailingPageContributor.cs @@ -23,8 +23,7 @@ public class EmailingPageContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.SettingManagement", l["Menu:Emailing"], - typeof(EmailSettingGroupViewComponent), - order : 3 + typeof(EmailSettingGroupViewComponent) ) ); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs index a23a32cb53..6effd64494 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Settings/TimeZonePageContributor.cs @@ -20,8 +20,7 @@ public class TimeZonePageContributor : ISettingComponentContributor new SettingComponentGroup( "Volo.Abp.TimeZone", l["Menu:TimeZone"], - typeof(TimeZoneSettingGroupViewComponent), - order : 4 + typeof(TimeZoneSettingGroupViewComponent) ) ); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs index 51490e4e63..957342592d 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs @@ -25,7 +25,7 @@ public class SettingPageCreationContext : IServiceProviderAccessor private void Order() { - var orderedItems = Groups.OrderBy(item => item.Order).ToArray(); + var orderedItems = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToArray(); Groups.Clear(); Groups.AddRange(orderedItems); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs index 0c369f12ff..5096404a11 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs @@ -23,8 +23,7 @@ public class EmailingPageContributor : SettingPageContributorBase new SettingPageGroup( "Volo.Abp.EmailSetting", l["Menu:Emailing"], - typeof(EmailSettingGroupViewComponent), - order : 3 + typeof(EmailSettingGroupViewComponent) ) ); return Task.CompletedTask; diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs index 21c35baccc..696d1204da 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/TimeZonePageContributor.cs @@ -25,8 +25,7 @@ public class TimeZonePageContributor : SettingPageContributorBase new SettingPageGroup( "Volo.Abp.TimeZone", l["Menu:TimeZone"], - typeof(TimeZoneSettingGroupViewComponent), - order : 4 + typeof(TimeZoneSettingGroupViewComponent) ) ); } From daa151108b4e3ae1db4a6a7dfeb7a0b2c7e414ff Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 2 Aug 2023 12:48:10 +0800 Subject: [PATCH 057/165] Update SettingComponentGroup.cs --- .../Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs index 7b1aca36aa..0577f38b76 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentGroup.cs @@ -5,7 +5,7 @@ namespace Volo.Abp.SettingManagement.Blazor; public class SettingComponentGroup { - public const int DefaultOrder = 1; + public const int DefaultOrder = 1000; public string Id { get => _id; From 132f2741f475f43a56a4a70f05aabead5e57e6c9 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 2 Aug 2023 13:25:49 +0800 Subject: [PATCH 058/165] Update SettingPageCreationContext --- .../SettingComponentCreationContext.cs | 6 ++---- .../Pages/SettingManagement/SettingPageCreationContext.cs | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs index ff386cc260..390110430c 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/SettingComponentCreationContext.cs @@ -9,7 +9,7 @@ public class SettingComponentCreationContext : IServiceProviderAccessor { public IServiceProvider ServiceProvider { get; } - public List Groups { get; } + public List Groups { get; private set; } public SettingComponentCreationContext(IServiceProvider serviceProvider) { @@ -25,8 +25,6 @@ public class SettingComponentCreationContext : IServiceProviderAccessor private void Order() { - var orderedItems = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToArray(); - Groups.Clear(); - Groups.AddRange(orderedItems); + Groups = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToList(); } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs index 957342592d..d620ced0b9 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageCreationContext.cs @@ -9,7 +9,7 @@ public class SettingPageCreationContext : IServiceProviderAccessor { public IServiceProvider ServiceProvider { get; } - public List Groups { get; } + public List Groups { get; private set; } public SettingPageCreationContext(IServiceProvider serviceProvider) { @@ -25,8 +25,6 @@ public class SettingPageCreationContext : IServiceProviderAccessor private void Order() { - var orderedItems = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToArray(); - Groups.Clear(); - Groups.AddRange(orderedItems); + Groups = Groups.OrderBy(item => item.Order).ThenBy(item => item.DisplayName).ToList(); } } From 2f112e136726e7340727f704da3d6567f73ebfe1 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Wed, 2 Aug 2023 13:54:32 +0300 Subject: [PATCH 059/165] SORT_COMPARE_FUNC injection token added --- .../packages/core/src/lib/core.module.ts | 5 ++++ .../core/src/lib/services/routes.service.ts | 24 +++-------------- .../core/src/lib/tokens/compare-func.token.ts | 27 +++++++++++++++++++ 3 files changed, 35 insertions(+), 21 deletions(-) create mode 100644 npm/ng-packs/packages/core/src/lib/tokens/compare-func.token.ts diff --git a/npm/ng-packs/packages/core/src/lib/core.module.ts b/npm/ng-packs/packages/core/src/lib/core.module.ts index c2d497ae7b..c4f7c78fa7 100644 --- a/npm/ng-packs/packages/core/src/lib/core.module.ts +++ b/npm/ng-packs/packages/core/src/lib/core.module.ts @@ -38,6 +38,7 @@ import { SafeHtmlPipe } from './pipes/safe-html.pipe'; import { QUEUE_MANAGER } from './tokens/queue.token'; import { DefaultQueueManager } from './utils/queue'; import { IncludeLocalizationResourcesProvider } from './providers/include-localization-resources.provider'; +import { SORT_COMPARE_FUNC, compareFuncFactory } from './tokens/compare-func.token'; /** * BaseCoreModule is the module that holds @@ -176,6 +177,10 @@ export class CoreModule { useValue: localizationContributor(options.localizations), deps: [LocalizationService], }, + { + provide: SORT_COMPARE_FUNC, + useFactory: compareFuncFactory + }, { provide: QUEUE_MANAGER, useClass: DefaultQueueManager, diff --git a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts index 5f05eaa8ab..c3a1ffe07f 100644 --- a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts @@ -12,7 +12,7 @@ import { } from '../utils/tree-utils'; import { ConfigStateService } from './config-state.service'; import { PermissionService } from './permission.service'; -import { LocalizationService } from './localization.service'; +import { SORT_COMPARE_FUNC } from '../tokens/compare-func.token'; // eslint-disable-next-line @typescript-eslint/ban-types export abstract class AbstractTreeService { @@ -159,7 +159,7 @@ export abstract class AbstractNavTreeService { private subscription: Subscription; private permissionService: PermissionService; - private localizationService: LocalizationService + private compareFunc; readonly id = 'name'; readonly parentId = 'parentName'; readonly hide = (item: T) => item.invisible || !this.isGranted(item); @@ -167,24 +167,6 @@ export abstract class AbstractNavTreeService return this.compareFunc(a,b) }; - readonly compareFunc = (a: T, b: T) => { - const aName = this.localizationService.instant(a.name); - const bName = this.localizationService.instant(b.name); - const aNumber = a.order; - const bNumber = b.order; - - if (!Number.isInteger(aNumber)) return 1; - if (!Number.isInteger(bNumber)) return -1; - - if (aNumber > bNumber) return 1 - if (aNumber < bNumber) return -1 - - if ( aName > bName ) return 1; - if ( aName < bName ) return -1; - - return 0 - } - constructor(protected injector: Injector) { super(); const configState = this.injector.get(ConfigStateService); @@ -192,8 +174,8 @@ export abstract class AbstractNavTreeService .createOnUpdateStream(state => state) .subscribe(() => this.refresh()); this.permissionService = injector.get(PermissionService); - this.localizationService = injector.get(LocalizationService); this.othersGroup = injector.get(OTHERS_GROUP); + this.compareFunc = injector.get(SORT_COMPARE_FUNC); } protected isGranted({ requiredPolicy }: T): boolean { diff --git a/npm/ng-packs/packages/core/src/lib/tokens/compare-func.token.ts b/npm/ng-packs/packages/core/src/lib/tokens/compare-func.token.ts new file mode 100644 index 0000000000..bf66ec2b54 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tokens/compare-func.token.ts @@ -0,0 +1,27 @@ +import { InjectionToken, inject } from '@angular/core'; +import { LocalizationService } from '../services'; + +export const SORT_COMPARE_FUNC = new InjectionToken< 0 | 1 | -1 >('SORT_COMPARE_FUNC'); + +export function compareFuncFactory() { + const localizationService = inject(LocalizationService) + const fn = (a,b) => { + const aName = localizationService.instant(a.name); + const bName = localizationService.instant(b.name); + const aNumber = a.order; + const bNumber = b.order; + + if (!Number.isInteger(aNumber)) return 1; + if (!Number.isInteger(bNumber)) return -1; + + if (aNumber > bNumber) return 1 + if (aNumber < bNumber) return -1 + + if ( aName > bName ) return 1; + if ( aName < bName ) return -1; + + return 0 + } + + return fn +} \ No newline at end of file From 272580aeeb59fc46a835c521bd9c6d0b32043ea6 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 3 Aug 2023 12:57:31 +0800 Subject: [PATCH 060/165] Update AbpHostingHostBuilderExtensions.cs Close #17261 --- .../Extensions/Hosting/AbpHostingHostBuilderExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs b/framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs index 767fa43f1d..09f6ed9bed 100644 --- a/framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs +++ b/framework/src/Volo.Abp.Core/Microsoft/Extensions/Hosting/AbpHostingHostBuilderExtensions.cs @@ -15,7 +15,7 @@ public static class AbpHostingHostBuilderExtensions return hostBuilder.ConfigureAppConfiguration((_, builder) => { builder.AddJsonFile( - path: AppSettingsSecretJsonPath, + path: path, optional: optional, reloadOnChange: reloadOnChange ); From b7ebe0121d3c4f04ab3dd88ec810eaced6585954 Mon Sep 17 00:00:00 2001 From: minhtaile2712 Date: Thu, 3 Aug 2023 12:17:10 +0700 Subject: [PATCH 061/165] Correct links Correct links to valid branch (`dev` instead of `master`). --- docs/en/Modules/Index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/Modules/Index.md b/docs/en/Modules/Index.md index d5037665f0..5e280268e7 100644 --- a/docs/en/Modules/Index.md +++ b/docs/en/Modules/Index.md @@ -4,8 +4,8 @@ ABP is a **modular application framework** which consists of dozens of **NuGet & There are **two types of modules.** They don't have any structural difference but are categorized by functionality and purpose: -* [**Framework modules**](https://github.com/abpframework/abp/tree/master/framework/src): These are **core modules of the framework** like caching, emailing, theming, security, serialization, validation, EF Core integration, MongoDB integration... etc. They do not have application/business functionalities but makes your daily development easier by providing common infrastructure, integration and abstractions. -* [**Application modules**](https://github.com/abpframework/abp/tree/master/modules): These modules implement specific application/business functionalities like blogging, document management, identity management, tenant management... etc. They generally have their own entities, services, APIs and UI components. +* [**Framework modules**](https://github.com/abpframework/abp/tree/dev/framework/src): These are **core modules of the framework** like caching, emailing, theming, security, serialization, validation, EF Core integration, MongoDB integration... etc. They do not have application/business functionalities but makes your daily development easier by providing common infrastructure, integration and abstractions. +* [**Application modules**](https://github.com/abpframework/abp/tree/dev/modules): These modules implement specific application/business functionalities like blogging, document management, identity management, tenant management... etc. They generally have their own entities, services, APIs and UI components. ## Open Source Application Modules @@ -29,4 +29,4 @@ See [the GitHub repository](https://github.com/abpframework/abp/tree/dev/modules ## Commercial Application Modules -[ABP Commercial](https://commercial.abp.io/) license provides **additional pre-built application modules** on top of the ABP framework. See the [module list](https://commercial.abp.io/modules) provided by the ABP Commercial. \ No newline at end of file +[ABP Commercial](https://commercial.abp.io/) license provides **additional pre-built application modules** on top of the ABP framework. See the [module list](https://commercial.abp.io/modules) provided by the ABP Commercial. From d9170bb3a1455d9278623026fd476721f0ed93a0 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Thu, 3 Aug 2023 09:53:55 +0300 Subject: [PATCH 062/165] update --- docs/en/UI/Angular/CapsLock.directive.md | 6 +++--- .../packages/core/src/lib/tests/capsLock.directive.spec.ts | 1 - .../core/src/lib/tests/show-password-directive.spec.ts | 6 +----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 1e1021bdd4..64a3fc42ca 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -39,7 +39,7 @@ See an example usage:
- icon + icon
` }) @@ -59,10 +59,10 @@ import { TrackCapsLockDirective } from '@abp/ng.core'
- icon + icon
`, - imports: [ TrackCapsLockDirective ] + imports: [TrackCapsLockDirective] }) export class StandaloneComponent{ capsLock = false; diff --git a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts index 17d50ba697..3182dfa2dd 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts @@ -28,7 +28,6 @@ describe('TrackCapsLockDirective',()=>{ des = fixture.debugElement.queryAll(By.directive(TrackCapsLockDirective)); }); - // tests test.each(['keydown','keyup'])('is %p works when press capslock and is emit status', (eventName) => { const event = new KeyboardEvent(eventName, { key: 'CapsLock', diff --git a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts index e1e9750995..8babb472c4 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts @@ -27,19 +27,15 @@ describe('ShowPasswordDirective',()=>{ imports: [ TestComponent ] }).createComponent(TestComponent) - fixture.detectChanges(); // initial binding + fixture.detectChanges(); - // all elements with an attached HighlightDirective des = fixture.debugElement.queryAll(By.directive(ShowPasswordDirective)); - // all inputs includes nondirective desAll = fixture.debugElement.queryAll(By.all()); - // the input without the ShowPasswordDirective bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); }) - // tests it('should have three input has ShowPasswordDirective elements', () => { expect(des.length).toBe(3); }); From 8d02cf83ef0873da98919ee6b2de95e274cc2d8e Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Tue, 1 Aug 2023 08:12:01 +0300 Subject: [PATCH 063/165] decreasing margin for form prop --- .../extensible-form/extensible-form-prop.component.html | 2 +- .../extensible-form/extensible-form-prop.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html index 26dcbf1297..2f16d5d905 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html @@ -7,7 +7,7 @@ -
+
[]> = of([]); From f178443b737dbc7b50853b24cf8ffac3c8e0471c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 3 Aug 2023 10:02:16 +0300 Subject: [PATCH 064/165] Update docs-nav.json --- docs/en/docs-nav.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index c6c07d9a7c..08046fa664 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -1522,6 +1522,10 @@ } ] }, + { + "text": "API Documentation", + "path": "{ApiDocumentationUrl}" + }, { "text": "Contribution Guide", "path": "Contribution/Index.md" From 5c066c5b3f6fcbad97149b44d065ae7a9fb1870b Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 28 Jul 2023 14:59:40 +0300 Subject: [PATCH 065/165] show password directive test and document --- docs/en/UI/Angular/Show-Password-Directive.md | 52 +++++++++++++++ .../Angular/images/showPasswordDirective1.png | Bin 0 -> 3707 bytes .../Angular/images/showPasswordDirective2.png | Bin 0 -> 3932 bytes .../lib/tests/show-password-directive.spec.ts | 59 ++++++++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 docs/en/UI/Angular/Show-Password-Directive.md create mode 100644 docs/en/UI/Angular/images/showPasswordDirective1.png create mode 100644 docs/en/UI/Angular/images/showPasswordDirective2.png create mode 100644 npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md new file mode 100644 index 0000000000..db54bcdd76 --- /dev/null +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -0,0 +1,52 @@ +# Show Password Directive + +In password input, text can be shown easily via changing input type attribute to `text`. To make this even easier, you can use the `ShowPasswordDirective` which has been exposed by the `@abp/ng.core` package. + + +## Getting Started + +In order to use the `ShowPasswordDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: + +```ts +// ... +import { CoreModule } from '@abp/ng.core'; + +@NgModule({ + //... + imports: [..., CoreModule], +}) +export class MyFeatureModule {} +``` + +## Usage + +The `ShowPasswordDirective` is very easy to use. The directive's selector is **`abpShowPassword`**. By adding the `abpShowPassword` attribute to an input element, you can activate the `ShowPasswordDirective` for the input element. + +See an example usage: + +```ts +@Component({ + selector: 'test-component', + standalone: true, + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + showPassword = false; +} +``` + +The `abpShowPassword` attribute has been added to the `` element. Click icon to activate the `ShowPasswordDirective`. + +See the result: + +![Show Password directive](./images/showPasswordDirective1.png) + +To see password input click icon. + +![Show Password directive](./images/showPasswordDirective2.png) \ No newline at end of file diff --git a/docs/en/UI/Angular/images/showPasswordDirective1.png b/docs/en/UI/Angular/images/showPasswordDirective1.png new file mode 100644 index 0000000000000000000000000000000000000000..7b64be2b5f14c8e8affb7849331f0f5398188193 GIT binary patch literal 3707 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 YNubRLytJp=IDz)l)k46FG%?Tr1J+;SK>z>% literal 0 HcmV?d00001 diff --git a/docs/en/UI/Angular/images/showPasswordDirective2.png b/docs/en/UI/Angular/images/showPasswordDirective2.png new file mode 100644 index 0000000000000000000000000000000000000000..43199ffeaa2b1a813743599a1f74137404254ee0 GIT binary patch literal 3932 zcma)9c{r5c+aIzg+4mt!mWYsb)W|+)rYPB$3`(|;ol(-*X~w=Q5h457cP4u=XzW`m zG)N5D-pBWP|NOr1?{}{2dCqyx@|^qr-1j;6{fW8**So;L%K!p_F2MA)jX@wv7|^~; zM+3ZjGvwDnpo{b{?OXT!vwqE@JPEtm_-*kf;t{K<#)AlHnHH)73MMRNmwXoN`BRSd zjJid*^c_*jD+F7X50*?Z{x&|tx+PTL>je5@AKtn zGBQ$M)L5St=%BwP1k={m7Nv?1JsW0b#{gg2ns@$n@QqAiWrtn&qv&3{$cKry0t|tv ze<#!J674F&hczG_cHecZKa2?Vv9qB&xOIXorJnD}(os#xmi)7IjHA4cLv*~5no^FP zGc5(`N$y9*_p;L%ZM=<+v$MGEKK#!?uP{(j$Lw~l#p;UuavKV95!~ZWmlT6joJlD> z$JNT_Qlrke4 z#)_Yn70TN^TyvmC)^Pk@KXSX~BQOx^mjCC0>|NzR0Yg&e?H6)keas6B6XUK|$es1H z{=daJ<1bd)L#*K^D0g9*9Ue}2H8Tg}=X>`f>W(>BSPp!n+7pqTDe^S%4az0h{@i_j ziRN4|n$pvOa{#rt(nvn9a?;h5HoC9Y7SKXzZDi-UN;|hn!)uFZ^X?TkIHZ$&C8IrcW zR?Nk_`s>2G5Ap2E5#{1fY3=lTy-T}iKO)YIC{qT22E(=Xk5yBI(_=qIcRpx*HN`s@ zgw^PGEj(T4?j^c1$`R}-_v@ceOq1-1OL7~k_u${0l))NZMHKR(zZpeIOP@(@uBY|X zVc}@Lr!z=&3Q||8wTHISPtKmdJDvx2obSb*0W-eG;jy`%L-+0Kq6c0+J&_U;Pf-?E z-(rnkGR8CeA;*ZSCPf1!o(P^m>f98-;8yM|Y?$F8*jiuj)dZ-Hg`w&+`PajNI$e3e zY9DaP)rAHQrQX{JhfY^69$ZTGDpcvq7MeC-O&3x;R=D7Qi4C7Kenc8^w}6)B|J=?@ zUlY_Cd;LI#8=7e;rV>@9WZZNU^uYS3hcs}OUQ2hTg1EbWJmDke*nTR%NFKdDp{q%L zy;v=5!|+K`t5T$yQzY*!I2_0<|-C>kG;c(dcVp z(TqlO0p`9T7PYBDKjUd*PHU5Y?Ld_j)EcHin{~53wNYwU|Ll0j`m;J6XF=T4jYhZT z`rf}Sj_(I&1_T9N03Y9*Rpv=bO!QpUM8vnOxxj-@ets(zuTeSQwVd(T#pR$s|NWwf zT()~b?PP|*He(YHibn`imrdOG;giQhV3BhLQk*Zq=qe;m_y9knGb%Xxn^Fb;b;VdQ(E z3FPY^w5EYng2pI+XyEiv))ZOkupf7q0|Itl&1O7C^3~$QQ{R==?|1l69og4LZADE3 zz9nyGmL+YDME9qDnm49R(@*!~qQ@&$I}M4sB-B4vGw#?^lp+QX>h?AhHNuuHO{?=+ z3uV3J#z*IEm-zpQHw{$MMz#cw$luDQ&rm77-Crn}Qj$FzCmU?843yBt<_uDSDC?EW zNeu9qEXIb;&t}31c14H%>|vWQFV9HZp>?`F-jn{DGy# zlfE&7#9Ytk2z$TGyy}rPzfM32J1^~Z`(%xsrn3|#s06AH)+s^a1BlX@SjH0vLQpW5 zc`V1_ubsZuQzp!Ee#4%`oDF^ymhH)=9JhX~5ctUZV~}N$YK7%-YM#JZ)XDoMvZpxL z9@`W;SdhlMM+hA*LZK^hj`9%Il;u;uj0MF$Bint6VXBL$&|UKNnzVYEWl7Rus@WcU zDe~~kr}TO-g(1l7Y5Av~X9-|KMuG>tb9*HM2S>e0o9U4>i?t11!tdM?*hyty_-UxB zV9gHA)G-)|a+qV7xX~KcoDDK}o!RVkKXEacCs`SP=W6dpVlGbD$xe;P|AuAT-um6m z>%z46?h+vE^Ka8tR2psQf_JDH#PABYI=aQI*JAr68^%?}V6IP?XxU#vn|gP}d�Y zx-=@ZKc@!UqB`SJS~_LXdsHc4kZavv)ya!NHN1YKx6!>ZL-8~2tgiLj$XwO;4d2+Ksk1Ka;xH8ZN3$6e-$NX3jNU>tlZ zQ4zb%Z~F#Oi;t_uFmlS1clM@ox8~DtyNp??q?Cu(Xb)zGy7Z^s^et7LP>40(j182Xjlu#7K|v}%u{U_&hCCOuTzgM(&s4_1Dys#{!414iZG}UF zRtzUsc~Bwr2Tv%xid7ipPLnh_+eL~+d5`xk2Sth5AnE!(hE}yJ!+aT;ZLP6uYij*D zbzLN3D@5sfNarK*@l%u8<)YY0E=vA9q@SeD0C;6`e`|bY+04es{Pt$PDj?TpQoAHP zXy$qVjjqNEx*xE=Xm>@vuh~?0_nhxW{%~$XG=^&x^VRqkiIvN7R?wrg zTzvfy_EjOQFRI&LO2WND!LRfj1XeKBj@k!(CvOurCEpU9JLJE_hfD=qAyAzsIyc0^ z4@3L|TWVLk)(@+Ot-L6{*95L@FA*&?Nbmf`fV;x0N84Rro^t8dk#JgaWlUxwaV%;fdRt0cIzjw`v++JMTNJ4&gZ?)2xP51m8SQ0zHm4)Tx?@- z0(r*{RmS0|)%iX4&dH^HY$4bhpC!NdSN23hRBMzJQjZRIB#sHu%eQD-=1|qZ2G!>e zuLZ}vf)=KGlM*lus(N3Guv5)=>zrJfd8@U2sSm% zKB@rOC=pkc*ftja%s}aUVOoc!?#~nfvXb~~vgW41dv7xPnU~3UX|Yn*hh`ddurcuu z?0ACavM=9b^v=n|URTK8?g9;p4*OufzOD7}+a+uZvA*ryo#!$cL-8U#v6~u_93+pM)@PVZhFKZ?&J1|(k3;aqTJif) zzhlq?Y(8)P8uAn(3JuK_L>c zjJq2d-D*_}tcU$l1>Wa%dN{rM+>Wqk(j~bD8R|G1jnw z`MCDZ@=)!+hCZ(R+0XZYB}6O%R#6?^v1)HWf0l`?81T6Y=mI@<6$%@5_J|p#eM>ps zI0gei1J*AznP~g#y!88)hlExH-%K4&(IGm@;fLbnm$?apyjeuv#aT08qHrpvk3CLO z?bVO3Dlf9ZH8@4`fkg-d?DP0r + + + `, + imports:[ShowPasswordDirective] +}) +class TestComponent { + showPassword:boolean = false +} + +describe('ShowPasswordDirective',()=>{ + let fixture: ComponentFixture;; + let des : DebugElement[]; + let desAll : DebugElement[]; + let bareInput; + + beforeEach(()=>{ + fixture = TestBed.configureTestingModule({ + imports: [ TestComponent ] + }).createComponent(TestComponent) + + fixture.detectChanges(); // initial binding + + // all elements with an attached HighlightDirective + des = fixture.debugElement.queryAll(By.directive(ShowPasswordDirective)); + + // all inputs includes nondirective + desAll = fixture.debugElement.queryAll(By.all()); + + // the input without the ShowPasswordDirective + bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); + }) + + // color tests + it('should have three input has ShowPasswordDirective elements', () => { + expect(des.length).toBe(3); + }); + + test.each([[0,'text'],[1,'password'],[2,'text'],[3,'password']])('%p. input type must be %p)', (index,inpType) => { + const inputType = desAll[index].nativeElement.type; + expect(inputType).toBe(inpType); + }); + + it('should have three input has ShowPasswordDirective elements', () => { + let input = des[2].nativeElement + expect(input.type).toBe('password') + fixture.componentInstance.showPassword = true + fixture.detectChanges() + expect(input.type).toBe('text') + }); + }); \ No newline at end of file From b61cd17d3167653b0f0a84b9717769bcafffa1f6 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Sun, 30 Jul 2023 23:48:51 +0300 Subject: [PATCH 066/165] capsLock doc and test --- .../src/lib/tests/capsLock.directive.spec.ts | 58 +++++++++++++++++++ .../lib/tests/show-password-directive.spec.ts | 2 +- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts diff --git a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts new file mode 100644 index 0000000000..17d50ba697 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts @@ -0,0 +1,58 @@ +import { Component, DebugElement } from '@angular/core' +import { ComponentFixture, TestBed } from '@angular/core/testing' +import { TrackCapsLockDirective } from '../directives'; +import { By } from '@angular/platform-browser'; + +@Component({ + standalone:true, + template: ` + + `, + imports:[TrackCapsLockDirective] +}) +class TestComponent { + capsLock:boolean = false +} + +describe('TrackCapsLockDirective',()=>{ + let fixture: ComponentFixture;; + let des : DebugElement[]; + + beforeEach(()=>{ + fixture = TestBed.configureTestingModule({ + imports: [ TestComponent ] + }).createComponent(TestComponent); + + fixture.detectChanges(); + + des = fixture.debugElement.queryAll(By.directive(TrackCapsLockDirective)); + }); + + // tests + test.each(['keydown','keyup'])('is %p works when press capslock and is emit status', (eventName) => { + const event = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: true + }); + window.dispatchEvent(event); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(true) + }); + + test.each(['keydown','keyup'])('is %p detect the change capslock is emit status', (eventName) => { + const trueEvent = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: true + }); + window.dispatchEvent(trueEvent); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(true) + const falseEvent = new KeyboardEvent(eventName, { + key: 'CapsLock', + modifierCapsLock: false + }); + window.dispatchEvent(falseEvent); + fixture.detectChanges(); + expect(fixture.componentInstance.capsLock).toBe(false) + }); + }); \ No newline at end of file diff --git a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts index 6b07997bc9..e1e9750995 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts @@ -39,7 +39,7 @@ describe('ShowPasswordDirective',()=>{ bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); }) - // color tests + // tests it('should have three input has ShowPasswordDirective elements', () => { expect(des.length).toBe(3); }); From 9f10aeb148b89aa86245f9f6b59464661877a2ab Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Sun, 30 Jul 2023 23:49:52 +0300 Subject: [PATCH 067/165] capsLock doc and test --- docs/en/UI/Angular/CapsLock.directive.md | 52 ++++++++++++++++++ .../UI/Angular/images/CapsLockDirective1.png | Bin 0 -> 2224 bytes .../UI/Angular/images/CapsLockDirective2.png | Bin 0 -> 4274 bytes 3 files changed, 52 insertions(+) create mode 100644 docs/en/UI/Angular/CapsLock.directive.md create mode 100644 docs/en/UI/Angular/images/CapsLockDirective1.png create mode 100644 docs/en/UI/Angular/images/CapsLockDirective2.png diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md new file mode 100644 index 0000000000..4b92d61124 --- /dev/null +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -0,0 +1,52 @@ +# Show Password Directive + +In password inputs,You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. + + +## Getting Started + +In order to use the `TrackCapsLockDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: + +```ts +// ... +import { CoreModule } from '@abp/ng.core'; + +@NgModule({ + //... + imports: [..., CoreModule], +}) +export class MyFeatureModule {} +``` + +## Usage + +The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. U can use this to warn user + +See an example usage: + +```ts +@Component({ + selector: 'test-component', + standalone: true, + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + capsLock = false; +} +``` + +The `abpCapsLock` event has been added to the `` element. Press Caps Lock to activate the `TrackCapsLockDirective`. + +See the result: + +![Show Password directive](./images/CapsLockDirective1.png) + +To see Caps Lock icon press Caps Lock. + +![Show Password directive](./images/CapsLockDirective2.png) \ No newline at end of file diff --git a/docs/en/UI/Angular/images/CapsLockDirective1.png b/docs/en/UI/Angular/images/CapsLockDirective1.png new file mode 100644 index 0000000000000000000000000000000000000000..2f143d755fd2d331beed42c8ce9c361cb8aeaa0b GIT binary patch literal 2224 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 U>BitD2Pwepw$-gl!+XE~7Z`*$lmGw# literal 0 HcmV?d00001 From 4fd8dbc49a32c2ab665e9a28429c5ef530f81049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:48:56 +0300 Subject: [PATCH 068/165] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 4b92d61124..a21057490c 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -5,15 +5,17 @@ In password inputs,You may want to show if Caps Lock is on. To make this even ea ## Getting Started -In order to use the `TrackCapsLockDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: +`TrackCapsLockDirective` is standalone. In order to use the `TrackCapsLockDirective` in an HTML template, import it to related module or your standalone component: ```ts -// ... -import { CoreModule } from '@abp/ng.core'; +import { TrackCapsLockDirective } from '@abp/ng.core'; @NgModule({ //... - imports: [..., CoreModule], + imports: [ + ..., + TrackCapsLockDirective + ], }) export class MyFeatureModule {} ``` @@ -25,6 +27,8 @@ The `TrackCapsLockDirective` is very easy to use. The directive's selector is ** See an example usage: ```ts +import { TrackCapsLockDirective } from '@abp/ng.core' + @Component({ selector: 'test-component', standalone: true, @@ -34,7 +38,8 @@ See an example usage: icon
- ` + `, + imports: [ TrackCapsLockDirective ] }) export class TestComponent{ capsLock = false; @@ -49,4 +54,4 @@ See the result: To see Caps Lock icon press Caps Lock. -![Show Password directive](./images/CapsLockDirective2.png) \ No newline at end of file +![Show Password directive](./images/CapsLockDirective2.png) From cd5867a3f8bd78fdd3b401384554a4934f04a445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:51:53 +0300 Subject: [PATCH 069/165] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index a21057490c..24bef39cdc 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -1,6 +1,6 @@ -# Show Password Directive +# Caps Lock Directive -In password inputs,You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. +In password inputs, You may want to show if Caps Lock is on. To make this even easier, you can use the `TrackCapsLockDirective` which has been exposed by the `@abp/ng.core` package. ## Getting Started From 00c41f56698e2bdb84b27bc36b2255ea3be0cf50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:58:53 +0300 Subject: [PATCH 070/165] Update Show-Password-Directive.md --- docs/en/UI/Angular/Show-Password-Directive.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md index db54bcdd76..6c3cbe4f45 100644 --- a/docs/en/UI/Angular/Show-Password-Directive.md +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -4,16 +4,17 @@ In password input, text can be shown easily via changing input type attribute to ## Getting Started - -In order to use the `ShowPasswordDirective` in an HTML template, the **`CoreModule`** should be imported into your module like this: +`ShowPasswordDirective` is standalone. In order to use the `ShowPasswordDirective` in an HTML template, import it to related module or your standalone component: ```ts -// ... -import { CoreModule } from '@abp/ng.core'; +import { ShowPasswordDirective } from '@abp/ng.core'; @NgModule({ //... - imports: [..., CoreModule], + imports: [ + ..., + ShowPasswordDirective + ], }) export class MyFeatureModule {} ``` @@ -25,6 +26,7 @@ The `ShowPasswordDirective` is very easy to use. The directive's selector is **` See an example usage: ```ts +import { ShowPasswordDirective } from '@abp/ng.core'; @Component({ selector: 'test-component', standalone: true, @@ -34,7 +36,8 @@ See an example usage: icon
- ` + `, + imports: [ShowPasswordDirective] }) export class TestComponent{ showPassword = false; @@ -49,4 +52,4 @@ See the result: To see password input click icon. -![Show Password directive](./images/showPasswordDirective2.png) \ No newline at end of file +![Show Password directive](./images/showPasswordDirective2.png) From 1659274d7cfc7d70be56f5f921167aa6d3f760f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 11:21:13 +0300 Subject: [PATCH 071/165] Update CapsLock.directive.md --- docs/en/UI/Angular/CapsLock.directive.md | 29 +++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 24bef39cdc..1e1021bdd4 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -7,11 +7,16 @@ In password inputs, You may want to show if Caps Lock is on. To make this even e `TrackCapsLockDirective` is standalone. In order to use the `TrackCapsLockDirective` in an HTML template, import it to related module or your standalone component: +**Importing to NgModule** ```ts import { TrackCapsLockDirective } from '@abp/ng.core'; @NgModule({ //... + declarations: [ + ..., + TestComponent + ], imports: [ ..., TrackCapsLockDirective @@ -22,15 +27,33 @@ export class MyFeatureModule {} ## Usage -The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. U can use this to warn user +The `TrackCapsLockDirective` is very easy to use. The directive's selector is **`abpCapsLock`**. By adding the `abpCapsLock` event to an element, you can track the status of Caps Lock. You can use this to warn user. See an example usage: +**NgModule Component usage** +```ts +@Component({ + selector: 'test-component', + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + capsLock = false; +} +``` + +**Standalone Component usage** ```ts import { TrackCapsLockDirective } from '@abp/ng.core' @Component({ - selector: 'test-component', + selector: 'standalone-component', standalone: true, template: `
@@ -41,7 +64,7 @@ import { TrackCapsLockDirective } from '@abp/ng.core' `, imports: [ TrackCapsLockDirective ] }) -export class TestComponent{ +export class StandaloneComponent{ capsLock = false; } ``` From 2372ce0f29cefaada74ec2b1a8eda306f39ecf87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Mon, 31 Jul 2023 12:22:36 +0300 Subject: [PATCH 072/165] Update Show-Password-Directive.md --- docs/en/UI/Angular/Show-Password-Directive.md | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/Show-Password-Directive.md b/docs/en/UI/Angular/Show-Password-Directive.md index 6c3cbe4f45..c19c8073bd 100644 --- a/docs/en/UI/Angular/Show-Password-Directive.md +++ b/docs/en/UI/Angular/Show-Password-Directive.md @@ -6,11 +6,16 @@ In password input, text can be shown easily via changing input type attribute to ## Getting Started `ShowPasswordDirective` is standalone. In order to use the `ShowPasswordDirective` in an HTML template, import it to related module or your standalone component: +**Importing to NgModule** ```ts import { ShowPasswordDirective } from '@abp/ng.core'; @NgModule({ //... + declarations: [ + ..., + TestComponent + ], imports: [ ..., ShowPasswordDirective @@ -25,10 +30,27 @@ The `ShowPasswordDirective` is very easy to use. The directive's selector is **` See an example usage: +**NgModule Component usage** ```ts -import { ShowPasswordDirective } from '@abp/ng.core'; @Component({ selector: 'test-component', + template: ` +
+ + + icon +
+ ` +}) +export class TestComponent{ + showPassword = false; +} +``` +**Standalone Component usage** +```ts +import { ShowPasswordDirective } from '@abp/ng.core'; +@Component({ + selector: 'standalone-component', standalone: true, template: `
@@ -39,7 +61,7 @@ import { ShowPasswordDirective } from '@abp/ng.core'; `, imports: [ShowPasswordDirective] }) -export class TestComponent{ +export class StandaloneComponent{ showPassword = false; } ``` From 65512dd433bc9b0e4e237f8a2736e9677e98f168 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Thu, 3 Aug 2023 09:53:55 +0300 Subject: [PATCH 073/165] update --- docs/en/UI/Angular/CapsLock.directive.md | 6 +++--- .../packages/core/src/lib/tests/capsLock.directive.spec.ts | 1 - .../core/src/lib/tests/show-password-directive.spec.ts | 6 +----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/docs/en/UI/Angular/CapsLock.directive.md b/docs/en/UI/Angular/CapsLock.directive.md index 1e1021bdd4..64a3fc42ca 100644 --- a/docs/en/UI/Angular/CapsLock.directive.md +++ b/docs/en/UI/Angular/CapsLock.directive.md @@ -39,7 +39,7 @@ See an example usage:
- icon + icon
` }) @@ -59,10 +59,10 @@ import { TrackCapsLockDirective } from '@abp/ng.core'
- icon + icon
`, - imports: [ TrackCapsLockDirective ] + imports: [TrackCapsLockDirective] }) export class StandaloneComponent{ capsLock = false; diff --git a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts index 17d50ba697..3182dfa2dd 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/capsLock.directive.spec.ts @@ -28,7 +28,6 @@ describe('TrackCapsLockDirective',()=>{ des = fixture.debugElement.queryAll(By.directive(TrackCapsLockDirective)); }); - // tests test.each(['keydown','keyup'])('is %p works when press capslock and is emit status', (eventName) => { const event = new KeyboardEvent(eventName, { key: 'CapsLock', diff --git a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts index e1e9750995..8babb472c4 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/show-password-directive.spec.ts @@ -27,19 +27,15 @@ describe('ShowPasswordDirective',()=>{ imports: [ TestComponent ] }).createComponent(TestComponent) - fixture.detectChanges(); // initial binding + fixture.detectChanges(); - // all elements with an attached HighlightDirective des = fixture.debugElement.queryAll(By.directive(ShowPasswordDirective)); - // all inputs includes nondirective desAll = fixture.debugElement.queryAll(By.all()); - // the input without the ShowPasswordDirective bareInput = fixture.debugElement.query(By.css('input:not([abpShowPassword])')); }) - // tests it('should have three input has ShowPasswordDirective elements', () => { expect(des.length).toBe(3); }); From 3dd099e2a96cffb20b66445a26ceabad93c55cea Mon Sep 17 00:00:00 2001 From: Salih Date: Fri, 4 Aug 2023 13:34:44 +0300 Subject: [PATCH 074/165] Update en.json --- .../Commercial/Localization/Resources/en.json | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index abd93b4547..0be3cb5dd7 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -600,7 +600,7 @@ "TotalDeveloperPrice": "Total Developer Price", "Purchase_PricePerDeveloper": "{0} {1} per developer", "Purchase_IncludedDeveloperInfo": "{0} {1} included.", - "Purchase_LicenseExtraDeveloperPurchaseMessage": "The {0} license contains {1} developer(s). You can add additional developers now or later.", + "Purchase_LicenseExtraDeveloperPurchaseMessage": "The {0} License includes {1} developers. You can add additional developers.", "StartupTemplates_Page_Title": "ABP Startup Templates", "StartupTemplates_Page_Description": "ABP Commercial allows you to build solutions with any level of complexity. It provides two main pre-built startup solutions. You can select the one close to your requirements and build your own custom solution on top of it.", "MicroserviceStartupSolutionForDotnet": "Microservice Startup Solution for .NET", @@ -963,6 +963,22 @@ "OneCodeBaseMultipleDevices": "One Code-Base Multiple Devices", "OneCodeBaseMultipleDevices_Description": "ABP Mobile applications are cross-platform. They are ready to be installed and run on iOS and Android devices, and they adapt to different form-factors using a single code base. Developers only need to create the UI and front-end code once, there is no need to adapt the code for each device you want to support.", "ComesWithTheSourceCode": "Comes with the Source-Code", - "ComesWithTheSourceCode_Description": "The mobile apps are provided with the source-code. Easily customize the UX/UI of your apps to meet branding guidelines." + "ComesWithTheSourceCode_Description": "The mobile apps are provided with the source-code. Easily customize the UX/UI of your apps to meet branding guidelines.", + "Purchase_OneYearPrice": "1 Year Price", + "Purchase_DeveloperSeatCount": "Developer Seat Count", + "Purchase_DevelopersAlreadyIncluded": "{0} developers already included", + "1Year": "1 year", + "{0}Years": "{0} years", + "1YearLicense": "1 year license", + "{0}YearsLicense": "{0} years license", + "1AdditionalDeveloper": "1 additional developer", + "{0}AdditionalDevelopers": "{0} additional developers", + "Discount": "Discount ({0}%)", + "Summary": "Summary", + "TrainingPack": "Training pack", + "TrainingPackDiscount": "Training pack discount", + "Purchase_OnboardingTraining_Description": "This live training package is discounted when purchase with the new license. This discounted price is valid only for new license purchases. Learn more ", + "Purchase_Save": "{0}% Save {1} {2}", + "RemoveBasket": "Remove from basket" } } From 42cb9293e226365508dc6a6f6c6fcc31e6979fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= <72804437+Sinan997@users.noreply.github.com> Date: Fri, 4 Aug 2023 15:38:13 +0300 Subject: [PATCH 075/165] Update Internet-Connection-Service.md --- docs/en/UI/Angular/Internet-Connection-Service.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/Internet-Connection-Service.md b/docs/en/UI/Angular/Internet-Connection-Service.md index 0a8aca69f4..9ef26a082e 100644 --- a/docs/en/UI/Angular/Internet-Connection-Service.md +++ b/docs/en/UI/Angular/Internet-Connection-Service.md @@ -14,14 +14,14 @@ When you inject InternetConnectionService you can get the current internet statu **You can get via signal** ```ts -class someComponent{ +class SomeComponent{ internetConnectionService = inject(InternetConnectionService); isOnline = this.internetConnectionService.networkStatus } ``` **or you can get as observable** ```ts -class someComponent{ +class SomeComponent{ internetConnectionService = inject(InternetConnectionService); isOnline = this.internetConnectionService.networkStatus$ } From 24e21ed836c28a4b2479868d85a9aae41d53895a Mon Sep 17 00:00:00 2001 From: masoodkhoshgard Date: Fri, 4 Aug 2023 17:23:47 +0330 Subject: [PATCH 076/165] use curly braces --- .../TagHelpers/Form/AbpInputTagHelperService.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 9923e57de0..9699baadd3 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -229,9 +229,7 @@ public class AbpInputTagHelperService : AbpTagHelperService if (attribute != null || TagHelper.FloatingLabel) { - var placeholderLocalized = _tagHelperLocalizer.GetLocalizedText(attribute?.Value ?? string.Empty, TagHelper.AspFor.ModelExplorer); - if (string.IsNullOrWhiteSpace(placeholderLocalized)) - placeholderLocalized = TagHelper.AspFor.Name; + var placeholderLocalized = _tagHelperLocalizer.GetLocalizedText(attribute?.Value ?? TagHelper.AspFor.Name, TagHelper.AspFor.ModelExplorer); inputTagHelperOutput.Attributes.Add("placeholder", placeholderLocalized); } } From 5a34f8194bca69ccf3d1a69619f88c892c3632ab Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Sat, 5 Aug 2023 01:09:00 +0300 Subject: [PATCH 077/165] Add feature check for CmsKit Page Middleware --- .../Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs index b5ad981cc0..5763f26053 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs @@ -3,6 +3,8 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; +using Volo.Abp.Features; +using Volo.CmsKit.Features; using Volo.CmsKit.Pages; using Volo.CmsKit.Public.Pages; @@ -12,6 +14,13 @@ public class DefaultHomePageMiddleware : IMiddleware, ITransientDependency { public async Task InvokeAsync(HttpContext context, RequestDelegate next) { + var featureChecker = context.RequestServices.GetRequiredService(); + + if (!await featureChecker.IsEnabledAsync(CmsKitFeatures.PageEnable)) + { + return; + } + if (context.Request.Path.Value == "/") { var pagePublicAppService = context.RequestServices.GetRequiredService(); From d7d9158ddd5ba9354e2c5c6b86f19d093b1b74b3 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Sat, 5 Aug 2023 01:35:33 +0300 Subject: [PATCH 078/165] Update DefaultHomePageMiddleware.cs --- .../DefaultHomePageMiddleware.cs | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs index 5763f26053..f80cba3970 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs @@ -16,23 +16,20 @@ public class DefaultHomePageMiddleware : IMiddleware, ITransientDependency { var featureChecker = context.RequestServices.GetRequiredService(); - if (!await featureChecker.IsEnabledAsync(CmsKitFeatures.PageEnable)) + if (await featureChecker.IsEnabledAsync(CmsKitFeatures.PageEnable)) { - return; - } - - if (context.Request.Path.Value == "/") - { - var pagePublicAppService = context.RequestServices.GetRequiredService(); - - var page = await pagePublicAppService.FindDefaultHomePageAsync(); - if (page != null) + if (context.Request.Path.Value == "/") { - context.Request.Path = $"{PageConsts.UrlPrefix}{page.Slug}"; + var pagePublicAppService = context.RequestServices.GetRequiredService(); + + var page = await pagePublicAppService.FindDefaultHomePageAsync(); + if (page != null) + { + context.Request.Path = $"{PageConsts.UrlPrefix}{page.Slug}"; + } } - } - + await next(context); } } \ No newline at end of file From f617a52ed73f8d230f907f2d0269e8f2a0c703ef Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Sat, 5 Aug 2023 13:45:35 +0300 Subject: [PATCH 079/165] Prevent calling `UpdateMany` when tehre is no changes --- .../Volo/CmsKit/Menus/PageChangedHandler.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/PageChangedHandler.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/PageChangedHandler.cs index 0c8d53d071..68d51841dd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/PageChangedHandler.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/PageChangedHandler.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; @@ -31,6 +32,11 @@ public class PageChangedHandler : .Where(x => x.PageId == eventData.Entity.Id) .ToArray(); + if (affectedMenuItems.IsNullOrEmpty()) + { + return; + } + foreach (var menuItem in affectedMenuItems) { MenuManager.SetPageUrl(menuItem, eventData.Entity); From 1654590621e4a886fb6cadcdda2c802220e49d49 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Sat, 5 Aug 2023 21:03:38 +0300 Subject: [PATCH 080/165] Add hidden Content inputs for BlogPost --- .../Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml | 2 ++ .../Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml index ab7cf99abe..5e182ef2ce 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml @@ -77,6 +77,8 @@ + +
+ +
Date: Mon, 7 Aug 2023 09:21:25 +0800 Subject: [PATCH 081/165] Check `Path.Value` first for better performance. --- .../Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs index f80cba3970..752e5f2f42 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/DefaultHomePageMiddleware.cs @@ -1,5 +1,4 @@ -using System.Net; -using System.Threading.Tasks; +using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; @@ -16,9 +15,9 @@ public class DefaultHomePageMiddleware : IMiddleware, ITransientDependency { var featureChecker = context.RequestServices.GetRequiredService(); - if (await featureChecker.IsEnabledAsync(CmsKitFeatures.PageEnable)) + if (context.Request.Path.Value == "/") { - if (context.Request.Path.Value == "/") + if (await featureChecker.IsEnabledAsync(CmsKitFeatures.PageEnable)) { var pagePublicAppService = context.RequestServices.GetRequiredService(); @@ -32,4 +31,4 @@ public class DefaultHomePageMiddleware : IMiddleware, ITransientDependency await next(context); } -} \ No newline at end of file +} From ac97d57fe16bcfedff4485ae7fb671ddbe9eb15e Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Aug 2023 11:22:45 +0800 Subject: [PATCH 082/165] Enable nullable annotations for Volo.Abp.Ddd.Domain --- .../Volo/Abp/Auditing/IDeletionAuditedObject.cs | 2 +- .../Volo/Abp/Auditing/IMayHaveCreator.cs | 3 +-- .../Abp/Auditing/IModificationAuditedObject.cs | 2 +- .../LookupExtensionProperty.razor | 2 +- .../Volo.Abp.Ddd.Domain.csproj | 2 ++ .../AbpCommonDbContextRegistrationOptions.cs | 10 +++++----- ...pCommonDbContextRegistrationOptionsBuilder.cs | 2 +- .../MultiTenantDbContextType.cs | 2 +- .../Auditing/AuditedAggregateRootWithUser.cs | 8 ++++---- .../Entities/Auditing/AuditedEntityWithUser.cs | 8 ++++---- .../CreationAuditedAggregateRootWithUser.cs | 4 ++-- .../Auditing/CreationAuditedEntityWithUser.cs | 4 ++-- .../Auditing/FullAuditedAggregateRootWithUser.cs | 12 ++++++------ .../Auditing/FullAuditedEntityWithUser.cs | 12 ++++++------ .../Domain/Entities/Caching/EntityCacheBase.cs | 12 ++++++------ .../EntityCacheServiceCollectionExtensions.cs | 6 +++--- .../Caching/EntityCacheWithObjectMapper.cs | 2 +- .../Caching/EntityCacheWithoutCacheItem.cs | 2 +- .../Abp/Domain/Entities/Caching/IEntityCache.cs | 3 +-- .../Volo/Abp/Domain/Entities/Entity.cs | 8 ++++---- .../Volo/Abp/Domain/Entities/EntityHelper.cs | 16 +++++++--------- .../Events/Distributed/EntitySynchronizer.cs | 7 +++---- .../Events/Distributed/EntityToEtoMapper.cs | 2 +- .../Entities/Events/EntityChangeEventHelper.cs | 2 +- .../Domain/Entities/Events/EntityEventData.cs | 2 +- .../Volo/Abp/Domain/Entities/IEntity.cs | 2 +- .../Domain/Repositories/BasicRepositoryBase.cs | 6 +++--- .../Repositories/IReadOnlyBasicRepository.cs | 2 +- .../Volo/Abp/Domain/Repositories/IRepository.cs | 2 +- .../Repositories/RepositoryAsyncExtensions.cs | 12 ++++++------ .../Abp/Domain/Repositories/RepositoryBase.cs | 8 ++++---- .../Domain/Repositories/RepositoryExtensions.cs | 8 ++++---- .../Repositories/RepositoryRegistrarBase.cs | 4 ++-- .../Volo/Abp/Domain/Services/DomainService.cs | 6 +++--- .../Volo/Abp/Linq/AsyncQueryableExecuter.cs | 8 ++++---- .../Volo/Abp/Linq/IAsyncQueryableExecuter.cs | 8 ++++---- .../Volo/Abp/Linq/IAsyncQueryableProvider.cs | 8 ++++---- 37 files changed, 103 insertions(+), 106 deletions(-) diff --git a/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IDeletionAuditedObject.cs b/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IDeletionAuditedObject.cs index a7be0c29a1..afec5e4e5f 100644 --- a/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IDeletionAuditedObject.cs +++ b/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IDeletionAuditedObject.cs @@ -22,5 +22,5 @@ public interface IDeletionAuditedObject : IDeletionAuditedObject /// /// Reference to the deleter user. /// - TUser Deleter { get; } + TUser? Deleter { get; } } diff --git a/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IMayHaveCreator.cs b/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IMayHaveCreator.cs index 25748f5af9..78989e16d2 100644 --- a/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IMayHaveCreator.cs +++ b/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IMayHaveCreator.cs @@ -8,8 +8,7 @@ public interface IMayHaveCreator /// /// Reference to the creator. /// - [CanBeNull] - TCreator Creator { get; } + TCreator? Creator { get; } } /// diff --git a/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IModificationAuditedObject.cs b/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IModificationAuditedObject.cs index 48f26b6299..a82e1452e8 100644 --- a/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IModificationAuditedObject.cs +++ b/framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/IModificationAuditedObject.cs @@ -22,5 +22,5 @@ public interface IModificationAuditedObject : IModificationAuditedObject /// /// Reference to the last modifier user of this entity. /// - TUser LastModifier { get; } + TUser? LastModifier { get; } } diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor index 7c32549d51..ecdae979f2 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor +++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor @@ -9,7 +9,7 @@ netstandard2.0;netstandard2.1;net7.0 + enable + Nullable Volo.Abp.Ddd.Domain Volo.Abp.Ddd.Domain $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/AbpCommonDbContextRegistrationOptions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/AbpCommonDbContextRegistrationOptions.cs index bc50368645..8342451056 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/AbpCommonDbContextRegistrationOptions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/AbpCommonDbContextRegistrationOptions.cs @@ -16,13 +16,13 @@ public abstract class AbpCommonDbContextRegistrationOptions : IAbpCommonDbContex public IServiceCollection Services { get; } - public Dictionary ReplacedDbContextTypes { get; } + public Dictionary ReplacedDbContextTypes { get; } public Type DefaultRepositoryDbContextType { get; protected set; } - public Type DefaultRepositoryImplementationType { get; private set; } + public Type? DefaultRepositoryImplementationType { get; private set; } - public Type DefaultRepositoryImplementationTypeWithoutKey { get; private set; } + public Type? DefaultRepositoryImplementationTypeWithoutKey { get; private set; } public bool RegisterDefaultRepositories { get; private set; } @@ -40,7 +40,7 @@ public abstract class AbpCommonDbContextRegistrationOptions : IAbpCommonDbContex Services = services; DefaultRepositoryDbContextType = originalDbContextType; CustomRepositories = new Dictionary(); - ReplacedDbContextTypes = new Dictionary(); + ReplacedDbContextTypes = new Dictionary(); SpecifiedDefaultRepositories = new List(); } @@ -54,7 +54,7 @@ public abstract class AbpCommonDbContextRegistrationOptions : IAbpCommonDbContex return ReplaceDbContext(typeof(TOtherDbContext), typeof(TTargetDbContext), multiTenancySides); } - public IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType, Type targetDbContextType = null, MultiTenancySides multiTenancySides = MultiTenancySides.Both) + public IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType, Type? targetDbContextType = null, MultiTenancySides multiTenancySides = MultiTenancySides.Both) { if (!otherDbContextType.IsAssignableFrom(OriginalDbContextType)) { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs index 58a82bf77d..ee580332a8 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs @@ -90,5 +90,5 @@ public interface IAbpCommonDbContextRegistrationOptionsBuilder /// The DbContext type to be replaced /// The target DbContext type (optional, used this DbContext type if not provided) /// MultiTenancy side - IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType, Type targetDbContextType = null, MultiTenancySides multiTenancySides = MultiTenancySides.Both); + IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType, Type? targetDbContextType = null, MultiTenancySides multiTenancySides = MultiTenancySides.Both); } diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/MultiTenantDbContextType.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/MultiTenantDbContextType.cs index ff0d74608a..b015b9204a 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/MultiTenantDbContextType.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/MultiTenantDbContextType.cs @@ -15,7 +15,7 @@ public class MultiTenantDbContextType MultiTenancySide = multiTenancySide; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { var other = obj as MultiTenantDbContextType; diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/AuditedAggregateRootWithUser.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/AuditedAggregateRootWithUser.cs index ebb573579b..f38c21d2fe 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/AuditedAggregateRootWithUser.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/AuditedAggregateRootWithUser.cs @@ -12,10 +12,10 @@ public abstract class AuditedAggregateRootWithUser : AuditedAggregateRoot where TUser : IEntity { /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } /// - public virtual TUser LastModifier { get; set; } + public virtual TUser? LastModifier { get; set; } } /// @@ -28,10 +28,10 @@ public abstract class AuditedAggregateRootWithUser : AuditedAggrega where TUser : IEntity { /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } /// - public virtual TUser LastModifier { get; set; } + public virtual TUser? LastModifier { get; set; } protected AuditedAggregateRootWithUser() { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/AuditedEntityWithUser.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/AuditedEntityWithUser.cs index 99b9b66303..3f8598d348 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/AuditedEntityWithUser.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/AuditedEntityWithUser.cs @@ -12,10 +12,10 @@ public abstract class AuditedEntityWithUser : AuditedEntity, IAuditedObje where TUser : IEntity { /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } /// - public virtual TUser LastModifier { get; set; } + public virtual TUser? LastModifier { get; set; } } /// @@ -28,10 +28,10 @@ public abstract class AuditedEntityWithUser : AuditedEntity, where TUser : IEntity { /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } /// - public virtual TUser LastModifier { get; set; } + public virtual TUser? LastModifier { get; set; } protected AuditedEntityWithUser() { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/CreationAuditedAggregateRootWithUser.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/CreationAuditedAggregateRootWithUser.cs index 73da9d2026..4407a93de8 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/CreationAuditedAggregateRootWithUser.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/CreationAuditedAggregateRootWithUser.cs @@ -11,7 +11,7 @@ namespace Volo.Abp.Domain.Entities.Auditing; public abstract class CreationAuditedAggregateRootWithUser : CreationAuditedAggregateRoot, ICreationAuditedObject { /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } } /// @@ -23,7 +23,7 @@ public abstract class CreationAuditedAggregateRootWithUser : CreationAudi public abstract class CreationAuditedAggregateRootWithUser : CreationAuditedAggregateRoot, ICreationAuditedObject { /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } protected CreationAuditedAggregateRootWithUser() { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/CreationAuditedEntityWithUser.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/CreationAuditedEntityWithUser.cs index 203967fb89..635bb06183 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/CreationAuditedEntityWithUser.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/CreationAuditedEntityWithUser.cs @@ -11,7 +11,7 @@ namespace Volo.Abp.Domain.Entities.Auditing; public abstract class CreationAuditedEntityWithUser : CreationAuditedEntity, ICreationAuditedObject { /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } } /// @@ -23,7 +23,7 @@ public abstract class CreationAuditedEntityWithUser : CreationAuditedEnti public abstract class CreationAuditedEntityWithUser : CreationAuditedEntity, ICreationAuditedObject { /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } protected CreationAuditedEntityWithUser() { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/FullAuditedAggregateRootWithUser.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/FullAuditedAggregateRootWithUser.cs index 918270088e..af8f196f00 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/FullAuditedAggregateRootWithUser.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/FullAuditedAggregateRootWithUser.cs @@ -12,13 +12,13 @@ public abstract class FullAuditedAggregateRootWithUser : FullAuditedAggre where TUser : IEntity { /// - public virtual TUser Deleter { get; set; } + public virtual TUser? Deleter { get; set; } /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } /// - public virtual TUser LastModifier { get; set; } + public virtual TUser? LastModifier { get; set; } } /// @@ -31,13 +31,13 @@ public abstract class FullAuditedAggregateRootWithUser : FullAudite where TUser : IEntity { /// - public virtual TUser Deleter { get; set; } + public virtual TUser? Deleter { get; set; } /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } /// - public virtual TUser LastModifier { get; set; } + public virtual TUser? LastModifier { get; set; } protected FullAuditedAggregateRootWithUser() { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/FullAuditedEntityWithUser.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/FullAuditedEntityWithUser.cs index 1f4886f4c0..834b106d95 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/FullAuditedEntityWithUser.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Auditing/FullAuditedEntityWithUser.cs @@ -12,13 +12,13 @@ public abstract class FullAuditedEntityWithUser : FullAuditedEntity, IFul where TUser : IEntity { /// - public virtual TUser Deleter { get; set; } + public virtual TUser? Deleter { get; set; } /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } /// - public virtual TUser LastModifier { get; set; } + public virtual TUser? LastModifier { get; set; } } /// @@ -31,13 +31,13 @@ public abstract class FullAuditedEntityWithUser : FullAuditedEntity where TUser : IEntity { /// - public virtual TUser Deleter { get; set; } + public virtual TUser? Deleter { get; set; } /// - public virtual TUser Creator { get; protected set; } + public virtual TUser? Creator { get; protected set; } /// - public virtual TUser LastModifier { get; set; } + public virtual TUser? LastModifier { get; set; } protected FullAuditedEntityWithUser() { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheBase.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheBase.cs index 7e5b17b687..2cb2b2c32b 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheBase.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheBase.cs @@ -27,23 +27,23 @@ public abstract class EntityCacheBase : UnitOfWorkManager = unitOfWorkManager; } - public virtual async Task FindAsync(TKey id) + public virtual async Task FindAsync(TKey id) { return await Cache.GetOrAddAsync( id, - async () => MapToCacheItem(await Repository.FindAsync(id)) + async () => MapToCacheItem(await Repository.FindAsync(id))! ); } public virtual async Task GetAsync(TKey id) { - return await Cache.GetOrAddAsync( + return (await Cache.GetOrAddAsync( id, - async () => MapToCacheItem(await Repository.GetAsync(id)) - ); + async () => MapToCacheItem(await Repository.GetAsync(id))! + ))!; } - protected abstract TEntityCacheItem MapToCacheItem(TEntity entity); + protected abstract TEntityCacheItem? MapToCacheItem(TEntity? entity); public async Task HandleEventAsync(EntityChangedEventData eventData) { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheServiceCollectionExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheServiceCollectionExtensions.cs index bf7ceac45c..c208c7b107 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheServiceCollectionExtensions.cs @@ -13,7 +13,7 @@ public static class EntityCacheServiceCollectionExtensions { public static IServiceCollection AddEntityCache( this IServiceCollection services, - [CanBeNull] DistributedCacheEntryOptions cacheOptions = null) + DistributedCacheEntryOptions? cacheOptions = null) where TEntity : Entity { services @@ -39,7 +39,7 @@ public static class EntityCacheServiceCollectionExtensions public static IServiceCollection AddEntityCache( this IServiceCollection services, - [CanBeNull] DistributedCacheEntryOptions cacheOptions = null) + DistributedCacheEntryOptions? cacheOptions = null) where TEntity : Entity where TEntityCacheItem : class { @@ -61,7 +61,7 @@ public static class EntityCacheServiceCollectionExtensions public static IServiceCollection AddEntityCache( this IServiceCollection services, - [CanBeNull] DistributedCacheEntryOptions cacheOptions = null) + DistributedCacheEntryOptions? cacheOptions = null) where TEntity : Entity where TEntityCacheItem : class { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheWithObjectMapper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheWithObjectMapper.cs index 727df63ea7..a37ad49b1e 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheWithObjectMapper.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheWithObjectMapper.cs @@ -23,7 +23,7 @@ public class EntityCacheWithObjectMapper : ObjectMapper = objectMapper; } - protected override TEntityCacheItem MapToCacheItem(TEntity entity) + protected override TEntityCacheItem? MapToCacheItem(TEntity? entity) { if (entity == null) { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheWithoutCacheItem.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheWithoutCacheItem.cs index c81f3e5e9e..0f300a7f28 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheWithoutCacheItem.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheWithoutCacheItem.cs @@ -16,7 +16,7 @@ public class EntityCacheWithoutCacheItem : { } - protected override TEntity MapToCacheItem(TEntity entity) + protected override TEntity? MapToCacheItem(TEntity? entity) { return entity; } diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/IEntityCache.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/IEntityCache.cs index 84f4486c65..bd8ba80a63 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/IEntityCache.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/IEntityCache.cs @@ -10,8 +10,7 @@ public interface IEntityCache /// Gets the entity with given , /// or returns null if the entity was not found. /// - [ItemCanBeNull] - Task FindAsync(TKey id); + Task FindAsync(TKey id); /// /// Gets the entity with given , diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs index 54ebd01d1e..9e52d1abfd 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs @@ -18,7 +18,7 @@ public abstract class Entity : IEntity return $"[ENTITY: {GetType().Name}] Keys = {GetKeys().JoinAsString(", ")}"; } - public abstract object[] GetKeys(); + public abstract object?[] GetKeys(); public bool EntityEquals(IEntity other) { @@ -31,7 +31,7 @@ public abstract class Entity : IEntity public abstract class Entity : Entity, IEntity { /// - public virtual TKey Id { get; protected set; } + public virtual TKey Id { get; protected set; } = default!; protected Entity() { @@ -43,9 +43,9 @@ public abstract class Entity : Entity, IEntity Id = id; } - public override object[] GetKeys() + public override object?[] GetKeys() { - return new object[] { Id }; + return new object?[] { Id }; } /// diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs index f7a4f27e5f..584807fac5 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs @@ -25,7 +25,7 @@ public static class EntityHelper return typeof(IMultiTenant).IsAssignableFrom(type); } - public static bool EntityEquals(IEntity entity1, IEntity entity2) + public static bool EntityEquals(IEntity? entity1, IEntity? entity2) { if (entity1 == null || entity2 == null) { @@ -131,7 +131,7 @@ public static class EntityHelper return IsValueObjectPredicate(type); } - public static bool IsValueObject(object obj) + public static bool IsValueObject(object? obj) { return obj != null && IsValueObject(obj.GetType()); } @@ -161,7 +161,7 @@ public static class EntityHelper public static bool HasDefaultId(IEntity entity) { - if (EqualityComparer.Default.Equals(entity.Id, default)) + if (EqualityComparer.Default.Equals(entity.Id, default!)) { return true; } @@ -180,7 +180,7 @@ public static class EntityHelper return false; } - private static bool IsDefaultKeyValue(object value) + private static bool IsDefaultKeyValue(object? value) { if (value == null) { @@ -222,8 +222,7 @@ public static class EntityHelper /// Tries to find the primary key type of the given entity type. /// May return null if given type does not implement /// - [CanBeNull] - public static Type FindPrimaryKeyType() + public static Type? FindPrimaryKeyType() where TEntity : IEntity { return FindPrimaryKeyType(typeof(TEntity)); @@ -233,8 +232,7 @@ public static class EntityHelper /// Tries to find the primary key type of the given entity type. /// May return null if given type does not implement /// - [CanBeNull] - public static Type FindPrimaryKeyType([NotNull] Type entityType) + public static Type? FindPrimaryKeyType([NotNull] Type entityType) { if (!typeof(IEntity).IsAssignableFrom(entityType)) { @@ -260,7 +258,7 @@ public static class EntityHelper var lambdaParam = Expression.Parameter(typeof(TEntity)); var leftExpression = Expression.PropertyOrField(lambdaParam, "Id"); var idValue = Convert.ChangeType(id, typeof(TKey)); - Expression> closure = () => idValue; + Expression> closure = () => idValue; var rightExpression = Expression.Convert(closure.Body, leftExpression.Type); var lambdaBody = Expression.Equal(leftExpression, rightExpression); return Expression.Lambda>(lambdaBody, lambdaParam); diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntitySynchronizer.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntitySynchronizer.cs index b971acc25f..5640c427c2 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntitySynchronizer.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntitySynchronizer.cs @@ -22,7 +22,7 @@ public abstract class EntitySynchronizer : Repository = repository; } - protected override Task FindLocalEntityAsync(TSourceEntityEto eto) + protected override Task FindLocalEntityAsync(TSourceEntityEto eto) { return Repository.FindAsync(eto.Id); } @@ -154,10 +154,9 @@ public abstract class EntitySynchronizer : return true; } - [ItemCanBeNull] - protected abstract Task FindLocalEntityAsync(TSourceEntityEto eto); + protected abstract Task FindLocalEntityAsync(TSourceEntityEto eto); - protected virtual Task IsEtoNewerAsync(TSourceEntityEto eto, [CanBeNull] TEntity localEntity) + protected virtual Task IsEtoNewerAsync(TSourceEntityEto eto, TEntity? localEntity) { if (localEntity is IHasEntityVersion versionedLocalEntity && eto is IHasEntityVersion versionedEto) { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs index b9d5911375..1710fe81e3 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs @@ -21,7 +21,7 @@ public class EntityToEtoMapper : IEntityToEtoMapper, ITransientDependency Options = options.Value; } - public object Map(object entityObj) + public object? Map(object entityObj) { Check.NotNull(entityObj, nameof(entityObj)); diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs index 20556f16ff..44eb5c058a 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs @@ -133,7 +133,7 @@ public class EntityChangeEventHelper : IEntityChangeEventHelper, ITransientDepen { var entityType = ProxyHelper.UnProxy(entityOrEto).GetType(); var eventType = genericEventType.MakeGenericType(entityType); - var eventData = Activator.CreateInstance(eventType, entityOrEto); + var eventData = Activator.CreateInstance(eventType, entityOrEto)!; var currentUow = UnitOfWorkManager.Current; if (currentUow == null) diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityEventData.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityEventData.cs index c2845da60e..b295f22f4e 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityEventData.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityEventData.cs @@ -27,7 +27,7 @@ public class EntityEventData : IEventDataWithInheritableGenericArgument public virtual object[] GetConstructorArgs() { - return new object[] { Entity }; + return new object[] { Entity! }; } public virtual bool IsMultiTenant(out Guid? tenantId) diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs index 7f4d425df2..1df1b75696 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs @@ -10,7 +10,7 @@ public interface IEntity /// Returns an array of ordered keys for this entity. /// /// - object[] GetKeys(); + object?[] GetKeys(); } /// diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs index 8a87f9c391..0d86045eea 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs @@ -20,9 +20,9 @@ public abstract class BasicRepositoryBase : IUnitOfWorkEnabled where TEntity : class, IEntity { - public IAbpLazyServiceProvider LazyServiceProvider { get; set; } + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } = default!; - public IServiceProvider ServiceProvider { get; set; } + public IServiceProvider ServiceProvider { get; set; } = default!; public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService(); @@ -123,7 +123,7 @@ public abstract class BasicRepositoryBase : BasicRepositoryBase FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default); + public abstract Task FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default); public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default) { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyBasicRepository.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyBasicRepository.cs index 6d447552f9..0736685709 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyBasicRepository.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyBasicRepository.cs @@ -51,5 +51,5 @@ public interface IReadOnlyBasicRepository : IReadOnlyBasicReposit /// Set true to include all children of this entity /// A to observe while waiting for the task to complete. /// Entity or null - Task FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default); + Task FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default); } diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IRepository.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IRepository.cs index da915626a8..3c7ae81875 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IRepository.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IRepository.cs @@ -28,7 +28,7 @@ public interface IRepository : IReadOnlyRepository, IBasicRepo /// A condition to find the entity /// Set true to include all children of this entity /// A to observe while waiting for the task to complete. - Task FindAsync( + Task FindAsync( [NotNull] Expression> predicate, bool includeDetails = true, CancellationToken cancellationToken = default diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs index 304f9ea0bd..2115d00200 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs @@ -120,7 +120,7 @@ public static class RepositoryAsyncExtensions return await repository.AsyncExecuter.FirstAsync(queryable, predicate, cancellationToken); } - public static async Task FirstOrDefaultAsync( + public static async Task FirstOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity @@ -129,7 +129,7 @@ public static class RepositoryAsyncExtensions return await repository.AsyncExecuter.FirstOrDefaultAsync(queryable, cancellationToken); } - public static async Task FirstOrDefaultAsync( + public static async Task FirstOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) @@ -162,7 +162,7 @@ public static class RepositoryAsyncExtensions return await repository.AsyncExecuter.LastAsync(queryable, predicate, cancellationToken); } - public static async Task LastOrDefaultAsync( + public static async Task LastOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity @@ -171,7 +171,7 @@ public static class RepositoryAsyncExtensions return await repository.AsyncExecuter.LastOrDefaultAsync(queryable, cancellationToken); } - public static async Task LastOrDefaultAsync( + public static async Task LastOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) @@ -204,7 +204,7 @@ public static class RepositoryAsyncExtensions return await repository.AsyncExecuter.SingleAsync(queryable, predicate, cancellationToken); } - public static async Task SingleOrDefaultAsync( + public static async Task SingleOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity @@ -213,7 +213,7 @@ public static class RepositoryAsyncExtensions return await repository.AsyncExecuter.SingleOrDefaultAsync(queryable, cancellationToken); } - public static async Task SingleOrDefaultAsync( + public static async Task SingleOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs index d843584fc4..eb2457f8c8 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs @@ -41,7 +41,7 @@ public abstract class RepositoryBase : BasicRepositoryBase, IR public abstract Task> GetQueryableAsync(); - public abstract Task FindAsync( + public abstract Task FindAsync( Expression> predicate, bool includeDetails = true, CancellationToken cancellationToken = default); @@ -76,13 +76,13 @@ public abstract class RepositoryBase : BasicRepositoryBase, IR { if (typeof(ISoftDelete).IsAssignableFrom(typeof(TOtherEntity))) { - query = (TQueryable)query.WhereIf(DataFilter.IsEnabled(), e => ((ISoftDelete)e).IsDeleted == false); + query = (TQueryable)query.WhereIf(DataFilter.IsEnabled(), e => ((ISoftDelete)e!).IsDeleted == false); } if (typeof(IMultiTenant).IsAssignableFrom(typeof(TOtherEntity))) { var tenantId = CurrentTenant.Id; - query = (TQueryable)query.WhereIf(DataFilter.IsEnabled(), e => ((IMultiTenant)e).TenantId == tenantId); + query = (TQueryable)query.WhereIf(DataFilter.IsEnabled(), e => ((IMultiTenant)e!).TenantId == tenantId); } return query; @@ -94,7 +94,7 @@ public abstract class RepositoryBase : RepositoryBase, I { public abstract Task GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default); - public abstract Task FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default); + public abstract Task FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default); public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default) { diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs index 379203f46a..cbebf62196 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs @@ -54,7 +54,7 @@ public static class RepositoryExtensions ) where TEntity : class, IEntity { - if (!await repository.AnyAsync(x => x.Id.Equals(id), cancellationToken)) + if (!await repository.AnyAsync(x => x.Id!.Equals(id), cancellationToken)) { throw new EntityNotFoundException(typeof(TEntity), id); } @@ -87,7 +87,7 @@ public static class RepositoryExtensions { using (var uow = uowManager.Begin()) { - await HardDeleteWithUnitOfWorkAsync(repository, predicate, autoSave, cancellationToken, uowManager.Current); + await HardDeleteWithUnitOfWorkAsync(repository, predicate, autoSave, cancellationToken, uowManager.Current!); await uow.CompleteAsync(cancellationToken); } } @@ -111,7 +111,7 @@ public static class RepositoryExtensions { using (var uow = uowManager.Begin()) { - await HardDeleteWithUnitOfWorkAsync(repository, entities, autoSave, cancellationToken, uowManager.Current); + await HardDeleteWithUnitOfWorkAsync(repository, entities, autoSave, cancellationToken, uowManager.Current!); await uow.CompleteAsync(cancellationToken); } } @@ -135,7 +135,7 @@ public static class RepositoryExtensions { using (var uow = uowManager.Begin()) { - await HardDeleteWithUnitOfWorkAsync(repository, entity, autoSave, cancellationToken, uowManager.Current); + await HardDeleteWithUnitOfWorkAsync(repository, entity, autoSave, cancellationToken, uowManager.Current!); await uow.CompleteAsync(cancellationToken); } } diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs index 320aed8312..d162f2ffea 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs @@ -75,12 +75,12 @@ public abstract class RepositoryRegistrarBase if (primaryKeyType == null) { return Options.SpecifiedDefaultRepositoryTypes - ? Options.DefaultRepositoryImplementationTypeWithoutKey.MakeGenericType(entityType) + ? Options.DefaultRepositoryImplementationTypeWithoutKey!.MakeGenericType(entityType) : GetRepositoryType(Options.DefaultRepositoryDbContextType, entityType); } return Options.SpecifiedDefaultRepositoryTypes - ? Options.DefaultRepositoryImplementationType.MakeGenericType(entityType, primaryKeyType) + ? Options.DefaultRepositoryImplementationType!.MakeGenericType(entityType, primaryKeyType) : GetRepositoryType(Options.DefaultRepositoryDbContextType, entityType, primaryKeyType); } diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs index 32cf42409c..b36b32eafd 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs @@ -11,10 +11,10 @@ namespace Volo.Abp.Domain.Services; public abstract class DomainService : IDomainService { - public IAbpLazyServiceProvider LazyServiceProvider { get; set; } + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } = default!; [Obsolete("Use LazyServiceProvider instead.")] - public IServiceProvider ServiceProvider { get; set; } + public IServiceProvider ServiceProvider { get; set; } = default!; protected IClock Clock => LazyServiceProvider.LazyGetRequiredService(); @@ -26,5 +26,5 @@ public abstract class DomainService : IDomainService protected IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService(); - protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); + protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName!) ?? NullLogger.Instance); } diff --git a/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/AsyncQueryableExecuter.cs b/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/AsyncQueryableExecuter.cs index 108d3bb595..a6b9fb7949 100644 --- a/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/AsyncQueryableExecuter.cs +++ b/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/AsyncQueryableExecuter.cs @@ -209,7 +209,7 @@ public class AsyncQueryableExecuter : IAsyncQueryableExecuter, ISingletonDepende return Task.FromResult(queryable.SingleOrDefault(predicate))!; } - public Task MinAsync(IQueryable queryable, CancellationToken cancellationToken = default) + public Task MinAsync(IQueryable queryable, CancellationToken cancellationToken = default) { var provider = FindProvider(queryable); @@ -221,7 +221,7 @@ public class AsyncQueryableExecuter : IAsyncQueryableExecuter, ISingletonDepende return Task.FromResult(queryable.Min())!; } - public Task MinAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default) + public Task MinAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default) { var provider = FindProvider(queryable); @@ -233,7 +233,7 @@ public class AsyncQueryableExecuter : IAsyncQueryableExecuter, ISingletonDepende return Task.FromResult(queryable.Min(selector))!; } - public Task MaxAsync(IQueryable queryable, CancellationToken cancellationToken = default) + public Task MaxAsync(IQueryable queryable, CancellationToken cancellationToken = default) { var provider = FindProvider(queryable); @@ -245,7 +245,7 @@ public class AsyncQueryableExecuter : IAsyncQueryableExecuter, ISingletonDepende return Task.FromResult(queryable.Max())!; } - public Task MaxAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default) + public Task MaxAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default) { var provider = FindProvider(queryable); diff --git a/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/IAsyncQueryableExecuter.cs b/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/IAsyncQueryableExecuter.cs index 2bea6c4604..4ee0666f4c 100644 --- a/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/IAsyncQueryableExecuter.cs +++ b/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/IAsyncQueryableExecuter.cs @@ -137,12 +137,12 @@ public interface IAsyncQueryableExecuter #region Min - Task MinAsync( + Task MinAsync( [NotNull] IQueryable queryable, CancellationToken cancellationToken = default); - Task MinAsync( + Task MinAsync( [NotNull] IQueryable queryable, [NotNull] Expression> selector, CancellationToken cancellationToken = default); @@ -151,12 +151,12 @@ public interface IAsyncQueryableExecuter #region Max - Task MaxAsync( + Task MaxAsync( [NotNull] IQueryable queryable, CancellationToken cancellationToken = default); - Task MaxAsync( + Task MaxAsync( [NotNull] IQueryable queryable, [NotNull] Expression> selector, CancellationToken cancellationToken = default); diff --git a/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/IAsyncQueryableProvider.cs b/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/IAsyncQueryableProvider.cs index 3f38553ac5..3239fde6d6 100644 --- a/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/IAsyncQueryableProvider.cs +++ b/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/IAsyncQueryableProvider.cs @@ -139,12 +139,12 @@ public interface IAsyncQueryableProvider #region Min - Task MinAsync( + Task MinAsync( [NotNull] IQueryable queryable, CancellationToken cancellationToken = default); - Task MinAsync( + Task MinAsync( [NotNull] IQueryable queryable, [NotNull] Expression> selector, CancellationToken cancellationToken = default); @@ -153,12 +153,12 @@ public interface IAsyncQueryableProvider #region Max - Task MaxAsync( + Task MaxAsync( [NotNull] IQueryable queryable, CancellationToken cancellationToken = default); - Task MaxAsync( + Task MaxAsync( [NotNull] IQueryable queryable, [NotNull] Expression> selector, CancellationToken cancellationToken = default); From 122fc4e874455c7756bdb5b8b61290ac50795aa0 Mon Sep 17 00:00:00 2001 From: Salih Date: Mon, 7 Aug 2023 09:16:43 +0300 Subject: [PATCH 083/165] Update en.json --- .../Commercial/Localization/Resources/en.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index abd93b4547..e2267d6a36 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -907,8 +907,12 @@ "ExtraQuestionCreditsFaqExplanation": "Yes, you can. To buy extra question credits, send an e-mail to info@abp.io with your organization's name. Here's the price list for the extra question credits:
  • 50 questions pack $999
  • 25 questions pack $625
  • 15 questions pack $450
", "AlreadyBetaTester": "You have already joined the beta tester program.", "AbpStudio": "ABP Studio", + "AbpStudio_Description": "ABP Studio is still under development. You can fill out the form below to be one of the first users.", "AbpStudio_Description1": "ABP Studio is a cross-platform desktop application for ABP developers.", "AbpStudio_Description2": "It is well integrated to the ABP Framework and aims to provide a comfortable development environment for you by automating things, providing insights about your solution, making develop, run and deploy your solutions much easier.", + "AbpStudio_ComingSoon": "Coming Soon Planned beta release date: Q4 of 2023.", + "AbpStudio_PlannedPreviewDate": "Planned preview release date: Q4 of 2023.", + "BetaRequest": "Beta Request", "CreateNewSolutions": "Create New Solutions", "CreateNewSolutions_Description1": "You can create from simple applications to modular monolith or microservice solutions easily with a lot of options. You get a full production-ready base software solution for your business.", "ArchitectYourSolutions": "Architect Your Solutions", From adaf8c7201643b21ec5ae3796146f1bc21baf0bd Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Aug 2023 14:23:40 +0800 Subject: [PATCH 084/165] Enable nullable annotations for Volo.Abp.Dapper --- framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj | 2 ++ .../Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs | 6 +++--- .../Abp/Domain/Repositories/Dapper/IDapperRepository.cs | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj b/framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj index e4236d697c..e42eca0d2b 100644 --- a/framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj +++ b/framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj @@ -5,6 +5,8 @@ net7.0 + enable + Nullable Volo.Abp.Dapper Volo.Abp.Dapper $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; diff --git a/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs b/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs index b9f061b9aa..fda89ab61d 100644 --- a/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs +++ b/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs @@ -16,7 +16,7 @@ namespace Volo.Abp.Domain.Repositories.Dapper; public class DapperRepository : IDapperRepository, IUnitOfWorkEnabled where TDbContext : IEfCoreDbContext { - public IAbpLazyServiceProvider LazyServiceProvider { get; set; } + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } = default!; public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService(); @@ -39,9 +39,9 @@ public class DapperRepository : IDapperRepository, IUnitOfWorkEnable public virtual async Task GetDbConnectionAsync() => (await _dbContextProvider.GetDbContextAsync()).Database.GetDbConnection(); [Obsolete("Use GetDbTransactionAsync method.")] - public IDbTransaction DbTransaction => _dbContextProvider.GetDbContext().Database.CurrentTransaction?.GetDbTransaction(); + public IDbTransaction? DbTransaction => _dbContextProvider.GetDbContext().Database.CurrentTransaction?.GetDbTransaction(); - public virtual async Task GetDbTransactionAsync() => (await _dbContextProvider.GetDbContextAsync()).Database.CurrentTransaction?.GetDbTransaction(); + public virtual async Task GetDbTransactionAsync() => (await _dbContextProvider.GetDbContextAsync()).Database.CurrentTransaction?.GetDbTransaction(); protected virtual CancellationToken GetCancellationToken(CancellationToken preferredValue = default) { diff --git a/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs b/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs index e5e8fa4c54..5a22e65e00 100644 --- a/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs +++ b/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs @@ -12,7 +12,7 @@ public interface IDapperRepository Task GetDbConnectionAsync(); [Obsolete("Use GetDbTransactionAsync method.")] - IDbTransaction DbTransaction { get; } + IDbTransaction? DbTransaction { get; } - Task GetDbTransactionAsync(); + Task GetDbTransactionAsync(); } From 671c6156a0f52ab55fb24930c54637b553b8d40b Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Aug 2023 14:28:27 +0800 Subject: [PATCH 085/165] Enable nullable annotations for Volo.Abp.Ddd.Domain.Shared --- .../Volo.Abp.Ddd.Domain.Shared.csproj | 2 ++ .../Abp/Domain/Entities/Events/Distributed/EntityEto.cs | 6 +++--- .../Entities/Events/Distributed/EtoMappingDictionary.cs | 2 +- .../Entities/Events/Distributed/EtoMappingDictionaryItem.cs | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo.Abp.Ddd.Domain.Shared.csproj b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo.Abp.Ddd.Domain.Shared.csproj index 2972ef23c1..efc808fdc7 100644 --- a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo.Abp.Ddd.Domain.Shared.csproj +++ b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo.Abp.Ddd.Domain.Shared.csproj @@ -5,6 +5,8 @@ netstandard2.0;netstandard2.1;net7.0 + enable + Nullable Volo.Abp.Ddd.Domain.Shared Volo.Abp.Ddd.Domain.Shared $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; diff --git a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityEto.cs b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityEto.cs index 8a2983b076..88e71f2e9f 100644 --- a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityEto.cs +++ b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityEto.cs @@ -5,9 +5,9 @@ namespace Volo.Abp.Domain.Entities.Events.Distributed; [Serializable] public class EntityEto : EtoBase { - public string EntityType { get; set; } + public string EntityType { get; set; } = default!; - public string KeysAsString { get; set; } + public string KeysAsString { get; set; } = default!; public EntityEto() { @@ -23,5 +23,5 @@ public class EntityEto : EtoBase public abstract class EntityEto : IEntityEto { - public TKey Id { get; set; } + public TKey Id { get; set; } = default!; } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs index bb9e362ac2..f62ccfd872 100644 --- a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs +++ b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs @@ -5,7 +5,7 @@ namespace Volo.Abp.Domain.Entities.Events.Distributed; public class EtoMappingDictionary : Dictionary { - public void Add(Type objectMappingContextType = null) + public void Add(Type? objectMappingContextType = null) { this[typeof(TEntity)] = new EtoMappingDictionaryItem(typeof(TEntityEto), objectMappingContextType); } diff --git a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs index a6065e1d5f..c250e6daae 100644 --- a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs +++ b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs @@ -6,9 +6,9 @@ public class EtoMappingDictionaryItem { public Type EtoType { get; } - public Type ObjectMappingContextType { get; } + public Type? ObjectMappingContextType { get; } - public EtoMappingDictionaryItem(Type etoType, Type objectMappingContextType = null) + public EtoMappingDictionaryItem(Type etoType, Type? objectMappingContextType = null) { EtoType = etoType; ObjectMappingContextType = objectMappingContextType; From fc515c5f996243ce17993b2d8e66cbb7018bcb7e Mon Sep 17 00:00:00 2001 From: selman koc <64414348+skoc10@users.noreply.github.com> Date: Mon, 7 Aug 2023 09:33:49 +0300 Subject: [PATCH 086/165] Update version to release 7.3.2 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index f356656fbf..994bb4a888 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 7.3.1 + 7.3.2 $(NoWarn);CS1591;CS0436 https://abp.io/assets/abp_nupkg.png https://abp.io/ From bf608c6a57b7c798b3ef64f81be27b5cbcbe6f7b Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Aug 2023 14:49:39 +0800 Subject: [PATCH 087/165] Enable nullable annotations for Volo.Abp.Application.Contracts --- .../Volo.Abp.Ddd.Application.Contracts.csproj | 2 ++ .../Abp/Application/Dtos/AuditedEntityWithUserDto.cs | 8 ++++---- .../Dtos/CreationAuditedEntityWithUserDto.cs | 4 ++-- .../Volo/Abp/Application/Dtos/EntityDto.cs | 2 +- .../Dtos/ExtensibleAuditedEntityWithUserDto.cs | 8 ++++---- .../ExtensibleCreationAuditedEntityWithUserDto.cs | 4 ++-- .../Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs | 2 +- .../Dtos/ExtensibleFullAuditedEntityWithUserDto.cs | 12 ++++++------ .../Application/Dtos/FullAuditedEntityWithUserDto.cs | 12 ++++++------ .../Abp/Application/Dtos/ISortedResultRequest.cs | 2 +- .../Abp/Application/Dtos/LimitedResultRequestDto.cs | 4 ++-- .../Volo/Abp/Application/Dtos/ListResultDto.cs | 4 ++-- .../Dtos/PagedAndSortedResultRequestDto.cs | 4 ++-- .../Events/Distributed/IEntityToEtoMapper.cs | 3 +-- .../Entities/Events/Distributed/EntityToEtoMapper.cs | 2 +- 15 files changed, 37 insertions(+), 36 deletions(-) diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo.Abp.Ddd.Application.Contracts.csproj b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo.Abp.Ddd.Application.Contracts.csproj index ae01d66fd0..891a4b8a33 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo.Abp.Ddd.Application.Contracts.csproj +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo.Abp.Ddd.Application.Contracts.csproj @@ -5,6 +5,8 @@ netstandard2.0;netstandard2.1;net7.0 + enable + Nullable Volo.Abp.Ddd.Application.Contracts Volo.Abp.Ddd.Application.Contracts $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/AuditedEntityWithUserDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/AuditedEntityWithUserDto.cs index 992abc68fe..dfdbb10590 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/AuditedEntityWithUserDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/AuditedEntityWithUserDto.cs @@ -12,10 +12,10 @@ namespace Volo.Abp.Application.Dtos; public abstract class AuditedEntityWithUserDto : AuditedEntityDto, IAuditedObject { /// - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } /// - public TUserDto LastModifier { get; set; } + public TUserDto? LastModifier { get; set; } } /// @@ -28,8 +28,8 @@ public abstract class AuditedEntityWithUserDto : AuditedEntityDto, IAu public abstract class AuditedEntityWithUserDto : AuditedEntityDto, IAuditedObject { /// - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } /// - public TUserDto LastModifier { get; set; } + public TUserDto? LastModifier { get; set; } } diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/CreationAuditedEntityWithUserDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/CreationAuditedEntityWithUserDto.cs index e566e8852b..241944bb69 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/CreationAuditedEntityWithUserDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/CreationAuditedEntityWithUserDto.cs @@ -11,7 +11,7 @@ namespace Volo.Abp.Application.Dtos; [Serializable] public abstract class CreationAuditedEntityWithUserDto : CreationAuditedEntityDto, ICreationAuditedObject { - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } } /// @@ -23,5 +23,5 @@ public abstract class CreationAuditedEntityWithUserDto : CreationAudit [Serializable] public abstract class CreationAuditedEntityWithUserDto : CreationAuditedEntityDto, ICreationAuditedObject { - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } } diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/EntityDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/EntityDto.cs index a205549695..656e63b0d5 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/EntityDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/EntityDto.cs @@ -17,7 +17,7 @@ public abstract class EntityDto : EntityDto, IEntityDto /// /// Id of the entity. /// - public TKey Id { get; set; } + public TKey Id { get; set; } = default!; public override string ToString() { diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityWithUserDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityWithUserDto.cs index 5f6fd28628..212dcfd807 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityWithUserDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityWithUserDto.cs @@ -15,10 +15,10 @@ namespace Volo.Abp.Application.Dtos; public abstract class ExtensibleAuditedEntityWithUserDto : ExtensibleAuditedEntityDto, IAuditedObject { /// - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } /// - public TUserDto LastModifier { get; set; } + public TUserDto? LastModifier { get; set; } protected ExtensibleAuditedEntityWithUserDto() : this(true) @@ -44,10 +44,10 @@ public abstract class ExtensibleAuditedEntityWithUserDto : ExtensibleA IAuditedObject { /// - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } /// - public TUserDto LastModifier { get; set; } + public TUserDto? LastModifier { get; set; } protected ExtensibleAuditedEntityWithUserDto() : this(true) diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityWithUserDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityWithUserDto.cs index 3ea1be97ab..21677718cb 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityWithUserDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityWithUserDto.cs @@ -14,7 +14,7 @@ namespace Volo.Abp.Application.Dtos; [Serializable] public abstract class ExtensibleCreationAuditedEntityWithUserDto : ExtensibleCreationAuditedEntityDto, ICreationAuditedObject { - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } protected ExtensibleCreationAuditedEntityWithUserDto() : this(true) @@ -39,7 +39,7 @@ public abstract class ExtensibleCreationAuditedEntityWithUserDto : ExtensibleCreationAuditedEntityDto, ICreationAuditedObject { - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } protected ExtensibleCreationAuditedEntityWithUserDto() : this(true) diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs index 1af46a3287..9687af0cf7 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs @@ -9,7 +9,7 @@ public abstract class ExtensibleEntityDto : ExtensibleObject, IEntityDto /// Id of the entity. /// - public TKey Id { get; set; } + public TKey Id { get; set; } = default!; protected ExtensibleEntityDto() : this(true) diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleFullAuditedEntityWithUserDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleFullAuditedEntityWithUserDto.cs index 018a84cd7a..9793774a47 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleFullAuditedEntityWithUserDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleFullAuditedEntityWithUserDto.cs @@ -15,13 +15,13 @@ namespace Volo.Abp.Application.Dtos; public abstract class ExtensibleFullAuditedEntityWithUserDto : ExtensibleFullAuditedEntityDto, IFullAuditedObject { /// - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } /// - public TUserDto LastModifier { get; set; } + public TUserDto? LastModifier { get; set; } /// - public TUserDto Deleter { get; set; } + public TUserDto? Deleter { get; set; } protected ExtensibleFullAuditedEntityWithUserDto() : this(true) @@ -47,13 +47,13 @@ public abstract class ExtensibleFullAuditedEntityWithUserDto : Extensi IFullAuditedObject { /// - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } /// - public TUserDto LastModifier { get; set; } + public TUserDto? LastModifier { get; set; } /// - public TUserDto Deleter { get; set; } + public TUserDto? Deleter { get; set; } protected ExtensibleFullAuditedEntityWithUserDto() : this(true) diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/FullAuditedEntityWithUserDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/FullAuditedEntityWithUserDto.cs index 0575c348b4..c9941d9127 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/FullAuditedEntityWithUserDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/FullAuditedEntityWithUserDto.cs @@ -12,13 +12,13 @@ namespace Volo.Abp.Application.Dtos; public abstract class FullAuditedEntityWithUserDto : FullAuditedEntityDto, IFullAuditedObject { /// - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } /// - public TUserDto LastModifier { get; set; } + public TUserDto? LastModifier { get; set; } /// - public TUserDto Deleter { get; set; } + public TUserDto? Deleter { get; set; } } /// @@ -31,11 +31,11 @@ public abstract class FullAuditedEntityWithUserDto : FullAuditedEntity public abstract class FullAuditedEntityWithUserDto : FullAuditedEntityDto, IFullAuditedObject { /// - public TUserDto Creator { get; set; } + public TUserDto? Creator { get; set; } /// - public TUserDto LastModifier { get; set; } + public TUserDto? LastModifier { get; set; } /// - public TUserDto Deleter { get; set; } + public TUserDto? Deleter { get; set; } } diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ISortedResultRequest.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ISortedResultRequest.cs index 0f0a4fe90f..b27c3bf99d 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ISortedResultRequest.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ISortedResultRequest.cs @@ -16,5 +16,5 @@ public interface ISortedResultRequest /// "Name DESC" /// "Name ASC, Age DESC" /// - string Sorting { get; set; } + string? Sorting { get; set; } } diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/LimitedResultRequestDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/LimitedResultRequestDto.cs index d72f7b0a77..646eb4d45e 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/LimitedResultRequestDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/LimitedResultRequestDto.cs @@ -42,7 +42,7 @@ public class LimitedResultRequestDto : ILimitedResultRequest, IValidatableObject "MaxResultCountExceededExceptionMessage", nameof(MaxResultCount), MaxMaxResultCount, - typeof(LimitedResultRequestDto).FullName, + typeof(LimitedResultRequestDto).FullName!, nameof(MaxMaxResultCount) ], new[] { nameof(MaxResultCount) }); @@ -90,7 +90,7 @@ public class ExtensibleLimitedResultRequestDto : ExtensibleEntityDto, ILimitedRe "MaxResultCountExceededExceptionMessage", nameof(MaxResultCount), MaxMaxResultCount, - typeof(ExtensibleLimitedResultRequestDto).FullName, + typeof(ExtensibleLimitedResultRequestDto).FullName!, nameof(MaxMaxResultCount) ], new[] { nameof(MaxResultCount) }); diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ListResultDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ListResultDto.cs index 361b27faac..56937e7049 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ListResultDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ListResultDto.cs @@ -13,7 +13,7 @@ public class ListResultDto : IListResult get { return _items ?? (_items = new List()); } set { _items = value; } } - private IReadOnlyList _items; + private IReadOnlyList? _items; /// /// Creates a new object. @@ -42,7 +42,7 @@ public class ExtensibleListResultDto : ExtensibleObject, IListResult get { return _items ?? (_items = new List()); } set { _items = value; } } - private IReadOnlyList _items; + private IReadOnlyList? _items; /// /// Creates a new object. diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/PagedAndSortedResultRequestDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/PagedAndSortedResultRequestDto.cs index 229178adbf..8a9b62bb60 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/PagedAndSortedResultRequestDto.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/PagedAndSortedResultRequestDto.cs @@ -8,7 +8,7 @@ namespace Volo.Abp.Application.Dtos; [Serializable] public class PagedAndSortedResultRequestDto : PagedResultRequestDto, IPagedAndSortedResultRequest { - public virtual string Sorting { get; set; } + public virtual string? Sorting { get; set; } } /// @@ -17,5 +17,5 @@ public class PagedAndSortedResultRequestDto : PagedResultRequestDto, IPagedAndSo [Serializable] public class ExtensiblePagedAndSortedResultRequestDto : ExtensiblePagedResultRequestDto, IPagedAndSortedResultRequest { - public virtual string Sorting { get; set; } + public virtual string? Sorting { get; set; } } diff --git a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/IEntityToEtoMapper.cs b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/IEntityToEtoMapper.cs index 6f0ea7a880..67406fd0d4 100644 --- a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/IEntityToEtoMapper.cs +++ b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/IEntityToEtoMapper.cs @@ -4,6 +4,5 @@ namespace Volo.Abp.Domain.Entities.Events.Distributed; public interface IEntityToEtoMapper { - [CanBeNull] - object Map(object entityObj); + object? Map(object entityObj); } diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs index 1710fe81e3..cab3fe4614 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs @@ -36,7 +36,7 @@ public class EntityToEtoMapper : IEntityToEtoMapper, ITransientDependency if (etoMappingItem == null) { var keys = entity.GetKeys().JoinAsString(","); - return new EntityEto(entityType.FullName, keys); + return new EntityEto(entityType.FullName!, keys); } using (var scope = HybridServiceScopeFactory.CreateScope()) From c19c22e995ccd316004e047b4e58af6697caf523 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Aug 2023 14:58:35 +0800 Subject: [PATCH 088/165] Enable nullable annotations for Volo.Abp.Application --- .../Volo.Abp.Ddd.Application.csproj | 2 ++ .../Services/AbstractKeyCrudAppService.cs | 6 +++--- .../Services/AbstractKeyReadOnlyAppService.cs | 6 +++--- .../Services/ApplicationService.cs | 20 +++++++++---------- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo.Abp.Ddd.Application.csproj b/framework/src/Volo.Abp.Ddd.Application/Volo.Abp.Ddd.Application.csproj index fc0586ce8e..03351adb7f 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo.Abp.Ddd.Application.csproj +++ b/framework/src/Volo.Abp.Ddd.Application/Volo.Abp.Ddd.Application.csproj @@ -5,6 +5,8 @@ netstandard2.0;netstandard2.1;net7.0 + enable + Nullable Volo.Abp.Ddd.Application Volo.Abp.Ddd.Application $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs index 6b6ad975d7..b3a2af6663 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs @@ -70,11 +70,11 @@ public abstract class AbstractKeyCrudAppService Repository { get; } - protected virtual string CreatePolicyName { get; set; } + protected virtual string? CreatePolicyName { get; set; } - protected virtual string UpdatePolicyName { get; set; } + protected virtual string? UpdatePolicyName { get; set; } - protected virtual string DeletePolicyName { get; set; } + protected virtual string? DeletePolicyName { get; set; } protected AbstractKeyCrudAppService(IRepository repository) : base(repository) diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs index e56e3ff042..8602792701 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs @@ -40,9 +40,9 @@ public abstract class AbstractKeyReadOnlyAppService ReadOnlyRepository { get; } - protected virtual string GetPolicyName { get; set; } + protected virtual string? GetPolicyName { get; set; } - protected virtual string GetListPolicyName { get; set; } + protected virtual string? GetListPolicyName { get; set; } protected AbstractKeyReadOnlyAppService(IReadOnlyRepository repository) { @@ -107,7 +107,7 @@ public abstract class AbstractKeyReadOnlyAppService LazyServiceProvider.LazyGetRequiredService(); - protected Type ObjectMapperContext { get; set; } + protected Type? ObjectMapperContext { get; set; } protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService(provider => ObjectMapperContext == null ? provider.GetRequiredService() @@ -85,34 +85,34 @@ public abstract class ApplicationService : return _localizer; } } - private IStringLocalizer _localizer; + private IStringLocalizer? _localizer; - protected Type LocalizationResource { + protected Type? LocalizationResource { get => _localizationResource; set { _localizationResource = value; _localizer = null; } } - private Type _localizationResource = typeof(DefaultResource); + private Type? _localizationResource = typeof(DefaultResource); - protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; + protected IUnitOfWork? CurrentUnitOfWork => UnitOfWorkManager?.Current; - protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); + protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName!) ?? NullLogger.Instance); /// /// Checks for given . /// Throws if given policy has not been granted. /// /// The policy name. This method does nothing if given is null or empty. - protected virtual async Task CheckPolicyAsync([CanBeNull] string policyName) + protected virtual async Task CheckPolicyAsync(string? policyName) { if (string.IsNullOrEmpty(policyName)) { return; } - await AuthorizationService.CheckAsync(policyName); + await AuthorizationService.CheckAsync(policyName!); } protected virtual IStringLocalizer CreateLocalizer() From 29f5b89114a2a4a235474e36ecdcea1df9a1ea69 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Aug 2023 15:06:26 +0800 Subject: [PATCH 089/165] Enable nullable annotations for Volo.Abp.Dapr --- framework/src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj | 2 ++ .../Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs | 8 ++++---- .../src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs | 8 ++++---- .../src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprOptions.cs | 8 ++++---- .../Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs | 4 ++-- .../Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs | 8 ++++---- .../Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs | 4 ++-- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/framework/src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj b/framework/src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj index f21af371bb..1b952e34cc 100644 --- a/framework/src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj +++ b/framework/src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj @@ -5,6 +5,8 @@ net7.0 + enable + Nullable diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs index aa14bbe7f2..43e9dbc953 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs @@ -24,7 +24,7 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency JsonSerializerOptions = CreateJsonSerializerOptions(systemTextJsonSerializerOptions.Value); } - public virtual DaprClient Create(Action builderAction = null) + public virtual DaprClient Create(Action? builderAction = null) { var builder = new DaprClientBuilder() .UseJsonSerializationOptions(JsonSerializerOptions); @@ -51,9 +51,9 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency } public virtual HttpClient CreateHttpClient( - string appId = null, - string daprEndpoint = null, - string daprApiToken = null) + string? appId = null, + string? daprEndpoint = null, + string? daprApiToken = null) { if(daprEndpoint.IsNullOrWhiteSpace() && !DaprOptions.HttpEndpoint.IsNullOrWhiteSpace()) diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs index 4153ae2ec1..e1ca4bb0db 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs @@ -33,14 +33,14 @@ public class AbpDaprModule : AbpModule var confEnv = configuration["DAPR_API_TOKEN"]; if (!confEnv.IsNullOrWhiteSpace()) { - options.DaprApiToken = confEnv; + options.DaprApiToken = confEnv!; } else { var env = Environment.GetEnvironmentVariable("DAPR_API_TOKEN"); if (!env.IsNullOrWhiteSpace()) { - options.DaprApiToken = env; + options.DaprApiToken = env!; } } } @@ -50,14 +50,14 @@ public class AbpDaprModule : AbpModule var confEnv = configuration["APP_API_TOKEN"]; if (!confEnv.IsNullOrWhiteSpace()) { - options.AppApiToken = confEnv; + options.AppApiToken = confEnv!; } else { var env = Environment.GetEnvironmentVariable("APP_API_TOKEN"); if (!env.IsNullOrWhiteSpace()) { - options.AppApiToken = env; + options.AppApiToken = env!; } } } diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprOptions.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprOptions.cs index 7ac19ad31c..f436f35147 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprOptions.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprOptions.cs @@ -2,11 +2,11 @@ public class AbpDaprOptions { - public string HttpEndpoint { get; set; } + public string? HttpEndpoint { get; set; } - public string GrpcEndpoint { get; set; } + public string? GrpcEndpoint { get; set; } - public string DaprApiToken { get; set; } + public string? DaprApiToken { get; set; } - public string AppApiToken { get; set; } + public string? AppApiToken { get; set; } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs index 10dd3913ed..c38f36bf10 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs @@ -12,12 +12,12 @@ public class DaprApiTokenProvider : IDaprApiTokenProvider, ISingletonDependency Options = options.Value; } - public virtual string GetDaprApiToken() + public virtual string? GetDaprApiToken() { return Options.DaprApiToken; } - public virtual string GetAppApiToken() + public virtual string? GetAppApiToken() { return Options.AppApiToken; } diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs index 65c4e76b7e..bbf074af6c 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs @@ -6,11 +6,11 @@ namespace Volo.Abp.Dapr; public interface IAbpDaprClientFactory { - DaprClient Create(Action builderAction = null); + DaprClient Create(Action? builderAction = null); HttpClient CreateHttpClient( - string appId = null, - string daprEndpoint = null, - string daprApiToken = null + string? appId = null, + string? daprEndpoint = null, + string? daprApiToken = null ); } diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs index 60f2195596..5e153ba2ea 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs @@ -2,7 +2,7 @@ namespace Volo.Abp.Dapr; public interface IDaprApiTokenProvider { - string GetDaprApiToken(); + string? GetDaprApiToken(); - string GetAppApiToken(); + string? GetAppApiToken(); } From 734c72f7f7b0171319a684dc5a91f4f94dfe6c5a Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Mon, 7 Aug 2023 10:22:20 +0300 Subject: [PATCH 090/165] Docs: Fix duplicate document results in search --- .../FullSearch/Elastic/ElasticDocumentFullSearch.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs index e5f8401b20..30ebf9a96f 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs @@ -204,11 +204,18 @@ namespace Volo.Docs.Documents.FullSearch.Elastic foreach (var hit in response.Hits) { var doc = hit.Source; + if(docs.Any(x => x.Id == doc.Id)) + { + continue; + } + + if (hit.Highlight.ContainsKey("content")) { doc.Highlight = new List(); doc.Highlight.AddRange(hit.Highlight["content"]); } + docs.Add(doc); } From 1ee1f1b12b7608bd05ac0a4f4b25457c941c6508 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Aug 2023 15:23:11 +0800 Subject: [PATCH 091/165] Enable nullable annotations for Volo.Abp.DistributedLocking.Abstractions --- .../Volo.Abp.DistributedLocking.Abstractions.csproj | 2 ++ .../Volo/Abp/DistributedLocking/IAbpDistributedLock.cs | 3 +-- .../Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo.Abp.DistributedLocking.Abstractions.csproj b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo.Abp.DistributedLocking.Abstractions.csproj index 7e01d295e7..e53f5b718c 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo.Abp.DistributedLocking.Abstractions.csproj +++ b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo.Abp.DistributedLocking.Abstractions.csproj @@ -5,6 +5,8 @@ netstandard2.0;netstandard2.1;net7.0 + enable + Nullable Volo.Abp.DistributedLocking.Abstractions Volo.Abp.DistributedLocking.Abstractions $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; diff --git a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/IAbpDistributedLock.cs b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/IAbpDistributedLock.cs index 754ae807f8..1d1b5e01db 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/IAbpDistributedLock.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/IAbpDistributedLock.cs @@ -16,8 +16,7 @@ public interface IAbpDistributedLock /// The name of the lock /// How long to wait before giving up on the acquisition attempt. Defaults to 0 /// Cancellation token - [ItemCanBeNull] - Task TryAcquireAsync( + Task TryAcquireAsync( [NotNull] string name, TimeSpan timeout = default, CancellationToken cancellationToken = default diff --git a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs index 490f024d36..58d67e1caf 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs @@ -22,7 +22,7 @@ public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public async Task TryAcquireAsync( + public async Task TryAcquireAsync( string name, TimeSpan timeout = default, CancellationToken cancellationToken = default) From 86e36cc7bd6ddba2b4d2fde30419e1ba74bf61d8 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Aug 2023 15:25:42 +0800 Subject: [PATCH 092/165] Enable nullable annotations for Volo.Abp.DistributedLocking --- .../Volo.Abp.DistributedLocking.csproj | 2 ++ .../Volo/Abp/DistributedLocking/MedallionAbpDistributedLock.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.DistributedLocking/Volo.Abp.DistributedLocking.csproj b/framework/src/Volo.Abp.DistributedLocking/Volo.Abp.DistributedLocking.csproj index ae9f960917..8abd0873bd 100644 --- a/framework/src/Volo.Abp.DistributedLocking/Volo.Abp.DistributedLocking.csproj +++ b/framework/src/Volo.Abp.DistributedLocking/Volo.Abp.DistributedLocking.csproj @@ -5,6 +5,8 @@ netstandard2.0;netstandard2.1;net7.0 + enable + Nullable Volo.Abp.DistributedLocking Volo.Abp.DistributedLocking $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; diff --git a/framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLock.cs b/framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLock.cs index 0defc5a75f..2d9d07b45a 100644 --- a/framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLock.cs +++ b/framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLock.cs @@ -25,7 +25,7 @@ public class MedallionAbpDistributedLock : IAbpDistributedLock, ITransientDepend DistributedLockKeyNormalizer = distributedLockKeyNormalizer; } - public async Task TryAcquireAsync( + public async Task TryAcquireAsync( string name, TimeSpan timeout = default, CancellationToken cancellationToken = default) From 3e3d6402daa84e136ae70fca3d3ef4b60ba080ea Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Aug 2023 15:30:04 +0800 Subject: [PATCH 093/165] Enable nullable annotations for Volo.Abp.DistributedLocking.Dapr --- .../Volo.Abp.DistributedLocking.Dapr.csproj | 2 ++ .../DistributedLocking/Dapr/AbpDistributedLockDaprOptions.cs | 2 +- .../Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo.Abp.DistributedLocking.Dapr.csproj b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo.Abp.DistributedLocking.Dapr.csproj index 79d39eedf0..a0ddaac22e 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo.Abp.DistributedLocking.Dapr.csproj +++ b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo.Abp.DistributedLocking.Dapr.csproj @@ -5,6 +5,8 @@ net7.0 + enable + Nullable diff --git a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/AbpDistributedLockDaprOptions.cs b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/AbpDistributedLockDaprOptions.cs index a51ed8ede7..b4572441d3 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/AbpDistributedLockDaprOptions.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/AbpDistributedLockDaprOptions.cs @@ -4,7 +4,7 @@ namespace Volo.Abp.DistributedLocking.Dapr; public class AbpDistributedLockDaprOptions { - public string StoreName { get; set; } + public string StoreName { get; set; } = default!; public string? Owner { get; set; } diff --git a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs index 974c6461a6..100fece989 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs @@ -24,7 +24,7 @@ public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency DistributedLockDaprOptions = distributedLockDaprOptions.Value; } - public async Task TryAcquireAsync( + public async Task TryAcquireAsync( string name, TimeSpan timeout = default, CancellationToken cancellationToken = default) From b1ee15dd590b7a024c8a02923d5ab89cccacf795 Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Mon, 7 Aug 2023 10:33:53 +0300 Subject: [PATCH 094/165] Update Docs module documentation for installation step --- docs/en/Modules/Docs.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/docs/en/Modules/Docs.md b/docs/en/Modules/Docs.md index 143ec7168d..58dd811397 100644 --- a/docs/en/Modules/Docs.md +++ b/docs/en/Modules/Docs.md @@ -22,22 +22,16 @@ When you use GitHub to store your docs, Docs Module supports versioning. If you ## Installation -### 1- Download +This document covers `Entity Framework Core` provider but you can also select `MongoDB` as your database provider. -If you do not have an existing ABP project, this step shows you how to create a new project from [abp.io](https://abp.io) to add the Docs Module. If you already have an ABP project, you can skip this step. +### 1- Creating an application -It is recommended to use ABP CLI to create new projects. Use the following command: +If you do not have an existing ABP project, you can either [generate a CLI command from the get started page of the abp.io website](https://abp.io/get-started) and runs it or run the command below: ```bash abp new Acme.MyProject ``` -You can also generate a CLI command from [get started page](https://abp.io/get-started). Enter your project name as `Acme.MyProject`, other use default options. - -Note that this document covers `Entity Framework Core` provider but you can also select `MongoDB` as your database provider. - -![Create new project](../images/docs-module_download-new-abp-project.png) - ### 2- Running The Empty Application After you download the project, extract the ZIP file and open `Acme.MyProject.sln`. You will see that the solution consists of `Application`, `Application.Contracts`, `DbMigrator`, `Domain`, `Domain.Shared`, `EntityFrameworkCore`, `HttpApi`, `HttpApi.Client` and `Web` projects. Right click on `Acme.MyProject.Web` project and **Set as StartUp Project**. From 1f630ebcd070dc046b835e085768b4d1a7054a00 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Aug 2023 15:56:28 +0800 Subject: [PATCH 095/165] CmsKit Add missing field --- .../Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml index b9bae20f40..673c402c2c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml @@ -74,7 +74,8 @@
-
+ + From b67a0e62d06d989172d795563dc6ed47ff28bbb5 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Mon, 7 Aug 2023 18:06:33 +0300 Subject: [PATCH 099/165] Article - Adding Dark Mode Support to the Basic Theme --- .../2023-08-07-Basic-Theme-Dark-Mode/POST.md | 125 ++++++++++++++++++ .../basictheme-dark-login.png | Bin 0 -> 28676 bytes .../basictheme-dark-settings.png | Bin 0 -> 33538 bytes .../basictheme-dark-users.png | Bin 0 -> 27124 bytes .../basictheme-toggle-demo.gif | Bin 0 -> 193440 bytes 5 files changed, 125 insertions(+) create mode 100644 docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md create mode 100644 docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/basictheme-dark-login.png create mode 100644 docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/basictheme-dark-settings.png create mode 100644 docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/basictheme-dark-users.png create mode 100644 docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/basictheme-toggle-demo.gif diff --git a/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md b/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md new file mode 100644 index 0000000000..f079c71546 --- /dev/null +++ b/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md @@ -0,0 +1,125 @@ +# Adding Dark Mode Support to the Basic Theme +Basic Theme uses plain bootstrap and does not have any custom colors & styles. This article will show you how to add dark mode support to the Basic Theme. + +Bootstrap brings [Color Modes](https://getbootstrap.com/docs/5.3/customize/color-modes/#dark-mode) feature with the version **5.3**. This feature allows you to add dark mode support to your website with a single line of code. Adding `data-bs-theme="dark"` attribute, changes the color mode of the element to dark mode. + +## Instructions + +1. Create a new project + ```bash + abp new BasicThemeDarkMode -t app --theme basic + ``` + +2. Create a component that toggles the color mode. + + - Create a new file named `Components/ChangeTheme/Default.cshtml` + ```html +
+ +
+ ``` + + - Create a new file named `Components/ChangeTheme/ChangeThemeViewComponent.cs` + ```csharp + using Microsoft.AspNetCore.Mvc; + using Volo.Abp.AspNetCore.Mvc; + + namespace BasicThemeDarkMode.Web.Components.ChangeTheme; + + [Widget(ScriptFiles = new[]{"/Components/ChangeTheme/ChangeTheme.js"})] + public class ChangeThemeViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View("~/Components/ChangeTheme/Default.cshtml"); + } + } + ``` + + - Create a JavaScript that manages last selected theme and toggles the color mode. It stores the last selected theme in the local storage. So, you don't need to store it in the database. + + - Create a new file named `Components/ChangeTheme/ChangeTheme.js` + ```js + $(function () { + function changeTheme(theme) { + window.localStorage.setItem('theme', theme); + document.getElementsByTagName('body')[0].setAttribute('data-bs-theme', theme); + } + + function toggleTheme(){ + getTheme() == 'light' ? changeTheme('dark') : changeTheme('light'); + } + + function getTheme(){ + return window.localStorage.getItem('theme') ?? 'dark'; + } + + function init(){ + let theme = getTheme(); + if(theme){ + changeTheme(theme); + } + } + + document.getElementById('ToolbarChangeTheme').addEventListener('click', () => { + toggleTheme(); + }); + + init(); + }); + ``` + +3. Create a new Toolbar Contributor and add newly created view component to the application toolbar. + + - Create a new class named `BasicThemeDarkModeToolbarContributor.cs` + ```csharp + using BasicThemeDarkMode.Web.Components.ChangeTheme; + using System.Threading.Tasks; + using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; + + namespace BasicThemeDarkMode.Web; + + public class BasicThemeDarkModeToolbarContributor : IToolbarContributor + { + public Task ConfigureToolbarAsync(IToolbarConfigurationContext context) + { + if (context.Toolbar.Name == StandardToolbars.Main) + { + context.Toolbar.Items + .Add(new ToolbarItem(typeof(ChangeThemeViewComponent))); + } + + return Task.CompletedTask; + } + } + ``` + + - Configure [Toolbar Options](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Toolbars) and add newly created contributor. + ```csharp + Configure(options => + { + options.Contributors.Add(new BasicThemeDarkModeToolbarContributor()); + }); + ``` + +That's it! Now, you can toggle the color mode by clicking the sun icon in the toolbar. + +![Dark Mode](basictheme-toggle-demo.gif) + +- Users Page in Dark Mode: + + ![Users Page in Dark Mode](basictheme-dark-users.png) + +- Settings Page in Dark Mode: + + ![Settings Page in Dark Mode](basictheme-dark-settings.png) + +- Login Page in Dark Mode: + + ![Login Page in Dark Mode](basictheme-dark-login.png) + +## Conclusion + +The theme is stored in **local storage** and it's initialized in the client-side. You can use **Cookies** to render the page in the last selected theme on **server-side** to prevent the flash effect while navigating pages. This documents show the concept of adding dark mode support of bootstrap to the Basic Theme. \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/basictheme-dark-login.png b/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/basictheme-dark-login.png new file mode 100644 index 0000000000000000000000000000000000000000..0ee18b54b96994e6aa54f9f41f68c40cfab84903 GIT binary patch literal 28676 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 literal 0 HcmV?d00001 diff --git a/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/basictheme-dark-settings.png b/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/basictheme-dark-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..6d32677c4cbddd4491f480b11af3faf24c2c2489 GIT binary patch literal 33538 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 aL=yjbGU?e_Q~yf#$T3U&TF&c*;c_hpl$Z~^Uub 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 literal 0 HcmV?d00001 diff --git a/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/basictheme-toggle-demo.gif b/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/basictheme-toggle-demo.gif new file mode 100644 index 0000000000000000000000000000000000000000..536b30e6ee0f2db9a486adb3f9a6726843d6f1a7 GIT binary patch literal 193440 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 literal 0 HcmV?d00001 From 8a16e217ad09a784332060af09b607f4560f5331 Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Mon, 7 Aug 2023 20:37:29 +0300 Subject: [PATCH 100/165] Update POST.md --- .../2023-08-07-Basic-Theme-Dark-Mode/POST.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md b/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md index f079c71546..01f17777ad 100644 --- a/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md +++ b/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md @@ -1,18 +1,18 @@ # Adding Dark Mode Support to the Basic Theme -Basic Theme uses plain bootstrap and does not have any custom colors & styles. This article will show you how to add dark mode support to the Basic Theme. +Basic Theme uses plain bootstrap and does not have any custom colors & styles. This article will show you how to add dark mode support to the [Basic Theme](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Basic-Theme). -Bootstrap brings [Color Modes](https://getbootstrap.com/docs/5.3/customize/color-modes/#dark-mode) feature with the version **5.3**. This feature allows you to add dark mode support to your website with a single line of code. Adding `data-bs-theme="dark"` attribute, changes the color mode of the element to dark mode. +Bootstrap brings [Color Modes](https://getbootstrap.com/docs/5.3/customize/color-modes/#dark-mode) feature with the version **5.3**. This feature allows you to add dark mode support to your website with a single line of code. Adding the `data-bs-theme="dark"` attribute changes the color mode of the element to dark mode. ## Instructions -1. Create a new project +1. Create a new project with the following command: ```bash abp new BasicThemeDarkMode -t app --theme basic ``` 2. Create a component that toggles the color mode. - - Create a new file named `Components/ChangeTheme/Default.cshtml` + - Create a new file named `Components/ChangeTheme/Default.cshtml`: ```html

``` - - Create a new file named `Components/ChangeTheme/ChangeThemeViewComponent.cs` + - Create a new file named `Components/ChangeTheme/ChangeThemeViewComponent.cs`: ```csharp using Microsoft.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc; @@ -38,9 +38,9 @@ Bootstrap brings [Color Modes](https://getbootstrap.com/docs/5.3/customize/color } ``` - - Create a JavaScript that manages last selected theme and toggles the color mode. It stores the last selected theme in the local storage. So, you don't need to store it in the database. + - Create a JavaScript that manages the last selected theme and toggles the color mode. It stores the last selected theme in the *local storage*. So, you don't need to store it in the database. - - Create a new file named `Components/ChangeTheme/ChangeTheme.js` + - Create a new file named `Components/ChangeTheme/ChangeTheme.js`: ```js $(function () { function changeTheme(theme) { @@ -71,9 +71,9 @@ Bootstrap brings [Color Modes](https://getbootstrap.com/docs/5.3/customize/color }); ``` -3. Create a new Toolbar Contributor and add newly created view component to the application toolbar. +3. Create a new [Toolbar Contributor](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Toolbars) and add a newly created view component to the application toolbar. - - Create a new class named `BasicThemeDarkModeToolbarContributor.cs` + - Create a new class named `BasicThemeDarkModeToolbarContributor.cs`: ```csharp using BasicThemeDarkMode.Web.Components.ChangeTheme; using System.Threading.Tasks; @@ -96,7 +96,7 @@ Bootstrap brings [Color Modes](https://getbootstrap.com/docs/5.3/customize/color } ``` - - Configure [Toolbar Options](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Toolbars) and add newly created contributor. + - Configure [Toolbar Options](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Toolbars) and add newly created contributor: ```csharp Configure(options => { @@ -104,7 +104,7 @@ Bootstrap brings [Color Modes](https://getbootstrap.com/docs/5.3/customize/color }); ``` -That's it! Now, you can toggle the color mode by clicking the sun icon in the toolbar. +That's it! Now, you can toggle the color mode by clicking the sun icon in the toolbar: ![Dark Mode](basictheme-toggle-demo.gif) @@ -122,4 +122,4 @@ That's it! Now, you can toggle the color mode by clicking the sun icon in the to ## Conclusion -The theme is stored in **local storage** and it's initialized in the client-side. You can use **Cookies** to render the page in the last selected theme on **server-side** to prevent the flash effect while navigating pages. This documents show the concept of adding dark mode support of bootstrap to the Basic Theme. \ No newline at end of file +The theme is stored in **local storage** and it's initialized on the client-side. You can use **Cookies** to render the page in the last selected theme on **server-side** to prevent the flash effect while navigating pages. This document shows the concept of adding dark mode support of bootstrap to the Basic Theme. From 994d3ae2b719d9657b9422d0d93e49a67a4ab28f Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 8 Aug 2023 09:22:58 +0800 Subject: [PATCH 101/165] Update AbpExceptionPageFilter.cs Close #17309 --- .../AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs index 9db528d620..31784cb6ea 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs @@ -83,7 +83,7 @@ public class AbpExceptionPageFilter : IAsyncPageFilter, ITransientDependency remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------"); remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService().Serialize(remoteServiceErrorInfo, indented: true)); - var logger = context.GetService>(NullLogger.Instance)!; + var logger = context.GetService>(NullLogger.Instance)!; logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString()); logger.LogException(context.Exception!, logLevel); From 8803e58a8f06a472217ecf3b561e9b033b12686e Mon Sep 17 00:00:00 2001 From: Hamza Albreem <94292623+braim23@users.noreply.github.com> Date: Tue, 8 Aug 2023 10:02:23 +0300 Subject: [PATCH 102/165] Update POST.md --- .../2023-08-07-Basic-Theme-Dark-Mode/POST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md b/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md index 01f17777ad..00325751ef 100644 --- a/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md +++ b/docs/en/Community-Articles/2023-08-07-Basic-Theme-Dark-Mode/POST.md @@ -1,7 +1,7 @@ # Adding Dark Mode Support to the Basic Theme Basic Theme uses plain bootstrap and does not have any custom colors & styles. This article will show you how to add dark mode support to the [Basic Theme](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Basic-Theme). -Bootstrap brings [Color Modes](https://getbootstrap.com/docs/5.3/customize/color-modes/#dark-mode) feature with the version **5.3**. This feature allows you to add dark mode support to your website with a single line of code. Adding the `data-bs-theme="dark"` attribute changes the color mode of the element to dark mode. +Bootstrap brings the [Color Modes](https://getbootstrap.com/docs/5.3/customize/color-modes/#dark-mode) feature with version **5.3**. This feature allows you to add dark mode support to your website with a single line of code. Adding the `data-bs-theme="dark"` attribute changes the color mode of the element to dark mode. ## Instructions @@ -96,7 +96,7 @@ Bootstrap brings [Color Modes](https://getbootstrap.com/docs/5.3/customize/color } ``` - - Configure [Toolbar Options](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Toolbars) and add newly created contributor: + - Configure [Toolbar Options](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Toolbars) and add a newly created contributor: ```csharp Configure(options => { From 129b1d66a8c0cef4fcafcbbc3443e380d04f1337 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Tue, 8 Aug 2023 10:22:11 +0300 Subject: [PATCH 103/165] adding document --- .../Angular/Ordering-Navigation-Elements.md | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 docs/en/UI/Angular/Ordering-Navigation-Elements.md diff --git a/docs/en/UI/Angular/Ordering-Navigation-Elements.md b/docs/en/UI/Angular/Ordering-Navigation-Elements.md new file mode 100644 index 0000000000..96a0ccbdb5 --- /dev/null +++ b/docs/en/UI/Angular/Ordering-Navigation-Elements.md @@ -0,0 +1,46 @@ + +# Sorting Navigation Elements + +When you want to add `Navigation Element` you can use `RoutesService`. For more info [click here](https://docs.abp.io/en/abp/latest/UI/Angular/Modifying-the-Menu#how-to-add-a-navigation-element). +However, in this documentation, we will talk more about how to sort navigation items via the `Routes Service` `order` attribute. + + +### Order Property +- This parameter is optional and used for sorting purposes. +- If you define this property it will be sorted by default sorting function. +- You can edit this function. + +**Default Compare Function;** +``compare-func.token.ts`` +```ts +export const SORT_COMPARE_FUNC = new InjectionToken<0 | 1 | -1>('SORT_COMPARE_FUNC'); + +export function compareFuncFactory() { + const localizationService = inject(LocalizationService); + const fn = (a,b) => { + const aName = localizationService.instant(a.name); + const bName = localizationService.instant(b.name); + + const aNumber = a.order; + const bNumber = b.order; + + if (!Number.isInteger(aNumber)) return 1; + if (!Number.isInteger(bNumber)) return -1; + + if (aNumber > bNumber) return 1 + if (aNumber < bNumber) return -1 + + if (aName > bName ) return 1; + if (aName < bName ) return -1; + + return 0 + } + return fn; +} +``` +**What this function do?** +- if order property defined, then it will be sorted by order value. +- if both navigation element has same order value then it will be sorted by name. +- If order property is not defined, it will be last element and sort by name between unordered navs. + +You can edit this sorting function behaviour as you wish. \ No newline at end of file From 7fbeef29acf9f746a194da41869078d5c7874975 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Tue, 8 Aug 2023 10:31:21 +0300 Subject: [PATCH 104/165] change file name --- ...ring-Navigation-Elements.md => Sorting-Navigation-Elements.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/en/UI/Angular/{Ordering-Navigation-Elements.md => Sorting-Navigation-Elements.md} (100%) diff --git a/docs/en/UI/Angular/Ordering-Navigation-Elements.md b/docs/en/UI/Angular/Sorting-Navigation-Elements.md similarity index 100% rename from docs/en/UI/Angular/Ordering-Navigation-Elements.md rename to docs/en/UI/Angular/Sorting-Navigation-Elements.md From 9374dd4d03064b2e8c4c731a278260cada5f0f47 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Tue, 8 Aug 2023 10:39:05 +0300 Subject: [PATCH 105/165] update --- docs/en/UI/Angular/Sorting-Navigation-Elements.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/Sorting-Navigation-Elements.md b/docs/en/UI/Angular/Sorting-Navigation-Elements.md index 96a0ccbdb5..e43de96993 100644 --- a/docs/en/UI/Angular/Sorting-Navigation-Elements.md +++ b/docs/en/UI/Angular/Sorting-Navigation-Elements.md @@ -1,8 +1,8 @@ - # Sorting Navigation Elements +This documentation is describing how navigation elements sorted and how you can change this default behaviour. When you want to add `Navigation Element` you can use `RoutesService`. For more info [click here](https://docs.abp.io/en/abp/latest/UI/Angular/Modifying-the-Menu#how-to-add-a-navigation-element). -However, in this documentation, we will talk more about how to sort navigation items via the `Routes Service` `order` attribute. +However, in this documentation, we will talk more about how to sort navigation elements via the `Routes Service` `order` attribute. ### Order Property From 2da4e5486f28e255d9a93cd264bb0eda206dcf14 Mon Sep 17 00:00:00 2001 From: Masum ULU Date: Tue, 8 Aug 2023 14:04:05 +0300 Subject: [PATCH 106/165] Add class & style property to EntityAction --- .../lib/components/grid-actions/grid-actions.component.html | 4 +++- .../theme-shared/extensions/src/lib/models/actions.ts | 2 ++ .../theme-shared/extensions/src/lib/models/entity-actions.ts | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html index 49cca7d326..2b43dceab5 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html @@ -52,7 +52,9 @@ *abpPermission="action.permission; runChangeDetection: false" (click)="action.action(data)" type="button" - class="btn btn-primary text-center" + class="btn text-center" + [class]="action.btnClass" + [style]="action.btnStyle" > { public readonly permission: string, public readonly visible: ActionPredicate = () => true, public readonly action: ActionCallback = () => {}, + public readonly btnClass?: string, + public readonly btnStyle?: string, ) {} } diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-actions.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-actions.ts index 99253c0da8..cb17b9f645 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-actions.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-actions.ts @@ -22,11 +22,15 @@ export class EntityActionsFactory extends ActionsFactory extends Action { readonly text: string; readonly icon: string; + readonly btnClass?: string; + readonly btnStyle?: string; constructor(options: EntityActionOptions) { super(options.permission || '', options.visible, options.action); this.text = options.text; this.icon = options.icon || ''; + this.btnClass = options.btnClass || 'btn-primary'; + this.btnStyle = options.btnStyle; } static create(options: EntityActionOptions) { From 74275a17ddbaa3944aa8904b69d473365d16d76c Mon Sep 17 00:00:00 2001 From: Masum ULU Date: Tue, 8 Aug 2023 15:14:15 +0300 Subject: [PATCH 107/165] Update doc. for entity-action-extensions --- docs/en/UI/Angular/Entity-Action-Extensions.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/en/UI/Angular/Entity-Action-Extensions.md b/docs/en/UI/Angular/Entity-Action-Extensions.md index 1ee0a3b70a..6a9df909fb 100644 --- a/docs/en/UI/Angular/Entity-Action-Extensions.md +++ b/docs/en/UI/Angular/Entity-Action-Extensions.md @@ -312,6 +312,8 @@ type EntityActionOptions = { icon?: string, permission?: string, visible?: ActionPredicate, + btnClass?: string, + btnStyle?: string, }; ``` @@ -322,6 +324,8 @@ As you see, passing `action` and `text` is enough to create an entity action. He - **icon** is the classes that define an icon to be placed before the text. (_default:_ `''`) - **permission** is the permission context which will be used to decide if this type of grid action should be displayed to the user or not. (_default:_ `undefined`) - **visible** is a predicate that will be used to decide if the current record should have this grid action or not. (_default:_ `() => true`) +- **btnClass** is the classes that will be applied to the button. (_default:_ `'btn btn-primary'`) +- **btnStyle** is the styles that will be applied to the button. (_default:_ `''`) You may find a full example below. @@ -339,6 +343,8 @@ const options: EntityActionOptions = { icon: 'fa fa-unlock', permission: 'AbpIdentity.Users.Update', visible: data => data.record.isLockedOut, + btnClass:'btn-warning', + btnStyle: 'margin-right: 5px;', }; const action = new EntityAction(options); From 7f2ca4e022ed5dc9d458986c1dacd05ba9d6b88b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 8 Aug 2023 15:55:02 +0300 Subject: [PATCH 108/165] Best practice: return this object from aggregate root / entity setter methods. --- docs/en/Best-Practices/Entities.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/en/Best-Practices/Entities.md b/docs/en/Best-Practices/Entities.md index 1c76469cb7..5a8c07c075 100644 --- a/docs/en/Best-Practices/Entities.md +++ b/docs/en/Best-Practices/Entities.md @@ -28,6 +28,7 @@ Every aggregate root is also an entity. So, these rules are valid for aggregate - **Do** keep the entity as always **valid** and **consistent** within its own boundary. - **Do** define properties with `private`, `protected`, `internal ` or `protected internal` setter where it is needed to protect the entity consistency and validity. - **Do** define `public `, `internal` or `protected internal` (virtual) **methods** to change the properties (with non-public setters) if necessary. + - **Do** return the entity object (`this`) from the setter methods. ### Aggregate Roots @@ -86,15 +87,16 @@ public class Issue : FullAuditedAggregateRoot //Using Guid as the key/iden Labels = new Collection(); //Always initialize the collection } - public virtual void SetTitle([NotNull] string title) + public virtual Issue SetTitle([NotNull] string title) { Title = Check.NotNullOrWhiteSpace(title, nameof(title)); //Validate + return this; } /* AddLabel & RemoveLabel methods manages the Labels collection * in a safe way (prevents adding the same label twice) */ - public virtual void AddLabel(Guid labelId) + public virtual Issue AddLabel(Guid labelId) { if (Labels.Any(l => l.LabelId == labelId)) { @@ -102,11 +104,13 @@ public class Issue : FullAuditedAggregateRoot //Using Guid as the key/iden } Labels.Add(new IssueLabel(Id, labelId)); + return this; } - public virtual void RemoveLabel(Guid labelId) + public virtual Issue RemoveLabel(Guid labelId) { Labels.RemoveAll(l => l.LabelId == labelId); + return this; } /* Close & ReOpen methods protect the consistency From 5d137a6dbf510c2c9e98b55e8d3624fb26d5de44 Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 9 Aug 2023 09:49:51 +0300 Subject: [PATCH 109/165] Update en.json --- .../AbpIoLocalization/Base/Localization/Resources/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index fb6207f8f8..6fb34a0731 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -218,7 +218,7 @@ "DetailedChangeNotes" : "Detailed Change Notes", "SeeTrainings": "See Trainings", "NoContent": "No content", - "ABPStudioBeta": "ABP Studio BETA", + "AbpStudio": "ABP Studio", "More": "More" } } From 5aed1b9a730560a96ecfb31925ad3b9a2cf64320 Mon Sep 17 00:00:00 2001 From: Masum ULU Date: Wed, 9 Aug 2023 09:50:04 +0300 Subject: [PATCH 110/165] Add icon property to NavItem model --- npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts index c673bc74e2..3afce94a0c 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts @@ -18,6 +18,7 @@ export class NavItem { order?: number; requiredPolicy?: string; visible?: NavBarPropPredicate; + icon?: string; constructor(props: Partial) { Object.assign(this, props); } From f8c9a8aec455a2e9af0286a673d51bcfdcc6c924 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Wed, 9 Aug 2023 11:15:11 +0300 Subject: [PATCH 111/165] Convert CmsKit Unified project to MongoDB --- .../CmsKitWebUnifiedModule.cs | 60 +++++-- .../EntityFrameworkCore/UnifiedDbContext.cs | 5 +- .../UnifiedDbContextFactory.cs | 4 +- .../MonbgoDB/UnifiedDbContext.cs | 33 ++++ .../Volo.CmsKit.Web.Unified.csproj | 146 ++++++++++-------- .../Volo.CmsKit.Web.Unified/appsettings.json | 3 +- 6 files changed, 167 insertions(+), 84 deletions(-) create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/MonbgoDB/UnifiedDbContext.cs diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs index f4f746a61d..585a47c127 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs @@ -10,34 +10,24 @@ using Volo.Abp.Account.Web; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Serilog; -using Volo.Abp.AuditLogging.EntityFrameworkCore; using Volo.Abp.Autofac; -using Volo.Abp.BlobStoring.Database.EntityFrameworkCore; using Volo.Abp.Data; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore.SqlServer; using Volo.Abp.FeatureManagement; -using Volo.Abp.FeatureManagement.EntityFrameworkCore; using Volo.Abp.Identity; -using Volo.Abp.Identity.EntityFrameworkCore; using Volo.Abp.Identity.Web; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.MultiTenancy; using Volo.Abp.PermissionManagement; -using Volo.Abp.PermissionManagement.EntityFrameworkCore; using Volo.Abp.PermissionManagement.HttpApi; using Volo.Abp.PermissionManagement.Identity; -using Volo.Abp.SettingManagement.EntityFrameworkCore; using Volo.Abp.Swashbuckle; using Volo.Abp.TenantManagement; -using Volo.Abp.TenantManagement.EntityFrameworkCore; using Volo.Abp.TenantManagement.Web; using Volo.Abp.Threading; using Volo.Abp.VirtualFileSystem; using Volo.CmsKit.Admin.Web; using Volo.CmsKit.Comments; -using Volo.CmsKit.EntityFrameworkCore; using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.MultiTenancy; using Volo.CmsKit.Public.Web; @@ -47,39 +37,73 @@ using Volo.CmsKit.Tags; using Volo.CmsKit.Web; using Volo.CmsKit.Web.Contents; +#if EntityFrameworkCore +using Volo.Abp.SettingManagement.EntityFrameworkCore; +using Volo.Abp.TenantManagement.EntityFrameworkCore; +using Volo.Abp.Identity.EntityFrameworkCore; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.FeatureManagement.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.SqlServer; +using Volo.Abp.BlobStoring.Database.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; +using Volo.Abp.AuditLogging.EntityFrameworkCore; +#elif MongoDB +using Volo.Abp.SettingManagement.MongoDB; +using Volo.Abp.TenantManagement.MongoDB; +using Volo.Abp.Identity.MongoDB; +using Volo.Abp.PermissionManagement.MongoDB; +using Volo.Abp.FeatureManagement.MongoDB; +using Volo.Abp.MongoDB; +using Volo.Abp.BlobStoring.Database.MongoDB; +using Volo.Abp.AuditLogging.MongoDB; +using Volo.CmsKit.MongoDB; +#endif + namespace Volo.CmsKit; [DependsOn( typeof(CmsKitWebModule), typeof(CmsKitApplicationModule), typeof(CmsKitHttpApiModule), +#if EntityFrameworkCore typeof(CmsKitEntityFrameworkCoreModule), typeof(AbpAuditLoggingEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreSqlServerModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpIdentityEntityFrameworkCoreModule), + typeof(AbpFeatureManagementEntityFrameworkCoreModule), + typeof(AbpTenantManagementEntityFrameworkCoreModule), + typeof(BlobStoringDatabaseEntityFrameworkCoreModule), +#elif MongoDB + typeof(CmsKitMongoDbModule), + typeof(AbpAuditLoggingMongoDbModule), + typeof(AbpSettingManagementMongoDbModule), + typeof(AbpPermissionManagementMongoDbModule), + typeof(AbpIdentityMongoDbModule), + typeof(AbpFeatureManagementMongoDbModule), + typeof(AbpTenantManagementMongoDbModule), + typeof(BlobStoringDatabaseMongoDbModule), +#endif typeof(AbpAutofacModule), typeof(AbpAccountWebModule), typeof(AbpAccountApplicationModule), typeof(AbpAccountHttpApiModule), - typeof(AbpEntityFrameworkCoreSqlServerModule), - typeof(AbpSettingManagementEntityFrameworkCoreModule), - typeof(AbpPermissionManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementApplicationModule), typeof(AbpPermissionManagementHttpApiModule), typeof(AbpIdentityWebModule), typeof(AbpIdentityApplicationModule), typeof(AbpIdentityHttpApiModule), - typeof(AbpIdentityEntityFrameworkCoreModule), typeof(AbpPermissionManagementDomainIdentityModule), typeof(AbpFeatureManagementApplicationModule), typeof(AbpFeatureManagementHttpApiModule), - typeof(AbpFeatureManagementEntityFrameworkCoreModule), typeof(AbpFeatureManagementWebModule), typeof(AbpTenantManagementWebModule), typeof(AbpTenantManagementApplicationModule), typeof(AbpTenantManagementHttpApiModule), - typeof(AbpTenantManagementEntityFrameworkCoreModule), typeof(AbpAspNetCoreMvcUiBasicThemeModule), typeof(AbpAspNetCoreSerilogModule), - typeof(BlobStoringDatabaseEntityFrameworkCoreModule), typeof(AbpSwashbuckleModule) )] public class CmsKitWebUnifiedModule : AbpModule @@ -95,10 +119,12 @@ public class CmsKitWebUnifiedModule : AbpModule ConfigureCmsKit(); +#if EntityFrameworkCore Configure(options => { options.UseSqlServer(); }); +#endif if (hostingEnvironment.IsDevelopment()) { diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs index 9109a772ed..cef51b6af3 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore; +#if EntityFrameworkCore +using Microsoft.EntityFrameworkCore; using Volo.Abp.AuditLogging.EntityFrameworkCore; using Volo.Abp.BlobStoring.Database.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; @@ -10,6 +11,7 @@ using Volo.Abp.TenantManagement.EntityFrameworkCore; namespace Volo.CmsKit.EntityFrameworkCore; +[ConnectionStringName("SqlServerDefault")] public class UnifiedDbContext : AbpDbContext { public UnifiedDbContext(DbContextOptions options) @@ -32,3 +34,4 @@ public class UnifiedDbContext : AbpDbContext modelBuilder.ConfigureBlobStoring(); } } +#endif diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContextFactory.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContextFactory.cs index 156a6f8ba9..481351e453 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContextFactory.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContextFactory.cs @@ -1,4 +1,5 @@ -using System.IO; +#if EntityFrameworkCore +using System.IO; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Microsoft.Extensions.Configuration; @@ -28,3 +29,4 @@ public class UnifiedDbContextFactory : IDesignTimeDbContextFactory + - - net7.0 - Volo.CmsKit - true - Volo.CmsKit-c2d31439-b723-48e2-b061-5ebd7aeb6010 - + + net7.0 + Volo.CmsKit + true + Volo.CmsKit-c2d31439-b723-48e2-b061-5ebd7aeb6010 + $(DefineConstants);MongoDB + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + - - - - - - - Public.cshtml - - + + + + + + + + + + + + - - - Always - - - Always - - + + + + + + + + + + + + + + + + + + + + + Public.cshtml + + + + + + Always + + + Always + + diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json index d351388ffd..beaba507ac 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json @@ -1,5 +1,6 @@ { "ConnectionStrings": { - "Default": "Server=(localdb)\\MSSQLLocalDB;Database=CmsKit_Unified;Trusted_Connection=True;TrustServerCertificate=True" + "SqlServerDefault": "Server=(localdb)\\MSSQLLocalDB;Database=CmsKit_Unified;Trusted_Connection=True;TrustServerCertificate=True", + "Default": "mongodb://localhost:27017/CmsKit_Unified" } } From d1ee37777d0117b163dc72c693ec85fbc11be775 Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 9 Aug 2023 12:08:10 +0300 Subject: [PATCH 112/165] Fix Tag Filter --- .../MongoDB/Blogs/MongoBlogPostRepository.cs | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs index 785ce2ec73..51a9117258 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs @@ -53,14 +53,10 @@ public class MongoBlogPostRepository : MongoDbRepository entityIdFilters = null; - if (tagId.HasValue) - { - entityIdFilters = await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken); - } + var entityIdFilters = await GetEntityIdsByTagId(tagId, cancellationToken); return await (await GetMongoQueryableAsync(cancellationToken)) - .WhereIf>(entityIdFilters != null, x => entityIdFilters.Contains(x.Id.ToString())) + .WhereIf>(entityIdFilters.Any(), x => entityIdFilters.Contains(x.Id)) .WhereIf>(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter)) .WhereIf>(blogId.HasValue, x => x.BlogId == blogId) .WhereIf>(authorId.HasValue, x => x.AuthorId == authorId) @@ -83,16 +79,12 @@ public class MongoBlogPostRepository : MongoDbRepository entityIdFilters = null; - if (tagId.HasValue) - { - entityIdFilters = await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken); - } - + var entityIdFilters = await GetEntityIdsByTagId(tagId, cancellationToken); + var usersQueryable = dbContext.Collection().AsQueryable(); var queryable = blogPostQueryable - .WhereIf(entityIdFilters != null, x => entityIdFilters.Contains(x.Id.ToString())) + .WhereIf(entityIdFilters.Any(), x => entityIdFilters.Contains(x.Id)) .WhereIf(blogId.HasValue, x => x.BlogId == blogId) .WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter)) .WhereIf(authorId.HasValue, x => x.AuthorId == authorId) @@ -118,6 +110,28 @@ public class MongoBlogPostRepository : MongoDbRepository> GetEntityIdsByTagId(Guid? tagId, CancellationToken cancellationToken) + { + var entityIdFilters = new List(); + if (!tagId.HasValue) + { + return entityIdFilters; + } + + var entityIds = + await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken); + + foreach (var entityId in entityIds) + { + if (Guid.TryParse(entityId, out var guid)) + { + entityIdFilters.Add(guid); + } + } + + return entityIdFilters; + } + public virtual async Task SlugExistsAsync(Guid blogId, [NotNull] string slug, CancellationToken cancellationToken = default) { From b2ee716b8cf7f9406cf7040cf305b5262454fed2 Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 9 Aug 2023 13:21:55 +0300 Subject: [PATCH 113/165] Update UnifiedDbContext.cs --- .../{MonbgoDB => MongoDB}/UnifiedDbContext.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) rename modules/cms-kit/host/Volo.CmsKit.Web.Unified/{MonbgoDB => MongoDB}/UnifiedDbContext.cs (91%) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/MonbgoDB/UnifiedDbContext.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/MongoDB/UnifiedDbContext.cs similarity index 91% rename from modules/cms-kit/host/Volo.CmsKit.Web.Unified/MonbgoDB/UnifiedDbContext.cs rename to modules/cms-kit/host/Volo.CmsKit.Web.Unified/MongoDB/UnifiedDbContext.cs index 78b1e09709..c998f103f5 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/MonbgoDB/UnifiedDbContext.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/MongoDB/UnifiedDbContext.cs @@ -1,5 +1,4 @@ #if MongoDB -using System.Reflection.Emit; using Volo.Abp.AuditLogging.MongoDB; using Volo.Abp.BlobStoring.Database.MongoDB; using Volo.Abp.Data; @@ -9,9 +8,8 @@ using Volo.Abp.MongoDB; using Volo.Abp.PermissionManagement.MongoDB; using Volo.Abp.SettingManagement.MongoDB; using Volo.Abp.TenantManagement.MongoDB; -using Volo.CmsKit.MongoDB; -namespace Volo.CmsKit.MonbgoDB; +namespace Volo.CmsKit.MongoDB; [ConnectionStringName("MongoDBDefault")] public class UnifiedDbContext : AbpMongoDbContext From 3ca026ad0f290cac55ab7dd4840b12d8aa51a125 Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 9 Aug 2023 13:22:49 +0300 Subject: [PATCH 114/165] Update MongoBlogPostRepository.cs --- .../Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs index 51a9117258..d3ae31926b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs @@ -123,9 +123,9 @@ public class MongoBlogPostRepository : MongoDbRepository Date: Wed, 9 Aug 2023 13:34:43 +0300 Subject: [PATCH 115/165] Update UnifiedDbContext.cs --- .../host/Volo.CmsKit.Web.Unified/MongoDB/UnifiedDbContext.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/MongoDB/UnifiedDbContext.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/MongoDB/UnifiedDbContext.cs index c998f103f5..45316705b4 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/MongoDB/UnifiedDbContext.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/MongoDB/UnifiedDbContext.cs @@ -1,7 +1,6 @@ #if MongoDB using Volo.Abp.AuditLogging.MongoDB; using Volo.Abp.BlobStoring.Database.MongoDB; -using Volo.Abp.Data; using Volo.Abp.FeatureManagement.MongoDB; using Volo.Abp.Identity.MongoDB; using Volo.Abp.MongoDB; @@ -11,7 +10,6 @@ using Volo.Abp.TenantManagement.MongoDB; namespace Volo.CmsKit.MongoDB; -[ConnectionStringName("MongoDBDefault")] public class UnifiedDbContext : AbpMongoDbContext { protected override void CreateModel(IMongoModelBuilder modelBuilder) From 7128033f9201c7cd9f3a8fcd290362a6bc427e13 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Wed, 9 Aug 2023 14:18:03 +0300 Subject: [PATCH 116/165] Use separate appsettings for MongoDb --- .../Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs | 1 + .../EntityFrameworkCore/UnifiedDbContext.cs | 2 +- modules/cms-kit/host/Volo.CmsKit.Web.Unified/Program.cs | 8 ++++++++ .../host/Volo.CmsKit.Web.Unified/appsettings.MongoDB.json | 5 +++++ .../cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json | 3 +-- 5 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.MongoDB.json diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs index 585a47c127..0ab0ae4d6d 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs @@ -120,6 +120,7 @@ public class CmsKitWebUnifiedModule : AbpModule ConfigureCmsKit(); #if EntityFrameworkCore + context.Services.AddDbContext(); Configure(options => { options.UseSqlServer(); diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs index cef51b6af3..9770d8ea1c 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs @@ -2,6 +2,7 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.AuditLogging.EntityFrameworkCore; using Volo.Abp.BlobStoring.Database.EntityFrameworkCore; +using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.FeatureManagement.EntityFrameworkCore; using Volo.Abp.Identity.EntityFrameworkCore; @@ -11,7 +12,6 @@ using Volo.Abp.TenantManagement.EntityFrameworkCore; namespace Volo.CmsKit.EntityFrameworkCore; -[ConnectionStringName("SqlServerDefault")] public class UnifiedDbContext : AbpDbContext { public UnifiedDbContext(DbContextOptions options) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Program.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Program.cs index 0c1ab52b43..22ea35327e 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Program.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Program.cs @@ -1,6 +1,7 @@ using System; using System.IO; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -38,6 +39,13 @@ public class Program internal static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) + .AddAppSettingsSecretsJson() +#if MongoDB + .ConfigureAppConfiguration(options => + { + options.AddJsonFile("appsettings.MongoDB.json"); + }) +#endif .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.MongoDB.json b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.MongoDB.json new file mode 100644 index 0000000000..73fc167f65 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.MongoDB.json @@ -0,0 +1,5 @@ +{ + "ConnectionStrings": { + "Default": "mongodb://localhost:27017/CmsKit_Unified" + } +} \ No newline at end of file diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json index beaba507ac..d351388ffd 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json @@ -1,6 +1,5 @@ { "ConnectionStrings": { - "SqlServerDefault": "Server=(localdb)\\MSSQLLocalDB;Database=CmsKit_Unified;Trusted_Connection=True;TrustServerCertificate=True", - "Default": "mongodb://localhost:27017/CmsKit_Unified" + "Default": "Server=(localdb)\\MSSQLLocalDB;Database=CmsKit_Unified;Trusted_Connection=True;TrustServerCertificate=True" } } From d4967779d8cca000d9e0d6df86161ca29107e5ad Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Wed, 9 Aug 2023 14:19:10 +0300 Subject: [PATCH 117/165] Revert formatting on csproj --- .../Volo.CmsKit.Web.Unified.csproj | 158 +++++++++--------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj index 8c0f979e3e..8ad50d3b05 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj @@ -1,89 +1,89 @@  - - net7.0 - Volo.CmsKit - true - Volo.CmsKit-c2d31439-b723-48e2-b061-5ebd7aeb6010 - $(DefineConstants);MongoDB - + + net7.0 + Volo.CmsKit + true + Volo.CmsKit-c2d31439-b723-48e2-b061-5ebd7aeb6010 + $(DefineConstants);MongoDB + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - Public.cshtml - - + + + - - - Always - - - Always - - + + + + + + + Public.cshtml + + + + + + Always + + + Always + + From 8165ecba8f88ce2b1faadfb6b5872b643efd7cd2 Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 9 Aug 2023 14:52:51 +0300 Subject: [PATCH 118/165] Update en.json --- .../Commercial/Localization/Resources/en.json | 77 ++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 96aaa28e13..1d977e3351 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -983,6 +983,81 @@ "TrainingPackDiscount": "Training pack discount", "Purchase_OnboardingTraining_Description": "This live training package is discounted when purchase with the new license. This discounted price is valid only for new license purchases.
Learn more ", "Purchase_Save": "{0}% Save {1} {2}", - "RemoveBasket": "Remove from basket" + "RemoveBasket": "Remove from basket", + "WhyABPIOPlatform?": "Why ABP.IO Platform?", + "DocumentAim": "This document aims to answer the big question:", + "DocumentAim_Description": "\"Why should you use the ABP.IO Platform instead of creating a new solution from scratch?\"", + "DocumentAim_Description2": "The document introduces the challenges of building a modern software solution and explains how ABP addresses these challenges.", + "CreatingANewSolution": "Creating a New Solution", + "CreatingANewSolution_Description": "When you need to start a new solution, there are a lot of questions you need to ask yourself, and you should spend a lot of time before starting to write your very first business code.", + "CreatingAnEmptySolution": "Creating an Empty Solution", + "THEPROBLEM": "THE PROBLEM", + "CreatingAnEmptySolution_THEPROBLEM_Description": "Even creating an almost-empty solution is challenging;", + "CreatingAnEmptySolution_THEPROBLEM_Description2": "How do you organize your codebase across projects?", + "CreatingAnEmptySolution_THEPROBLEM_Description3": "What are the layers and how do they interact?", + "CreatingAnEmptySolution_THEPROBLEM_Description4": "How do you integrate to 3rd-party library and systems?", + "CreatingAnEmptySolution_THEPROBLEM_Description5": "How to set up the automated tests?", + "ABPSOLUTION": "ABP SOLUTION", + "CreatingAnEmptySolution_ABPSOLUTION_Description": "ABP provides a well-architected, layered and production-ready startup solution based on the Domain Driven Design principles. The solution also includes a pre-configured unit and integration test projects for each layer.", + "CommonLibraries": "Common Libraries", + "CommonLibraries_THEPROBLEM_Description": "Which libraries should you use to implement common requirements? The software development ecosystem is highly dynamic and it is hard to follow the latest tools, libraries, trends and approaches.", + "CommonLibraries_ABPSOLUTION_Description": "ABP pre-integrates the popular, mature and up-to-date libraries into the solution. You don't spend time integrating them and talking to each other. They properly work out of the box.", + "UITheme&Layout": "UI Theme & Layout", + "UITheme&Layout_THEPROBLEM_Description": "When it comes to the UI, there are a lot of challenges, including preparing a foundation to create a responsive, modern and flexible UI kit with a consistent look & feel and tons of features (like left/top navigation menu, header, toolbar, footer, widgets and so.).", + "UITheme&Layout_THEPROBLEM_Description2": "Even if you buy a pre-built theme, integrating it into your solution may take days of development. Upgrading such a theme is another problem. Most of the time, the theme's HTML/CSS structure is mixed with your UI code, and it is not easy to upgrade or change the theme later.", + "UITheme&Layout_ABPSOLUTION_Description": "ABP Framework provides a theming system that makes your UI code independent from the theme. Themes are isolated, and they are NuGet/NPM packages. Installing or upgrading a theme is just a minute. While you can build your theme (or integrate an existing theme), ABP Commercial offers professional and modern themes.There are also UI component providers (like Telerik and DevExpress). But they only provide individual components. You are responsible for creating your own layout system. You can use such libraries in your ABP-based solutions just like in any other project.", + "TestInfrastructure": "Test Infrastructure", + "TestInfrastructure_THEPROBLEM_Description": "Which libraries should you use to implement common requirements? The software development ecosystem is highly dynamic and it is hard to follow the latest tools, libraries, trends and approaches.", + "TestInfrastructure_ABPSOLUTION_Description": "ABP Startup Templates comes with the test projects already configured for you, and you can immediately write your first unit or integration test code on day 1. Writing unit tests is very clear with the ABP Framework; see how to write tests.", + "CodingStandards&Training": "Coding Standards & Training", + "CodingStandards&Training_THEPROBLEM_Description": "Once you create the development-ready solution, you typically need to train the developers to explain the system and develop it with the same conventions in a standard and consistent way. Even if you train the developers, it is hard to prepare and maintain your documentation. Over time, every developer will write the code differently, and coding standards will begin to diverge.", + "CodingStandards&Training_ABPSOLUTION_Description": "ABP solution is already well-defined and well-documented. Tutorials and best practice guides clearly explain how to make development on an ABP project.", + "KeepingYourSolutionUpToDate": "Keeping Your Solution Up to Date", + "KeepingYourSolutionUpToDate_THEPROBLEM_Description": "After you start your development, you must keep track of the new versions of the libraries you use for upgrades & patches. We regularly update all packages to the latest versions and test them before the stable release. When you update the ABP Framework, all its dependencies are upgraded to edge technology.", + "KeepingYourSolutionUpToDate_ABPSOLUTION_Description": "Abp update CLI command automatically discovers and upgrades all ABP-dependant NuGet and NPM packages in a solution. With ABP, it is easier to stay with the latest versions.", + "DRY": "Don't Repeat Yourself!", + "DRY_Description": "Creating a base solution takes significant time and requires well architectural experience. However, this is just the beginning! As you start developing, you will likely have to write lots of repetitive code; that would be great if all this could be handled automatically.", + "DRY_Description2": "ABP automates and simplifies repeating code as much as possible by following the convention over configuration principle. However, it doesn't restrict you when you need to switch to manual gear. The control is always in your hands.", + "Authentication": "Authentication", + "Authentication_THEPROBLEM_Description": "Single Sign On, Active Directory / LDAP Integration, OpenIddict integration, social logins, two-factor authentication, forgot/reset password, email activation, new user registration, password complexity control, locking account on failed attempts, showing failed login attemps ... etc. We know that all these generic requirements are familiar to you. You are not alone!", + "Authentication_ABPSOLUTION_Description": "ABP Framework and the commercial version provide all these standard stuff pre-implemented for you as a re-usable account module. You just enable and configure what you need.", + "CrossCuttingConcerns": "Cross-Cutting Concerns", + "CrossCuttingConcerns_THEPROBLEM_Description": "Cross-Cutting Concerns are the fundamental repeating logic that should be implementedfor each use case. Some examples;", + "CrossCuttingConcerns_ABPSOLUTION_Description": "ABP Framework automates or simplifies all the common cross-cutting concerns. You only write code that matters for your business and ABP handles the rest by conventions.", + "ArchitecturalInfrastructure": "Architectural Infrastructure", + "ArchitecturalInfrastructure_THEPROBLEM_Description": "You typically need to build infrastructure to implement your architecture properly. For example, you generally implement the Repository pattern. You define some base classes to simplify and standardize to create entities, services, controllers and other objects.", + "ArchitecturalInfrastructure_ABPSOLUTION_Description": "ABP Framework provides all these and more out of the box. It is mature and well-documented.", + "EnterpriseApplicationRequirements": "Enterprise Application Requirements", + "EnterpriseApplicationRequirements_THEPROBLEM_Description": "There are a lot of requirements you repeatedly implement in every business application;", + "EnterpriseApplicationRequirements_ABPSOLUTION_Description": "There is much more. ABP provides infrastructure to implement such requirements easily. Again, you don't spend your valuable time to re-implement all these again and again.", + "GeneratingInitialCode&Tooling": "Generating Initial Code & Tooling", + "GeneratingInitialCode&Tooling_THEPROBLEM_Description": "ABP Suite can generate a full-stack CRUD page for your entities in seconds. The generated code is layered and clean. All the standard validation and authorization requirements are implemented. Plus, unit test classes are generated. Once you get a fully running page, you can modify it according to your business requirements.", + "GeneratingInitialCode&Tooling_ABPSOLUTION_Description": "ABP Framework provides all these and more out of the box. It is mature and well-documented.", + "IntegratingTo3rdPartyLibrariesAndSystems": "Integrating to 3rd-Party Libraries and Systems", + "IntegratingTo3rdPartyLibrariesAndSystems_THEPROBLEM_Description": "Most libraries are designed as low level, and you typically do some work to integrate them properly without repeating the same integration and configuration code everywhere in your solution. For example, assume you must use RabbitMQ to implement your distributed event bus. All you want to do is; send a message to a queue and handle the incoming messages. But you need to understand messaging patterns, queue and exchange details. To write an efficient code, you must create a pool to manage connections, clients and channels. You also must deal with exceptions, ACK messages, re-connecting to RabbitMQ on failures and more.", + "IntegratingTo3rdPartyLibrariesAndSystems_ABPSOLUTION_Description": "ABP's RabbitMQ Distributed Event Bus integration abstracts all these details. You send and receive messages without the hustle and bustle. Do you need to write low-level code? No problem, you can always do that. ABP doesn't restrict you when you need to use low-level features of the library you are using.", + "WhyNotBuildYourOwnFramework?": "Why Not Build Your Own Framework?", + "WhyNotBuildYourOwnFramework_THEPROBLEM_Description": "All the infrastructure, even in the most simple way, takes a lot of time to build, maintain and document. It gets bigger over time, and it becomes hard to maintain it in your solution. Separating these into a re-usable project is the starting point for building your own internal framework.", + "WhyNotBuildYourOwnFramework_ABPSOLUTION_Description": "Building, documenting, training and maintaining an internal framework is really hard. If you don't have an experienced, dedicated framework team, your internal framework rapidly becomes an undocumented legacy code that no one can understand and maintain anymore. On the other hand, these frameworks are generally developed by one or two developers in the team. And these fellows are becoming a knowledge silo. It is good for them but bad for the company because they are the project's single point of failure -SPOF-. Once they leave the company, the project dramatically goes down.", + "TonsOfFeatures": "Tons of Features", + "TonesOfFeatures_Description": "Tag helpers, dynamic forms, BLOB storing system and many other ABP features help you keep DRY (don't repeat yourself) and focus on your business.", + "ArchitecturalInfrastructure_Description": "SaaS applications, modular or microservice systems are most used enterprise software models. Building such systems not only requires a good understanding and experience, but also requires a strong software infrastructure. Otherwise, you will find yourself spending a great effort to support these architectural details in your codebase.", + "Modularity": "Modularity", + "Modularity_THEPROBLEM_Description": "Building a truly modular system is not easy! All the aspects of the system (database, entities, APIs, UI pages/components) can be split into modules, and each module can be re-usable without others. The plain ASP.NET Core doesn't provide such a modular architecture. If you need it, you should think about it from scratch.", + "Modularity_ABPSOLUTION_Description": "The ABP Framework is born to be a modular application development structure. Every feature in the framework is developed to be compatible with modularity. Documentation and guides explain how to develop re-usable modules in a standard way.", + "SaaSMultiTenancy": "SaaS / Multi-Tenancy", + "SaaSMultiTenancy_THEPROBLEM_Description": "Multi-Tenancy is a common way to implement SaaS systems. However, implementing a consistent multi-tenant infrastructure may become complicated.", + "SaaSMultiTenancy_ABPSOLUTION_Description": "ABP Framework provides a complete multi-tenant infrastructure and abstract complexity from your business code. Your application code will be mostly multi-tenancy aware while the ABP Framework automatically isolates the database, cache and other details of the tenants from each other. It supports single database, per tenant database and hybrid approaches. It properly configures the libraries like Microsoft Identity, IdentityServer, OpenIddict, which are not normally multi-tenancy compatible.", + "Microservices": "Microservices", + "Microservices_THEPROBLEM_Description": "Building a microservice system requires many infrastructure details: Authenticating and authorizing applications and microservices and implementing asynchronous messaging and synchronous (Rest/GRPC) communication patterns between microservices are the most fundamental issues.", + "Microservices_ABPSOLUTION_Description": "The ABP Framework provides services, guides, and samples to help you implement your microservice solution using the industry standard tools. ABP Commercial even goes one step further and provides a complete startup template to kick-start your microservice solution.", + "PreBuiltModules": "Pre-Built Modules", + "PreBuiltModules_THEPROBLEM_Description": "All of us have similar but slightly different business requirements. However, we all should re-invent the wheel since no one's code can directly work in our solution. They are all embedded parts of a larger solution.", + "PreBuiltModules_ABPSOLUTION_Description":"ABP Commercial modules provides a lot of re-usable application modules like payment, chat, file management, audit log reporting... etc. All of these modules are easily installed into your solution and directly work. We are constantly adding more modules.", + "PreBuiltModules_ABPSOLUTION_Description2": "All modules are designed as customizable for your business requirements. If you need complete control, you can download the full source code of any module and completely customize based on your specific business requirements.", + "ABPCommunity": "ABP Community", + "ABPCommunity_Description": "Being in a big community where everyone follows similar coding styles and principles and shares a common infrastructure brings power when you have troubles or need help with design decisions. Since we write code similarly, we can help each other much better. ABP is a community-backed project with almost 10K stars on GitHub.", + "ABPCommunity_Description2": "It is easy to share code or even re-usable libraries between ABP developers. A code snippet that works for you will also work for others. There are a lot of samples and tutorials that you can directly implement for your application.", + "ABPCommunity_Description3": "When you hire a developer who worked before with the ABP architecture will immediately understand your solution and start development in a very short time." } } From 8eb5e495097a5ed8337c2028dfae32f34056e518 Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 9 Aug 2023 15:22:49 +0300 Subject: [PATCH 119/165] Update en.json --- .../AbpIoLocalization/Base/Localization/Resources/en.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index fb6207f8f8..dc740e04e2 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -219,6 +219,7 @@ "SeeTrainings": "See Trainings", "NoContent": "No content", "ABPStudioBeta": "ABP Studio BETA", - "More": "More" + "More": "More", + "WhyABPIOPlatform": "Why ABP.IO Platform" } } From 4f0c6022d1dea13a7848beb1486de4e26105831d Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 9 Aug 2023 15:45:47 +0300 Subject: [PATCH 120/165] Update en.json --- .../AbpIoLocalization/Base/Localization/Resources/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index f2ca45a612..45d2b733ac 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -219,7 +219,7 @@ "SeeTrainings": "See Trainings", "NoContent": "No content", "More": "More", - "WhyABPIOPlatform": "Why ABP.IO Platform" - "AbpStudio": "ABP Studio", + "WhyABPIOPlatform": "Why ABP.IO Platform", + "AbpStudio": "ABP Studio" } } From da4b48b828ee1362a0edbf2f04d6c2f3101543a9 Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 9 Aug 2023 16:11:05 +0300 Subject: [PATCH 121/165] Update en.json --- .../AbpIoLocalization/Admin/Localization/Resources/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index 8333e0efbe..0fe0147c87 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -470,7 +470,7 @@ "SubTotal": "Sub Total", "TotalDue": "Total Due", "QuotationNo": "Quotation no", - "ValidFor": "Valid for", + "ValidTill": "Valid till", "QuotationNote": "Quotation note", "QuotationTemplate.Address": "Address", "QuotationTemplate.Address:": "Address:", @@ -482,7 +482,7 @@ "QuotationTemplate.Details": "Details", "QuotationTemplate.QuotationNo:": "Quotation:", "QuotationTemplate.IssueDate:": "Issue Date:", - "QuotationTemplate.ValidFor:": "Valid For:", + "QuotationTemplate.ValidTill:": "Valid Till:", "QuotationTemplate.ValidDays": "{0} Days", "QuotationTemplate.Description": "Description", "QuotationTemplate.UnitPrice": "Unit Price", From 19df30d344ac62f86527a1e0c44d3d58b6828528 Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 9 Aug 2023 16:18:52 +0300 Subject: [PATCH 122/165] Update en.json --- .../AbpIoLocalization/Base/Localization/Resources/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index 45d2b733ac..9ef432a8bd 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -213,13 +213,13 @@ "SpringCampaign": "Welcome
Spring Sale!", "SpringCampaign2": "Limited
Time Offer!
", "AboutUs": "About Us", - "HowItWorks": "How it works?", + "HowItWorks": "How it Works?", "ReleaseNotes": "Release Notes", "DetailedChangeNotes" : "Detailed Change Notes", "SeeTrainings": "See Trainings", "NoContent": "No content", "More": "More", - "WhyABPIOPlatform": "Why ABP.IO Platform", + "WhyABPIOPlatform": "Why ABP.IO Platform?", "AbpStudio": "ABP Studio" } } From 5f7a8aa0885ae58dafd9f02df9566ebb13291af3 Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 9 Aug 2023 18:32:04 +0300 Subject: [PATCH 123/165] Update en.json --- .../Commercial/Localization/Resources/en.json | 52 ++++++++++++------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 1d977e3351..9ea157bc3d 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -998,23 +998,25 @@ "CreatingAnEmptySolution_THEPROBLEM_Description4": "How do you integrate to 3rd-party library and systems?", "CreatingAnEmptySolution_THEPROBLEM_Description5": "How to set up the automated tests?", "ABPSOLUTION": "ABP SOLUTION", - "CreatingAnEmptySolution_ABPSOLUTION_Description": "ABP provides a well-architected, layered and production-ready startup solution based on the Domain Driven Design principles. The solution also includes a pre-configured unit and integration test projects for each layer.", + "CreatingAnEmptySolution_ABPSOLUTION_Description": "ABP provides a well-architected, layered and production-ready startup solution based on the Domain Driven Design principles. The solution also includes a pre-configured unit and integration test projects for each layer.", "CommonLibraries": "Common Libraries", "CommonLibraries_THEPROBLEM_Description": "Which libraries should you use to implement common requirements? The software development ecosystem is highly dynamic and it is hard to follow the latest tools, libraries, trends and approaches.", "CommonLibraries_ABPSOLUTION_Description": "ABP pre-integrates the popular, mature and up-to-date libraries into the solution. You don't spend time integrating them and talking to each other. They properly work out of the box.", "UITheme&Layout": "UI Theme & Layout", "UITheme&Layout_THEPROBLEM_Description": "When it comes to the UI, there are a lot of challenges, including preparing a foundation to create a responsive, modern and flexible UI kit with a consistent look & feel and tons of features (like left/top navigation menu, header, toolbar, footer, widgets and so.).", "UITheme&Layout_THEPROBLEM_Description2": "Even if you buy a pre-built theme, integrating it into your solution may take days of development. Upgrading such a theme is another problem. Most of the time, the theme's HTML/CSS structure is mixed with your UI code, and it is not easy to upgrade or change the theme later.", - "UITheme&Layout_ABPSOLUTION_Description": "ABP Framework provides a theming system that makes your UI code independent from the theme. Themes are isolated, and they are NuGet/NPM packages. Installing or upgrading a theme is just a minute. While you can build your theme (or integrate an existing theme), ABP Commercial offers professional and modern themes.There are also UI component providers (like Telerik and DevExpress). But they only provide individual components. You are responsible for creating your own layout system. You can use such libraries in your ABP-based solutions just like in any other project.", + "UITheme&Layout_ABPSOLUTION_Description": "ABP Framework provides a theming system that makes your UI code independent from the theme. Themes are isolated, and they are NuGet/NPM packages. Installing or upgrading a theme is just a minute. While you can build your theme (or integrate an existing theme), ABP Commercial offers professional and modern themes.", + "UITheme&Layout_ABPSOLUTION_Description2": "There are also UI component providers (like Telerik and DevExpress). But they only provide individual components. You are responsible for creating your own layout system. You can use such libraries in your ABP-based solutions just like in any other project.", "TestInfrastructure": "Test Infrastructure", - "TestInfrastructure_THEPROBLEM_Description": "Which libraries should you use to implement common requirements? The software development ecosystem is highly dynamic and it is hard to follow the latest tools, libraries, trends and approaches.", - "TestInfrastructure_ABPSOLUTION_Description": "ABP Startup Templates comes with the test projects already configured for you, and you can immediately write your first unit or integration test code on day 1. Writing unit tests is very clear with the ABP Framework; see how to write tests.", + "TestInfrastructure_THEPROBLEM_Description": "Preparing a robust test environment takes time. You need to setup test projects in your solution, select the tools, mock the services and database, create the required base classes and utility services to reduce repeating code in the tests and so on.", + "TestInfrastructure_ABPSOLUTION_Description": "ABP Startup Templates comes with the test projects already configured for you, and you can immediately write your first unit or integration test code on day 1.", "CodingStandards&Training": "Coding Standards & Training", "CodingStandards&Training_THEPROBLEM_Description": "Once you create the development-ready solution, you typically need to train the developers to explain the system and develop it with the same conventions in a standard and consistent way. Even if you train the developers, it is hard to prepare and maintain your documentation. Over time, every developer will write the code differently, and coding standards will begin to diverge.", - "CodingStandards&Training_ABPSOLUTION_Description": "ABP solution is already well-defined and well-documented. Tutorials and best practice guides clearly explain how to make development on an ABP project.", + "CodingStandards&Training_ABPSOLUTION_Description": "ABP solution is already well-defined and well-documented. Tutorials and best practice guides clearly explain how to make development on an ABP project.", "KeepingYourSolutionUpToDate": "Keeping Your Solution Up to Date", - "KeepingYourSolutionUpToDate_THEPROBLEM_Description": "After you start your development, you must keep track of the new versions of the libraries you use for upgrades & patches. We regularly update all packages to the latest versions and test them before the stable release. When you update the ABP Framework, all its dependencies are upgraded to edge technology.", - "KeepingYourSolutionUpToDate_ABPSOLUTION_Description": "Abp update CLI command automatically discovers and upgrades all ABP-dependant NuGet and NPM packages in a solution. With ABP, it is easier to stay with the latest versions.", + "KeepingYourSolutionUpToDate_THEPROBLEM_Description": "After you start your development, you must keep track of the new versions of the libraries you use for upgrades & patches.", + "KeepingYourSolutionUpToDate_ABPSOLUTION_Description": "We regularly update all packages to the latest versions and test them before the stable release. When you update the ABP Framework, all its dependencies are upgraded to edge technology.", + "KeepingYourSolutionUpToDate_ABPSOLUTION_Description2": "Abp update CLI command automatically discovers and upgrades all ABP-dependant NuGet and NPM packages in a solution. With ABP, it is easier to stay with the latest versions.", "DRY": "Don't Repeat Yourself!", "DRY_Description": "Creating a base solution takes significant time and requires well architectural experience. However, this is just the beginning! As you start developing, you will likely have to write lots of repetitive code; that would be great if all this could be handled automatically.", "DRY_Description2": "ABP automates and simplifies repeating code as much as possible by following the convention over configuration principle. However, it doesn't restrict you when you need to switch to manual gear. The control is always in your hands.", @@ -1023,41 +1025,53 @@ "Authentication_ABPSOLUTION_Description": "ABP Framework and the commercial version provide all these standard stuff pre-implemented for you as a re-usable account module. You just enable and configure what you need.", "CrossCuttingConcerns": "Cross-Cutting Concerns", "CrossCuttingConcerns_THEPROBLEM_Description": "Cross-Cutting Concerns are the fundamental repeating logic that should be implementedfor each use case. Some examples;", + "CrossCuttingConcerns_THEPROBLEM_Description2": "Starting transactions, committing on success and rollback on errors.", + "CrossCuttingConcerns_THEPROBLEM_Description3": "Handling and reporting exceptions, returning a proper error response to the clients and handling error cases on the client-side.", + "CrossCuttingConcerns_THEPROBLEM_Description4": "Implementing authorization and validation, returning proper responses and handling these on the client-side.", "CrossCuttingConcerns_ABPSOLUTION_Description": "ABP Framework automates or simplifies all the common cross-cutting concerns. You only write code that matters for your business and ABP handles the rest by conventions.", "ArchitecturalInfrastructure": "Architectural Infrastructure", "ArchitecturalInfrastructure_THEPROBLEM_Description": "You typically need to build infrastructure to implement your architecture properly. For example, you generally implement the Repository pattern. You define some base classes to simplify and standardize to create entities, services, controllers and other objects.", "ArchitecturalInfrastructure_ABPSOLUTION_Description": "ABP Framework provides all these and more out of the box. It is mature and well-documented.", "EnterpriseApplicationRequirements": "Enterprise Application Requirements", "EnterpriseApplicationRequirements_THEPROBLEM_Description": "There are a lot of requirements you repeatedly implement in every business application;", + "EnterpriseApplicationRequirements_THEPROBLEM_Description2": "Detailed permission system and managing permissions on the UI based on roles and users.", + "EnterpriseApplicationRequirements_THEPROBLEM_Description3": "Writing audit logs and entity histories to track when a user modifies a database record.", + "EnterpriseApplicationRequirements_THEPROBLEM_Description4": "Make your entities soft delete, so they are marked as deleted instead of physically deleting from the database and automatically filtering deleted entities on your queries.", + "EnterpriseApplicationRequirements_THEPROBLEM_Description5": "Creating abstractions and wrappers to consume your backend APIs from the frontend code.", + "EnterpriseApplicationRequirements_THEPROBLEM_Description6": "Enqueuing and executing background jobs.", + "EnterpriseApplicationRequirements_THEPROBLEM_Description7": "Handling multiple time zones in a global system.", + "EnterpriseApplicationRequirements_THEPROBLEM_Description8": "Sharing validation, localization, authorization logic between server and client.", "EnterpriseApplicationRequirements_ABPSOLUTION_Description": "There is much more. ABP provides infrastructure to implement such requirements easily. Again, you don't spend your valuable time to re-implement all these again and again.", "GeneratingInitialCode&Tooling": "Generating Initial Code & Tooling", - "GeneratingInitialCode&Tooling_THEPROBLEM_Description": "ABP Suite can generate a full-stack CRUD page for your entities in seconds. The generated code is layered and clean. All the standard validation and authorization requirements are implemented. Plus, unit test classes are generated. Once you get a fully running page, you can modify it according to your business requirements.", - "GeneratingInitialCode&Tooling_ABPSOLUTION_Description": "ABP Framework provides all these and more out of the box. It is mature and well-documented.", + "GeneratingInitialCode&Tooling_THEPROBLEM_Description": "You will build many similar pages in a typical web application. Most of them will perform similar CRUD operations. It is very tedious and also error prone to repeatedly create such pages.", + "GeneratingInitialCode&Tooling_ABPSOLUTION_Description": "ABP Suite can generate a full-stack CRUD page for your entities in seconds. The generated code is layered and clean. All the standard validation and authorization requirements are implemented. Plus, unit test classes are generated. Once you get a fully running page, you can modify it according to your business requirements.", "IntegratingTo3rdPartyLibrariesAndSystems": "Integrating to 3rd-Party Libraries and Systems", "IntegratingTo3rdPartyLibrariesAndSystems_THEPROBLEM_Description": "Most libraries are designed as low level, and you typically do some work to integrate them properly without repeating the same integration and configuration code everywhere in your solution. For example, assume you must use RabbitMQ to implement your distributed event bus. All you want to do is; send a message to a queue and handle the incoming messages. But you need to understand messaging patterns, queue and exchange details. To write an efficient code, you must create a pool to manage connections, clients and channels. You also must deal with exceptions, ACK messages, re-connecting to RabbitMQ on failures and more.", - "IntegratingTo3rdPartyLibrariesAndSystems_ABPSOLUTION_Description": "ABP's RabbitMQ Distributed Event Bus integration abstracts all these details. You send and receive messages without the hustle and bustle. Do you need to write low-level code? No problem, you can always do that. ABP doesn't restrict you when you need to use low-level features of the library you are using.", + "IntegratingTo3rdPartyLibrariesAndSystems_ABPSOLUTION_Description": "For example, ABP's RabbitMQ Distributed Event Bus integration abstracts all these details. You send and receive messages without the hustle and bustle. Do you need to write low-level code? No problem, you can always do that. ABP doesn't restrict you when you need to use low-level features of the library you are using.", "WhyNotBuildYourOwnFramework?": "Why Not Build Your Own Framework?", "WhyNotBuildYourOwnFramework_THEPROBLEM_Description": "All the infrastructure, even in the most simple way, takes a lot of time to build, maintain and document. It gets bigger over time, and it becomes hard to maintain it in your solution. Separating these into a re-usable project is the starting point for building your own internal framework.", - "WhyNotBuildYourOwnFramework_ABPSOLUTION_Description": "Building, documenting, training and maintaining an internal framework is really hard. If you don't have an experienced, dedicated framework team, your internal framework rapidly becomes an undocumented legacy code that no one can understand and maintain anymore. On the other hand, these frameworks are generally developed by one or two developers in the team. And these fellows are becoming a knowledge silo. It is good for them but bad for the company because they are the project's single point of failure -SPOF-. Once they leave the company, the project dramatically goes down.", - "TonsOfFeatures": "Tons of Features", - "TonesOfFeatures_Description": "Tag helpers, dynamic forms, BLOB storing system and many other ABP features help you keep DRY (don't repeat yourself) and focus on your business.", + "WhyNotBuildYourOwnFramework_THEPROBLEM_Description2": "Building, documenting, training and maintaining an internal framework is really hard. If you don't have an experienced, dedicated framework team, your internal framework rapidly becomes an undocumented legacy code that no one can understand and maintain anymore. On the other hand, these frameworks are generally developed by one or two developers in the team. And these fellows are becoming a knowledge silo. It is good for them but bad for the company because they are the project's single point of failure -SPOF-. Once they leave the company, the project dramatically goes down.", + "WhyNotBuildYourOwnFramework_ABPSOLUTION_Description": "ABP Framework is a community-driven, well-documented, mature and generic application framework. A team of highly experienced developers are working hard to keep it up-to-date, easy to understand and comfortable to use. Using such a stable framework makes you focus on your own business code and get help with the framework from experts whenever you need it.", "ArchitecturalInfrastructure_Description": "SaaS applications, modular or microservice systems are most used enterprise software models. Building such systems not only requires a good understanding and experience, but also requires a strong software infrastructure. Otherwise, you will find yourself spending a great effort to support these architectural details in your codebase.", "Modularity": "Modularity", "Modularity_THEPROBLEM_Description": "Building a truly modular system is not easy! All the aspects of the system (database, entities, APIs, UI pages/components) can be split into modules, and each module can be re-usable without others. The plain ASP.NET Core doesn't provide such a modular architecture. If you need it, you should think about it from scratch.", "Modularity_ABPSOLUTION_Description": "The ABP Framework is born to be a modular application development structure. Every feature in the framework is developed to be compatible with modularity. Documentation and guides explain how to develop re-usable modules in a standard way.", "SaaSMultiTenancy": "SaaS / Multi-Tenancy", - "SaaSMultiTenancy_THEPROBLEM_Description": "Multi-Tenancy is a common way to implement SaaS systems. However, implementing a consistent multi-tenant infrastructure may become complicated.", - "SaaSMultiTenancy_ABPSOLUTION_Description": "ABP Framework provides a complete multi-tenant infrastructure and abstract complexity from your business code. Your application code will be mostly multi-tenancy aware while the ABP Framework automatically isolates the database, cache and other details of the tenants from each other. It supports single database, per tenant database and hybrid approaches. It properly configures the libraries like Microsoft Identity, IdentityServer, OpenIddict, which are not normally multi-tenancy compatible.", + "SaaSMultiTenancy_THEPROBLEM_Description": "Multi-Tenancy is a common way to implement SaaS systems. However, implementing a consistent multi-tenant infrastructure may become complicated.", + "SaaSMultiTenancy_ABPSOLUTION_Description": "ABP Framework provides a complete multi-tenant infrastructure and abstract complexity from your business code. Your application code will be mostly multi-tenancy aware while the ABP Framework automatically isolates the database, cache and other details of the tenants from each other. It supports single database, per tenant database and hybrid approaches. It properly configures the libraries like Microsoft Identity and OpenIddict, which are not normally multi-tenancy compatible.", "Microservices": "Microservices", "Microservices_THEPROBLEM_Description": "Building a microservice system requires many infrastructure details: Authenticating and authorizing applications and microservices and implementing asynchronous messaging and synchronous (Rest/GRPC) communication patterns between microservices are the most fundamental issues.", - "Microservices_ABPSOLUTION_Description": "The ABP Framework provides services, guides, and samples to help you implement your microservice solution using the industry standard tools. ABP Commercial even goes one step further and provides a complete startup template to kick-start your microservice solution.", + "Microservices_ABPSOLUTION_Description": "The ABP Framework provides services, guides, and samples to help you implement your microservice solution using the industry standard tools.", + "Microservices_ABPSOLUTION_Description2": "ABP Commercial even goes one step further and provides a complete startup template to kick-start your microservice solution.", "PreBuiltModules": "Pre-Built Modules", "PreBuiltModules_THEPROBLEM_Description": "All of us have similar but slightly different business requirements. However, we all should re-invent the wheel since no one's code can directly work in our solution. They are all embedded parts of a larger solution.", - "PreBuiltModules_ABPSOLUTION_Description":"ABP Commercial modules provides a lot of re-usable application modules like payment, chat, file management, audit log reporting... etc. All of these modules are easily installed into your solution and directly work. We are constantly adding more modules.", + "PreBuiltModules_ABPSOLUTION_Description":"ABP Commercial modules provides a lot of re-usable application modules like payment, chat, file management, audit log reporting... etc. All of these modules are easily installed into your solution and directly work. We are constantly adding more modules.", "PreBuiltModules_ABPSOLUTION_Description2": "All modules are designed as customizable for your business requirements. If you need complete control, you can download the full source code of any module and completely customize based on your specific business requirements.", "ABPCommunity": "ABP Community", - "ABPCommunity_Description": "Being in a big community where everyone follows similar coding styles and principles and shares a common infrastructure brings power when you have troubles or need help with design decisions. Since we write code similarly, we can help each other much better. ABP is a community-backed project with almost 10K stars on GitHub.", + "ABPCommunity_Description": "Finally, Being in a big community where everyone follows similar coding styles and principles and shares a common infrastructure brings power when you have troubles or need help with design decisions. Since we write code similarly, we can help each other much better. ABP is a community-backed project with more then 10K stars on GitHub.", "ABPCommunity_Description2": "It is easy to share code or even re-usable libraries between ABP developers. A code snippet that works for you will also work for others. There are a lot of samples and tutorials that you can directly implement for your application.", - "ABPCommunity_Description3": "When you hire a developer who worked before with the ABP architecture will immediately understand your solution and start development in a very short time." + "ABPCommunity_Description3": "When you hire a developer who worked before with the ABP architecture will immediately understand your solution and start development in a very short time.", + "WhyAbpIo_Page_Title": "Why ABP Framework?", + "AbpStudio_Page_Title": "ABP Studio" } } From 741b569a52421bacfaafbb03edc4012281aff434 Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 9 Aug 2023 18:48:13 +0300 Subject: [PATCH 124/165] Update en.json --- .../AbpIoLocalization/Commercial/Localization/Resources/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 9ea157bc3d..02f8087299 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -825,7 +825,7 @@ "ExpirationDate": "Expiration Date", "SpringCampaignDiscount": "Spring Campaign Discount", "WhyUseAbpIoPlatform": "Why should I use the ABP.IO Platform instead of creating a new solution from scratch?", - "WhyUseAbpIoPlatformFaqExplanation": "See that document for a detailed explanation of why using ABP.IO Platform has a significant advantage over doing everything yourself.", + "WhyUseAbpIoPlatformFaqExplanation": "See that page for a detailed explanation of why using ABP.IO Platform has a significant advantage over doing everything yourself.", "EulaPageTitle": "End User License Agreement (EULA)", "PrivacyPolicyPageTitle": "Privacy Policy - Cookie Policy", "TermsConditionsPageTitle": "Terms and Conditions", From ddb141f7860b36214c4aaf508e455da0f120e067 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 10 Aug 2023 09:07:54 +0800 Subject: [PATCH 125/165] Update Openiddict to `4.7.0`. --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 838ffcc995..cfb62d58d2 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -43,7 +43,7 @@ true - 4.6.0 + 4.7.0 From d2f24b41263ca676386ecaf5a96ff9bc4dcad25c Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 9 Aug 2023 23:24:29 -0400 Subject: [PATCH 126/165] Added oidc flows and updated discovery endpoint --- .../AbpSwaggerGenServiceCollectionExtensions.cs | 5 +++-- .../Volo/Abp/Swashbuckle/AbpOidcFlows.cs | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpOidcFlows.cs diff --git a/framework/src/Volo.Abp.Swashbuckle/Microsoft/Extensions/DependencyInjection/AbpSwaggerGenServiceCollectionExtensions.cs b/framework/src/Volo.Abp.Swashbuckle/Microsoft/Extensions/DependencyInjection/AbpSwaggerGenServiceCollectionExtensions.cs index 13f1f2a296..0acdf852e5 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Microsoft/Extensions/DependencyInjection/AbpSwaggerGenServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.Swashbuckle/Microsoft/Extensions/DependencyInjection/AbpSwaggerGenServiceCollectionExtensions.cs @@ -5,6 +5,7 @@ using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using Swashbuckle.AspNetCore.SwaggerUI; using Volo.Abp.Content; +using Volo.Abp.Swashbuckle; namespace Microsoft.Extensions.DependencyInjection; @@ -88,10 +89,10 @@ public static class AbpSwaggerGenServiceCollectionExtensions Action? setupAction = null) { var discoveryUrl = discoveryEndpoint != null ? - new Uri(discoveryEndpoint) : + new Uri($"{discoveryEndpoint.TrimEnd('/')}/.well-known/openid-configuration") : new Uri($"{authority.TrimEnd('/')}/.well-known/openid-configuration"); - flows ??= new [] { "authorization_code" }; + flows ??= new [] { AbpSwaggerOidcFlows.AuthorizationCode }; services.Configure(swaggerUiOptions => { diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpOidcFlows.cs b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpOidcFlows.cs new file mode 100644 index 0000000000..cbc30c5f29 --- /dev/null +++ b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpOidcFlows.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.Swashbuckle; + +public static class AbpSwaggerOidcFlows +{ + public const string AuthorizationCode = "authorization_code"; + public const string Implicit = "implicit"; + public const string Password = "password"; + public const string ClientCredentials = "client_credentials"; +} \ No newline at end of file From 3d3b5e245d2cc089018989fb6c44de44d8c4141c Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 9 Aug 2023 23:28:36 -0400 Subject: [PATCH 127/165] file name update --- .../Abp/Swashbuckle/{AbpOidcFlows.cs => AbpSwaggerOidcFlows.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/{AbpOidcFlows.cs => AbpSwaggerOidcFlows.cs} (100%) diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpOidcFlows.cs b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwaggerOidcFlows.cs similarity index 100% rename from framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpOidcFlows.cs rename to framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwaggerOidcFlows.cs From 39879ba929348f586ad9e43dc69baa77c5df9205 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 10 Aug 2023 11:45:55 +0800 Subject: [PATCH 128/165] Add `PermissionIntegrationService` to permission-management module. --- .../IPermissionIntegrationService.cs | 13 ++ .../Integration/IsGrantedInput.cs | 10 ++ .../Integration/IsGrantedOutput.cs | 11 ++ .../PermissionIntegrationService.cs | 43 +++++ ...missionIntegrationClientProxy.Generated.cs | 36 ++++ .../PermissionIntegrationClientProxy.cs | 7 + .../PermissionsClientProxy.Generated.cs | 8 +- .../PermissionsClientProxy.cs | 2 +- .../permissionManagement-generate-proxy.json | 155 +++++++++++++++++- ...lo.Abp.PermissionManagement.HttpApi.csproj | 1 + .../PermissionIntegrationController.cs | 35 ++++ 11 files changed, 316 insertions(+), 5 deletions(-) create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedInput.cs create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedOutput.cs create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.cs rename modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/{ => Volo/Abp/PermissionManagement}/PermissionsClientProxy.Generated.cs (93%) rename modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/{ => Volo/Abp/PermissionManagement}/PermissionsClientProxy.cs (74%) create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs new file mode 100644 index 0000000000..62fa2ed107 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace Volo.Abp.PermissionManagement.Integration; + +[IntegrationService] +public interface IPermissionIntegrationService : IApplicationService +{ + Task IsGrantedAsync(IsGrantedInput input); + + Task> IsGrantedAsync(List input); +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedInput.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedInput.cs new file mode 100644 index 0000000000..4f5c06ed9b --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedInput.cs @@ -0,0 +1,10 @@ +using System; + +namespace Volo.Abp.PermissionManagement.Integration; + +public class IsGrantedInput +{ + public Guid UserId { get; set; } + + public string[] PermissionNames { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedOutput.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedOutput.cs new file mode 100644 index 0000000000..df8179387e --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedOutput.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; + +namespace Volo.Abp.PermissionManagement.Integration; + +public class IsGrantedOutput +{ + public Guid UserId { get; set; } + + public List GrantedPermissionNames { get; set; } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs new file mode 100644 index 0000000000..4b226c2a84 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Application.Services; +using Volo.Abp.Authorization.Permissions; + +namespace Volo.Abp.PermissionManagement.Integration; + +[IntegrationService] +public class PermissionIntegrationService : ApplicationService, IPermissionIntegrationService +{ + protected IPermissionManager PermissionManager { get; } + + public PermissionIntegrationService(IPermissionManager permissionManager) + { + PermissionManager = permissionManager; + } + + public virtual async Task IsGrantedAsync(IsGrantedInput input) + { + return new IsGrantedOutput + { + UserId = input.UserId, + GrantedPermissionNames = (await PermissionManager.GetAsync(input.PermissionNames, UserPermissionValueProvider.ProviderName, input.UserId.ToString())).Result.Where(x => x.IsGranted).Select(x => x.Name).ToList() + }; + } + + public virtual async Task> IsGrantedAsync(List input) + { + var result = new List(); + foreach (var item in input) + { + result.Add(new IsGrantedOutput + { + UserId = item.UserId, + GrantedPermissionNames = (await PermissionManager.GetAsync(item.PermissionNames, UserPermissionValueProvider.ProviderName, item.UserId.ToString())).Result.Where(x => x.IsGranted).Select(x => x.Name).ToList() + }); + } + + return result; + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs new file mode 100644 index 0000000000..1ffc7ad17b --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs @@ -0,0 +1,36 @@ +// This file is automatically generated by ABP framework to use MVC Controllers from CSharp +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; +using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; +using Volo.Abp.PermissionManagement.Integration; + +// ReSharper disable once CheckNamespace +namespace Volo.Abp.PermissionManagement.Integration; + +[Dependency(ReplaceServices = true)] +[ExposeServices(typeof(IPermissionIntegrationService), typeof(PermissionIntegrationClientProxy))] +[IntegrationService] +public partial class PermissionIntegrationClientProxy : ClientProxyBase, IPermissionIntegrationService +{ + public virtual async Task IsGrantedAsync(IsGrantedInput input) + { + return await RequestAsync(nameof(IsGrantedAsync), new ClientProxyRequestTypeValue + { + { typeof(IsGrantedInput), input } + }); + } + + public async Task> IsGrantedAsync(List input) + { + return await RequestAsync>(nameof(IsGrantedAsync), new ClientProxyRequestTypeValue + { + { typeof(IsGrantedInput), input } + }); + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.cs new file mode 100644 index 0000000000..115be0ac35 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.cs @@ -0,0 +1,7 @@ +// This file is part of PermissionIntegrationClientProxy, you can customize it here +// ReSharper disable once CheckNamespace +namespace Volo.Abp.PermissionManagement.Integration; + +public partial class PermissionIntegrationClientProxy +{ +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/PermissionsClientProxy.Generated.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/PermissionsClientProxy.Generated.cs similarity index 93% rename from modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/PermissionsClientProxy.Generated.cs rename to modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/PermissionsClientProxy.Generated.cs index d0955c61cd..c89b505da2 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/PermissionsClientProxy.Generated.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/PermissionsClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Abp.PermissionManagement; // ReSharper disable once CheckNamespace -namespace Volo.Abp.PermissionManagement.ClientProxies; +namespace Volo.Abp.PermissionManagement; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IPermissionAppService), typeof(PermissionsClientProxy))] diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/PermissionsClientProxy.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/PermissionsClientProxy.cs similarity index 74% rename from modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/PermissionsClientProxy.cs rename to modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/PermissionsClientProxy.cs index 7037f81157..d01866ffb3 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/PermissionsClientProxy.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/PermissionsClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of PermissionsClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Abp.PermissionManagement.ClientProxies; +namespace Volo.Abp.PermissionManagement; public partial class PermissionsClientProxy { diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json index 3f867ea85b..2c928da5c1 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json @@ -7,10 +7,74 @@ "Volo.Abp.PermissionManagement.PermissionsController": { "controllerName": "Permissions", "controllerGroupName": "Permissions", + "isRemoteService": true, + "isIntegrationService": false, + "apiVersion": null, "type": "Volo.Abp.PermissionManagement.PermissionsController", "interfaces": [ { - "type": "Volo.Abp.PermissionManagement.IPermissionAppService" + "type": "Volo.Abp.PermissionManagement.IPermissionAppService", + "name": "IPermissionAppService", + "methods": [ + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.GetPermissionListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.GetPermissionListResultDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.PermissionManagement.UpdatePermissionsDto, Volo.Abp.PermissionManagement.Application.Contracts", + "type": "Volo.Abp.PermissionManagement.UpdatePermissionsDto", + "typeSimple": "Volo.Abp.PermissionManagement.UpdatePermissionsDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { @@ -149,6 +213,95 @@ "implementFrom": "Volo.Abp.PermissionManagement.IPermissionAppService" } } + }, + "Volo.Abp.PermissionManagement.Integration.PermissionIntegrationController": { + "controllerName": "PermissionIntegration", + "controllerGroupName": "PermissionIntegration", + "isRemoteService": true, + "isIntegrationService": true, + "apiVersion": null, + "type": "Volo.Abp.PermissionManagement.Integration.PermissionIntegrationController", + "interfaces": [ + { + "type": "Volo.Abp.PermissionManagement.Integration.IPermissionIntegrationService", + "name": "IPermissionIntegrationService", + "methods": [ + { + "name": "IsGrantedAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput, Volo.Abp.PermissionManagement.Application.Contracts", + "type": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", + "typeSimple": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.Integration.IsGrantedOutput", + "typeSimple": "Volo.Abp.PermissionManagement.Integration.IsGrantedOutput" + } + }, + { + "name": "IsGrantedAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.Integration.IsGrantedInput, Volo.Abp.PermissionManagement.Application.Contracts, Version=7.4.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.PermissionManagement.Integration.IsGrantedInput]", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.PermissionManagement.Integration.IsGrantedOutput]" + } + } + ] + } + ], + "actions": { + "IsGrantedAsyncByInput": { + "uniqueName": "IsGrantedAsyncByInput", + "name": "IsGrantedAsync", + "httpMethod": "POST", + "url": "integration-api/permission-management/permissions/is-granted", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput, Volo.Abp.PermissionManagement.Application.Contracts", + "type": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", + "typeSimple": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "jsonName": null, + "type": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", + "typeSimple": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.Integration.IsGrantedOutput", + "typeSimple": "Volo.Abp.PermissionManagement.Integration.IsGrantedOutput" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Abp.PermissionManagement.Integration.IPermissionIntegrationService" + } + } } } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.csproj b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.csproj index 870cd86aa1..f8f1eff54a 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.csproj +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.csproj @@ -19,4 +19,5 @@ + diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs new file mode 100644 index 0000000000..c5b88fe3bf --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; + +namespace Volo.Abp.PermissionManagement.Integration; + +[RemoteService(Name = PermissionManagementRemoteServiceConsts.RemoteServiceName)] +[Area(PermissionManagementRemoteServiceConsts.ModuleName)] +[ControllerName("PermissionIntegration")] +[Route("integration-api/permission-management/permissions")] +public class PermissionIntegrationController: AbpControllerBase, IPermissionIntegrationService +{ + protected IPermissionIntegrationService PermissionIntegrationService { get; } + + public PermissionIntegrationController(IPermissionIntegrationService permissionIntegrationService) + { + PermissionIntegrationService = permissionIntegrationService; + } + + [HttpPost] + [Route("is-granted")] + public virtual Task IsGrantedAsync(IsGrantedInput input) + { + return PermissionIntegrationService.IsGrantedAsync(input); + } + + [HttpPost] + [Route("is-granted/multiple")] + public virtual Task> IsGrantedAsync(List input) + { + return PermissionIntegrationService.IsGrantedAsync(input); + } +} From ad510cead1fe3743719fcd471f674b31c9866478 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 10 Aug 2023 14:08:32 +0800 Subject: [PATCH 129/165] Only keep one method of `IPermissionIntegrationService`. --- .../IPermissionIntegrationService.cs | 4 +- ...rantedInput.cs => PermissionGrantInput.cs} | 2 +- ...ntedOutput.cs => PermissionGrantOutput.cs} | 4 +- .../PermissionIntegrationService.cs | 20 +++------ ...missionIntegrationClientProxy.Generated.cs | 14 ++----- .../permissionManagement-generate-proxy.json | 41 ++++++------------- .../PermissionIntegrationController.cs | 10 +---- 7 files changed, 25 insertions(+), 70 deletions(-) rename modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/{IsGrantedInput.cs => PermissionGrantInput.cs} (82%) rename modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/{IsGrantedOutput.cs => PermissionGrantOutput.cs} (59%) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs index 62fa2ed107..09b8ae538e 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs @@ -7,7 +7,5 @@ namespace Volo.Abp.PermissionManagement.Integration; [IntegrationService] public interface IPermissionIntegrationService : IApplicationService { - Task IsGrantedAsync(IsGrantedInput input); - - Task> IsGrantedAsync(List input); + Task > IsGrantedAsync(List input); } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedInput.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantInput.cs similarity index 82% rename from modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedInput.cs rename to modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantInput.cs index 4f5c06ed9b..d5639f8b22 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedInput.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantInput.cs @@ -2,7 +2,7 @@ using System; namespace Volo.Abp.PermissionManagement.Integration; -public class IsGrantedInput +public class PermissionGrantInput { public Guid UserId { get; set; } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedOutput.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs similarity index 59% rename from modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedOutput.cs rename to modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs index df8179387e..613c7407bf 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IsGrantedOutput.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; namespace Volo.Abp.PermissionManagement.Integration; -public class IsGrantedOutput +public class PermissionGrantOutput { public Guid UserId { get; set; } - public List GrantedPermissionNames { get; set; } + public Dictionary Permissions { get; set; } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs index 4b226c2a84..ff6319dda6 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -17,24 +16,15 @@ public class PermissionIntegrationService : ApplicationService, IPermissionInteg PermissionManager = permissionManager; } - public virtual async Task IsGrantedAsync(IsGrantedInput input) + public virtual async Task> IsGrantedAsync(List input) { - return new IsGrantedOutput - { - UserId = input.UserId, - GrantedPermissionNames = (await PermissionManager.GetAsync(input.PermissionNames, UserPermissionValueProvider.ProviderName, input.UserId.ToString())).Result.Where(x => x.IsGranted).Select(x => x.Name).ToList() - }; - } - - public virtual async Task> IsGrantedAsync(List input) - { - var result = new List(); + var result = new List(); foreach (var item in input) { - result.Add(new IsGrantedOutput - { + result.Add(new PermissionGrantOutput { UserId = item.UserId, - GrantedPermissionNames = (await PermissionManager.GetAsync(item.PermissionNames, UserPermissionValueProvider.ProviderName, item.UserId.ToString())).Result.Where(x => x.IsGranted).Select(x => x.Name).ToList() + Permissions = (await PermissionManager.GetAsync(item.PermissionNames, UserPermissionValueProvider.ProviderName, item.UserId.ToString())).Result + .ToDictionary(x => x.Name, x => x.IsGranted) }); } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs index 1ffc7ad17b..dd43db07f4 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs @@ -18,19 +18,11 @@ namespace Volo.Abp.PermissionManagement.Integration; [IntegrationService] public partial class PermissionIntegrationClientProxy : ClientProxyBase, IPermissionIntegrationService { - public virtual async Task IsGrantedAsync(IsGrantedInput input) + public virtual async Task> IsGrantedAsync(List input) { - return await RequestAsync(nameof(IsGrantedAsync), new ClientProxyRequestTypeValue + return await RequestAsync>(nameof(IsGrantedAsync), new ClientProxyRequestTypeValue { - { typeof(IsGrantedInput), input } - }); - } - - public async Task> IsGrantedAsync(List input) - { - return await RequestAsync>(nameof(IsGrantedAsync), new ClientProxyRequestTypeValue - { - { typeof(IsGrantedInput), input } + { typeof(List), input } }); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json index 2c928da5c1..0e7dec06ee 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json @@ -231,33 +231,16 @@ "parametersOnMethod": [ { "name": "input", - "typeAsString": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput, Volo.Abp.PermissionManagement.Application.Contracts", - "type": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", - "typeSimple": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", + "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.Integration.PermissionGrantInput, Volo.Abp.PermissionManagement.Application.Contracts, Version=7.4.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.PermissionManagement.Integration.PermissionGrantInput]", "isOptional": false, "defaultValue": null } ], "returnValue": { - "type": "Volo.Abp.PermissionManagement.Integration.IsGrantedOutput", - "typeSimple": "Volo.Abp.PermissionManagement.Integration.IsGrantedOutput" - } - }, - { - "name": "IsGrantedAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.Integration.IsGrantedInput, Volo.Abp.PermissionManagement.Application.Contracts, Version=7.4.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", - "type": "System.Collections.Generic.List", - "typeSimple": "[Volo.Abp.PermissionManagement.Integration.IsGrantedInput]", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "System.Collections.Generic.List", - "typeSimple": "[Volo.Abp.PermissionManagement.Integration.IsGrantedOutput]" + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.PermissionManagement.Integration.PermissionGrantOutput]" } } ] @@ -273,9 +256,9 @@ "parametersOnMethod": [ { "name": "input", - "typeAsString": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput, Volo.Abp.PermissionManagement.Application.Contracts", - "type": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", - "typeSimple": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", + "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.Integration.PermissionGrantInput, Volo.Abp.PermissionManagement.Application.Contracts, Version=7.4.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.PermissionManagement.Integration.PermissionGrantInput]", "isOptional": false, "defaultValue": null } @@ -285,8 +268,8 @@ "nameOnMethod": "input", "name": "input", "jsonName": null, - "type": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", - "typeSimple": "Volo.Abp.PermissionManagement.Integration.IsGrantedInput", + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.PermissionManagement.Integration.PermissionGrantInput]", "isOptional": false, "defaultValue": null, "constraintTypes": null, @@ -295,8 +278,8 @@ } ], "returnValue": { - "type": "Volo.Abp.PermissionManagement.Integration.IsGrantedOutput", - "typeSimple": "Volo.Abp.PermissionManagement.Integration.IsGrantedOutput" + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.PermissionManagement.Integration.PermissionGrantOutput]" }, "allowAnonymous": null, "implementFrom": "Volo.Abp.PermissionManagement.Integration.IPermissionIntegrationService" diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs index c5b88fe3bf..4f989c8941 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; @@ -21,14 +20,7 @@ public class PermissionIntegrationController: AbpControllerBase, IPermissionInte [HttpPost] [Route("is-granted")] - public virtual Task IsGrantedAsync(IsGrantedInput input) - { - return PermissionIntegrationService.IsGrantedAsync(input); - } - - [HttpPost] - [Route("is-granted/multiple")] - public virtual Task> IsGrantedAsync(List input) + public virtual Task> IsGrantedAsync(List input) { return PermissionIntegrationService.IsGrantedAsync(input); } From 2e2dee86319c558d24e2dc82aa6b6a508d590130 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 10 Aug 2023 14:09:08 +0800 Subject: [PATCH 130/165] Update Volo.Abp.PermissionManagement.HttpApi.csproj --- .../Volo.Abp.PermissionManagement.HttpApi.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.csproj b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.csproj index f8f1eff54a..870cd86aa1 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.csproj +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.csproj @@ -19,5 +19,4 @@ - From cb80e3230e38d45308a00d74bdb4b9ed87af9de8 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 10 Aug 2023 16:10:51 +0800 Subject: [PATCH 131/165] Update some code of `IPermissionIntegrationService`. --- .../Integration/IPermissionIntegrationService.cs | 3 ++- .../Integration/PermissionGrantOutput.cs | 3 --- .../Integration/PermissionIntegrationService.cs | 9 +++++---- .../PermissionIntegrationClientProxy.Generated.cs | 4 ++-- .../permissionManagement-generate-proxy.json | 12 ++++++------ .../Integration/PermissionIntegrationController.cs | 5 +++-- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs index 09b8ae538e..25b35d87c3 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; namespace Volo.Abp.PermissionManagement.Integration; @@ -7,5 +8,5 @@ namespace Volo.Abp.PermissionManagement.Integration; [IntegrationService] public interface IPermissionIntegrationService : IApplicationService { - Task > IsGrantedAsync(List input); + Task> IsGrantedAsync(List input); } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs index 613c7407bf..b2873b9848 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs @@ -1,11 +1,8 @@ -using System; using System.Collections.Generic; namespace Volo.Abp.PermissionManagement.Integration; public class PermissionGrantOutput { - public Guid UserId { get; set; } - public Dictionary Permissions { get; set; } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs index ff6319dda6..1a8b4c16b8 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; using Volo.Abp.Authorization.Permissions; @@ -16,18 +17,18 @@ public class PermissionIntegrationService : ApplicationService, IPermissionInteg PermissionManager = permissionManager; } - public virtual async Task> IsGrantedAsync(List input) + public virtual async Task> IsGrantedAsync(List input) { var result = new List(); foreach (var item in input) { - result.Add(new PermissionGrantOutput { - UserId = item.UserId, + result.Add(new PermissionGrantOutput + { Permissions = (await PermissionManager.GetAsync(item.PermissionNames, UserPermissionValueProvider.ProviderName, item.UserId.ToString())).Result .ToDictionary(x => x.Name, x => x.IsGranted) }); } - return result; + return new ListResultDto(result); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs index dd43db07f4..a3e4537729 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs @@ -18,9 +18,9 @@ namespace Volo.Abp.PermissionManagement.Integration; [IntegrationService] public partial class PermissionIntegrationClientProxy : ClientProxyBase, IPermissionIntegrationService { - public virtual async Task> IsGrantedAsync(List input) + public virtual async Task> IsGrantedAsync(List input) { - return await RequestAsync>(nameof(IsGrantedAsync), new ClientProxyRequestTypeValue + return await RequestAsync>(nameof(IsGrantedAsync), new ClientProxyRequestTypeValue { { typeof(List), input } }); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json index 0e7dec06ee..ffad289f5a 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json @@ -239,8 +239,8 @@ } ], "returnValue": { - "type": "System.Collections.Generic.List", - "typeSimple": "[Volo.Abp.PermissionManagement.Integration.PermissionGrantOutput]" + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" } } ] @@ -250,7 +250,7 @@ "IsGrantedAsyncByInput": { "uniqueName": "IsGrantedAsyncByInput", "name": "IsGrantedAsync", - "httpMethod": "POST", + "httpMethod": "GET", "url": "integration-api/permission-management/permissions/is-granted", "supportedVersions": [], "parametersOnMethod": [ @@ -273,13 +273,13 @@ "isOptional": false, "defaultValue": null, "constraintTypes": null, - "bindingSourceId": "Body", + "bindingSourceId": "ModelBinding", "descriptorName": "" } ], "returnValue": { - "type": "System.Collections.Generic.List", - "typeSimple": "[Volo.Abp.PermissionManagement.Integration.PermissionGrantOutput]" + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" }, "allowAnonymous": null, "implementFrom": "Volo.Abp.PermissionManagement.Integration.IPermissionIntegrationService" diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs index 4f989c8941..f6adff7300 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Application.Dtos; using Volo.Abp.AspNetCore.Mvc; namespace Volo.Abp.PermissionManagement.Integration; @@ -18,9 +19,9 @@ public class PermissionIntegrationController: AbpControllerBase, IPermissionInte PermissionIntegrationService = permissionIntegrationService; } - [HttpPost] + [HttpGet] [Route("is-granted")] - public virtual Task> IsGrantedAsync(List input) + public virtual Task> IsGrantedAsync(List input) { return PermissionIntegrationService.IsGrantedAsync(input); } From 4d33f3592e3ed3e08ffabe43c4ee9b40c6f8c97e Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 10 Aug 2023 16:21:09 +0800 Subject: [PATCH 132/165] Add `UserId` to `PermissionGrantOutput `. --- .../PermissionManagement/Integration/PermissionGrantOutput.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs index b2873b9848..613c7407bf 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs @@ -1,8 +1,11 @@ +using System; using System.Collections.Generic; namespace Volo.Abp.PermissionManagement.Integration; public class PermissionGrantOutput { + public Guid UserId { get; set; } + public Dictionary Permissions { get; set; } } From 24c58272df575f9c3d57dc73062fdd66fa416c5c Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 10 Aug 2023 16:30:19 +0800 Subject: [PATCH 133/165] Set `UserId` of `PermissionGrantOutput`. --- .../Integration/PermissionIntegrationService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs index 1a8b4c16b8..319619efc7 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs @@ -24,6 +24,7 @@ public class PermissionIntegrationService : ApplicationService, IPermissionInteg { result.Add(new PermissionGrantOutput { + UserId = item.UserId, Permissions = (await PermissionManager.GetAsync(item.PermissionNames, UserPermissionValueProvider.ProviderName, item.UserId.ToString())).Result .ToDictionary(x => x.Name, x => x.IsGranted) }); From 09006788afb900528f5aa4dd9698462e079b65a8 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 10 Aug 2023 18:06:31 +0800 Subject: [PATCH 134/165] Remove duplicate proxy classes --- .../IdentityRoleClientProxy.Generated.cs | 65 ------------ .../Abp/Identity/IdentityRoleClientProxy.cs | 7 -- .../IdentityUserClientProxy.Generated.cs | 98 ------------------- .../Abp/Identity/IdentityUserClientProxy.cs | 7 -- ...IdentityUserLookupClientProxy.Generated.cs | 52 ---------- .../Identity/IdentityUserLookupClientProxy.cs | 7 -- 6 files changed, 236 deletions(-) delete mode 100644 modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.Generated.cs delete mode 100644 modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.cs delete mode 100644 modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.Generated.cs delete mode 100644 modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.cs delete mode 100644 modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.Generated.cs delete mode 100644 modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.cs diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.Generated.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.Generated.cs deleted file mode 100644 index 64279a8019..0000000000 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.Generated.cs +++ /dev/null @@ -1,65 +0,0 @@ -// This file is automatically generated by ABP framework to use MVC Controllers from CSharp -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Client.ClientProxying; -using Volo.Abp.Http.Modeling; -using Volo.Abp.Identity; - -// ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity; - -[Dependency(ReplaceServices = true)] -[ExposeServices(typeof(IIdentityRoleAppService), typeof(IdentityRoleClientProxy))] -public partial class IdentityRoleClientProxy : ClientProxyBase, IIdentityRoleAppService -{ - public virtual async Task> GetAllListAsync() - { - return await RequestAsync>(nameof(GetAllListAsync)); - } - - public virtual async Task> GetListAsync(GetIdentityRolesInput input) - { - return await RequestAsync>(nameof(GetListAsync), new ClientProxyRequestTypeValue - { - { typeof(GetIdentityRolesInput), input } - }); - } - - public virtual async Task GetAsync(Guid id) - { - return await RequestAsync(nameof(GetAsync), new ClientProxyRequestTypeValue - { - { typeof(Guid), id } - }); - } - - public virtual async Task CreateAsync(IdentityRoleCreateDto input) - { - return await RequestAsync(nameof(CreateAsync), new ClientProxyRequestTypeValue - { - { typeof(IdentityRoleCreateDto), input } - }); - } - - public virtual async Task UpdateAsync(Guid id, IdentityRoleUpdateDto input) - { - return await RequestAsync(nameof(UpdateAsync), new ClientProxyRequestTypeValue - { - { typeof(Guid), id }, - { typeof(IdentityRoleUpdateDto), input } - }); - } - - public virtual async Task DeleteAsync(Guid id) - { - await RequestAsync(nameof(DeleteAsync), new ClientProxyRequestTypeValue - { - { typeof(Guid), id } - }); - } -} diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.cs deleted file mode 100644 index 6e42400a96..0000000000 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.cs +++ /dev/null @@ -1,7 +0,0 @@ -// This file is part of IdentityRoleClientProxy, you can customize it here -// ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity; - -public partial class IdentityRoleClientProxy -{ -} diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.Generated.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.Generated.cs deleted file mode 100644 index b6e18e1e0f..0000000000 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.Generated.cs +++ /dev/null @@ -1,98 +0,0 @@ -// This file is automatically generated by ABP framework to use MVC Controllers from CSharp -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Client.ClientProxying; -using Volo.Abp.Http.Modeling; -using Volo.Abp.Identity; - -// ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity; - -[Dependency(ReplaceServices = true)] -[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserClientProxy))] -public partial class IdentityUserClientProxy : ClientProxyBase, IIdentityUserAppService -{ - public virtual async Task GetAsync(Guid id) - { - return await RequestAsync(nameof(GetAsync), new ClientProxyRequestTypeValue - { - { typeof(Guid), id } - }); - } - - public virtual async Task> GetListAsync(GetIdentityUsersInput input) - { - return await RequestAsync>(nameof(GetListAsync), new ClientProxyRequestTypeValue - { - { typeof(GetIdentityUsersInput), input } - }); - } - - public virtual async Task CreateAsync(IdentityUserCreateDto input) - { - return await RequestAsync(nameof(CreateAsync), new ClientProxyRequestTypeValue - { - { typeof(IdentityUserCreateDto), input } - }); - } - - public virtual async Task UpdateAsync(Guid id, IdentityUserUpdateDto input) - { - return await RequestAsync(nameof(UpdateAsync), new ClientProxyRequestTypeValue - { - { typeof(Guid), id }, - { typeof(IdentityUserUpdateDto), input } - }); - } - - public virtual async Task DeleteAsync(Guid id) - { - await RequestAsync(nameof(DeleteAsync), new ClientProxyRequestTypeValue - { - { typeof(Guid), id } - }); - } - - public virtual async Task> GetRolesAsync(Guid id) - { - return await RequestAsync>(nameof(GetRolesAsync), new ClientProxyRequestTypeValue - { - { typeof(Guid), id } - }); - } - - public virtual async Task> GetAssignableRolesAsync() - { - return await RequestAsync>(nameof(GetAssignableRolesAsync)); - } - - public virtual async Task UpdateRolesAsync(Guid id, IdentityUserUpdateRolesDto input) - { - await RequestAsync(nameof(UpdateRolesAsync), new ClientProxyRequestTypeValue - { - { typeof(Guid), id }, - { typeof(IdentityUserUpdateRolesDto), input } - }); - } - - public virtual async Task FindByUsernameAsync(string userName) - { - return await RequestAsync(nameof(FindByUsernameAsync), new ClientProxyRequestTypeValue - { - { typeof(string), userName } - }); - } - - public virtual async Task FindByEmailAsync(string email) - { - return await RequestAsync(nameof(FindByEmailAsync), new ClientProxyRequestTypeValue - { - { typeof(string), email } - }); - } -} diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.cs deleted file mode 100644 index 8c40a7c313..0000000000 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.cs +++ /dev/null @@ -1,7 +0,0 @@ -// This file is part of IdentityUserClientProxy, you can customize it here -// ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity; - -public partial class IdentityUserClientProxy -{ -} diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.Generated.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.Generated.cs deleted file mode 100644 index effdd5ef51..0000000000 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.Generated.cs +++ /dev/null @@ -1,52 +0,0 @@ -// This file is automatically generated by ABP framework to use MVC Controllers from CSharp -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Client.ClientProxying; -using Volo.Abp.Http.Modeling; -using Volo.Abp.Identity; -using Volo.Abp.Users; - -// ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity; - -[Dependency(ReplaceServices = true)] -[ExposeServices(typeof(IIdentityUserLookupAppService), typeof(IdentityUserLookupClientProxy))] -public partial class IdentityUserLookupClientProxy : ClientProxyBase, IIdentityUserLookupAppService -{ - public virtual async Task FindByIdAsync(Guid id) - { - return await RequestAsync(nameof(FindByIdAsync), new ClientProxyRequestTypeValue - { - { typeof(Guid), id } - }); - } - - public virtual async Task FindByUserNameAsync(string userName) - { - return await RequestAsync(nameof(FindByUserNameAsync), new ClientProxyRequestTypeValue - { - { typeof(string), userName } - }); - } - - public virtual async Task> SearchAsync(UserLookupSearchInputDto input) - { - return await RequestAsync>(nameof(SearchAsync), new ClientProxyRequestTypeValue - { - { typeof(UserLookupSearchInputDto), input } - }); - } - - public virtual async Task GetCountAsync(UserLookupCountInputDto input) - { - return await RequestAsync(nameof(GetCountAsync), new ClientProxyRequestTypeValue - { - { typeof(UserLookupCountInputDto), input } - }); - } -} diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.cs deleted file mode 100644 index 3d54f2d1bb..0000000000 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.cs +++ /dev/null @@ -1,7 +0,0 @@ -// This file is part of IdentityUserLookupClientProxy, you can customize it here -// ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity; - -public partial class IdentityUserLookupClientProxy -{ -} From 2bc023ba620741214ccadb3f47bb2f25d65f1d0f Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 10 Aug 2023 18:19:53 +0800 Subject: [PATCH 135/165] Introduce `IPermissionFinder`. --- .../IdentityUserIntegrationService.cs | 12 +++---- .../IPermissionIntegrationService.cs | 2 +- .../PermissionIntegrationService.cs | 23 +++---------- .../PermissionManagement/IPermissionFinder.cs | 9 +++++ .../PermissionManagement/IsGrantedRequest.cs} | 4 +-- .../IsGrantedResponse.cs} | 4 +-- .../PermissionFinderExtensions.cs | 26 +++++++++++++++ .../PermissionManagement/PermissionFinder.cs | 33 +++++++++++++++++++ ...missionIntegrationClientProxy.Generated.cs | 7 ++-- .../permissionManagement-generate-proxy.json | 24 +++++++------- .../HttpClientPermissionFinder.cs | 23 +++++++++++++ .../PermissionIntegrationController.cs | 2 +- 12 files changed, 124 insertions(+), 45 deletions(-) create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IPermissionFinder.cs rename modules/permission-management/src/{Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantInput.cs => Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IsGrantedRequest.cs} (55%) rename modules/permission-management/src/{Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs => Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IsGrantedResponse.cs} (63%) create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionFinderExtensions.cs create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionFinder.cs create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/HttpClientPermissionFinder.cs diff --git a/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs b/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs index 5b95d40c9d..b18f58f3a5 100644 --- a/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs +++ b/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs @@ -5,15 +5,15 @@ namespace Volo.Abp.Identity.Integration; public class IdentityUserIntegrationService : IdentityAppServiceBase, IIdentityUserIntegrationService { - protected IIdentityUserRepository UserRepository { get; } + protected IUserRoleFinder UserRoleFinder { get; } - public IdentityUserIntegrationService(IIdentityUserRepository userRepository) + public IdentityUserIntegrationService(IUserRoleFinder userRoleFinder) { - UserRepository = userRepository; + UserRoleFinder = userRoleFinder; } - public async Task GetRoleNamesAsync(Guid id) + public virtual async Task GetRoleNamesAsync(Guid id) { - return (await UserRepository.GetRoleNamesAsync(id)).ToArray(); + return await UserRoleFinder.GetRoleNamesAsync(id); } -} \ No newline at end of file +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs index 25b35d87c3..912fd4abdc 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/IPermissionIntegrationService.cs @@ -8,5 +8,5 @@ namespace Volo.Abp.PermissionManagement.Integration; [IntegrationService] public interface IPermissionIntegrationService : IApplicationService { - Task> IsGrantedAsync(List input); + Task> IsGrantedAsync(List input); } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs index 319619efc7..e7cef44c01 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationService.cs @@ -1,35 +1,22 @@ using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; -using Volo.Abp.Authorization.Permissions; namespace Volo.Abp.PermissionManagement.Integration; [IntegrationService] public class PermissionIntegrationService : ApplicationService, IPermissionIntegrationService { - protected IPermissionManager PermissionManager { get; } + protected IPermissionFinder PermissionFinder { get; } - public PermissionIntegrationService(IPermissionManager permissionManager) + public PermissionIntegrationService(IPermissionFinder permissionFinder) { - PermissionManager = permissionManager; + PermissionFinder = permissionFinder; } - public virtual async Task> IsGrantedAsync(List input) + public virtual async Task> IsGrantedAsync(List input) { - var result = new List(); - foreach (var item in input) - { - result.Add(new PermissionGrantOutput - { - UserId = item.UserId, - Permissions = (await PermissionManager.GetAsync(item.PermissionNames, UserPermissionValueProvider.ProviderName, item.UserId.ToString())).Result - .ToDictionary(x => x.Name, x => x.IsGranted) - }); - } - - return new ListResultDto(result); + return new ListResultDto(await PermissionFinder.IsGrantedAsync(input)); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IPermissionFinder.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IPermissionFinder.cs new file mode 100644 index 0000000000..805a1549d7 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IPermissionFinder.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Volo.Abp.PermissionManagement; + +public interface IPermissionFinder +{ + Task> IsGrantedAsync(List input); +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantInput.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IsGrantedRequest.cs similarity index 55% rename from modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantInput.cs rename to modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IsGrantedRequest.cs index d5639f8b22..e7cb3f92bb 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantInput.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IsGrantedRequest.cs @@ -1,8 +1,8 @@ using System; -namespace Volo.Abp.PermissionManagement.Integration; +namespace Volo.Abp.PermissionManagement; -public class PermissionGrantInput +public class IsGrantedRequest { public Guid UserId { get; set; } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IsGrantedResponse.cs similarity index 63% rename from modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs rename to modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IsGrantedResponse.cs index 613c7407bf..4cc8d07594 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/Integration/PermissionGrantOutput.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IsGrantedResponse.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -namespace Volo.Abp.PermissionManagement.Integration; +namespace Volo.Abp.PermissionManagement; -public class PermissionGrantOutput +public class IsGrantedResponse { public Guid UserId { get; set; } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionFinderExtensions.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionFinderExtensions.cs new file mode 100644 index 0000000000..d7e9f7c144 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionFinderExtensions.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Volo.Abp.PermissionManagement; + +public static class PermissionFinderExtensions +{ + public async static Task IsGrantedAsync(this IPermissionFinder permissionFinder, Guid userId, string permissionName) + { + return await permissionFinder.IsGrantedAsync(userId, new[] { permissionName }); + } + + public async static Task IsGrantedAsync(this IPermissionFinder permissionFinder, Guid userId, string[] permissionNames) + { + return (await permissionFinder.IsGrantedAsync(new List + { + new IsGrantedRequest + { + UserId = userId, + PermissionNames = permissionNames + } + })).Any(x => x.UserId == userId && x.Permissions.All(p => permissionNames.Contains(p.Key) && p.Value)); + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionFinder.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionFinder.cs new file mode 100644 index 0000000000..39adbe9903 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionFinder.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.PermissionManagement; + +public class PermissionFinder : IPermissionFinder, ITransientDependency +{ + protected IPermissionManager PermissionManager { get; } + + public PermissionFinder(IPermissionManager permissionManager) + { + PermissionManager = permissionManager; + } + + public virtual async Task> IsGrantedAsync(List input) + { + var result = new List(); + foreach (var item in input) + { + result.Add(new IsGrantedResponse + { + UserId = item.UserId, + Permissions = (await PermissionManager.GetAsync(item.PermissionNames, UserPermissionValueProvider.ProviderName, item.UserId.ToString())).Result + .ToDictionary(x => x.Name, x => x.IsGranted) + }); + } + + return result; + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs index a3e4537729..e609f0df4d 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationClientProxy.Generated.cs @@ -8,6 +8,7 @@ using Volo.Abp.DependencyInjection; using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; using Volo.Abp.Http.Modeling; +using Volo.Abp.PermissionManagement; using Volo.Abp.PermissionManagement.Integration; // ReSharper disable once CheckNamespace @@ -18,11 +19,11 @@ namespace Volo.Abp.PermissionManagement.Integration; [IntegrationService] public partial class PermissionIntegrationClientProxy : ClientProxyBase, IPermissionIntegrationService { - public virtual async Task> IsGrantedAsync(List input) + public virtual async Task> IsGrantedAsync(List input) { - return await RequestAsync>(nameof(IsGrantedAsync), new ClientProxyRequestTypeValue + return await RequestAsync>(nameof(IsGrantedAsync), new ClientProxyRequestTypeValue { - { typeof(List), input } + { typeof(List), input } }); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json index ffad289f5a..2a57defab4 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json @@ -231,16 +231,16 @@ "parametersOnMethod": [ { "name": "input", - "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.Integration.PermissionGrantInput, Volo.Abp.PermissionManagement.Application.Contracts, Version=7.4.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", - "type": "System.Collections.Generic.List", - "typeSimple": "[Volo.Abp.PermissionManagement.Integration.PermissionGrantInput]", + "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.IsGrantedRequest, Volo.Abp.PermissionManagement.Domain.Shared, Version=7.4.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.PermissionManagement.IsGrantedRequest]", "isOptional": false, "defaultValue": null } ], "returnValue": { - "type": "Volo.Abp.Application.Dtos.ListResultDto", - "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" } } ] @@ -256,9 +256,9 @@ "parametersOnMethod": [ { "name": "input", - "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.Integration.PermissionGrantInput, Volo.Abp.PermissionManagement.Application.Contracts, Version=7.4.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", - "type": "System.Collections.Generic.List", - "typeSimple": "[Volo.Abp.PermissionManagement.Integration.PermissionGrantInput]", + "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.IsGrantedRequest, Volo.Abp.PermissionManagement.Domain.Shared, Version=7.4.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.PermissionManagement.IsGrantedRequest]", "isOptional": false, "defaultValue": null } @@ -268,8 +268,8 @@ "nameOnMethod": "input", "name": "input", "jsonName": null, - "type": "System.Collections.Generic.List", - "typeSimple": "[Volo.Abp.PermissionManagement.Integration.PermissionGrantInput]", + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.PermissionManagement.IsGrantedRequest]", "isOptional": false, "defaultValue": null, "constraintTypes": null, @@ -278,8 +278,8 @@ } ], "returnValue": { - "type": "Volo.Abp.Application.Dtos.ListResultDto", - "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" }, "allowAnonymous": null, "implementFrom": "Volo.Abp.PermissionManagement.Integration.IPermissionIntegrationService" diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/HttpClientPermissionFinder.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/HttpClientPermissionFinder.cs new file mode 100644 index 0000000000..d6da602a4b --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/HttpClientPermissionFinder.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.PermissionManagement.Integration; + +namespace Volo.Abp.PermissionManagement; + +[Dependency(TryRegister = true)] +public class HttpClientPermissionFinder : IPermissionFinder, ITransientDependency +{ + protected IPermissionIntegrationService PermissionIntegrationService { get; } + + public HttpClientPermissionFinder(IPermissionIntegrationService permissionIntegrationService) + { + PermissionIntegrationService = permissionIntegrationService; + } + + public virtual async Task> IsGrantedAsync(List input) + { + return (await PermissionIntegrationService.IsGrantedAsync(input)).Items.ToList(); + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs index f6adff7300..48ba4b9541 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs @@ -21,7 +21,7 @@ public class PermissionIntegrationController: AbpControllerBase, IPermissionInte [HttpGet] [Route("is-granted")] - public virtual Task> IsGrantedAsync(List input) + public virtual Task> IsGrantedAsync(List input) { return PermissionIntegrationService.IsGrantedAsync(input); } From 109a923f5df738c0396f59439c97be4ab3ebfcf0 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Thu, 10 Aug 2023 14:27:47 +0300 Subject: [PATCH 136/165] CLI: Fix leptonx package update wrong version problem --- .../VoloNugetPackagesVersionUpdater.cs | 20 +++++++++++++------ .../Version/PackageVersionCheckerService.cs | 20 +++++-------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs index a718249a5f..ddc2928447 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs @@ -229,12 +229,20 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency { if ((includeNightlyPreviews || (currentVersion.Contains("-preview") && !switchToStable)) && !includeReleaseCandidates) { - var latestVersion = latestMyGetVersion == null || isLeptonXPackage ? - await GetLatestVersionFromMyGet(packageId) : latestMyGetVersion; + string latestVersion; + if(isLeptonXPackage) + { + latestVersion = (await _packageVersionCheckerService.GetLatestVersionOrNullAsync(packageId, includeNightlyPreviews, includeReleaseCandidates))?.Version?.ToString(); + } + else + { + latestVersion = latestMyGetVersion == null ? await GetLatestVersionFromMyGet(packageId) : latestMyGetVersion; + } - if(latestVersion == null && isLeptonXPackage) //leptonx-pro package + if(latestVersion == null) { - latestVersion = await GetLatestVersionFromMyGet("Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme", isNightly: includeNightlyPreviews); + Logger.LogWarning("Package: {0} could not be updated. Please manually update the package version yourself to prevent version mismatches.", packageId); + continue; } if (currentVersion != latestVersion) @@ -288,10 +296,10 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency return await Task.FromResult(content); } - private async Task GetLatestVersionFromMyGet(string packageId, bool isNightly = false) + private async Task GetLatestVersionFromMyGet(string packageId) { var myGetPack = await _myGetPackageListFinder.GetPackagesAsync(); - return myGetPack.Packages.FirstOrDefault(p => p.Id == packageId)?.Versions.LastOrDefault(x => isNightly ? x.Contains("-preview") : true); + return myGetPack.Packages.FirstOrDefault(p => p.Id == packageId)?.Versions.LastOrDefault(); } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs index de8511cdca..f4b87ea047 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs @@ -80,21 +80,11 @@ public class PackageVersionCheckerService : ITransientDependency return null; } - List versions; - - if (!includeNightly && includeReleaseCandidates) - { - versions = versionList - .Where(v => !v.Contains("-preview")) - .Select(SemanticVersion.Parse) - .OrderByDescending(v => v, new VersionComparer()).ToList(); - } - else - { - versions = versionList - .Select(SemanticVersion.Parse) - .OrderByDescending(v => v, new VersionComparer()).ToList(); - } + List versions = versionList + .WhereIf(!includeNightly, v => !v.Contains("-preview")) + .WhereIf(!includeReleaseCandidates, v => !v.Contains("rc")) + .Select(SemanticVersion.Parse) + .OrderByDescending(v => v, new VersionComparer()).ToList(); return versions.Any() ? new LatestVersionInfo(versions.Max()) From eb51ad91a7508ebc6947f7629e62af5792f5c13b Mon Sep 17 00:00:00 2001 From: Masum ULU Date: Thu, 10 Aug 2023 14:46:05 +0300 Subject: [PATCH 137/165] Update btnClass default value in EntityAction --- .../src/lib/components/grid-actions/grid-actions.component.html | 1 - .../theme-shared/extensions/src/lib/models/entity-actions.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html index 2b43dceab5..9f567271a4 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html @@ -52,7 +52,6 @@ *abpPermission="action.permission; runChangeDetection: false" (click)="action.action(data)" type="button" - class="btn text-center" [class]="action.btnClass" [style]="action.btnStyle" > diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-actions.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-actions.ts index cb17b9f645..4a801e841e 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-actions.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-actions.ts @@ -29,7 +29,7 @@ export class EntityAction extends Action { super(options.permission || '', options.visible, options.action); this.text = options.text; this.icon = options.icon || ''; - this.btnClass = options.btnClass || 'btn-primary'; + this.btnClass = options.btnClass || 'btn btn-primary text-center'; this.btnStyle = options.btnStyle; } From 51cdfd4cc69a52e7ca151f6c5b2f168533f75cb1 Mon Sep 17 00:00:00 2001 From: Masum ULU <49063256+masumulu28@users.noreply.github.com> Date: Thu, 10 Aug 2023 14:59:39 +0300 Subject: [PATCH 138/165] Update Entity-Action-Extensions.md --- docs/en/UI/Angular/Entity-Action-Extensions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/UI/Angular/Entity-Action-Extensions.md b/docs/en/UI/Angular/Entity-Action-Extensions.md index 6a9df909fb..3ab035b04a 100644 --- a/docs/en/UI/Angular/Entity-Action-Extensions.md +++ b/docs/en/UI/Angular/Entity-Action-Extensions.md @@ -324,7 +324,7 @@ As you see, passing `action` and `text` is enough to create an entity action. He - **icon** is the classes that define an icon to be placed before the text. (_default:_ `''`) - **permission** is the permission context which will be used to decide if this type of grid action should be displayed to the user or not. (_default:_ `undefined`) - **visible** is a predicate that will be used to decide if the current record should have this grid action or not. (_default:_ `() => true`) -- **btnClass** is the classes that will be applied to the button. (_default:_ `'btn btn-primary'`) +- **btnClass** is the classes that will be applied to the button. (_default:_ `'btn btn-primary text-center'`) - **btnStyle** is the styles that will be applied to the button. (_default:_ `''`) You may find a full example below. @@ -343,8 +343,8 @@ const options: EntityActionOptions = { icon: 'fa fa-unlock', permission: 'AbpIdentity.Users.Update', visible: data => data.record.isLockedOut, - btnClass:'btn-warning', - btnStyle: 'margin-right: 5px;', + btnClass:'btn btn-warning text-center', + btnStyle: '', //Adds inline style }; const action = new EntityAction(options); From 38b96ec9b6dc05d820dd06711b6907367ab94541 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 10 Aug 2023 21:05:46 +0800 Subject: [PATCH 139/165] Rename the parameter name. --- .../Volo/Abp/PermissionManagement/IPermissionFinder.cs | 2 +- .../Volo/Abp/PermissionManagement/PermissionFinder.cs | 4 ++-- .../Abp/PermissionManagement/HttpClientPermissionFinder.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IPermissionFinder.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IPermissionFinder.cs index 805a1549d7..9b28a7c200 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IPermissionFinder.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/IPermissionFinder.cs @@ -5,5 +5,5 @@ namespace Volo.Abp.PermissionManagement; public interface IPermissionFinder { - Task> IsGrantedAsync(List input); + Task> IsGrantedAsync(List requests); } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionFinder.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionFinder.cs index 39adbe9903..a1a1d8782c 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionFinder.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionFinder.cs @@ -15,10 +15,10 @@ public class PermissionFinder : IPermissionFinder, ITransientDependency PermissionManager = permissionManager; } - public virtual async Task> IsGrantedAsync(List input) + public virtual async Task> IsGrantedAsync(List requests) { var result = new List(); - foreach (var item in input) + foreach (var item in requests) { result.Add(new IsGrantedResponse { diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/HttpClientPermissionFinder.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/HttpClientPermissionFinder.cs index d6da602a4b..f62bfaf29b 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/HttpClientPermissionFinder.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/HttpClientPermissionFinder.cs @@ -16,8 +16,8 @@ public class HttpClientPermissionFinder : IPermissionFinder, ITransientDependenc PermissionIntegrationService = permissionIntegrationService; } - public virtual async Task> IsGrantedAsync(List input) + public virtual async Task> IsGrantedAsync(List requests) { - return (await PermissionIntegrationService.IsGrantedAsync(input)).Items.ToList(); + return (await PermissionIntegrationService.IsGrantedAsync(requests)).Items.ToList(); } } From dc422bbeef3a150388bd6950678605d9f9f12536 Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 10 Aug 2023 16:40:04 +0300 Subject: [PATCH 140/165] Update en.json --- .../Admin/Localization/Resources/en.json | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index 0fe0147c87..e5df7c7915 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -472,15 +472,14 @@ "QuotationNo": "Quotation no", "ValidTill": "Valid till", "QuotationNote": "Quotation note", - "QuotationTemplate.Address": "Address", "QuotationTemplate.Address:": "Address:", - "QuotationTemplate.VATNo": "VAT No", - "QuotationTemplate.Phone": "Phone", - "QuotationTemplate.E-mail": "E-mail", + "QuotationTemplate.VATNo:": "VAT No:", + "QuotationTemplate.Phone:": "Phone:", + "QuotationTemplate.E-mail:": "E-mail:", "QuotationTemplate.Quotation": "Quotation", "QuotationTemplate.To": "To", "QuotationTemplate.Details": "Details", - "QuotationTemplate.QuotationNo:": "Quotation:", + "QuotationTemplate.QuotationNo:": "Quotation #:", "QuotationTemplate.IssueDate:": "Issue Date:", "QuotationTemplate.ValidTill:": "Valid Till:", "QuotationTemplate.ValidDays": "{0} Days", @@ -490,10 +489,10 @@ "QuotationTemplate.Discount": "Discount", "QuotationTemplate.Total": "Total", "QuotationTemplate.Notes": "Notes", - "QuotationTemplate.SubTotal": "Sub Total", - "QuotationTemplate.Tax/VAT": "Tax / VAT (%{0})", - "QuotationTemplate.TotalDiscount": "Total Discount", - "QuotationTemplate.TotalDue": "Total Due", - "QuotationTemplate.ThanksForYourBusiness": "Thanks for your business!" + "QuotationTemplate.SubTotal:": "Sub Total :", + "QuotationTemplate.Tax/VAT:": "Tax / Vat (%{0}) :", + "QuotationTemplate.TotalDiscount:": "Total Discount :", + "QuotationTemplate.TOTALDUE:": "TOTAL DUE :", + "QuotationTemplate.BankAccount": "Our bank account information can be found at {0}" } } From e987acaad373b3eadd6823fd025258409ba6e906 Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 10 Aug 2023 16:40:07 +0300 Subject: [PATCH 141/165] Update tr.json --- .../Admin/Localization/Resources/tr.json | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json index c7c2febc28..0aca0b7333 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json @@ -423,28 +423,26 @@ "SubTotal": "Ara Toplam", "TotalDue": "NET TOPLAM", "DiscountAmount": "İndirim Tutarı", - "QuotationTemplate.Address": "Adres", "QuotationTemplate.Address:": "Adres:", - "QuotationTemplate.VATNo": "Vergi Dairesi/No", - "QuotationTemplate.Phone": "Telefon", - "QuotationTemplate.E-mail": "E-posta", + "QuotationTemplate.VATNo:": "Vergi Dairesi/No:", + "QuotationTemplate.Phone:": "Telefon:", + "QuotationTemplate.E-mail:": "E-posta:", "QuotationTemplate.Quotation": "Fiyat Teklifi", "QuotationTemplate.To": "Müşteri", "QuotationTemplate.Details": "Detay", "QuotationTemplate.QuotationNo:": "Teklif No:", "QuotationTemplate.IssueDate:": "Teklif Tarihi:", - "QuotationTemplate.ValidFor:": "Geçerlilik Süresi:", - "QuotationTemplate.ValidDays": "{0} Gün", + "QuotationTemplate.ValidTill:": "Geçerlilik Tarihi:", "QuotationTemplate.Description": "Açıklama", "QuotationTemplate.UnitPrice": "Birim Fiyat", "QuotationTemplate.Qty": "Adet", "QuotationTemplate.Discount": "İndirim", "QuotationTemplate.Total": "Tutar", "QuotationTemplate.Notes": "Notlar", - "QuotationTemplate.SubTotal": "Alt Toplam", - "QuotationTemplate.Tax/VAT": "Vergiler (%{0})", - "QuotationTemplate.TotalDiscount": "Toplam İndirim", - "QuotationTemplate.TotalDue": "NET TOPLAM", - "QuotationTemplate.ThanksForYourBusiness": "Değerli siparişlerinizi bekleriz." + "QuotationTemplate.SubTotal:": "Alt Toplam :", + "QuotationTemplate.Tax/VAT:": "Vergiler (%{0}) :", + "QuotationTemplate.TotalDiscount:": "Toplam İndirim :", + "QuotationTemplate.TOTALDUE:": "NET TOPLAM :", + "QuotationTemplate.BankAccount": "Banka hesabı bilgilerimiz {0} adresinde bulunabilir." } } From 3e748460b1e87f81a8ce5ba876f91a23203c55b5 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Thu, 10 Aug 2023 16:43:12 +0300 Subject: [PATCH 142/165] Create migration guide for v7.4 --- docs/en/Migration-Guides/Abp-7_4.md | 89 +++++++++++++++++++++++++++++ docs/en/Migration-Guides/Index.md | 1 + 2 files changed, 90 insertions(+) create mode 100644 docs/en/Migration-Guides/Abp-7_4.md diff --git a/docs/en/Migration-Guides/Abp-7_4.md b/docs/en/Migration-Guides/Abp-7_4.md new file mode 100644 index 0000000000..47f27fa059 --- /dev/null +++ b/docs/en/Migration-Guides/Abp-7_4.md @@ -0,0 +1,89 @@ +# ABP Version 7.4 Migration Guide + +This document is a guide for upgrading ABP v7.3 solutions to ABP v7.4. There are a few changes in this version that may affect your applications, please read it carefully and apply the necessary changes to your application. + +## Renamed `AddGlobalFilters<>` method as `FilterQueryable<>` in `IMongoDbRepositoryFilterer` + +ABP Framework provides services to automatically filter data on querying from a database. Prior to this version, creating a new class that derives from the `MongoDbRepositoryFilterer` and overriding its `AddGlobalFilters` method was needed for implementing a data filter for MongoDB. + +In this version, the `AddGlobalFilters` method renamed as `FilterQueryable`. Therefore, you need to update the method name if you have used data filtering for MongoDB, in your application. + +## Exposing Integration Services + +[Integration Services](../Integration-Services.md) are now not being exposed by default. Hiding integration services is useful because in a monolith application, integration services don't need to be exposed outside since the modules probably would be in-process communication with each other. Therefore, from this version on, the integration services will not be exposed as endpoints by default. + +If you build a microservice solution, or you need to access an integration service via a network call from any other application, you probably will need to expose the integration services, so the other applications can consume them. + +To expose integration services and controllers, you can configure the `AbpAspNetCoreMvcOptions` and set the `ExposeIntegrationServices` property as *true* in the `ConfigureServices` method of your [module class](../Module-Development-Basics.md): + +```csharp +Configure(options => +{ + options.ExposeIntegrationServices = true; +}); +``` + +## `LocalizationResource` removed from the `TemplateDefinition` class + +In this version, the `LocalizationResource` property (`Type`) removed from the `TemplateDefinition` class and instead the `LocalizationResourceName` property (`string`) has been added. + +## Changed method signature for `ICorrelationIdProvider.Get()` + +Prior to this version, `ICorrelationIdProvider.Get()` method was returning not nullable string that represents a *correlationId* (a unique key that used in distributed applications to trace requests accross multiple services/operations). With this version, now this method may return `null` if hasn't been generated by `AbpCorrelationIdMiddleware` before. + +```diff +public interface ICorrelationIdProvider +{ + +- [NotNull] string Get(); ++ string? Get(); + + //other methods + +} +``` + +Therefore, if you used this method in your application, you might want to make a null check for the method result. + +> See [#16795](https://github.com/abpframework/abp/pull/16795) for more information. + +## Dynamic Setting Store - Setting Management Module + +In this version, ABP Framework introduces Dynamic Setting Store, which is an important feature that allow us to collect and get all setting definitions from a single point. This feature requires some actions that need to be taken care of as in the following: + +* You need to create a new migration and apply it to your database because a new database table has been added. +* `ISettingDefinitionManager`'s sync methods have been removed and instead asynchrounus versions of the existing methods have been added. + +```diff +public interface ISettingDefinitionManager +{ +- SettingDefinition Get([NotNull] string name); ++ Task GetAsync([NotNull] string name); + +- IReadOnlyList GetAll(); ++ Task> GetAllAsync(); + +- SettingDefinition? GetOrNull(string name); ++ Task GetOrNullAsync([NotNull] string name); +} +``` + +## `IdentityUserIntegrationService` - Identity Module + +In this version, ABP Framework introduces the `IdentityUserIntegrationService`, which is designed to get current user's information such as his/her role names within a non-authorized integration service. This was need to prevent multiple calls to both permission and identity microservices, to be able to use the remote identity service. + +> For more information see the related PR: [#16962](https://github.com/abpframework/abp/pull/16962) + +This is a breaking change for microservice solutions because of the following two reasons and it should be cared: + +* `IdentityUserIntegrationService` provides non-authorized services. This is not breaking the application, but should be taken care of. Since, everyone can use the service to retrieve some informations for a certain user (for example, role names of a user). +* Secondly, since integration services are not exposed by default anymore as explained in the *Exposing Integration Services* section above, you should explicitly enable exposing integration services. Otherwise, the operation will be failed and you get a `404` error from the identity microservice. + +To expose integration services and controllers, you can configure the `AbpAspNetCoreMvcOptions` and set the `ExposeIntegrationServices` property as *true* in the `ConfigureServices` method of your [module class](../Module-Development-Basics.md): + +```csharp +Configure(options => +{ + options.ExposeIntegrationServices = true; +}); +``` \ No newline at end of file diff --git a/docs/en/Migration-Guides/Index.md b/docs/en/Migration-Guides/Index.md index c87004cfb5..88a2087ba0 100644 --- a/docs/en/Migration-Guides/Index.md +++ b/docs/en/Migration-Guides/Index.md @@ -2,6 +2,7 @@ The following documents explain how to migrate your existing ABP applications. We write migration documents only if you need to take an action while upgrading your solution. Otherwise, you can easily upgrade your solution using the [abp update command](../Upgrading.md). +- [7.3 to 7.4](Abp-7_4.md) - [7.2 to 7.3](Abp-7_3.md) - [7.1 to 7.2](Abp-7_2.md) - [7.0 to 7.1](Abp-7_1.md) From 7bba7cd36411efed30d4a392a15870526cc80e03 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Thu, 10 Aug 2023 16:55:16 +0300 Subject: [PATCH 143/165] Update Abp-7_4.md --- docs/en/Migration-Guides/Abp-7_4.md | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/docs/en/Migration-Guides/Abp-7_4.md b/docs/en/Migration-Guides/Abp-7_4.md index 47f27fa059..1c3bc0fe8c 100644 --- a/docs/en/Migration-Guides/Abp-7_4.md +++ b/docs/en/Migration-Guides/Abp-7_4.md @@ -4,13 +4,13 @@ This document is a guide for upgrading ABP v7.3 solutions to ABP v7.4. There are ## Renamed `AddGlobalFilters<>` method as `FilterQueryable<>` in `IMongoDbRepositoryFilterer` -ABP Framework provides services to automatically filter data on querying from a database. Prior to this version, creating a new class that derives from the `MongoDbRepositoryFilterer` and overriding its `AddGlobalFilters` method was needed for implementing a data filter for MongoDB. +ABP Framework provides services to automatically filter data on querying from a database. Prior to this version, creating a new class that derives from the `MongoDbRepositoryFilterer` and overriding its `AddGlobalFilters` method was needed for implementing a data filter for [MongoDB](../MongoDB.md). -In this version, the `AddGlobalFilters` method renamed as `FilterQueryable`. Therefore, you need to update the method name if you have used data filtering for MongoDB, in your application. +In this version, the `AddGlobalFilters<>` method is renamed as `FilterQueryable<>`. Therefore, you need to update the method name if you have used data filtering for MongoDB, in your application. ## Exposing Integration Services -[Integration Services](../Integration-Services.md) are now not being exposed by default. Hiding integration services is useful because in a monolith application, integration services don't need to be exposed outside since the modules probably would be in-process communication with each other. Therefore, from this version on, the integration services will not be exposed as endpoints by default. +[Integration Services](../Integration-Services.md) are now not being exposed by default. In a monolith application, integration services don't need to be exposed outside since the modules probably would be in-process communication with each other. Therefore, from this version on, the integration services will not be exposed as endpoints by default. If you build a microservice solution, or you need to access an integration service via a network call from any other application, you probably will need to expose the integration services, so the other applications can consume them. @@ -23,13 +23,18 @@ Configure(options => }); ``` -## `LocalizationResource` removed from the `TemplateDefinition` class +## `LocalizationResource` property removed from the `TemplateDefinition` class -In this version, the `LocalizationResource` property (`Type`) removed from the `TemplateDefinition` class and instead the `LocalizationResourceName` property (`string`) has been added. +In this version, the `LocalizationResource` property was removed from the `TemplateDefinition` class and instead the `LocalizationResourceName` property has been added. + +```diff +- public Type LocalizationResource { get; set; } ++ public string LocalizationResourceName { get; set; } +``` ## Changed method signature for `ICorrelationIdProvider.Get()` -Prior to this version, `ICorrelationIdProvider.Get()` method was returning not nullable string that represents a *correlationId* (a unique key that used in distributed applications to trace requests accross multiple services/operations). With this version, now this method may return `null` if hasn't been generated by `AbpCorrelationIdMiddleware` before. +Prior to this version, `ICorrelationIdProvider.Get()` method was returning a not nullable string that represents a *correlationId* (a unique key that is used in distributed applications to trace requests across multiple services/operations). With this version, now this method may return `null` if hasn't been generated by `AbpCorrelationIdMiddleware` before. ```diff public interface ICorrelationIdProvider @@ -43,16 +48,16 @@ public interface ICorrelationIdProvider } ``` -Therefore, if you used this method in your application, you might want to make a null check for the method result. +Therefore, if you used this method in your application, you might want to make a null check and update the method signature where it's used. > See [#16795](https://github.com/abpframework/abp/pull/16795) for more information. ## Dynamic Setting Store - Setting Management Module -In this version, ABP Framework introduces Dynamic Setting Store, which is an important feature that allow us to collect and get all setting definitions from a single point. This feature requires some actions that need to be taken care of as in the following: +In this version, ABP Framework introduces Dynamic Setting Store, which is an important feature that allows us to collect and get all setting definitions from a single point. This feature requires some actions that need to be taken care of as the following: * You need to create a new migration and apply it to your database because a new database table has been added. -* `ISettingDefinitionManager`'s sync methods have been removed and instead asynchrounus versions of the existing methods have been added. +* `ISettingDefinitionManager`'s sync methods have been removed and instead, asynchronous versions of the existing methods have been added. ```diff public interface ISettingDefinitionManager @@ -70,13 +75,13 @@ public interface ISettingDefinitionManager ## `IdentityUserIntegrationService` - Identity Module -In this version, ABP Framework introduces the `IdentityUserIntegrationService`, which is designed to get current user's information such as his/her role names within a non-authorized integration service. This was need to prevent multiple calls to both permission and identity microservices, to be able to use the remote identity service. +In this version, ABP Framework introduces the `IdentityUserIntegrationService`, which is designed to get current user's information such as his/her role names within a non-authorized integration service. > For more information see the related PR: [#16962](https://github.com/abpframework/abp/pull/16962) -This is a breaking change for microservice solutions because of the following two reasons and it should be cared: +This is a breaking change for microservice solutions because of the following two reasons and it should be cared about: -* `IdentityUserIntegrationService` provides non-authorized services. This is not breaking the application, but should be taken care of. Since, everyone can use the service to retrieve some informations for a certain user (for example, role names of a user). +* `IdentityUserIntegrationService` provides non-authorized services. This is not breaking the application, but should be taken care of. Since, everyone can use the service to retrieve some information for a certain user (for example, the role names of a user). * Secondly, since integration services are not exposed by default anymore as explained in the *Exposing Integration Services* section above, you should explicitly enable exposing integration services. Otherwise, the operation will be failed and you get a `404` error from the identity microservice. To expose integration services and controllers, you can configure the `AbpAspNetCoreMvcOptions` and set the `ExposeIntegrationServices` property as *true* in the `ConfigureServices` method of your [module class](../Module-Development-Basics.md): From 2ef4f57237bbb7f8fa2050b67ca679a3563f0bdf Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Thu, 10 Aug 2023 16:58:56 +0300 Subject: [PATCH 144/165] Update Abp-7_4.md --- docs/en/Migration-Guides/Abp-7_4.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/Migration-Guides/Abp-7_4.md b/docs/en/Migration-Guides/Abp-7_4.md index 1c3bc0fe8c..decd5bb424 100644 --- a/docs/en/Migration-Guides/Abp-7_4.md +++ b/docs/en/Migration-Guides/Abp-7_4.md @@ -10,7 +10,7 @@ In this version, the `AddGlobalFilters<>` method is renamed as `FilterQueryable< ## Exposing Integration Services -[Integration Services](../Integration-Services.md) are now not being exposed by default. In a monolith application, integration services don't need to be exposed outside since the modules probably would be in-process communication with each other. Therefore, from this version on, the integration services will not be exposed as endpoints by default. +[Integration Services](../Integration-Services.md) are now not being exposed by default. In a monolith application, integration services don't need to be exposed outside since the modules probably would be in-process communication with each other. Therefore, they don't need to be exposed for most of the time. If you build a microservice solution, or you need to access an integration service via a network call from any other application, you probably will need to expose the integration services, so the other applications can consume them. @@ -91,4 +91,4 @@ Configure(options => { options.ExposeIntegrationServices = true; }); -``` \ No newline at end of file +``` From da9015764305c8f4a27a5f50ca35e0d74eca9c1d Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Thu, 10 Aug 2023 17:30:39 +0300 Subject: [PATCH 145/165] Add equal spaces for top & bottom for Blazor toolbar --- .../Layout/PageHeader.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor index e6959f1d3a..2bb222feb8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor @@ -50,7 +50,7 @@ @foreach (var toolbarItemRender in ToolbarItemRenders) { - + @toolbarItemRender } From 0291909450d520191659fde1902702e9d32fc838 Mon Sep 17 00:00:00 2001 From: Hamza Albreem <94292623+braim23@users.noreply.github.com> Date: Fri, 11 Aug 2023 11:13:58 +0300 Subject: [PATCH 146/165] Update Abp-7_4.md --- docs/en/Migration-Guides/Abp-7_4.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/en/Migration-Guides/Abp-7_4.md b/docs/en/Migration-Guides/Abp-7_4.md index decd5bb424..d34b891b66 100644 --- a/docs/en/Migration-Guides/Abp-7_4.md +++ b/docs/en/Migration-Guides/Abp-7_4.md @@ -2,7 +2,7 @@ This document is a guide for upgrading ABP v7.3 solutions to ABP v7.4. There are a few changes in this version that may affect your applications, please read it carefully and apply the necessary changes to your application. -## Renamed `AddGlobalFilters<>` method as `FilterQueryable<>` in `IMongoDbRepositoryFilterer` +## Renamed the `AddGlobalFilters<>` method as `FilterQueryable<>` in `IMongoDbRepositoryFilterer` ABP Framework provides services to automatically filter data on querying from a database. Prior to this version, creating a new class that derives from the `MongoDbRepositoryFilterer` and overriding its `AddGlobalFilters` method was needed for implementing a data filter for [MongoDB](../MongoDB.md). @@ -10,9 +10,9 @@ In this version, the `AddGlobalFilters<>` method is renamed as `FilterQueryable< ## Exposing Integration Services -[Integration Services](../Integration-Services.md) are now not being exposed by default. In a monolith application, integration services don't need to be exposed outside since the modules probably would be in-process communication with each other. Therefore, they don't need to be exposed for most of the time. +[Integration Services](../Integration-Services.md) are now not being exposed by default. In a monolith application, integration services don't need to be exposed outside since the modules would probably be in-process communication with each other. Therefore, they don't need to be exposed for most of the time. -If you build a microservice solution, or you need to access an integration service via a network call from any other application, you probably will need to expose the integration services, so the other applications can consume them. +If you build a microservice solution or you need to access an integration service via a network call from any other application, you will probably need to expose the integration services so the other applications can consume them. To expose integration services and controllers, you can configure the `AbpAspNetCoreMvcOptions` and set the `ExposeIntegrationServices` property as *true* in the `ConfigureServices` method of your [module class](../Module-Development-Basics.md): @@ -25,16 +25,16 @@ Configure(options => ## `LocalizationResource` property removed from the `TemplateDefinition` class -In this version, the `LocalizationResource` property was removed from the `TemplateDefinition` class and instead the `LocalizationResourceName` property has been added. +In this version, the `LocalizationResource` property was removed from the `TemplateDefinition` class and instead, the `LocalizationResourceName` property has been added. ```diff - public Type LocalizationResource { get; set; } + public string LocalizationResourceName { get; set; } ``` -## Changed method signature for `ICorrelationIdProvider.Get()` +## Changed the method signature for `ICorrelationIdProvider.Get()` -Prior to this version, `ICorrelationIdProvider.Get()` method was returning a not nullable string that represents a *correlationId* (a unique key that is used in distributed applications to trace requests across multiple services/operations). With this version, now this method may return `null` if hasn't been generated by `AbpCorrelationIdMiddleware` before. +Prior to this version, the `ICorrelationIdProvider.Get()` method used to return a non nullable string that represented a *correlationId* (a unique key that is used in distributed applications to trace requests across multiple services/operations). In this version, this method may return `null` if it hasn't been generated by `AbpCorrelationIdMiddleware` before. ```diff public interface ICorrelationIdProvider @@ -48,7 +48,7 @@ public interface ICorrelationIdProvider } ``` -Therefore, if you used this method in your application, you might want to make a null check and update the method signature where it's used. +Therefore, if you've used this method in your application, you might want to make a null check and update the method signature where it's used. > See [#16795](https://github.com/abpframework/abp/pull/16795) for more information. @@ -75,14 +75,14 @@ public interface ISettingDefinitionManager ## `IdentityUserIntegrationService` - Identity Module -In this version, ABP Framework introduces the `IdentityUserIntegrationService`, which is designed to get current user's information such as his/her role names within a non-authorized integration service. +In this version, ABP Framework introduces the `IdentityUserIntegrationService`, which is designed to get the current user's information, such as his/her role names within a non-authorized integration service. -> For more information see the related PR: [#16962](https://github.com/abpframework/abp/pull/16962) +> For more information, see the related PR: [#16962](https://github.com/abpframework/abp/pull/16962) -This is a breaking change for microservice solutions because of the following two reasons and it should be cared about: +This is a breaking change for microservice solutions because of the following two reasons and it should be considered: * `IdentityUserIntegrationService` provides non-authorized services. This is not breaking the application, but should be taken care of. Since, everyone can use the service to retrieve some information for a certain user (for example, the role names of a user). -* Secondly, since integration services are not exposed by default anymore as explained in the *Exposing Integration Services* section above, you should explicitly enable exposing integration services. Otherwise, the operation will be failed and you get a `404` error from the identity microservice. +* Secondly, since integration services are not exposed by default anymore as explained in the *Exposing Integration Services* section above, you should explicitly enable exposing integration services. Otherwise, the operation will fail and you'll get a `404` error from the identity microservice. To expose integration services and controllers, you can configure the `AbpAspNetCoreMvcOptions` and set the `ExposeIntegrationServices` property as *true* in the `ConfigureServices` method of your [module class](../Module-Development-Basics.md): From 6c566d14943c2e93007e45b3f335ffd673d5318d Mon Sep 17 00:00:00 2001 From: Salih Date: Fri, 11 Aug 2023 11:46:14 +0300 Subject: [PATCH 147/165] Update localizations for commercial.abp.io --- .../Commercial/Localization/Resources/en.json | 5 +++-- .../Commercial/Localization/Resources/tr.json | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 02f8087299..bf90a666f7 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -501,6 +501,7 @@ "DoYouNeedTraining": "Do you need {0} training?", "GetInTouchUs": "Get in touch with us", "ForMoreInformationClickHere": "For more information, click here.", + "ForMoreInformationClickHereByClass": "For more information, click here.", "IsGetOnboardingTraining": "Would you like to get onboarding & web application development training?", "OnboardingWebApplicationDevelopmentTrainingMessage": "To schedule your training calendar, please contact {0} after creating the organization", "CustomPurchaseMessage": "For the next step, click {0} to contact us.", @@ -1041,7 +1042,7 @@ "EnterpriseApplicationRequirements_THEPROBLEM_Description6": "Enqueuing and executing background jobs.", "EnterpriseApplicationRequirements_THEPROBLEM_Description7": "Handling multiple time zones in a global system.", "EnterpriseApplicationRequirements_THEPROBLEM_Description8": "Sharing validation, localization, authorization logic between server and client.", - "EnterpriseApplicationRequirements_ABPSOLUTION_Description": "There is much more. ABP provides infrastructure to implement such requirements easily. Again, you don't spend your valuable time to re-implement all these again and again.", + "EnterpriseApplicationRequirements_ABPSOLUTION_Description": "ABP provides infrastructure to implement such requirements easily. Again, you don't spend your valuable time to re-implement all these again and again.", "GeneratingInitialCode&Tooling": "Generating Initial Code & Tooling", "GeneratingInitialCode&Tooling_THEPROBLEM_Description": "You will build many similar pages in a typical web application. Most of them will perform similar CRUD operations. It is very tedious and also error prone to repeatedly create such pages.", "GeneratingInitialCode&Tooling_ABPSOLUTION_Description": "ABP Suite can generate a full-stack CRUD page for your entities in seconds. The generated code is layered and clean. All the standard validation and authorization requirements are implemented. Plus, unit test classes are generated. Once you get a fully running page, you can modify it according to your business requirements.", @@ -1071,7 +1072,7 @@ "ABPCommunity_Description": "Finally, Being in a big community where everyone follows similar coding styles and principles and shares a common infrastructure brings power when you have troubles or need help with design decisions. Since we write code similarly, we can help each other much better. ABP is a community-backed project with more then 10K stars on GitHub.", "ABPCommunity_Description2": "It is easy to share code or even re-usable libraries between ABP developers. A code snippet that works for you will also work for others. There are a lot of samples and tutorials that you can directly implement for your application.", "ABPCommunity_Description3": "When you hire a developer who worked before with the ABP architecture will immediately understand your solution and start development in a very short time.", - "WhyAbpIo_Page_Title": "Why ABP Framework?", + "WhyAbpIo_Page_Title": "Why ABP.IO Platform?", "AbpStudio_Page_Title": "ABP Studio" } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json index e7781f9fe5..8d4f9cc6bc 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json @@ -511,6 +511,7 @@ "DoYouNeedTraining": "{0} eğitimine ihtiyacınız var mı?", "GetInTouchUs": "Bize Ulaşın", "ForMoreInformationClickHere": "Daha fazla bilgi için buraya tıklayın.", + "ForMoreInformationClickHereByClass": "Daha fazla bilgi için buraya tıklayın.", "IsGetOnboardingTraining": "İşe alım ve web uygulaması geliştirme eğitimi almak ister misiniz?", "OnboardingWebApplicationDevelopmentTrainingMessage": "Eğitim takviminizi planlamak için lütfen organizasyonu oluşturduktan sonra {0} ile iletişime geçin", "CustomPurchaseMessage": "Bir sonraki adım için, bizimle iletişime geçmek üzere {0}'a tıklayın.", From ade770da86e526e1438d70967906d5b0364e256c Mon Sep 17 00:00:00 2001 From: Salih Date: Fri, 11 Aug 2023 14:44:09 +0300 Subject: [PATCH 148/165] Update localizations from commercial.abp.io --- .../AbpIoLocalization/Commercial/Localization/Resources/ar.json | 2 +- .../AbpIoLocalization/Commercial/Localization/Resources/en.json | 2 +- .../AbpIoLocalization/Commercial/Localization/Resources/fi.json | 2 +- .../AbpIoLocalization/Commercial/Localization/Resources/hu.json | 2 +- .../AbpIoLocalization/Commercial/Localization/Resources/tr.json | 2 +- .../Commercial/Localization/Resources/zh-Hans.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json index a7cfc334a9..7226737b84 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json @@ -618,7 +618,7 @@ "TrialLicensePaymentInfoSection_Description": "شراء رخصة: بشراء رخصة، ستستمر في الحصول على الدعم المتميز. ستتمكن أيضًا من الحصول على تحديثات رئيسية أو ثانوية للوحدات والسمات. ستتمكن من الاستمرار في إنشاء مشاريع جديدة. وستظل قادرًا على استخدام ABP Suite مما يسرع من تطويرك.
راجع جدول مقارنة الرخصة للتحقق من الاختلافات بين أنواع الرخص.", "SelectTargetLicense": "حدد الرخصة المرادة", "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "نعم، قم بتمديد تاريخ انتهاء رخصتي لمدة عام واحد.", - "UpgradePaymentInfoSection_WantToExtendLicense": "هل تريد تمديد ترخيصك لمدة {0} سنة (سنوات) أخرى؟", + "UpgradePaymentInfoSection_WantToExtendLicense": "هل تريد تمديد ترخيصك لمدة 1 سنة (سنوات) أخرى؟", "UpgradePaymentInfoSection_UpgradingWillNotExtendLicense": "لن تؤدي الترقية إلى تمديد تاريخ انتهاء رخصتك!", "UpgradePaymentInfoSection_LicenseUpgradeDescription": "من خلال ترقية رخصتك، ستقوم بالترقية إلى نوع رخصة أعلى مما سيتيح لك الحصول على مزايا إضافية. راجع جدول مقارنة الرخص للتحقق من الاختلافات بين أنواع الرخص.", "Landing_Page_CustomerStories": "قصص العملاء", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index bf90a666f7..1b8c972d5c 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -644,7 +644,7 @@ "TrialLicensePaymentInfoSection_Description": "Purchase license: By purchasing a license, you will continue to get premium support. You will also be able to get major or minor updates for modules and themes. You will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development.
See the license comparison table to check the differences between the license types.", "SelectTargetLicense": "Select Target License", "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "Yes, extend my license expiration date for 1 year.", - "UpgradePaymentInfoSection_WantToExtendLicense": "Do you want to extend your license for {0} more year(s)?", + "UpgradePaymentInfoSection_WantToExtendLicense": "Do you want to extend your license for 1 more year?", "UpgradePaymentInfoSection_UpgradingWillNotExtendLicense": "Upgrading will not extend your license expiration date!", "UpgradePaymentInfoSection_LicenseUpgradeDescription": "By upgrading your license, you will promote to a higher license type which will allow you to get additional benefits. See the license comparison table to check the differences between the license types.", "Landing_Page_CustomerStories": "Customer Stories", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json index a4b3ac3a80..3e1b92ff90 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json @@ -642,7 +642,7 @@ "TrialLicensePaymentInfoSection_Description": "Osta käyttölupa: Ostamalla lisenssin saat edelleen premium-tuen. Voit myös saada suurempia tai pieniä päivityksiä moduuleille ja teemoille. Voit jatkaa uusien projektien luomista. Voit edelleen käyttää ABP Suitea, joka nopeuttaa kehitystäsi.
Katso käyttölupien vertailutaulukko, jolla voit tarkistaa lisenssityyppien väliset erot.", "SelectTargetLicense": "Valitse kohdelisenssi", "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "Kyllä, jatka lisenssini voimassaolopäivää 1 vuodella.", - "UpgradePaymentInfoSection_WantToExtendLicense": "Haluatko jatkaa lisenssiäsi vielä {0} vuodella?", + "UpgradePaymentInfoSection_WantToExtendLicense": "Haluatko jatkaa lisenssiäsi vielä 1 vuodella?", "UpgradePaymentInfoSection_UpgradingWillNotExtendLicense": "Päivitys ei pidennä lisenssisi vanhenemispäivää!", "UpgradePaymentInfoSection_LicenseUpgradeDescription": "Päivittämällä lisenssisi ylennät korkeampaan lisenssityyppiin, mikä antaa sinulle lisäetuja. Katso lisenssityyppien väliset erot lisenssivertailutaulukosta.", "Landing_Page_CustomerStories": "Asiakkaiden tarinoita", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json index 8b9fb041b7..351a468fe4 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json @@ -642,7 +642,7 @@ "TrialLicensePaymentInfoSection_Description": "Licensz vásárlása: licensz megvásárlásával továbbra is prémium támogatást kap . Emellett kisebb-nagyobb frissítéseket is kaphat a modulokhoz és témákhoz. Folytathatja új projektek létrehozását. És továbbra is használhatja az ABP Suite -ot, amely felgyorsítja a fejlesztést.
Tekintse meg a licensz-összehasonlító táblázatot a licensztípusok közötti különbségek ellenőrzéséhez.", "SelectTargetLicense": "Válassza a Target License lehetőséget", "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "Igen, meghosszabbítom az engedélyem lejárati dátumát 1 évvel.", - "UpgradePaymentInfoSection_WantToExtendLicense": "Szeretné meghosszabbítani licenszét további {0} évre?", + "UpgradePaymentInfoSection_WantToExtendLicense": "Szeretné meghosszabbítani licenszét további 1 évre?", "UpgradePaymentInfoSection_UpgradingWillNotExtendLicense": "A frissítés nem hosszabbítja meg a licensz lejárati dátumát!", "UpgradePaymentInfoSection_LicenseUpgradeDescription": "Licenszének frissítésével magasabb licensztípusra lép, amely további előnyökhöz juttatja Önt. Tekintse meg a licensz-összehasonlító táblázatot a licensztípusok közötti különbségek ellenőrzéséhez.", "Landing_Page_CustomerStories": "Ügyféltörténetek", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json index 8d4f9cc6bc..7c4df52c6c 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json @@ -651,7 +651,7 @@ "TrialLicensePaymentInfoSection_Description": "Lisans satın alma: Bir lisans satın alarak premium destek almaya devam edeceksiniz. Ayrıca modüller ve temalar için büyük veya küçük güncellemeler alabileceksiniz. Yeni projeler oluşturmaya devam edebileceksiniz. Ve gelişiminizi hızlandıran ABP Suite'i kullanmaya devam edebileceksiniz. Lisans türleri arasındaki farkları kontrol etmek için lisans karşılaştırma tablosuna bakın.", "SelectTargetLicense": "Hedef Lisansı Seçin", "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "Evet, lisansımın geçerlilik süresini 1 yıl uzatın.", - "UpgradePaymentInfoSection_WantToExtendLicense": "Lisansınızı {0} yıl daha uzatmak istiyor musunuz?", + "UpgradePaymentInfoSection_WantToExtendLicense": "Lisansınızı 1 yıl daha uzatmak istiyor musunuz?", "UpgradePaymentInfoSection_UpgradingWillNotExtendLicense": "Yükseltme işlemi lisansınızın son kullanma tarihini uzatmayacaktır!", "UpgradePaymentInfoSection_LicenseUpgradeDescription": "Lisansınızı yükselterek, ek avantajlar elde etmenizi sağlayacak daha yüksek bir lisans türüne terfi edeceksiniz. Lisans türleri arasındaki farkları kontrol etmek için lisans karşılaştırma tablosuna bakın.", "Landing_Page_CustomerStories": "Müşteri Hikayeleri", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json index 699cc0abf2..0aadd74a52 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json @@ -641,7 +641,7 @@ "TrialLicensePaymentInfoSection_Description": "购买许可证:通过购买许可证,您将继续获得高级支持。 您还将能够获得模块和主题的重大更新。 您将能够继续创建新项目。 而且您仍然可以使用 ABP 套件 加速您的开发。
请参阅 许可证比较表来查看许可证类型之间的差异。", "SelectTargetLicense": "选择目标许可证", "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "是的,将我的许可证到期日期延长 1 年。", - "UpgradePaymentInfoSection_WantToExtendLicense": "您想将许可证再延长 {0} 年吗?", + "UpgradePaymentInfoSection_WantToExtendLicense": "您想将许可证再延长 1 年吗?", "UpgradePaymentInfoSection_UpgradingWillNotExtendLicense": "升级不会延长您的许可证到期日期!", "UpgradePaymentInfoSection_LicenseUpgradeDescription": "通过升级您的许可证,您将升级到更高的许可证类型,这将使您获得额外的好处。 请参阅许可证比较表以查看许可证类型之间的差异。", "Landing_Page_CustomerStories": "客户故事", From 2b1e1ee7ee0bed22eb856ec350885f417590fafc Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 11 Aug 2023 15:59:33 +0300 Subject: [PATCH 149/165] sort navigation elements doc added to ui/angular/customization --- docs/en/docs-nav.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 08046fa664..afdf89657c 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -1188,6 +1188,10 @@ "text": "Modifying the Menu", "path": "UI/Angular/Modifying-the-Menu.md" }, + { + "text": "Sorting Navigation Elements", + "path": "UI/Angular/Sorting-Navigation-Elements.md" + }, { "text": "Component Replacement", "path": "UI/Angular/Component-Replacement.md" From 18fd9d94882188c3ee9a2194aedc8fbe67343434 Mon Sep 17 00:00:00 2001 From: Hamza Albreem <94292623+braim23@users.noreply.github.com> Date: Fri, 11 Aug 2023 18:07:51 +0300 Subject: [PATCH 150/165] Update Internet-Connection-Service.md --- docs/en/UI/Angular/Internet-Connection-Service.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/en/UI/Angular/Internet-Connection-Service.md b/docs/en/UI/Angular/Internet-Connection-Service.md index 9ef26a082e..d9002b660e 100644 --- a/docs/en/UI/Angular/Internet-Connection-Service.md +++ b/docs/en/UI/Angular/Internet-Connection-Service.md @@ -1,16 +1,16 @@ # Internet Connection Service -`InternetConnectionService` is a service which is exposed by `@abp/ng.core` package. **If you want to detect whether you are connected to the internet or not, you can use this service.** +`InternetConnectionService` is a service which is exposed by the `@abp/ng.core` package. **You can use this service in order to check your internet connection** ## Getting Started -When you inject InternetConnectionService you can get the current internet status also if status changes you can catch them immediately. +When you inject the InternetConnectionService you can get the current internet status, and it gets immediately updated if the status changes. -`InternetConnectionService` is providing 2 alternatives for catching network status; +`InternetConnectionService` provides two choices to catch the network status: 1. Signal (readonly) 2. Observable # How To Use -İt's easy just inject the service and get network status. +İt's easy, just inject the service and get the network status. **You can get via signal** ```ts @@ -19,7 +19,7 @@ class SomeComponent{ isOnline = this.internetConnectionService.networkStatus } ``` -**or you can get as observable** +**or you can get the observable** ```ts class SomeComponent{ internetConnectionService = inject(InternetConnectionService); @@ -27,4 +27,4 @@ class SomeComponent{ } ``` -To see how we implement to template, check `InternetConnectionStatusComponent` +To see how we implement to the template, check the `InternetConnectionStatusComponent` From 35fddf6da1aeb487478ea04d7145302a094eb860 Mon Sep 17 00:00:00 2001 From: Hamza Albreem <94292623+braim23@users.noreply.github.com> Date: Fri, 11 Aug 2023 18:21:30 +0300 Subject: [PATCH 151/165] Update Sorting-Navigation-Elements.md --- .../UI/Angular/Sorting-Navigation-Elements.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/en/UI/Angular/Sorting-Navigation-Elements.md b/docs/en/UI/Angular/Sorting-Navigation-Elements.md index e43de96993..3eac9901d6 100644 --- a/docs/en/UI/Angular/Sorting-Navigation-Elements.md +++ b/docs/en/UI/Angular/Sorting-Navigation-Elements.md @@ -1,13 +1,13 @@ # Sorting Navigation Elements -This documentation is describing how navigation elements sorted and how you can change this default behaviour. +This documentation describes how the navigation elements are sorted and how to change this default behaviour. -When you want to add `Navigation Element` you can use `RoutesService`. For more info [click here](https://docs.abp.io/en/abp/latest/UI/Angular/Modifying-the-Menu#how-to-add-a-navigation-element). -However, in this documentation, we will talk more about how to sort navigation elements via the `Routes Service` `order` attribute. +When you want to add the `Navigation Element` you can use the `RoutesService`. For more details, see the [document](https://docs.abp.io/en/abp/latest/UI/Angular/Modifying-the-Menu#how-to-add-a-navigation-element). +However, in this documentation, we will talk more about how to sort the navigation elements with the `order` attribute from the `Routes Service`. ### Order Property -- This parameter is optional and used for sorting purposes. -- If you define this property it will be sorted by default sorting function. +- This parameter is optional and is used for sorting purposes. +- If you define this property it will be sorted by the default sorting function. - You can edit this function. **Default Compare Function;** @@ -38,9 +38,9 @@ export function compareFuncFactory() { return fn; } ``` -**What this function do?** -- if order property defined, then it will be sorted by order value. -- if both navigation element has same order value then it will be sorted by name. -- If order property is not defined, it will be last element and sort by name between unordered navs. +**What does this function do?** +- if the order property is defined, then it will be sorted by the order value. +- if both of the navigation elements have the same order value then it will be sorted by the name. +- If the order property is not defined, it will be the last element and the unordered navs will be sorted by name. -You can edit this sorting function behaviour as you wish. \ No newline at end of file +You can edit this sorting function behaviour as you wish. From c4766e11853df4eece84037180f97ca6ce30adf6 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Fri, 11 Aug 2023 23:42:31 +0300 Subject: [PATCH 152/165] Initial commit for "ABP Commercial - GDPR Module Overview" community article --- .../POST.md | 53 ++++++++++++++++++ .../gdpr-personal-data-menu.png | Bin 0 -> 8878 bytes .../gdpr-personal-data-page.png | Bin 0 -> 36704 bytes 3 files changed, 53 insertions(+) create mode 100644 docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md create mode 100644 docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/gdpr-personal-data-menu.png create mode 100644 docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/gdpr-personal-data-page.png diff --git a/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md new file mode 100644 index 0000000000..a6e7d77b69 --- /dev/null +++ b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md @@ -0,0 +1,53 @@ +# ABP Commercial - GDPR Module Overview + +In this article, I will highlight the ABP Commercial's [GDPR Module](https://commercial.abp.io/modules/Volo.Gdpr) and show you how to provide personal data to the GDPR Module that collected by your application and make it aligned with personal data download result. + +## GDPR Module + +[GDPR Module](https://docs.abp.io/en/commercial/latest/modules/gdpr) allows users to download and delete their data collected by the application. It's used for Personal Data Management obligating by the GDPR regulation and provides the following features: + +* Allows users to request their personal data. +* Lists the personal data requests and users can download their personal data by the listed request times. +* Allows users to delete their personal data and their accounts permanently. + +The GDPR module is pre-installed in the [Application](https://docs.abp.io/en/commercial/latest/startup-templates/application/index) and [Application (Single Layer)](https://docs.abp.io/en/commercial/latest/startup-templates/application-single-layer/index) Pro Startup templates for ABP Commercial customers. Therefore, most of the time you don't need to manually install it. + +> If you need to install the GDPR Module manually, you can refer to the [GDPR Module documentation](https://docs.abp.io/en/commercial/latest/modules/gdpr#how-to-install). + +Let's create an Application template with the following command and see the UI for the GDPR module: + +```csharp +abp new GdprDemo -t app-pro +``` + +After the application is created, we can run the application and login. Then, when we check the user menu, we should be able to see the "Personal Data" menu item: + +![](./gdpr-personal-data-menu.png) + +We can click this menu item to see the "Personal Data Management" page: + +![](./gdpr-personal-data-page.png) + +This page is used to manage personal data requests. You can view the past requests, current status of the latest request, create a new personal data download request, download the prepared personal data or delete all your personal data (makes the data anonymized) and account from the application. + +### Downloading Personal Data + +After a quick overview of the GDPR module, now we can deep dive into the Personal Data Download process. + +The GDPR module requests the information from the other modules that reference the `Volo.Abp.Gdpr.Abstractions` package and merges the response data into a single JSON file and the personal data can be downloaded later by the user from the "Personal Data Management" when it's prepared (when the specified preperation time has been passed). + +Currently, only the [Identity Pro module](https://docs.abp.io/en/commercial/latest/modules/identity) provides some personal data to the GDPR Module because it's the only module that can be considered as collecting personal data, such as user's name, surname, email address and so on. Therefore, ABP makes the everything that needed such as getting all data collecting that when the personal data download request has been made or delete/anonymize the personal data when the personal data delete request has been made. + +This might be enough for some of your applications and you would not need to collect any other sensitive data from a user. However, most of the time you would probably need to collect some personal data from users for certain reasons. + +In that case, you should provide the personal data that you collected for a certain user in your application/module or provider to the GPDR module. So, when the personal data download request has been made, the GDPR module can request the information from the different part of your application and merges the response data into a single JSON file to be downloaded. + +In the next section, we will see how to provide personal data from a different module/provider within a scenerio. + +## Providing Personal Data + +//TODO: consider a scenerio!!! (getting address from a user might be used) + +## Conclusion + +In this article, I've explained the GDPR Module's data collection system and give you a brief overview of the module. \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/gdpr-personal-data-menu.png b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/gdpr-personal-data-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..ce9242373871bccd3a4a3149275cac6c63559c92 GIT binary patch literal 8878 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 Date: Sat, 12 Aug 2023 09:43:26 +0300 Subject: [PATCH 153/165] Update the gpdr module overview article --- .../POST.md | 105 +++++++++++++++++- .../personal-data-download.png | Bin 0 -> 28777 bytes 2 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/personal-data-download.png diff --git a/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md index a6e7d77b69..1fca1d8a13 100644 --- a/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md +++ b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md @@ -20,7 +20,7 @@ Let's create an Application template with the following command and see the UI f abp new GdprDemo -t app-pro ``` -After the application is created, we can run the application and login. Then, when we check the user menu, we should be able to see the "Personal Data" menu item: +After the application is created, we can run the application and login to the application. Then, when we check the user menu, we should be able to see the "Personal Data" menu item: ![](./gdpr-personal-data-menu.png) @@ -34,20 +34,113 @@ This page is used to manage personal data requests. You can view the past reques After a quick overview of the GDPR module, now we can deep dive into the Personal Data Download process. -The GDPR module requests the information from the other modules that reference the `Volo.Abp.Gdpr.Abstractions` package and merges the response data into a single JSON file and the personal data can be downloaded later by the user from the "Personal Data Management" when it's prepared (when the specified preperation time has been passed). +The GDPR module requests the information from the other modules that reference the `Volo.Abp.Gdpr.Abstractions` package and merges the response data into a single JSON file and the personal data can be downloaded later by the user from the "Personal Data Management" page when it's prepared (when the specified preperation time has been passed). Currently, only the [Identity Pro module](https://docs.abp.io/en/commercial/latest/modules/identity) provides some personal data to the GDPR Module because it's the only module that can be considered as collecting personal data, such as user's name, surname, email address and so on. Therefore, ABP makes the everything that needed such as getting all data collecting that when the personal data download request has been made or delete/anonymize the personal data when the personal data delete request has been made. This might be enough for some of your applications and you would not need to collect any other sensitive data from a user. However, most of the time you would probably need to collect some personal data from users for certain reasons. -In that case, you should provide the personal data that you collected for a certain user in your application/module or provider to the GPDR module. So, when the personal data download request has been made, the GDPR module can request the information from the different part of your application and merges the response data into a single JSON file to be downloaded. +In that case, you should provide the personal data that you collected for a certain user in your application/module or provider to the GPDR module. So, when the personal data download request has been made, the GDPR module can request the information from the different part of your application and merges the response data into a single JSON file to be downloaded. In other word, the data that provided by you will be considered as personal data and whenever a user request his/her personal data, it'll be included in the result. -In the next section, we will see how to provide personal data from a different module/provider within a scenerio. +In the next section, we will see how to provide personal data from a different module/provider. ## Providing Personal Data -//TODO: consider a scenerio!!! (getting address from a user might be used) +Let's assume that we have an e-commerce application and we need to get the address from a user to send their order. Address information is considered as personal data according to GDPR regulations. Therefore, we need to provide the address information to the GDPR Module. + +For this purpose, we need subscribe to the `GdprUserDataDeletionRequestedEto` and `GdprUserDataRequestEto` distributed events. These ETOs (event transfer objects) come from the `Volo.Abp.Gdpr.Abstractions` package, which are used to start deleting/anonymizing and download personal data requests. `Volo.Abp.Gdpr.Domain` package is pre-installed in the domain layer and has reference to that package, so most of the time you don't need to reference to the `Volo.Abp.Gdpr.Abstractions` package. + +But, if you want to use these ETOs in a different project, you should add the the `Volo.Abp.Gdpr.Abstractions` package. You can use the following command to add it yo your project: + +```bash +abp add-package Volo.Abp.Gdpr.Abstractions +``` + +After, we have ensured that we have reference to the package, then we can create a new event handler class named `AddressGdprEventHandler` and subscribe to the `GdprUserDataDeletionRequestedEto` and `GdprUserDataRequestEto` distributed events: + +```csharp +public class AddressGdprEventHandler : + IDistributedEventHandler, + IDistributedEventHandler, + ITransientDependency +{ + //inject your services + protected IDistributedEventBus EventBus { get; } + + public AddressGdprEventHandler(IDistributedEventBus eventBus) + { + EventBus = eventBus; + } + + public Task HandleEventAsync(GdprUserDataDeletionRequestedEto eventData) + { + //anonymize the personal data + + return Task.CompletedTask; + } + + public async Task HandleEventAsync(GdprUserDataRequestedEto eventData) + { + //assume we have retrieved the address for a certain user + //by querying eventData.UserId + var address = new Address + { + City = "Istanbul", + Postcode = "...", + + //other properties... + }; + + var gdprDataInfo = new GdprDataInfo + { + { "City", address.City }, + { "Postcode", address.Postcode } + }; + + await EventBus.PublishAsync( + new GdprUserDataPreparedEto + { + RequestId = eventData.RequestId, + Data = gdprDataInfo, //collected personal data + Provider = GetType().FullName //your module/provider name + }); + } +} +``` + +* Here, we have subscribed to the `GdprUserDataDeletionRequestedEto` and `GdprUserDataRequestEto` distributed events. +* When a user made a personal data preperation request, then the `GdprUserDataRequestEto` published by GDPR module and the data preparation process starts. Modules/providers provide sensitive personal data by subscribing to this event and publishing a `GdprUserDataPreparedEto` distributed event, with the data and the provider information. Thanks to this, you can distinguish the personal data by the collected provider/module. +* Then, the GDPR module subscribes to the `GdprUserDataPreparedEto` distributed events that published by multiple modules/providers, and merges the response data into a single JSON file and the personal data can be downloaded later by the user, when the data preperation is done. +* On the other hand, when a user made a request to delete his/her personal data from the application, the `GdprUserDataDeletionRequestedEto` being publish, so we can subscribe to the event and anonymize the personal data in our application. +* Also, the Identity Pro module, delete the user's account permenantly. + +Now, let's run the application once again and make a personal data download request. But before that we can configure the `AbpGdprOptions` as follows to not wait for long and show our personal data result: + +```csharp +Configure(options => +{ + options.MinutesForDataPreparation = 5; //wait 5 minutes for data-preperation +}); +``` + +After, we have made a personal data preperation request, we need to wait for 5 minutes to personal data to be collected and then we can download it. After 5 minutes have passed, we can see the "Download" action button for the request in the "Personal Data Management" page: + +![](./personal-data-download.png) + +Then, we can click the download button and a zip file will be downloaded. We can unzip the file and examine the JSON files that contains our personal data. If you follow and apply the steps from now, you should be seeing two JSON files. One of them for user specific information provided by Identity Pro module and the other one is the address information provided by us (our application specific personal data). + +*Basic information for the user:* + +```json +{"Username":"admin","Name":"admin","Surname":null,"Email":"admin@abp.io","Phone Number":null} +``` + +*Address information that we provided in this article:* + +```json +{"City":"Istanbul","Postcode":"..."} +``` ## Conclusion -In this article, I've explained the GDPR Module's data collection system and give you a brief overview of the module. \ No newline at end of file +In this article, I've explained the GDPR Module's data collection system and give you a brief overview about the module. GDPR Module allows you to request to download personal data, delete/anonymize your own personal data and delete your account permenantly. It's pre-installed in the Application and Application(single layer) Pro Startup templates, but you can easily configure it to your existing application. \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/personal-data-download.png b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/personal-data-download.png new file mode 100644 index 0000000000000000000000000000000000000000..2371e31beda81b6f5991132700d046c2959e5ba8 GIT binary patch literal 28777 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 PG>67CPSpPbnk(k9 literal 0 HcmV?d00001 From 703a53514b3e6362214e36bca7e3f6d088754ee1 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Sat, 12 Aug 2023 10:02:41 +0300 Subject: [PATCH 154/165] Finalize the gdpr module overview article --- .../POST.md | 38 +++++++++--------- .../personal-data-files.png | Bin 0 -> 7344 bytes 2 files changed, 20 insertions(+), 18 deletions(-) create mode 100644 docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/personal-data-files.png diff --git a/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md index 1fca1d8a13..65cc8e1140 100644 --- a/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md +++ b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md @@ -1,10 +1,10 @@ # ABP Commercial - GDPR Module Overview -In this article, I will highlight the ABP Commercial's [GDPR Module](https://commercial.abp.io/modules/Volo.Gdpr) and show you how to provide personal data to the GDPR Module that collected by your application and make it aligned with personal data download result. +In this article, I will highlight ABP Commercial's [GDPR Module](https://commercial.abp.io/modules/Volo.Gdpr) and show you how to provide personal data to the GDPR Module that is collected by your application and make it aligned with personal data download results. ## GDPR Module -[GDPR Module](https://docs.abp.io/en/commercial/latest/modules/gdpr) allows users to download and delete their data collected by the application. It's used for Personal Data Management obligating by the GDPR regulation and provides the following features: +[GDPR Module](https://docs.abp.io/en/commercial/latest/modules/gdpr) allows users to download and delete the data collected by the application. It's used for Personal Data Management obligating by the GDPR regulation and provides the following features: * Allows users to request their personal data. * Lists the personal data requests and users can download their personal data by the listed request times. @@ -24,23 +24,23 @@ After the application is created, we can run the application and login to the ap ![](./gdpr-personal-data-menu.png) -We can click this menu item to see the "Personal Data Management" page: +We can click this menu item to navigate to the "Personal Data Management" page: ![](./gdpr-personal-data-page.png) -This page is used to manage personal data requests. You can view the past requests, current status of the latest request, create a new personal data download request, download the prepared personal data or delete all your personal data (makes the data anonymized) and account from the application. +This page is used to manage personal data requests. You can view past requests, the current status of the latest request, create a new personal data download request, download the prepared personal data or delete all your personal data (makes the data anonymized) and account from the application. ### Downloading Personal Data After a quick overview of the GDPR module, now we can deep dive into the Personal Data Download process. -The GDPR module requests the information from the other modules that reference the `Volo.Abp.Gdpr.Abstractions` package and merges the response data into a single JSON file and the personal data can be downloaded later by the user from the "Personal Data Management" page when it's prepared (when the specified preperation time has been passed). +The GDPR module requests information from the other modules that reference the `Volo.Abp.Gdpr.Abstractions` package and merges the response data into a single JSON file and the personal data can be downloaded later by the user from the "Personal Data Management" page when it's prepared (when the specified preparation time has been passed). -Currently, only the [Identity Pro module](https://docs.abp.io/en/commercial/latest/modules/identity) provides some personal data to the GDPR Module because it's the only module that can be considered as collecting personal data, such as user's name, surname, email address and so on. Therefore, ABP makes the everything that needed such as getting all data collecting that when the personal data download request has been made or delete/anonymize the personal data when the personal data delete request has been made. +Currently, only the [Identity Pro module](https://docs.abp.io/en/commercial/latest/modules/identity) provides some personal data to the GDPR Module because it's the only module that can be considered as collecting personal data, such as the user's name, surname, email address, and so on. Therefore, ABP makes everything that is needed such as getting all data collected when the personal data download request has been made or deleting/anonymizing the personal data when the personal data delete request has been made. This might be enough for some of your applications and you would not need to collect any other sensitive data from a user. However, most of the time you would probably need to collect some personal data from users for certain reasons. -In that case, you should provide the personal data that you collected for a certain user in your application/module or provider to the GPDR module. So, when the personal data download request has been made, the GDPR module can request the information from the different part of your application and merges the response data into a single JSON file to be downloaded. In other word, the data that provided by you will be considered as personal data and whenever a user request his/her personal data, it'll be included in the result. +In that case, you should provide the personal data that you collected for a certain user in your application/module or provider to the GPDR module. So, when the personal data download request has been made, the GDPR module can request the information from the different part of your application and merges the response data into a single JSON file to be downloaded. In other words, the data provided by you will be considered as personal data and whenever a user requests his/her personal data, it'll be included in the result. In the next section, we will see how to provide personal data from a different module/provider. @@ -48,15 +48,15 @@ In the next section, we will see how to provide personal data from a different m Let's assume that we have an e-commerce application and we need to get the address from a user to send their order. Address information is considered as personal data according to GDPR regulations. Therefore, we need to provide the address information to the GDPR Module. -For this purpose, we need subscribe to the `GdprUserDataDeletionRequestedEto` and `GdprUserDataRequestEto` distributed events. These ETOs (event transfer objects) come from the `Volo.Abp.Gdpr.Abstractions` package, which are used to start deleting/anonymizing and download personal data requests. `Volo.Abp.Gdpr.Domain` package is pre-installed in the domain layer and has reference to that package, so most of the time you don't need to reference to the `Volo.Abp.Gdpr.Abstractions` package. +For this purpose, we need to subscribe to the `GdprUserDataDeletionRequestedEto` and `GdprUserDataRequestEto` distributed events. These ETOs (event transfer objects) come from the `Volo.Abp.Gdpr.Abstractions` package, which is used to start deleting/anonymizing and downloading personal data requests. `Volo.Abp.Gdpr.Domain` package is pre-installed in the domain layer and has reference to that package, so most of the time you don't need to reference to the `Volo.Abp.Gdpr.Abstractions` package. -But, if you want to use these ETOs in a different project, you should add the the `Volo.Abp.Gdpr.Abstractions` package. You can use the following command to add it yo your project: +But, if you want to use these ETOs in a different project, you should add the `Volo.Abp.Gdpr.Abstractions` package. You can use the following command to add it to your project: ```bash abp add-package Volo.Abp.Gdpr.Abstractions ``` -After, we have ensured that we have reference to the package, then we can create a new event handler class named `AddressGdprEventHandler` and subscribe to the `GdprUserDataDeletionRequestedEto` and `GdprUserDataRequestEto` distributed events: +After we have ensured that we have reference to the package, then we can create a new event handler class named `AddressGdprEventHandler` and subscribe to the `GdprUserDataDeletionRequestedEto` and `GdprUserDataRequestEto` distributed events: ```csharp public class AddressGdprEventHandler : @@ -109,12 +109,12 @@ public class AddressGdprEventHandler : ``` * Here, we have subscribed to the `GdprUserDataDeletionRequestedEto` and `GdprUserDataRequestEto` distributed events. -* When a user made a personal data preperation request, then the `GdprUserDataRequestEto` published by GDPR module and the data preparation process starts. Modules/providers provide sensitive personal data by subscribing to this event and publishing a `GdprUserDataPreparedEto` distributed event, with the data and the provider information. Thanks to this, you can distinguish the personal data by the collected provider/module. -* Then, the GDPR module subscribes to the `GdprUserDataPreparedEto` distributed events that published by multiple modules/providers, and merges the response data into a single JSON file and the personal data can be downloaded later by the user, when the data preperation is done. -* On the other hand, when a user made a request to delete his/her personal data from the application, the `GdprUserDataDeletionRequestedEto` being publish, so we can subscribe to the event and anonymize the personal data in our application. -* Also, the Identity Pro module, delete the user's account permenantly. +* When a user made a personal data preparation request, then the `GdprUserDataRequestEto` is published by th GDPR module and the data preparation process starts. Modules/providers provide sensitive personal data by subscribing to this event and publishing a `GdprUserDataPreparedEto` distributed event, with the data and the provider information. Thanks to this, you can distinguish the personal data by the collected provider/module. +* Then, the GDPR module subscribes to the `GdprUserDataPreparedEto` distributed events that are published by multiple modules/providers and merge the response data into a single JSON file, and the personal data can be downloaded later by the user when the data preparation is done. +* On the other hand, when a user made a request to delete his/her personal data from the application, the `GdprUserDataDeletionRequestedEto` is published, so we can subscribe to the event and anonymize the personal data in our application. +* Also, the Identity Pro module deletes the user's account permanently. -Now, let's run the application once again and make a personal data download request. But before that we can configure the `AbpGdprOptions` as follows to not wait for long and show our personal data result: +Now, let's run the application once again and make a personal data download request. But before that, we can configure the `AbpGdprOptions` as follows to not wait for long and show our personal data result: ```csharp Configure(options => @@ -123,11 +123,13 @@ Configure(options => }); ``` -After, we have made a personal data preperation request, we need to wait for 5 minutes to personal data to be collected and then we can download it. After 5 minutes have passed, we can see the "Download" action button for the request in the "Personal Data Management" page: +After we have made a personal data preparation request, we need to wait for 5 minutes for personal data to be collected and then we can download it. After 5 minutes have passed, we can see the "Download" action button for the request on the "Personal Data Management" page: ![](./personal-data-download.png) -Then, we can click the download button and a zip file will be downloaded. We can unzip the file and examine the JSON files that contains our personal data. If you follow and apply the steps from now, you should be seeing two JSON files. One of them for user specific information provided by Identity Pro module and the other one is the address information provided by us (our application specific personal data). +Then, when we clicked the download button, a zip file will be downloaded. We can unzip the file and examine the JSON files that contain our personal data. If you have followed and applied the steps from now, you should be seeing two JSON files. One of them is for user-specific information provided by the Identity Pro module and the other one is the address information provided by us (our application-specific personal data). + +![](./personal-data-files.png) *Basic information for the user:* @@ -143,4 +145,4 @@ Then, we can click the download button and a zip file will be downloaded. We can ## Conclusion -In this article, I've explained the GDPR Module's data collection system and give you a brief overview about the module. GDPR Module allows you to request to download personal data, delete/anonymize your own personal data and delete your account permenantly. It's pre-installed in the Application and Application(single layer) Pro Startup templates, but you can easily configure it to your existing application. \ No newline at end of file +In this article, I've explained the GDPR Module's data collection system and given you a brief overview of the module. GDPR Module allows you to request to download personal data, delete/anonymize your own personal data and delete your account permanently. It's pre-installed in the Application and Application(single layer) Pro Startup templates, but you can easily configure it to your existing application. \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/personal-data-files.png b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/personal-data-files.png new file mode 100644 index 0000000000000000000000000000000000000000..66edf52dffec25db4a90b0af6cbe7e883dfc550d GIT binary patch literal 7344 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 Date: Sat, 12 Aug 2023 15:02:26 +0300 Subject: [PATCH 155/165] Create cover-image.png --- .../cover-image.png | Bin 0 -> 423079 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/cover-image.png diff --git a/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/cover-image.png b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/cover-image.png new file mode 100644 index 0000000000000000000000000000000000000000..a733b688f6be24dd4d19ba1ab96a657ae6edfd20 GIT binary patch literal 423079 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
3Nsd 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�E{UkM`@5y=aCf!ztd`m-V$i# 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%0A_1vz| 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 Date: Sun, 13 Aug 2023 11:38:20 +0300 Subject: [PATCH 156/165] Fix typo on the gdpr module article --- .../2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md index 65cc8e1140..38cfab67e9 100644 --- a/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md +++ b/docs/en/Community-Articles/2023-08-12-ABP-Commercial-GDPR-Module-Overview/POST.md @@ -109,7 +109,7 @@ public class AddressGdprEventHandler : ``` * Here, we have subscribed to the `GdprUserDataDeletionRequestedEto` and `GdprUserDataRequestEto` distributed events. -* When a user made a personal data preparation request, then the `GdprUserDataRequestEto` is published by th GDPR module and the data preparation process starts. Modules/providers provide sensitive personal data by subscribing to this event and publishing a `GdprUserDataPreparedEto` distributed event, with the data and the provider information. Thanks to this, you can distinguish the personal data by the collected provider/module. +* When a user made a personal data preparation request, then the `GdprUserDataRequestEto` is published by the GDPR module and the data preparation process starts. Modules/providers provide sensitive personal data by subscribing to this event and publishing a `GdprUserDataPreparedEto` distributed event, with the data and the provider information. Thanks to this, you can distinguish the personal data by the collected provider/module. * Then, the GDPR module subscribes to the `GdprUserDataPreparedEto` distributed events that are published by multiple modules/providers and merge the response data into a single JSON file, and the personal data can be downloaded later by the user when the data preparation is done. * On the other hand, when a user made a request to delete his/her personal data from the application, the `GdprUserDataDeletionRequestedEto` is published, so we can subscribe to the event and anonymize the personal data in our application. * Also, the Identity Pro module deletes the user's account permanently. @@ -145,4 +145,4 @@ Then, when we clicked the download button, a zip file will be downloaded. We can ## Conclusion -In this article, I've explained the GDPR Module's data collection system and given you a brief overview of the module. GDPR Module allows you to request to download personal data, delete/anonymize your own personal data and delete your account permanently. It's pre-installed in the Application and Application(single layer) Pro Startup templates, but you can easily configure it to your existing application. \ No newline at end of file +In this article, I've explained the GDPR Module's data collection system and given you a brief overview of the module. GDPR Module allows you to request to download personal data, delete/anonymize your own personal data and delete your account permanently. It's pre-installed in the Application and Application(single layer) Pro Startup templates, but you can easily configure it to your existing application. From 39805fd03176adf9afadef607049741ebbe0ecbf Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 14 Aug 2023 09:15:26 +0800 Subject: [PATCH 157/165] Output security logs correctly. Resolve #17361 --- .../Controllers/TokenController.Password.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.Password.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.Password.cs index 33b01a7449..9617d4f409 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.Password.cs +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.Password.cs @@ -96,6 +96,14 @@ public partial class TokenController var result = await SignInManager.CheckPasswordSignInAsync(user, request.Password, true); if (!result.Succeeded) { + await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext + { + Identity = OpenIddictSecurityLogIdentityConsts.OpenIddict, + Action = result.ToIdentitySecurityLogAction(), + UserName = request.Username, + ClientId = request.ClientId + }); + string errorDescription; if (result.IsLockedOut) { @@ -138,14 +146,6 @@ public partial class TokenController return await HandleTwoFactorLoginAsync(request, user); } - await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext - { - Identity = OpenIddictSecurityLogIdentityConsts.OpenIddict, - Action = result.ToIdentitySecurityLogAction(), - UserName = request.Username, - ClientId = request.ClientId - }); - return await SetSuccessResultAsync(request, user); } } From a8d671fa051be5915be5697e24823fdd683faf09 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 14 Aug 2023 11:07:05 +0800 Subject: [PATCH 158/165] Encode the `returnUrl` if it start with `/connect/authorize?`. --- .../Volo/Abp/Account/Emailing/AccountEmailer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs b/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs index a997435168..4c5ab17ef3 100644 --- a/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs +++ b/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs @@ -101,6 +101,11 @@ public class AccountEmailer : IAccountEmailer, ITransientDependency } } + if (returnUrl.StartsWith("/connect/authorize?", StringComparison.OrdinalIgnoreCase)) + { + return HttpUtility.UrlEncode(returnUrl); + } + return returnUrl; } } From 905c3653422b6594fa5709b35005738914ba793b Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 14 Aug 2023 11:09:24 +0800 Subject: [PATCH 159/165] Revert "Encode `returnUrl` when sending `PasswordReset` email.." --- .../Volo/Abp/Account/Emailing/AccountEmailer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs b/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs index 783e23e456..a997435168 100644 --- a/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs +++ b/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs @@ -53,7 +53,7 @@ public class AccountEmailer : IAccountEmailer, ITransientDependency if (!returnUrl.IsNullOrEmpty()) { - link += "&returnUrl=" + UrlEncoder.Default.Encode(NormalizeReturnUrl(returnUrl)); + link += "&returnUrl=" + NormalizeReturnUrl(returnUrl); } if (!returnUrlHash.IsNullOrEmpty()) From e8fb08cf38a8244aac906e26c32fc189fd0b2d4a Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 14 Aug 2023 14:15:30 +0800 Subject: [PATCH 160/165] Regenerate proxy files for all modules. Resolve #17349 --- .../Account}/AccountClientProxy.Generated.cs | 10 +- .../Abp/Account}/AccountClientProxy.cs | 2 +- .../Account}/ProfileClientProxy.Generated.cs | 10 +- .../Abp/Account}/ProfileClientProxy.cs | 2 +- .../ClientProxies/account-generate-proxy.json | 123 ++- .../BlogManagementClientProxy.Generated.cs | 8 +- .../Admin}/BlogManagementClientProxy.cs | 2 +- .../bloggingAdmin-generate-proxy.json | 109 ++- .../MembersClientProxy.Generated.cs | 36 - .../ClientProxies/MembersClientProxy.cs | 7 - .../BlogFilesClientProxy.Generated.cs | 10 +- .../Blogging}/BlogFilesClientProxy.cs | 2 +- .../Blogging}/BlogsClientProxy.Generated.cs | 8 +- .../{ => Volo/Blogging}/BlogsClientProxy.cs | 2 +- .../CommentsClientProxy.Generated.cs | 9 +- .../Blogging}/CommentsClientProxy.cs | 2 +- .../Blogging}/PostsClientProxy.Generated.cs | 11 +- .../{ => Volo/Blogging}/PostsClientProxy.cs | 2 +- .../Blogging}/TagsClientProxy.Generated.cs | 9 +- .../{ => Volo/Blogging}/TagsClientProxy.cs | 2 +- .../blogging-generate-proxy.json | 505 +++++++++- .../wwwroot/client-proxies/blogging-proxy.js | 35 +- .../Blogs}/BlogAdminClientProxy.Generated.cs | 8 +- .../Admin/Blogs}/BlogAdminClientProxy.cs | 2 +- .../BlogFeatureAdminClientProxy.Generated.cs | 9 +- .../Blogs}/BlogFeatureAdminClientProxy.cs | 2 +- .../BlogPostAdminClientProxy.Generated.cs | 8 +- .../Admin/Blogs}/BlogPostAdminClientProxy.cs | 2 +- .../CommentAdminClientProxy.Generated.cs | 8 +- .../Comments}/CommentAdminClientProxy.cs | 2 +- ...lobalResourceAdminClientProxy.Generated.cs | 8 +- .../GlobalResourceAdminClientProxy.cs | 2 +- ...diaDescriptorAdminClientProxy.Generated.cs | 8 +- .../MediaDescriptorAdminClientProxy.cs | 2 +- .../MenuItemAdminClientProxy.Generated.cs | 8 +- .../Admin/Menus}/MenuItemAdminClientProxy.cs | 2 +- .../Pages}/PageAdminClientProxy.Generated.cs | 8 +- .../Admin/Pages}/PageAdminClientProxy.cs | 2 +- .../EntityTagAdminClientProxy.Generated.cs | 8 +- .../Admin/Tags}/EntityTagAdminClientProxy.cs | 2 +- .../Tags}/TagAdminClientProxy.Generated.cs | 9 +- .../CmsKit/Admin/Tags}/TagAdminClientProxy.cs | 2 +- .../cms-kit-admin-generate-proxy.json | 887 +++++++++++++++++- .../wwwroot/client-proxies/cms-kit-proxy.js | 236 +++++ .../DocumentsAdminClientProxy.Generated.cs | 9 +- .../Docs/Admin}/DocumentsAdminClientProxy.cs | 2 +- .../ProjectsAdminClientProxy.Generated.cs | 9 +- .../Docs/Admin}/ProjectsAdminClientProxy.cs | 2 +- .../docs-admin-generate-proxy.json | 262 +++++- .../client-proxies/docs-admin-proxy.js | 2 +- .../ClientProxies/docs-generate-proxy.json | 84 -- .../wwwroot/client-proxies/docs-proxy.js | 15 - .../FeaturesClientProxy.Generated.cs | 10 +- .../FeatureManagement}/FeaturesClientProxy.cs | 2 +- .../featureManagement-generate-proxy.json | 89 +- .../IdentityRoleClientProxy.Generated.cs | 8 +- .../Abp/Identity}/IdentityRoleClientProxy.cs | 2 +- .../IdentityUserClientProxy.Generated.cs | 8 +- .../Abp/Identity}/IdentityUserClientProxy.cs | 2 +- ...IdentityUserLookupClientProxy.Generated.cs | 8 +- .../IdentityUserLookupClientProxy.cs | 2 +- .../TenantClientProxy.Generated.cs | 8 +- .../TenantManagement}/TenantClientProxy.cs | 2 +- .../multi-tenancy-generate-proxy.json | 160 +++- 64 files changed, 2513 insertions(+), 304 deletions(-) rename modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/{ => Volo/Abp/Account}/AccountClientProxy.Generated.cs (95%) rename modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/{ => Volo/Abp/Account}/AccountClientProxy.cs (78%) rename modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/{ => Volo/Abp/Account}/ProfileClientProxy.Generated.cs (94%) rename modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/{ => Volo/Abp/Account}/ProfileClientProxy.cs (78%) rename modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/{ => Volo/Blogging/Admin}/BlogManagementClientProxy.Generated.cs (96%) rename modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/{ => Volo/Blogging/Admin}/BlogManagementClientProxy.cs (79%) delete mode 100644 modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/MembersClientProxy.Generated.cs delete mode 100644 modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/MembersClientProxy.cs rename modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/{ => Volo/Blogging}/BlogFilesClientProxy.Generated.cs (94%) rename modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/{ => Volo/Blogging}/BlogFilesClientProxy.cs (80%) rename modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/{ => Volo/Blogging}/BlogsClientProxy.Generated.cs (94%) rename modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/{ => Volo/Blogging}/BlogsClientProxy.cs (79%) rename modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/{ => Volo/Blogging}/CommentsClientProxy.Generated.cs (97%) rename modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/{ => Volo/Blogging}/CommentsClientProxy.cs (80%) rename modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/{ => Volo/Blogging}/PostsClientProxy.Generated.cs (91%) rename modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/{ => Volo/Blogging}/PostsClientProxy.cs (79%) rename modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/{ => Volo/Blogging}/TagsClientProxy.Generated.cs (95%) rename modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/{ => Volo/Blogging}/TagsClientProxy.cs (79%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Blogs}/BlogAdminClientProxy.Generated.cs (95%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Blogs}/BlogAdminClientProxy.cs (76%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Blogs}/BlogFeatureAdminClientProxy.Generated.cs (96%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Blogs}/BlogFeatureAdminClientProxy.cs (78%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Blogs}/BlogPostAdminClientProxy.Generated.cs (97%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Blogs}/BlogPostAdminClientProxy.cs (77%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Comments}/CommentAdminClientProxy.Generated.cs (94%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Comments}/CommentAdminClientProxy.cs (76%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/GlobalResources}/GlobalResourceAdminClientProxy.Generated.cs (91%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/GlobalResources}/GlobalResourceAdminClientProxy.cs (75%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/MediaDescriptors}/MediaDescriptorAdminClientProxy.Generated.cs (92%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/MediaDescriptors}/MediaDescriptorAdminClientProxy.cs (75%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Menus}/MenuItemAdminClientProxy.Generated.cs (96%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Menus}/MenuItemAdminClientProxy.cs (77%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Pages}/PageAdminClientProxy.Generated.cs (96%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Pages}/PageAdminClientProxy.cs (76%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Tags}/EntityTagAdminClientProxy.Generated.cs (94%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Tags}/EntityTagAdminClientProxy.cs (77%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Tags}/TagAdminClientProxy.Generated.cs (97%) rename modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/{ => Volo/CmsKit/Admin/Tags}/TagAdminClientProxy.cs (76%) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Web/wwwroot/client-proxies/cms-kit-proxy.js rename modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/{ => Volo/Docs/Admin}/DocumentsAdminClientProxy.Generated.cs (98%) rename modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/{ => Volo/Docs/Admin}/DocumentsAdminClientProxy.cs (80%) rename modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/{ => Volo/Docs/Admin}/ProjectsAdminClientProxy.Generated.cs (98%) rename modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/{ => Volo/Docs/Admin}/ProjectsAdminClientProxy.cs (80%) rename modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/{ => Volo/Abp/FeatureManagement}/FeaturesClientProxy.Generated.cs (94%) rename modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/{ => Volo/Abp/FeatureManagement}/FeaturesClientProxy.cs (75%) rename modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/{ => Volo/Abp/Identity}/IdentityRoleClientProxy.Generated.cs (96%) rename modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/{ => Volo/Abp/Identity}/IdentityRoleClientProxy.cs (79%) rename modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/{ => Volo/Abp/Identity}/IdentityUserClientProxy.Generated.cs (97%) rename modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/{ => Volo/Abp/Identity}/IdentityUserClientProxy.cs (79%) rename modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/{ => Volo/Abp/Identity}/IdentityUserLookupClientProxy.Generated.cs (95%) rename modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/{ => Volo/Abp/Identity}/IdentityUserLookupClientProxy.cs (80%) rename modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/{ => Volo/Abp/TenantManagement}/TenantClientProxy.Generated.cs (96%) rename modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/{ => Volo/Abp/TenantManagement}/TenantClientProxy.cs (75%) diff --git a/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/AccountClientProxy.Generated.cs b/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/AccountClientProxy.Generated.cs similarity index 95% rename from modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/AccountClientProxy.Generated.cs rename to modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/AccountClientProxy.Generated.cs index b92a60a604..7016b5f8ea 100644 --- a/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/AccountClientProxy.Generated.cs +++ b/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/AccountClientProxy.Generated.cs @@ -1,16 +1,18 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Account; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; -using Volo.Abp.Account; +using Volo.Abp.Http.Modeling; using Volo.Abp.Identity; // ReSharper disable once CheckNamespace -namespace Volo.Abp.Account.ClientProxies; +namespace Volo.Abp.Account; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IAccountAppService), typeof(AccountClientProxy))] diff --git a/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/AccountClientProxy.cs b/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/AccountClientProxy.cs similarity index 78% rename from modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/AccountClientProxy.cs rename to modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/AccountClientProxy.cs index 08b4a59954..31a500fcde 100644 --- a/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/AccountClientProxy.cs +++ b/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/AccountClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of AccountClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Abp.Account.ClientProxies; +namespace Volo.Abp.Account; public partial class AccountClientProxy { diff --git a/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/ProfileClientProxy.Generated.cs b/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/ProfileClientProxy.Generated.cs similarity index 94% rename from modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/ProfileClientProxy.Generated.cs rename to modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/ProfileClientProxy.Generated.cs index 1c2ae7b3d8..6164530553 100644 --- a/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/ProfileClientProxy.Generated.cs +++ b/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/ProfileClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Account; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; -using Volo.Abp.Account; +using Volo.Abp.Http.Modeling; // ReSharper disable once CheckNamespace -namespace Volo.Abp.Account.ClientProxies; +namespace Volo.Abp.Account; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IProfileAppService), typeof(ProfileClientProxy))] diff --git a/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/ProfileClientProxy.cs b/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/ProfileClientProxy.cs similarity index 78% rename from modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/ProfileClientProxy.cs rename to modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/ProfileClientProxy.cs index 6153620a8b..17a0ad1a20 100644 --- a/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/ProfileClientProxy.cs +++ b/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/Volo/Abp/Account/ProfileClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of ProfileClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Abp.Account.ClientProxies; +namespace Volo.Abp.Account; public partial class ProfileClientProxy { diff --git a/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/account-generate-proxy.json b/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/account-generate-proxy.json index 1fd443328a..24bd9c6079 100644 --- a/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/account-generate-proxy.json +++ b/modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/account-generate-proxy.json @@ -8,11 +8,83 @@ "controllerName": "Account", "controllerGroupName": "Account", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.Abp.Account.AccountController", "interfaces": [ { - "type": "Volo.Abp.Account.IAccountAppService" + "type": "Volo.Abp.Account.IAccountAppService", + "name": "IAccountAppService", + "methods": [ + { + "name": "RegisterAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.RegisterDto, Volo.Abp.Account.Application.Contracts", + "type": "Volo.Abp.Account.RegisterDto", + "typeSimple": "Volo.Abp.Account.RegisterDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentityUserDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserDto" + } + }, + { + "name": "SendPasswordResetCodeAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.SendPasswordResetCodeDto, Volo.Abp.Account.Application.Contracts", + "type": "Volo.Abp.Account.SendPasswordResetCodeDto", + "typeSimple": "Volo.Abp.Account.SendPasswordResetCodeDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "VerifyPasswordResetTokenAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.VerifyPasswordResetTokenInput, Volo.Abp.Account.Application.Contracts", + "type": "Volo.Abp.Account.VerifyPasswordResetTokenInput", + "typeSimple": "Volo.Abp.Account.VerifyPasswordResetTokenInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Boolean", + "typeSimple": "boolean" + } + }, + { + "name": "ResetPasswordAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.ResetPasswordDto, Volo.Abp.Account.Application.Contracts", + "type": "Volo.Abp.Account.ResetPasswordDto", + "typeSimple": "Volo.Abp.Account.ResetPasswordDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { @@ -170,6 +242,7 @@ "controllerName": "Account", "controllerGroupName": "Login", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.Abp.Account.Web.Areas.Account.Controllers.AccountController", "interfaces": [], @@ -269,11 +342,57 @@ "controllerName": "Profile", "controllerGroupName": "Profile", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.Abp.Account.ProfileController", "interfaces": [ { - "type": "Volo.Abp.Account.IProfileAppService" + "type": "Volo.Abp.Account.IProfileAppService", + "name": "IProfileAppService", + "methods": [ + { + "name": "GetAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "Volo.Abp.Account.ProfileDto", + "typeSimple": "Volo.Abp.Account.ProfileDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.UpdateProfileDto, Volo.Abp.Account.Application.Contracts", + "type": "Volo.Abp.Account.UpdateProfileDto", + "typeSimple": "Volo.Abp.Account.UpdateProfileDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Account.ProfileDto", + "typeSimple": "Volo.Abp.Account.ProfileDto" + } + }, + { + "name": "ChangePasswordAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.ChangePasswordInput, Volo.Abp.Account.Application.Contracts", + "type": "Volo.Abp.Account.ChangePasswordInput", + "typeSimple": "Volo.Abp.Account.ChangePasswordInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { diff --git a/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/BlogManagementClientProxy.Generated.cs b/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/Volo/Blogging/Admin/BlogManagementClientProxy.Generated.cs similarity index 96% rename from modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/BlogManagementClientProxy.Generated.cs rename to modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/Volo/Blogging/Admin/BlogManagementClientProxy.Generated.cs index bfa96d50e9..80700cc604 100644 --- a/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/BlogManagementClientProxy.Generated.cs +++ b/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/Volo/Blogging/Admin/BlogManagementClientProxy.Generated.cs @@ -1,16 +1,18 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Blogging.Admin.Blogs; using Volo.Blogging.Blogs.Dtos; // ReSharper disable once CheckNamespace -namespace Volo.Blogging.Admin.ClientProxies; +namespace Volo.Blogging.Admin; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IBlogManagementAppService), typeof(BlogManagementClientProxy))] diff --git a/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/BlogManagementClientProxy.cs b/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/Volo/Blogging/Admin/BlogManagementClientProxy.cs similarity index 79% rename from modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/BlogManagementClientProxy.cs rename to modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/Volo/Blogging/Admin/BlogManagementClientProxy.cs index 5c8089f1b3..02f6f9b491 100644 --- a/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/BlogManagementClientProxy.cs +++ b/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/Volo/Blogging/Admin/BlogManagementClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of BlogManagementClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Blogging.Admin.ClientProxies; +namespace Volo.Blogging.Admin; public partial class BlogManagementClientProxy { diff --git a/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/bloggingAdmin-generate-proxy.json b/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/bloggingAdmin-generate-proxy.json index 01a6fc3d82..73fc925962 100644 --- a/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/bloggingAdmin-generate-proxy.json +++ b/modules/blogging/src/Volo.Blogging.Admin.HttpApi.Client/ClientProxies/bloggingAdmin-generate-proxy.json @@ -7,10 +7,117 @@ "Volo.Blogging.Admin.BlogManagementController": { "controllerName": "BlogManagement", "controllerGroupName": "BlogManagement", + "isRemoteService": true, + "isIntegrationService": false, + "apiVersion": null, "type": "Volo.Blogging.Admin.BlogManagementController", "interfaces": [ { - "type": "Volo.Blogging.Admin.Blogs.IBlogManagementAppService" + "type": "Volo.Blogging.Admin.Blogs.IBlogManagementAppService", + "name": "IBlogManagementAppService", + "methods": [ + { + "name": "GetListAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Blogs.Dtos.BlogDto", + "typeSimple": "Volo.Blogging.Blogs.Dtos.BlogDto" + } + }, + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Blogging.Admin.Blogs.CreateBlogDto, Volo.Blogging.Admin.Application.Contracts", + "type": "Volo.Blogging.Admin.Blogs.CreateBlogDto", + "typeSimple": "Volo.Blogging.Admin.Blogs.CreateBlogDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Blogs.Dtos.BlogDto", + "typeSimple": "Volo.Blogging.Blogs.Dtos.BlogDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Blogging.Admin.Blogs.UpdateBlogDto, Volo.Blogging.Admin.Application.Contracts", + "type": "Volo.Blogging.Admin.Blogs.UpdateBlogDto", + "typeSimple": "Volo.Blogging.Admin.Blogs.UpdateBlogDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Blogs.Dtos.BlogDto", + "typeSimple": "Volo.Blogging.Blogs.Dtos.BlogDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "ClearCacheAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/MembersClientProxy.Generated.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/MembersClientProxy.Generated.cs deleted file mode 100644 index 4a563e79e3..0000000000 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/MembersClientProxy.Generated.cs +++ /dev/null @@ -1,36 +0,0 @@ -// This file is automatically generated by ABP framework to use MVC Controllers from CSharp -using System; -using System.Threading.Tasks; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Http.Client.ClientProxying; -using Volo.Blogging.Blogs; -using Volo.Blogging.Blogs.Dtos; -using Volo.Blogging.Members; -using Volo.Blogging.Posts; - -// ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; - -[Dependency(ReplaceServices = true)] -[ExposeServices(typeof(IMemberAppService), typeof(MembersClientProxy))] -public partial class MembersClientProxy : ClientProxyBase, IMemberAppService -{ - public Task FindAsync(string username) - { - return RequestAsync(nameof(FindAsync), new ClientProxyRequestTypeValue - { - { typeof(string), username } - }); - } - - public Task UpdateUserProfileAsync(CustomIdentityBlogUserUpdateDto input) - { - return RequestAsync(nameof(UpdateUserProfileAsync), new ClientProxyRequestTypeValue - { - { typeof(CustomIdentityBlogUserUpdateDto), input } - }); - } -} diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/MembersClientProxy.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/MembersClientProxy.cs deleted file mode 100644 index 61e4f3df1e..0000000000 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/MembersClientProxy.cs +++ /dev/null @@ -1,7 +0,0 @@ -// This file is part of MembersClientProxy, you can customize it here -// ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; - -public partial class MembersClientProxy -{ -} diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogFilesClientProxy.Generated.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogFilesClientProxy.Generated.cs similarity index 94% rename from modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogFilesClientProxy.Generated.cs rename to modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogFilesClientProxy.Generated.cs index ca1e2d5378..aab22a461d 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogFilesClientProxy.Generated.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogFilesClientProxy.Generated.cs @@ -1,16 +1,18 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; +using Volo.Abp.Content; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Blogging.Files; -using Volo.Abp.Content; // ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; +namespace Volo.Blogging; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IFileAppService), typeof(BlogFilesClientProxy))] diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogFilesClientProxy.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogFilesClientProxy.cs similarity index 80% rename from modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogFilesClientProxy.cs rename to modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogFilesClientProxy.cs index d37240531c..9a077c28a6 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogFilesClientProxy.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogFilesClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of BlogFilesClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; +namespace Volo.Blogging; public partial class BlogFilesClientProxy { diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogsClientProxy.Generated.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogsClientProxy.Generated.cs similarity index 94% rename from modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogsClientProxy.Generated.cs rename to modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogsClientProxy.Generated.cs index 72d8cf360c..eac02c12cb 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogsClientProxy.Generated.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogsClientProxy.Generated.cs @@ -1,16 +1,18 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Blogging.Blogs; using Volo.Blogging.Blogs.Dtos; // ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; +namespace Volo.Blogging; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IBlogAppService), typeof(BlogsClientProxy))] diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogsClientProxy.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogsClientProxy.cs similarity index 79% rename from modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogsClientProxy.cs rename to modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogsClientProxy.cs index 91ad5b4d0c..ba6eadd32c 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/BlogsClientProxy.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/BlogsClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of BlogsClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; +namespace Volo.Blogging; public partial class BlogsClientProxy { diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/CommentsClientProxy.Generated.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/CommentsClientProxy.Generated.cs similarity index 97% rename from modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/CommentsClientProxy.Generated.cs rename to modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/CommentsClientProxy.Generated.cs index b512aafb9e..4bce634b2e 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/CommentsClientProxy.Generated.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/CommentsClientProxy.Generated.cs @@ -1,17 +1,18 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Blogging.Comments; -using System.Collections.Generic; using Volo.Blogging.Comments.Dtos; // ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; +namespace Volo.Blogging; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(ICommentAppService), typeof(CommentsClientProxy))] diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/CommentsClientProxy.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/CommentsClientProxy.cs similarity index 80% rename from modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/CommentsClientProxy.cs rename to modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/CommentsClientProxy.cs index 96043bcc66..df4ac2e6e6 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/CommentsClientProxy.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/CommentsClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of CommentsClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; +namespace Volo.Blogging; public partial class CommentsClientProxy { diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/PostsClientProxy.Generated.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/PostsClientProxy.Generated.cs similarity index 91% rename from modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/PostsClientProxy.Generated.cs rename to modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/PostsClientProxy.Generated.cs index 7f730ee3f2..bfc0e856b2 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/PostsClientProxy.Generated.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/PostsClientProxy.Generated.cs @@ -2,15 +2,16 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Blogging.Posts; // ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; +namespace Volo.Blogging; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IPostAppService), typeof(PostsClientProxy))] @@ -74,9 +75,9 @@ public partial class PostsClientProxy : ClientProxyBase, IPostA }); } - public Task> GetLatestBlogPostsAsync(Guid blogId, int count) + public virtual async Task> GetLatestBlogPostsAsync(Guid blogId, int count) { - return RequestAsync>(nameof(GetLatestBlogPostsAsync), new ClientProxyRequestTypeValue + return await RequestAsync>(nameof(GetLatestBlogPostsAsync), new ClientProxyRequestTypeValue { { typeof(Guid), blogId }, { typeof(int), count } diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/PostsClientProxy.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/PostsClientProxy.cs similarity index 79% rename from modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/PostsClientProxy.cs rename to modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/PostsClientProxy.cs index 49d0334dda..cdd2437ad6 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/PostsClientProxy.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/PostsClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of PostsClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; +namespace Volo.Blogging; public partial class PostsClientProxy { diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/TagsClientProxy.Generated.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/TagsClientProxy.Generated.cs similarity index 95% rename from modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/TagsClientProxy.Generated.cs rename to modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/TagsClientProxy.Generated.cs index 37762c02e8..c1e8187999 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/TagsClientProxy.Generated.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/TagsClientProxy.Generated.cs @@ -1,17 +1,18 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Blogging.Tagging; -using System.Collections.Generic; using Volo.Blogging.Tagging.Dtos; // ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; +namespace Volo.Blogging; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(ITagAppService), typeof(TagsClientProxy))] diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/TagsClientProxy.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/TagsClientProxy.cs similarity index 79% rename from modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/TagsClientProxy.cs rename to modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/TagsClientProxy.cs index 5ba235ea06..92b53c15ee 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/TagsClientProxy.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/Volo/Blogging/TagsClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of TagsClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Blogging.ClientProxies; +namespace Volo.Blogging; public partial class TagsClientProxy { diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/blogging-generate-proxy.json b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/blogging-generate-proxy.json index 7e4ba7ef13..68a7e59fbc 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/blogging-generate-proxy.json +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/blogging-generate-proxy.json @@ -7,10 +7,67 @@ "Volo.Blogging.BlogFilesController": { "controllerName": "BlogFiles", "controllerGroupName": "BlogFiles", + "isRemoteService": true, + "isIntegrationService": false, + "apiVersion": null, "type": "Volo.Blogging.BlogFilesController", "interfaces": [ { - "type": "Volo.Blogging.Files.IFileAppService" + "type": "Volo.Blogging.Files.IFileAppService", + "name": "IFileAppService", + "methods": [ + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "name", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Files.RawFileDto", + "typeSimple": "Volo.Blogging.Files.RawFileDto" + } + }, + { + "name": "GetFileAsync", + "parametersOnMethod": [ + { + "name": "name", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Content.IRemoteStreamContent", + "typeSimple": "Volo.Abp.Content.IRemoteStreamContent" + } + }, + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Blogging.Files.FileUploadInputDto, Volo.Blogging.Application.Contracts", + "type": "Volo.Blogging.Files.FileUploadInputDto", + "typeSimple": "Volo.Blogging.Files.FileUploadInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Files.FileUploadOutputDto", + "typeSimple": "Volo.Blogging.Files.FileUploadOutputDto" + } + } + ] } ], "actions": { @@ -142,10 +199,58 @@ "Volo.Blogging.BlogsController": { "controllerName": "Blogs", "controllerGroupName": "Blogs", + "isRemoteService": true, + "isIntegrationService": false, + "apiVersion": null, "type": "Volo.Blogging.BlogsController", "interfaces": [ { - "type": "Volo.Blogging.Blogs.IBlogAppService" + "type": "Volo.Blogging.Blogs.IBlogAppService", + "name": "IBlogAppService", + "methods": [ + { + "name": "GetListAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + { + "name": "GetByShortNameAsync", + "parametersOnMethod": [ + { + "name": "shortName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Blogs.Dtos.BlogDto", + "typeSimple": "Volo.Blogging.Blogs.Dtos.BlogDto" + } + }, + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Blogs.Dtos.BlogDto", + "typeSimple": "Volo.Blogging.Blogs.Dtos.BlogDto" + } + } + ] } ], "actions": { @@ -243,10 +348,92 @@ "Volo.Blogging.CommentsController": { "controllerName": "Comments", "controllerGroupName": "Comments", + "isRemoteService": true, + "isIntegrationService": false, + "apiVersion": null, "type": "Volo.Blogging.CommentsController", "interfaces": [ { - "type": "Volo.Blogging.Comments.ICommentAppService" + "type": "Volo.Blogging.Comments.ICommentAppService", + "name": "ICommentAppService", + "methods": [ + { + "name": "GetHierarchicalListOfPostAsync", + "parametersOnMethod": [ + { + "name": "postId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Blogging.Comments.Dtos.CommentWithRepliesDto]" + } + }, + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Blogging.Comments.Dtos.CreateCommentDto, Volo.Blogging.Application.Contracts", + "type": "Volo.Blogging.Comments.Dtos.CreateCommentDto", + "typeSimple": "Volo.Blogging.Comments.Dtos.CreateCommentDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Comments.Dtos.CommentWithDetailsDto", + "typeSimple": "Volo.Blogging.Comments.Dtos.CommentWithDetailsDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Blogging.Comments.Dtos.UpdateCommentDto, Volo.Blogging.Application.Contracts", + "type": "Volo.Blogging.Comments.Dtos.UpdateCommentDto", + "typeSimple": "Volo.Blogging.Comments.Dtos.UpdateCommentDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Comments.Dtos.CommentWithDetailsDto", + "typeSimple": "Volo.Blogging.Comments.Dtos.CommentWithDetailsDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { @@ -423,10 +610,193 @@ "Volo.Blogging.PostsController": { "controllerName": "Posts", "controllerGroupName": "Posts", + "isRemoteService": true, + "isIntegrationService": false, + "apiVersion": null, "type": "Volo.Blogging.PostsController", "interfaces": [ { - "type": "Volo.Blogging.Posts.IPostAppService" + "type": "Volo.Blogging.Posts.IPostAppService", + "name": "IPostAppService", + "methods": [ + { + "name": "GetListByBlogIdAndTagNameAsync", + "parametersOnMethod": [ + { + "name": "blogId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "tagName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + { + "name": "GetTimeOrderedListAsync", + "parametersOnMethod": [ + { + "name": "blogId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + { + "name": "GetForReadingAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Blogging.Posts.GetPostInput, Volo.Blogging.Application.Contracts", + "type": "Volo.Blogging.Posts.GetPostInput", + "typeSimple": "Volo.Blogging.Posts.GetPostInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Posts.PostWithDetailsDto", + "typeSimple": "Volo.Blogging.Posts.PostWithDetailsDto" + } + }, + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Posts.PostWithDetailsDto", + "typeSimple": "Volo.Blogging.Posts.PostWithDetailsDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Blogging.Posts.CreatePostDto, Volo.Blogging.Application.Contracts", + "type": "Volo.Blogging.Posts.CreatePostDto", + "typeSimple": "Volo.Blogging.Posts.CreatePostDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Posts.PostWithDetailsDto", + "typeSimple": "Volo.Blogging.Posts.PostWithDetailsDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Blogging.Posts.UpdatePostDto, Volo.Blogging.Application.Contracts", + "type": "Volo.Blogging.Posts.UpdatePostDto", + "typeSimple": "Volo.Blogging.Posts.UpdatePostDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Blogging.Posts.PostWithDetailsDto", + "typeSimple": "Volo.Blogging.Posts.PostWithDetailsDto" + } + }, + { + "name": "GetListByUserIdAsync", + "parametersOnMethod": [ + { + "name": "userId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Blogging.Posts.PostWithDetailsDto]" + } + }, + { + "name": "GetLatestBlogPostsAsync", + "parametersOnMethod": [ + { + "name": "blogId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "count", + "typeAsString": "System.Int32, System.Private.CoreLib", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Blogging.Posts.PostWithDetailsDto]" + } + } + ] } ], "actions": { @@ -704,6 +1074,100 @@ "allowAnonymous": null, "implementFrom": "Volo.Blogging.Posts.IPostAppService" }, + "GetListByUserIdAsyncByUserId": { + "uniqueName": "GetListByUserIdAsyncByUserId", + "name": "GetListByUserIdAsync", + "httpMethod": "GET", + "url": "api/blogging/posts/user/{userId}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "userId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "userId", + "name": "userId", + "jsonName": null, + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Blogging.Posts.PostWithDetailsDto]" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Blogging.Posts.IPostAppService" + }, + "GetLatestBlogPostsAsyncByBlogIdAndCount": { + "uniqueName": "GetLatestBlogPostsAsyncByBlogIdAndCount", + "name": "GetLatestBlogPostsAsync", + "httpMethod": "GET", + "url": "api/blogging/posts/{blogId}/latest/{count}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "blogId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "count", + "typeAsString": "System.Int32, System.Private.CoreLib", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "blogId", + "name": "blogId", + "jsonName": null, + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "count", + "name": "count", + "jsonName": null, + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Blogging.Posts.PostWithDetailsDto]" + }, + "allowAnonymous": null, + "implementFrom": "Volo.Blogging.Posts.IPostAppService" + }, "DeleteAsyncById": { "uniqueName": "DeleteAsyncById", "name": "DeleteAsync", @@ -746,10 +1210,41 @@ "Volo.Blogging.TagsController": { "controllerName": "Tags", "controllerGroupName": "Tags", + "isRemoteService": true, + "isIntegrationService": false, + "apiVersion": null, "type": "Volo.Blogging.TagsController", "interfaces": [ { - "type": "Volo.Blogging.Tagging.ITagAppService" + "type": "Volo.Blogging.Tagging.ITagAppService", + "name": "ITagAppService", + "methods": [ + { + "name": "GetPopularTagsAsync", + "parametersOnMethod": [ + { + "name": "blogId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Blogging.Tagging.Dtos.GetPopularTagsInput, Volo.Blogging.Application.Contracts", + "type": "Volo.Blogging.Tagging.Dtos.GetPopularTagsInput", + "typeSimple": "Volo.Blogging.Tagging.Dtos.GetPopularTagsInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Blogging.Tagging.Dtos.TagDto]" + } + } + ] } ], "actions": { diff --git a/modules/blogging/src/Volo.Blogging.Web/wwwroot/client-proxies/blogging-proxy.js b/modules/blogging/src/Volo.Blogging.Web/wwwroot/client-proxies/blogging-proxy.js index f3358106d3..5ab0f30cdb 100644 --- a/modules/blogging/src/Volo.Blogging.Web/wwwroot/client-proxies/blogging-proxy.js +++ b/modules/blogging/src/Volo.Blogging.Web/wwwroot/client-proxies/blogging-proxy.js @@ -152,20 +152,28 @@ }, ajaxParams)); }; - volo.blogging.posts['delete'] = function(id, ajaxParams) { + volo.blogging.posts.getListByUserId = function(userId, ajaxParams) { return abp.ajax($.extend(true, { - url: abp.appPath + 'api/blogging/posts/' + id + '', - type: 'DELETE', - dataType: null + url: abp.appPath + 'api/blogging/posts/user/' + userId + '', + type: 'GET' }, ajaxParams)); }; - volo.blogging.posts.getListByUserId = function (userId, ajaxParams) { + volo.blogging.posts.getLatestBlogPosts = function(blogId, count, ajaxParams) { return abp.ajax($.extend(true, { - url: abp.appPath + 'api/blogging/posts/user/' + userId + '', + url: abp.appPath + 'api/blogging/posts/' + blogId + '/latest/' + count + '', type: 'GET' }, ajaxParams)); }; + + volo.blogging.posts['delete'] = function(id, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/blogging/posts/' + id + '', + type: 'DELETE', + dataType: null + }, ajaxParams)); + }; + })(); // controller volo.blogging.tags @@ -182,20 +190,7 @@ }; })(); - - // controller volo.blogging.members - - (function() { - abp.utils.createNamespace(window, 'volo.blogging.members'); - - volo.blogging.members.get = function (username, ajaxParams) { - return abp.ajax($.extend(true, { - url: abp.appPath + 'api/blogging/members/' + username + '', - type: 'GET' - }, ajaxParams)); - }; - })(); - + })(); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogAdminClientProxy.Generated.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogAdminClientProxy.Generated.cs similarity index 95% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogAdminClientProxy.Generated.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogAdminClientProxy.Generated.cs index 1768711291..d102ea4d1f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogAdminClientProxy.Generated.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogAdminClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.CmsKit.Admin.Blogs; // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Blogs.ClientProxies; +namespace Volo.CmsKit.Admin.Blogs; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IBlogAdminAppService), typeof(BlogAdminClientProxy))] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogAdminClientProxy.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogAdminClientProxy.cs similarity index 76% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogAdminClientProxy.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogAdminClientProxy.cs index 35361cdfea..4c1b65ede6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogAdminClientProxy.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of BlogAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Blogs.ClientProxies; +namespace Volo.CmsKit.Admin.Blogs; public partial class BlogAdminClientProxy { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogFeatureAdminClientProxy.Generated.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminClientProxy.Generated.cs similarity index 96% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogFeatureAdminClientProxy.Generated.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminClientProxy.Generated.cs index eb96db72bb..09723520a8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogFeatureAdminClientProxy.Generated.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminClientProxy.Generated.cs @@ -1,17 +1,18 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.CmsKit.Admin.Blogs; -using System.Collections.Generic; using Volo.CmsKit.Blogs; // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Blogs.ClientProxies; +namespace Volo.CmsKit.Admin.Blogs; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IBlogFeatureAdminAppService), typeof(BlogFeatureAdminClientProxy))] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogFeatureAdminClientProxy.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminClientProxy.cs similarity index 78% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogFeatureAdminClientProxy.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminClientProxy.cs index 1d4a61cf8d..617a2a4b8a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogFeatureAdminClientProxy.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of BlogFeatureAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Blogs.ClientProxies; +namespace Volo.CmsKit.Admin.Blogs; public partial class BlogFeatureAdminClientProxy { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogPostAdminClientProxy.Generated.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogPostAdminClientProxy.Generated.cs similarity index 97% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogPostAdminClientProxy.Generated.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogPostAdminClientProxy.Generated.cs index ba54e8e334..62ede9195b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogPostAdminClientProxy.Generated.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogPostAdminClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.CmsKit.Admin.Blogs; // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Blogs.ClientProxies; +namespace Volo.CmsKit.Admin.Blogs; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IBlogPostAdminAppService), typeof(BlogPostAdminClientProxy))] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogPostAdminClientProxy.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogPostAdminClientProxy.cs similarity index 77% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogPostAdminClientProxy.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogPostAdminClientProxy.cs index e9edd5b710..3f8c49ee0e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogPostAdminClientProxy.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogPostAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of BlogPostAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Blogs.ClientProxies; +namespace Volo.CmsKit.Admin.Blogs; public partial class BlogPostAdminClientProxy { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/CommentAdminClientProxy.Generated.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Comments/CommentAdminClientProxy.Generated.cs similarity index 94% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/CommentAdminClientProxy.Generated.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Comments/CommentAdminClientProxy.Generated.cs index d9cf02f915..a92570cd0e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/CommentAdminClientProxy.Generated.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Comments/CommentAdminClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.CmsKit.Admin.Comments; // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Comments.ClientProxies; +namespace Volo.CmsKit.Admin.Comments; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(ICommentAdminAppService), typeof(CommentAdminClientProxy))] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/CommentAdminClientProxy.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Comments/CommentAdminClientProxy.cs similarity index 76% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/CommentAdminClientProxy.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Comments/CommentAdminClientProxy.cs index cc815bc052..7d5a18fdac 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/CommentAdminClientProxy.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Comments/CommentAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of CommentAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Comments.ClientProxies; +namespace Volo.CmsKit.Admin.Comments; public partial class CommentAdminClientProxy { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/GlobalResourceAdminClientProxy.Generated.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/GlobalResources/GlobalResourceAdminClientProxy.Generated.cs similarity index 91% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/GlobalResourceAdminClientProxy.Generated.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/GlobalResources/GlobalResourceAdminClientProxy.Generated.cs index f1ee975d59..d401f78865 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/GlobalResourceAdminClientProxy.Generated.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/GlobalResources/GlobalResourceAdminClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.CmsKit.Admin.GlobalResources; // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.GlobalResources.ClientProxies; +namespace Volo.CmsKit.Admin.GlobalResources; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IGlobalResourceAdminAppService), typeof(GlobalResourceAdminClientProxy))] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/GlobalResourceAdminClientProxy.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/GlobalResources/GlobalResourceAdminClientProxy.cs similarity index 75% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/GlobalResourceAdminClientProxy.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/GlobalResources/GlobalResourceAdminClientProxy.cs index 49a4f4c558..e1b75fd069 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/GlobalResourceAdminClientProxy.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/GlobalResources/GlobalResourceAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of GlobalResourceAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.GlobalResources.ClientProxies; +namespace Volo.CmsKit.Admin.GlobalResources; public partial class GlobalResourceAdminClientProxy { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MediaDescriptorAdminClientProxy.Generated.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminClientProxy.Generated.cs similarity index 92% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MediaDescriptorAdminClientProxy.Generated.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminClientProxy.Generated.cs index 426e215cf0..9eb39221cc 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MediaDescriptorAdminClientProxy.Generated.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.CmsKit.Admin.MediaDescriptors; // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.MediaDescriptors.ClientProxies; +namespace Volo.CmsKit.Admin.MediaDescriptors; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IMediaDescriptorAdminAppService), typeof(MediaDescriptorAdminClientProxy))] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MediaDescriptorAdminClientProxy.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminClientProxy.cs similarity index 75% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MediaDescriptorAdminClientProxy.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminClientProxy.cs index ebf76040da..8d594e0138 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MediaDescriptorAdminClientProxy.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of MediaDescriptorAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.MediaDescriptors.ClientProxies; +namespace Volo.CmsKit.Admin.MediaDescriptors; public partial class MediaDescriptorAdminClientProxy { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MenuItemAdminClientProxy.Generated.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Menus/MenuItemAdminClientProxy.Generated.cs similarity index 96% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MenuItemAdminClientProxy.Generated.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Menus/MenuItemAdminClientProxy.Generated.cs index 93e069bbe7..461ae877bd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MenuItemAdminClientProxy.Generated.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Menus/MenuItemAdminClientProxy.Generated.cs @@ -1,16 +1,18 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.CmsKit.Admin.Menus; using Volo.CmsKit.Menus; // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Menus.ClientProxies; +namespace Volo.CmsKit.Admin.Menus; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IMenuItemAdminAppService), typeof(MenuItemAdminClientProxy))] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MenuItemAdminClientProxy.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Menus/MenuItemAdminClientProxy.cs similarity index 77% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MenuItemAdminClientProxy.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Menus/MenuItemAdminClientProxy.cs index 861b3f6082..4357104178 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/MenuItemAdminClientProxy.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Menus/MenuItemAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of MenuItemAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Menus.ClientProxies; +namespace Volo.CmsKit.Admin.Menus; public partial class MenuItemAdminClientProxy { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/PageAdminClientProxy.Generated.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Pages/PageAdminClientProxy.Generated.cs similarity index 96% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/PageAdminClientProxy.Generated.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Pages/PageAdminClientProxy.Generated.cs index efa0315690..1ac8549a11 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/PageAdminClientProxy.Generated.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Pages/PageAdminClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.CmsKit.Admin.Pages; // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Pages.ClientProxies; +namespace Volo.CmsKit.Admin.Pages; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IPageAdminAppService), typeof(PageAdminClientProxy))] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/PageAdminClientProxy.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Pages/PageAdminClientProxy.cs similarity index 76% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/PageAdminClientProxy.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Pages/PageAdminClientProxy.cs index c9d87b3ead..da0a6e4e7e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/PageAdminClientProxy.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Pages/PageAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of PageAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Pages.ClientProxies; +namespace Volo.CmsKit.Admin.Pages; public partial class PageAdminClientProxy { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/EntityTagAdminClientProxy.Generated.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/EntityTagAdminClientProxy.Generated.cs similarity index 94% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/EntityTagAdminClientProxy.Generated.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/EntityTagAdminClientProxy.Generated.cs index fe117682eb..3307a9dcd9 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/EntityTagAdminClientProxy.Generated.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/EntityTagAdminClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.CmsKit.Admin.Tags; // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Tags.ClientProxies; +namespace Volo.CmsKit.Admin.Tags; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IEntityTagAdminAppService), typeof(EntityTagAdminClientProxy))] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/EntityTagAdminClientProxy.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/EntityTagAdminClientProxy.cs similarity index 77% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/EntityTagAdminClientProxy.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/EntityTagAdminClientProxy.cs index 08cf572c9d..bd11398dbb 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/EntityTagAdminClientProxy.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/EntityTagAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of EntityTagAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Tags.ClientProxies; +namespace Volo.CmsKit.Admin.Tags; public partial class EntityTagAdminClientProxy { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/TagAdminClientProxy.Generated.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/TagAdminClientProxy.Generated.cs similarity index 97% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/TagAdminClientProxy.Generated.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/TagAdminClientProxy.Generated.cs index a835953a5e..8953741cca 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/TagAdminClientProxy.Generated.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/TagAdminClientProxy.Generated.cs @@ -1,17 +1,18 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.CmsKit.Admin.Tags; using Volo.CmsKit.Tags; -using System.Collections.Generic; // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Tags.ClientProxies; +namespace Volo.CmsKit.Admin.Tags; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(ITagAdminAppService), typeof(TagAdminClientProxy))] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/TagAdminClientProxy.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/TagAdminClientProxy.cs similarity index 76% rename from modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/TagAdminClientProxy.cs rename to modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/TagAdminClientProxy.cs index fe63cfa72f..074461736c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/TagAdminClientProxy.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Tags/TagAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of TagAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.CmsKit.Admin.Tags.ClientProxies; +namespace Volo.CmsKit.Admin.Tags; public partial class TagAdminClientProxy { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json index 4ce515dfd1..73b1e7dfd4 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json @@ -8,11 +8,66 @@ "controllerName": "EntityTagAdmin", "controllerGroupName": "EntityTagAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.CmsKit.Admin.Tags.EntityTagAdminController", "interfaces": [ { - "type": "Volo.CmsKit.Admin.Tags.IEntityTagAdminAppService" + "type": "Volo.CmsKit.Admin.Tags.IEntityTagAdminAppService", + "name": "IEntityTagAdminAppService", + "methods": [ + { + "name": "AddTagToEntityAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Tags.EntityTagCreateDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Tags.EntityTagCreateDto", + "typeSimple": "Volo.CmsKit.Admin.Tags.EntityTagCreateDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "RemoveTagFromEntityAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Tags.EntityTagRemoveDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Tags.EntityTagRemoveDto", + "typeSimple": "Volo.CmsKit.Admin.Tags.EntityTagRemoveDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "SetEntityTagsAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Tags.EntityTagSetDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Tags.EntityTagSetDto", + "typeSimple": "Volo.CmsKit.Admin.Tags.EntityTagSetDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { @@ -157,11 +212,116 @@ "controllerName": "TagAdmin", "controllerGroupName": "TagAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.CmsKit.Admin.Tags.TagAdminController", "interfaces": [ { - "type": "Volo.CmsKit.Admin.Tags.ITagAdminAppService" + "type": "Volo.CmsKit.Admin.Tags.ITagAdminAppService", + "name": "ITagAdminAppService", + "methods": [ + { + "name": "GetTagDefinitionsAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.CmsKit.Admin.Tags.TagDefinitionDto]" + } + }, + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Tags.TagDto", + "typeSimple": "Volo.CmsKit.Tags.TagDto" + } + }, + { + "name": "GetListAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Tags.TagGetListInput, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Tags.TagGetListInput", + "typeSimple": "Volo.CmsKit.Admin.Tags.TagGetListInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Tags.TagCreateDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Tags.TagCreateDto", + "typeSimple": "Volo.CmsKit.Admin.Tags.TagCreateDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Tags.TagDto", + "typeSimple": "Volo.CmsKit.Tags.TagDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Tags.TagUpdateDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Tags.TagUpdateDto", + "typeSimple": "Volo.CmsKit.Admin.Tags.TagUpdateDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Tags.TagDto", + "typeSimple": "Volo.CmsKit.Tags.TagDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { @@ -427,11 +587,125 @@ "controllerName": "PageAdmin", "controllerGroupName": "PageAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.CmsKit.Admin.Pages.PageAdminController", "interfaces": [ { - "type": "Volo.CmsKit.Admin.Pages.IPageAdminAppService" + "type": "Volo.CmsKit.Admin.Pages.IPageAdminAppService", + "name": "IPageAdminAppService", + "methods": [ + { + "name": "SetAsHomePageAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Pages.PageDto", + "typeSimple": "Volo.CmsKit.Admin.Pages.PageDto" + } + }, + { + "name": "GetListAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Pages.GetPagesInputDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Pages.GetPagesInputDto", + "typeSimple": "Volo.CmsKit.Admin.Pages.GetPagesInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Pages.CreatePageInputDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Pages.CreatePageInputDto", + "typeSimple": "Volo.CmsKit.Admin.Pages.CreatePageInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Pages.PageDto", + "typeSimple": "Volo.CmsKit.Admin.Pages.PageDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Pages.UpdatePageInputDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Pages.UpdatePageInputDto", + "typeSimple": "Volo.CmsKit.Admin.Pages.UpdatePageInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Pages.PageDto", + "typeSimple": "Volo.CmsKit.Admin.Pages.PageDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { @@ -719,11 +993,141 @@ "controllerName": "MenuItemAdmin", "controllerGroupName": "MenuItemAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.CmsKit.Admin.Menus.MenuItemAdminController", "interfaces": [ { - "type": "Volo.CmsKit.Admin.Menus.IMenuItemAdminAppService" + "type": "Volo.CmsKit.Admin.Menus.IMenuItemAdminAppService", + "name": "IMenuItemAdminAppService", + "methods": [ + { + "name": "GetListAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Menus.MenuItemDto", + "typeSimple": "Volo.CmsKit.Menus.MenuItemDto" + } + }, + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Menus.MenuItemCreateInput, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Menus.MenuItemCreateInput", + "typeSimple": "Volo.CmsKit.Admin.Menus.MenuItemCreateInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Menus.MenuItemDto", + "typeSimple": "Volo.CmsKit.Menus.MenuItemDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Menus.MenuItemUpdateInput, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Menus.MenuItemUpdateInput", + "typeSimple": "Volo.CmsKit.Admin.Menus.MenuItemUpdateInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Menus.MenuItemDto", + "typeSimple": "Volo.CmsKit.Menus.MenuItemDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "MoveMenuItemAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Menus.MenuItemMoveInput, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Menus.MenuItemMoveInput", + "typeSimple": "Volo.CmsKit.Admin.Menus.MenuItemMoveInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "GetPageLookupAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Menus.PageLookupInputDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Menus.PageLookupInputDto", + "typeSimple": "Volo.CmsKit.Admin.Menus.PageLookupInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + } + ] } ], "actions": { @@ -1046,11 +1450,57 @@ "controllerName": "MediaDescriptorAdmin", "controllerGroupName": "MediaDescriptorAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.CmsKit.Admin.MediaDescriptors.MediaDescriptorAdminController", "interfaces": [ { - "type": "Volo.CmsKit.Admin.MediaDescriptors.IMediaDescriptorAdminAppService" + "type": "Volo.CmsKit.Admin.MediaDescriptors.IMediaDescriptorAdminAppService", + "name": "IMediaDescriptorAdminAppService", + "methods": [ + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "entityType", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "inputStream", + "typeAsString": "Volo.CmsKit.Admin.MediaDescriptors.CreateMediaInputWithStream, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.MediaDescriptors.CreateMediaInputWithStream", + "typeSimple": "Volo.CmsKit.Admin.MediaDescriptors.CreateMediaInputWithStream", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.MediaDescriptors.MediaDescriptorDto", + "typeSimple": "Volo.CmsKit.Admin.MediaDescriptors.MediaDescriptorDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { @@ -1166,11 +1616,40 @@ "controllerName": "GlobalResourceAdmin", "controllerGroupName": "GlobalResourceAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.CmsKit.Admin.GlobalResources.GlobalResourceAdminController", "interfaces": [ { - "type": "Volo.CmsKit.Admin.GlobalResources.IGlobalResourceAdminAppService" + "type": "Volo.CmsKit.Admin.GlobalResources.IGlobalResourceAdminAppService", + "name": "IGlobalResourceAdminAppService", + "methods": [ + { + "name": "GetAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "Volo.CmsKit.Admin.GlobalResources.GlobalResourcesDto", + "typeSimple": "Volo.CmsKit.Admin.GlobalResources.GlobalResourcesDto" + } + }, + { + "name": "SetGlobalResourcesAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.GlobalResources.GlobalResourcesUpdateDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.GlobalResources.GlobalResourcesUpdateDto", + "typeSimple": "Volo.CmsKit.Admin.GlobalResources.GlobalResourcesUpdateDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { @@ -1232,11 +1711,66 @@ "controllerName": "CommentAdmin", "controllerGroupName": "CommentAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.CmsKit.Admin.Comments.CommentAdminController", "interfaces": [ { - "type": "Volo.CmsKit.Admin.Comments.ICommentAdminAppService" + "type": "Volo.CmsKit.Admin.Comments.ICommentAdminAppService", + "name": "ICommentAdminAppService", + "methods": [ + { + "name": "GetListAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Comments.CommentGetListInput, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Comments.CommentGetListInput", + "typeSimple": "Volo.CmsKit.Admin.Comments.CommentGetListInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Comments.CommentWithAuthorDto", + "typeSimple": "Volo.CmsKit.Admin.Comments.CommentWithAuthorDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { @@ -1453,11 +1987,108 @@ "controllerName": "BlogAdmin", "controllerGroupName": "BlogAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.CmsKit.Admin.Blogs.BlogAdminController", "interfaces": [ { - "type": "Volo.CmsKit.Admin.Blogs.IBlogAdminAppService" + "type": "Volo.CmsKit.Admin.Blogs.IBlogAdminAppService", + "name": "IBlogAdminAppService", + "methods": [ + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Blogs.BlogDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogDto" + } + }, + { + "name": "GetListAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Blogs.BlogGetListInput, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Blogs.BlogGetListInput", + "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogGetListInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Blogs.CreateBlogDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Blogs.CreateBlogDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.CreateBlogDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Blogs.BlogDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Blogs.UpdateBlogDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Blogs.UpdateBlogDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.UpdateBlogDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Blogs.BlogDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { @@ -1708,11 +2339,57 @@ "controllerName": "BlogFeatureAdmin", "controllerGroupName": "BlogFeatureAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.CmsKit.Admin.Blogs.BlogFeatureAdminController", "interfaces": [ { - "type": "Volo.CmsKit.Admin.Blogs.IBlogFeatureAdminAppService" + "type": "Volo.CmsKit.Admin.Blogs.IBlogFeatureAdminAppService", + "name": "IBlogFeatureAdminAppService", + "methods": [ + { + "name": "SetAsync", + "parametersOnMethod": [ + { + "name": "blogId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "dto", + "typeAsString": "Volo.CmsKit.Admin.Blogs.BlogFeatureInputDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Blogs.BlogFeatureInputDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogFeatureInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "GetListAsync", + "parametersOnMethod": [ + { + "name": "blogId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.CmsKit.Blogs.BlogFeatureDto]" + } + } + ] } ], "actions": { @@ -1816,11 +2493,201 @@ "controllerName": "BlogPostAdmin", "controllerGroupName": "BlogPostAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.CmsKit.Admin.Blogs.BlogPostAdminController", "interfaces": [ { - "type": "Volo.CmsKit.Admin.Blogs.IBlogPostAdminAppService" + "type": "Volo.CmsKit.Admin.Blogs.IBlogPostAdminAppService", + "name": "IBlogPostAdminAppService", + "methods": [ + { + "name": "PublishAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "DraftAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "CreateAndPublishAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Blogs.BlogPostDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogPostDto" + } + }, + { + "name": "SendToReviewAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "CreateAndSendToReviewAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Blogs.BlogPostDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogPostDto" + } + }, + { + "name": "HasBlogPostWaitingForReviewAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "System.Boolean", + "typeSimple": "boolean" + } + }, + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Blogs.BlogPostDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogPostDto" + } + }, + { + "name": "GetListAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Blogs.BlogPostGetListInput, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Blogs.BlogPostGetListInput", + "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogPostGetListInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Blogs.BlogPostDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogPostDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.CmsKit.Admin.Blogs.UpdateBlogPostDto, Volo.CmsKit.Admin.Application.Contracts", + "type": "Volo.CmsKit.Admin.Blogs.UpdateBlogPostDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.UpdateBlogPostDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.CmsKit.Admin.Blogs.BlogPostDto", + "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogPostDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { diff --git a/modules/cms-kit/src/Volo.CmsKit.Web/wwwroot/client-proxies/cms-kit-proxy.js b/modules/cms-kit/src/Volo.CmsKit.Web/wwwroot/client-proxies/cms-kit-proxy.js new file mode 100644 index 0000000000..9075fab645 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Web/wwwroot/client-proxies/cms-kit-proxy.js @@ -0,0 +1,236 @@ +/* This file is automatically generated by ABP framework to use MVC Controllers from javascript. */ + + +// module cms-kit + +(function(){ + + // controller volo.cmsKit.public.tags.tagPublic + + (function(){ + + abp.utils.createNamespace(window, 'volo.cmsKit.public.tags.tagPublic'); + + volo.cmsKit.public.tags.tagPublic.getAllRelatedTags = function(entityType, entityId, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/tags/' + entityType + '/' + entityId + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.cmsKit.public.tags.tagPublic.getPopularTags = function(entityType, maxCount, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/tags/popular/' + entityType + '/' + maxCount + '', + type: 'GET' + }, ajaxParams)); + }; + + })(); + + // controller volo.cmsKit.public.reactions.reactionPublic + + (function(){ + + abp.utils.createNamespace(window, 'volo.cmsKit.public.reactions.reactionPublic'); + + volo.cmsKit.public.reactions.reactionPublic.getForSelection = function(entityType, entityId, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/reactions/' + entityType + '/' + entityId + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.cmsKit.public.reactions.reactionPublic.create = function(entityType, entityId, reaction, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/reactions/' + entityType + '/' + entityId + '/' + reaction + '', + type: 'PUT', + dataType: null + }, ajaxParams)); + }; + + volo.cmsKit.public.reactions.reactionPublic['delete'] = function(entityType, entityId, reaction, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/reactions/' + entityType + '/' + entityId + '/' + reaction + '', + type: 'DELETE', + dataType: null + }, ajaxParams)); + }; + + })(); + + // controller volo.cmsKit.public.ratings.ratingPublic + + (function(){ + + abp.utils.createNamespace(window, 'volo.cmsKit.public.ratings.ratingPublic'); + + volo.cmsKit.public.ratings.ratingPublic.create = function(entityType, entityId, input, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/ratings/' + entityType + '/' + entityId + '', + type: 'PUT', + data: JSON.stringify(input) + }, ajaxParams)); + }; + + volo.cmsKit.public.ratings.ratingPublic['delete'] = function(entityType, entityId, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/ratings/' + entityType + '/' + entityId + '', + type: 'DELETE', + dataType: null + }, ajaxParams)); + }; + + volo.cmsKit.public.ratings.ratingPublic.getGroupedStarCounts = function(entityType, entityId, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/ratings/' + entityType + '/' + entityId + '', + type: 'GET' + }, ajaxParams)); + }; + + })(); + + // controller volo.cmsKit.public.pages.pagesPublic + + (function(){ + + abp.utils.createNamespace(window, 'volo.cmsKit.public.pages.pagesPublic'); + + volo.cmsKit.public.pages.pagesPublic.findBySlug = function(slug, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/pages/' + slug + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.cmsKit.public.pages.pagesPublic.findDefaultHomePage = function(ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/pages', + type: 'GET' + }, ajaxParams)); + }; + + })(); + + // controller volo.cmsKit.public.menus.menuItemPublic + + (function(){ + + abp.utils.createNamespace(window, 'volo.cmsKit.public.menus.menuItemPublic'); + + volo.cmsKit.public.menus.menuItemPublic.getList = function(ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/menu-items', + type: 'GET' + }, ajaxParams)); + }; + + })(); + + // controller volo.cmsKit.public.globalResources.globalResourcePublic + + (function(){ + + abp.utils.createNamespace(window, 'volo.cmsKit.public.globalResources.globalResourcePublic'); + + volo.cmsKit.public.globalResources.globalResourcePublic.getGlobalScript = function(ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/global-resources/script', + type: 'GET' + }, ajaxParams)); + }; + + volo.cmsKit.public.globalResources.globalResourcePublic.getGlobalStyle = function(ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/global-resources/style', + type: 'GET' + }, ajaxParams)); + }; + + })(); + + // controller volo.cmsKit.public.comments.commentPublic + + (function(){ + + abp.utils.createNamespace(window, 'volo.cmsKit.public.comments.commentPublic'); + + volo.cmsKit.public.comments.commentPublic.getList = function(entityType, entityId, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/comments/' + entityType + '/' + entityId + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.cmsKit.public.comments.commentPublic.create = function(entityType, entityId, input, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/comments/' + entityType + '/' + entityId + '', + type: 'POST', + data: JSON.stringify(input) + }, ajaxParams)); + }; + + volo.cmsKit.public.comments.commentPublic.update = function(id, input, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/comments/' + id + '', + type: 'PUT', + data: JSON.stringify(input) + }, ajaxParams)); + }; + + volo.cmsKit.public.comments.commentPublic['delete'] = function(id, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/comments/' + id + '', + type: 'DELETE', + dataType: null + }, ajaxParams)); + }; + + })(); + + // controller volo.cmsKit.public.blogs.blogPostPublic + + (function(){ + + abp.utils.createNamespace(window, 'volo.cmsKit.public.blogs.blogPostPublic'); + + volo.cmsKit.public.blogs.blogPostPublic.get = function(blogSlug, blogPostSlug, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/blog-posts/' + blogSlug + '/' + blogPostSlug + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.cmsKit.public.blogs.blogPostPublic.getList = function(blogSlug, input, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/blog-posts/' + blogSlug + '' + abp.utils.buildQueryString([{ name: 'authorId', value: input.authorId }, { name: 'tagId', value: input.tagId }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.cmsKit.public.blogs.blogPostPublic.getAuthorsHasBlogPosts = function(input, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/blog-posts/authors' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.cmsKit.public.blogs.blogPostPublic.getAuthorHasBlogPost = function(id, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/blog-posts/authors/' + id + '', + type: 'GET' + }, ajaxParams)); + }; + + volo.cmsKit.public.blogs.blogPostPublic['delete'] = function(id, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/cms-kit-public/blog-posts/' + id + '', + type: 'DELETE', + dataType: null + }, ajaxParams)); + }; + + })(); + +})(); + + diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/DocumentsAdminClientProxy.Generated.cs b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentsAdminClientProxy.Generated.cs similarity index 98% rename from modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/DocumentsAdminClientProxy.Generated.cs rename to modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentsAdminClientProxy.Generated.cs index e2b9fa2783..8a6e2b7173 100644 --- a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/DocumentsAdminClientProxy.Generated.cs +++ b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentsAdminClientProxy.Generated.cs @@ -1,16 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Docs.Admin.Documents; -using System.Collections.Generic; // ReSharper disable once CheckNamespace -namespace Volo.Docs.Admin.ClientProxies; +namespace Volo.Docs.Admin; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IDocumentAdminAppService), typeof(DocumentsAdminClientProxy))] diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/DocumentsAdminClientProxy.cs b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentsAdminClientProxy.cs similarity index 80% rename from modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/DocumentsAdminClientProxy.cs rename to modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentsAdminClientProxy.cs index 34899f1c49..cabfe5500c 100644 --- a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/DocumentsAdminClientProxy.cs +++ b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentsAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of DocumentsAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Docs.Admin.ClientProxies; +namespace Volo.Docs.Admin; public partial class DocumentsAdminClientProxy { diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/ProjectsAdminClientProxy.Generated.cs b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/ProjectsAdminClientProxy.Generated.cs similarity index 98% rename from modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/ProjectsAdminClientProxy.Generated.cs rename to modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/ProjectsAdminClientProxy.Generated.cs index 072106df0e..54f1ec22d5 100644 --- a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/ProjectsAdminClientProxy.Generated.cs +++ b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/ProjectsAdminClientProxy.Generated.cs @@ -1,16 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Docs.Admin.Projects; -using System.Collections.Generic; // ReSharper disable once CheckNamespace -namespace Volo.Docs.Admin.ClientProxies; +namespace Volo.Docs.Admin; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IProjectAdminAppService), typeof(ProjectsAdminClientProxy))] diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/ProjectsAdminClientProxy.cs b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/ProjectsAdminClientProxy.cs similarity index 80% rename from modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/ProjectsAdminClientProxy.cs rename to modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/ProjectsAdminClientProxy.cs index c9584cffbf..4376ec04ff 100644 --- a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/ProjectsAdminClientProxy.cs +++ b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/ProjectsAdminClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of ProjectsAdminClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Docs.Admin.ClientProxies; +namespace Volo.Docs.Admin; public partial class ProjectsAdminClientProxy { diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/docs-admin-generate-proxy.json b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/docs-admin-generate-proxy.json index c6cf885b09..7875b68b43 100644 --- a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/docs-admin-generate-proxy.json +++ b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/docs-admin-generate-proxy.json @@ -8,11 +8,125 @@ "controllerName": "DocumentsAdmin", "controllerGroupName": "DocumentsAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.Docs.Admin.DocumentsAdminController", "interfaces": [ { - "type": "Volo.Docs.Admin.Documents.IDocumentAdminAppService" + "type": "Volo.Docs.Admin.Documents.IDocumentAdminAppService", + "name": "IDocumentAdminAppService", + "methods": [ + { + "name": "ClearCacheAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Docs.Admin.Documents.ClearCacheInput, Volo.Docs.Admin.Application.Contracts", + "type": "Volo.Docs.Admin.Documents.ClearCacheInput", + "typeSimple": "Volo.Docs.Admin.Documents.ClearCacheInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "PullAllAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Docs.Admin.Documents.PullAllDocumentInput, Volo.Docs.Admin.Application.Contracts", + "type": "Volo.Docs.Admin.Documents.PullAllDocumentInput", + "typeSimple": "Volo.Docs.Admin.Documents.PullAllDocumentInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "PullAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Docs.Admin.Documents.PullDocumentInput, Volo.Docs.Admin.Application.Contracts", + "type": "Volo.Docs.Admin.Documents.PullDocumentInput", + "typeSimple": "Volo.Docs.Admin.Documents.PullDocumentInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "GetAllAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Docs.Admin.Documents.GetAllInput, Volo.Docs.Admin.Application.Contracts", + "type": "Volo.Docs.Admin.Documents.GetAllInput", + "typeSimple": "Volo.Docs.Admin.Documents.GetAllInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + { + "name": "RemoveFromCacheAsync", + "parametersOnMethod": [ + { + "name": "documentId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "ReindexAsync", + "parametersOnMethod": [ + { + "name": "documentId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "GetFilterItemsAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Docs.Admin.Documents.DocumentInfoDto]" + } + } + ] } ], "actions": { @@ -451,11 +565,141 @@ "controllerName": "ProjectsAdmin", "controllerGroupName": "ProjectsAdmin", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.Docs.Admin.ProjectsAdminController", "interfaces": [ { - "type": "Volo.Docs.Admin.Projects.IProjectAdminAppService" + "type": "Volo.Docs.Admin.Projects.IProjectAdminAppService", + "name": "IProjectAdminAppService", + "methods": [ + { + "name": "GetListAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto, Volo.Abp.Ddd.Application.Contracts", + "type": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Docs.Admin.Projects.ProjectDto", + "typeSimple": "Volo.Docs.Admin.Projects.ProjectDto" + } + }, + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Docs.Admin.Projects.CreateProjectDto, Volo.Docs.Admin.Application.Contracts", + "type": "Volo.Docs.Admin.Projects.CreateProjectDto", + "typeSimple": "Volo.Docs.Admin.Projects.CreateProjectDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Docs.Admin.Projects.ProjectDto", + "typeSimple": "Volo.Docs.Admin.Projects.ProjectDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Docs.Admin.Projects.UpdateProjectDto, Volo.Docs.Admin.Application.Contracts", + "type": "Volo.Docs.Admin.Projects.UpdateProjectDto", + "typeSimple": "Volo.Docs.Admin.Projects.UpdateProjectDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Docs.Admin.Projects.ProjectDto", + "typeSimple": "Volo.Docs.Admin.Projects.ProjectDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "ReindexAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Docs.Admin.Projects.ReindexInput, Volo.Docs.Admin.Application.Contracts", + "type": "Volo.Docs.Admin.Projects.ReindexInput", + "typeSimple": "Volo.Docs.Admin.Projects.ReindexInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "ReindexAllAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "GetListWithoutDetailsAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Docs.Admin.Projects.ProjectWithoutDetailsDto]" + } + } + ] } ], "actions": { @@ -478,10 +722,10 @@ "parameters": [ { "nameOnMethod": "input", - "name": "SkipCount", + "name": "Sorting", "jsonName": null, - "type": "System.Int32", - "typeSimple": "number", + "type": "System.String", + "typeSimple": "string", "isOptional": false, "defaultValue": null, "constraintTypes": null, @@ -490,7 +734,7 @@ }, { "nameOnMethod": "input", - "name": "MaxResultCount", + "name": "SkipCount", "jsonName": null, "type": "System.Int32", "typeSimple": "number", @@ -502,10 +746,10 @@ }, { "nameOnMethod": "input", - "name": "Sorting", + "name": "MaxResultCount", "jsonName": null, - "type": "System.String", - "typeSimple": "string", + "type": "System.Int32", + "typeSimple": "number", "isOptional": false, "defaultValue": null, "constraintTypes": null, diff --git a/modules/docs/src/Volo.Docs.Admin.Web/wwwroot/client-proxies/docs-admin-proxy.js b/modules/docs/src/Volo.Docs.Admin.Web/wwwroot/client-proxies/docs-admin-proxy.js index a39386aa3b..303ca5fdb0 100644 --- a/modules/docs/src/Volo.Docs.Admin.Web/wwwroot/client-proxies/docs-admin-proxy.js +++ b/modules/docs/src/Volo.Docs.Admin.Web/wwwroot/client-proxies/docs-admin-proxy.js @@ -78,7 +78,7 @@ volo.docs.admin.projectsAdmin.getList = function(input, ajaxParams) { return abp.ajax($.extend(true, { - url: abp.appPath + 'api/docs/admin/projects' + abp.utils.buildQueryString([{ name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }, { name: 'sorting', value: input.sorting }]) + '', + url: abp.appPath + 'api/docs/admin/projects' + abp.utils.buildQueryString([{ name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '', type: 'GET' }, ajaxParams)); }; diff --git a/modules/docs/src/Volo.Docs.HttpApi.Client/ClientProxies/docs-generate-proxy.json b/modules/docs/src/Volo.Docs.HttpApi.Client/ClientProxies/docs-generate-proxy.json index 0726d8b8de..13e9ebffb2 100644 --- a/modules/docs/src/Volo.Docs.HttpApi.Client/ClientProxies/docs-generate-proxy.json +++ b/modules/docs/src/Volo.Docs.HttpApi.Client/ClientProxies/docs-generate-proxy.json @@ -879,90 +879,6 @@ "implementFrom": "Volo.Docs.Documents.IDocumentAppService" } } - }, - "Volo.Docs.Areas.Documents.DocumentResourceController": { - "controllerName": "DocumentResource", - "controllerGroupName": "DocumentResource", - "isRemoteService": true, - "isIntegrationService": false, - "apiVersion": null, - "type": "Volo.Docs.Areas.Documents.DocumentResourceController", - "interfaces": [], - "actions": { - "GetResourceByInput": { - "uniqueName": "GetResourceByInput", - "name": "GetResource", - "httpMethod": "GET", - "url": "document-resources", - "supportedVersions": [], - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "Volo.Docs.Documents.GetDocumentResourceInput, Volo.Docs.Application.Contracts", - "type": "Volo.Docs.Documents.GetDocumentResourceInput", - "typeSimple": "Volo.Docs.Documents.GetDocumentResourceInput", - "isOptional": false, - "defaultValue": null - } - ], - "parameters": [ - { - "nameOnMethod": "input", - "name": "ProjectId", - "jsonName": null, - "type": "System.Guid", - "typeSimple": "string", - "isOptional": false, - "defaultValue": null, - "constraintTypes": null, - "bindingSourceId": "ModelBinding", - "descriptorName": "input" - }, - { - "nameOnMethod": "input", - "name": "Name", - "jsonName": null, - "type": "System.String", - "typeSimple": "string", - "isOptional": false, - "defaultValue": null, - "constraintTypes": null, - "bindingSourceId": "ModelBinding", - "descriptorName": "input" - }, - { - "nameOnMethod": "input", - "name": "Version", - "jsonName": null, - "type": "System.String", - "typeSimple": "string", - "isOptional": false, - "defaultValue": null, - "constraintTypes": null, - "bindingSourceId": "ModelBinding", - "descriptorName": "input" - }, - { - "nameOnMethod": "input", - "name": "LanguageCode", - "jsonName": null, - "type": "System.String", - "typeSimple": "string", - "isOptional": false, - "defaultValue": null, - "constraintTypes": null, - "bindingSourceId": "ModelBinding", - "descriptorName": "input" - } - ], - "returnValue": { - "type": "Microsoft.AspNetCore.Mvc.FileResult", - "typeSimple": "Microsoft.AspNetCore.Mvc.FileResult" - }, - "allowAnonymous": null, - "implementFrom": "Volo.Docs.Areas.Documents.DocumentResourceController" - } - } } } } diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/client-proxies/docs-proxy.js b/modules/docs/src/Volo.Docs.Web/wwwroot/client-proxies/docs-proxy.js index be998b251a..3195d15cd6 100644 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/client-proxies/docs-proxy.js +++ b/modules/docs/src/Volo.Docs.Web/wwwroot/client-proxies/docs-proxy.js @@ -5,21 +5,6 @@ (function(){ - // controller volo.docs.areas.documents.documentResource - - (function(){ - - abp.utils.createNamespace(window, 'volo.docs.areas.documents.documentResource'); - - volo.docs.areas.documents.documentResource.getResource = function(input, ajaxParams) { - return abp.ajax($.extend(true, { - url: abp.appPath + 'document-resources' + abp.utils.buildQueryString([{ name: 'projectId', value: input.projectId }, { name: 'name', value: input.name }, { name: 'version', value: input.version }, { name: 'languageCode', value: input.languageCode }]) + '', - type: 'GET' - }, ajaxParams)); - }; - - })(); - // controller volo.docs.projects.docsProject (function(){ diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/FeaturesClientProxy.Generated.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/Volo/Abp/FeatureManagement/FeaturesClientProxy.Generated.cs similarity index 94% rename from modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/FeaturesClientProxy.Generated.cs rename to modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/Volo/Abp/FeatureManagement/FeaturesClientProxy.Generated.cs index fc1ef481f0..03c7ab3865 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/FeaturesClientProxy.Generated.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/Volo/Abp/FeatureManagement/FeaturesClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; -using Volo.Abp.Http.Client.ClientProxying; using Volo.Abp.FeatureManagement; +using Volo.Abp.Http.Client; +using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; // ReSharper disable once CheckNamespace -namespace Volo.Abp.FeatureManagement.ClientProxies; +namespace Volo.Abp.FeatureManagement; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IFeatureAppService), typeof(FeaturesClientProxy))] diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/FeaturesClientProxy.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/Volo/Abp/FeatureManagement/FeaturesClientProxy.cs similarity index 75% rename from modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/FeaturesClientProxy.cs rename to modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/Volo/Abp/FeatureManagement/FeaturesClientProxy.cs index 0a37a76900..d3701e0db5 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/FeaturesClientProxy.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/Volo/Abp/FeatureManagement/FeaturesClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of FeaturesClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Abp.FeatureManagement.ClientProxies; +namespace Volo.Abp.FeatureManagement; public partial class FeaturesClientProxy { diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/featureManagement-generate-proxy.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/featureManagement-generate-proxy.json index 20c621eb69..df4f6b3b13 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/featureManagement-generate-proxy.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/ClientProxies/featureManagement-generate-proxy.json @@ -8,11 +8,98 @@ "controllerName": "Features", "controllerGroupName": "Features", "isRemoteService": true, + "isIntegrationService": false, "apiVersion": null, "type": "Volo.Abp.FeatureManagement.FeaturesController", "interfaces": [ { - "type": "Volo.Abp.FeatureManagement.IFeatureAppService" + "type": "Volo.Abp.FeatureManagement.IFeatureAppService", + "name": "IFeatureAppService", + "methods": [ + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.FeatureManagement.GetFeatureListResultDto", + "typeSimple": "Volo.Abp.FeatureManagement.GetFeatureListResultDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.FeatureManagement.UpdateFeaturesDto, Volo.Abp.FeatureManagement.Application.Contracts", + "type": "Volo.Abp.FeatureManagement.UpdateFeaturesDto", + "typeSimple": "Volo.Abp.FeatureManagement.UpdateFeaturesDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityRoleClientProxy.Generated.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.Generated.cs similarity index 96% rename from modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityRoleClientProxy.Generated.cs rename to modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.Generated.cs index 4a02b9c44b..64279a8019 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityRoleClientProxy.Generated.cs +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Abp.Identity; // ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity.ClientProxies; +namespace Volo.Abp.Identity; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IIdentityRoleAppService), typeof(IdentityRoleClientProxy))] diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityRoleClientProxy.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.cs similarity index 79% rename from modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityRoleClientProxy.cs rename to modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.cs index a7a5bf4a24..6e42400a96 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityRoleClientProxy.cs +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityRoleClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of IdentityRoleClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity.ClientProxies; +namespace Volo.Abp.Identity; public partial class IdentityRoleClientProxy { diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserClientProxy.Generated.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.Generated.cs similarity index 97% rename from modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserClientProxy.Generated.cs rename to modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.Generated.cs index 0b1018fdf7..b6e18e1e0f 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserClientProxy.Generated.cs +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Abp.Identity; // ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity.ClientProxies; +namespace Volo.Abp.Identity; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserClientProxy))] diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserClientProxy.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.cs similarity index 79% rename from modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserClientProxy.cs rename to modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.cs index 99954e2eb5..8c40a7c313 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserClientProxy.cs +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of IdentityUserClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity.ClientProxies; +namespace Volo.Abp.Identity; public partial class IdentityUserClientProxy { diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserLookupClientProxy.Generated.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.Generated.cs similarity index 95% rename from modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserLookupClientProxy.Generated.cs rename to modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.Generated.cs index 7a05ffbfa4..effdd5ef51 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserLookupClientProxy.Generated.cs +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.Generated.cs @@ -1,16 +1,18 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Abp.Identity; using Volo.Abp.Users; // ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity.ClientProxies; +namespace Volo.Abp.Identity; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IIdentityUserLookupAppService), typeof(IdentityUserLookupClientProxy))] diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserLookupClientProxy.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.cs similarity index 80% rename from modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserLookupClientProxy.cs rename to modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.cs index e9d1ad8a82..3d54f2d1bb 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/IdentityUserLookupClientProxy.cs +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserLookupClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of IdentityUserLookupClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Abp.Identity.ClientProxies; +namespace Volo.Abp.Identity; public partial class IdentityUserLookupClientProxy { diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/TenantClientProxy.Generated.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/Volo/Abp/TenantManagement/TenantClientProxy.Generated.cs similarity index 96% rename from modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/TenantClientProxy.Generated.cs rename to modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/Volo/Abp/TenantManagement/TenantClientProxy.Generated.cs index eb3b77feb0..5918f03d16 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/TenantClientProxy.Generated.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/Volo/Abp/TenantManagement/TenantClientProxy.Generated.cs @@ -1,15 +1,17 @@ // This file is automatically generated by ABP framework to use MVC Controllers from CSharp using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; using Volo.Abp.TenantManagement; // ReSharper disable once CheckNamespace -namespace Volo.Abp.TenantManagement.ClientProxies; +namespace Volo.Abp.TenantManagement; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(ITenantAppService), typeof(TenantClientProxy))] diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/TenantClientProxy.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/Volo/Abp/TenantManagement/TenantClientProxy.cs similarity index 75% rename from modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/TenantClientProxy.cs rename to modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/Volo/Abp/TenantManagement/TenantClientProxy.cs index c8a962e3c4..9e9d21c5f0 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/TenantClientProxy.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/Volo/Abp/TenantManagement/TenantClientProxy.cs @@ -1,6 +1,6 @@ // This file is part of TenantClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace Volo.Abp.TenantManagement.ClientProxies; +namespace Volo.Abp.TenantManagement; public partial class TenantClientProxy { diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/multi-tenancy-generate-proxy.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/multi-tenancy-generate-proxy.json index 4a0e20debe..de1f6494f6 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/multi-tenancy-generate-proxy.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/ClientProxies/multi-tenancy-generate-proxy.json @@ -7,10 +7,168 @@ "Volo.Abp.TenantManagement.TenantController": { "controllerName": "Tenant", "controllerGroupName": "Tenant", + "isRemoteService": true, + "isIntegrationService": false, + "apiVersion": null, "type": "Volo.Abp.TenantManagement.TenantController", "interfaces": [ { - "type": "Volo.Abp.TenantManagement.ITenantAppService" + "type": "Volo.Abp.TenantManagement.ITenantAppService", + "name": "ITenantAppService", + "methods": [ + { + "name": "GetDefaultConnectionStringAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.String", + "typeSimple": "string" + } + }, + { + "name": "UpdateDefaultConnectionStringAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "defaultConnectionString", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "DeleteDefaultConnectionStringAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.TenantManagement.TenantDto", + "typeSimple": "Volo.Abp.TenantManagement.TenantDto" + } + }, + { + "name": "GetListAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.TenantManagement.GetTenantsInput, Volo.Abp.TenantManagement.Application.Contracts", + "type": "Volo.Abp.TenantManagement.GetTenantsInput", + "typeSimple": "Volo.Abp.TenantManagement.GetTenantsInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + { + "name": "CreateAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.TenantManagement.TenantCreateDto, Volo.Abp.TenantManagement.Application.Contracts", + "type": "Volo.Abp.TenantManagement.TenantCreateDto", + "typeSimple": "Volo.Abp.TenantManagement.TenantCreateDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.TenantManagement.TenantDto", + "typeSimple": "Volo.Abp.TenantManagement.TenantDto" + } + }, + { + "name": "UpdateAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.TenantManagement.TenantUpdateDto, Volo.Abp.TenantManagement.Application.Contracts", + "type": "Volo.Abp.TenantManagement.TenantUpdateDto", + "typeSimple": "Volo.Abp.TenantManagement.TenantUpdateDto", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.TenantManagement.TenantDto", + "typeSimple": "Volo.Abp.TenantManagement.TenantDto" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] } ], "actions": { From d3c7375562b781611c90adc386ef4a19846e2910 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 14 Aug 2023 16:00:05 +0800 Subject: [PATCH 161/165] Update Volo.CmsKit.Web.csproj --- modules/cms-kit/src/Volo.CmsKit.Web/Volo.CmsKit.Web.csproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Web/Volo.CmsKit.Web.csproj b/modules/cms-kit/src/Volo.CmsKit.Web/Volo.CmsKit.Web.csproj index ea7e47859b..812eca5cb1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Web/Volo.CmsKit.Web.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.Web/Volo.CmsKit.Web.csproj @@ -18,6 +18,12 @@ + + + + + + From 7d3363ed7c0cf4a3092c0d6896644d76dbac037c Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Tue, 1 Aug 2023 09:57:23 +0300 Subject: [PATCH 162/165] hold current page --- .../packages/core/src/lib/services/list.service.ts | 13 ++++++++----- .../src/lib/proxy/identity/identity-user.service.ts | 7 +++++-- .../src/lib/components/users/users.component.ts | 5 ++++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/list.service.ts b/npm/ng-packs/packages/core/src/lib/services/list.service.ts index 3025b91682..00eed90933 100644 --- a/npm/ng-packs/packages/core/src/lib/services/list.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/list.service.ts @@ -121,12 +121,15 @@ export class ListService implements } private resetPageWhenUnchanged() { + console.log('this.page',this._page); + console.log('this._maxResultCount',this._maxResultCount); + console.log('this._skipCount',this._skipCount); const skipCount = this._page * this._maxResultCount; - - if (skipCount === this._skipCount) { - this._page = 0; - this._skipCount = 0; - } else this._skipCount = skipCount; + console.log({skipCount}); + this._skipCount = skipCount; + console.log('this.page',this._page); + console.log('this._maxResultCount',this._maxResultCount); + console.log('this._skipCount',this._skipCount); } private next() { diff --git a/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts b/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts index 1d36c7a2e7..b7951bca10 100644 --- a/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts +++ b/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts @@ -52,13 +52,16 @@ export class IdentityUserService { }, { apiName: this.apiName }); - getList = (input: GetIdentityUsersInput) => - this.restService.request>({ + getList = (input: GetIdentityUsersInput) => { + console.log({input}); + return this.restService.request>({ method: 'GET', url: '/api/identity/users', params: { filter: input.filter, sorting: input.sorting, skipCount: input.skipCount, maxResultCount: input.maxResultCount }, }, { apiName: this.apiName }); + } + getRoles = (id: string) => this.restService.request>({ diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts index 6dd1ab9f17..5dcd3be238 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts @@ -184,7 +184,10 @@ export class UsersComponent implements OnInit { } private hookToQuery() { - this.list.hookToQuery(query => this.service.getList(query)).subscribe(res => (this.data = res)); + this.list.hookToQuery(query => this.service.getList(query)).subscribe(res => { + (this.data = res) + console.log(this.data); + }); } openPermissionsModal(providerKey: string, entityDisplayName?: string) { From 3da12685415e7dbe5c174b2b4e7fbdf57ac05d57 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Tue, 1 Aug 2023 12:01:08 +0300 Subject: [PATCH 163/165] setting total count on service. (find a better way) --- .../core/src/lib/services/list.service.ts | 29 +++++++++++++------ .../lib/components/users/users.component.ts | 4 +-- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/list.service.ts b/npm/ng-packs/packages/core/src/lib/services/list.service.ts index 00eed90933..9395f87d5a 100644 --- a/npm/ng-packs/packages/core/src/lib/services/list.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/list.service.ts @@ -52,6 +52,17 @@ export class ListService implements return this._page; } + private _totalCount = 0 + set totalCount(value: number) { + if (value === this._totalCount) return; + + this._totalCount = value; + this.get(); + } + get totalCount(): number { + return this._totalCount; + } + private _sortKey = ''; set sortKey(value: string) { this._sortKey = value; @@ -121,15 +132,15 @@ export class ListService implements } private resetPageWhenUnchanged() { - console.log('this.page',this._page); - console.log('this._maxResultCount',this._maxResultCount); - console.log('this._skipCount',this._skipCount); - const skipCount = this._page * this._maxResultCount; - console.log({skipCount}); - this._skipCount = skipCount; - console.log('this.page',this._page); - console.log('this._maxResultCount',this._maxResultCount); - console.log('this._skipCount',this._skipCount); + const skipCount = this._page * this._maxResultCount; // 10 + if(skipCount === this._totalCount){ + if(this.page > 0){ + this.page = this.page - 1; + } + }else{ + this._skipCount = skipCount; + } + } private next() { diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts index 5dcd3be238..447a2a4d92 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts @@ -185,8 +185,8 @@ export class UsersComponent implements OnInit { private hookToQuery() { this.list.hookToQuery(query => this.service.getList(query)).subscribe(res => { - (this.data = res) - console.log(this.data); + this.data = res; + this.list.totalCount = res.totalCount }); } From 4b6268ecb0e609fafb3cf3b8f693fdb2836d40d8 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Wed, 2 Aug 2023 17:28:39 +0300 Subject: [PATCH 164/165] making page persistent after edit/delete --- .../packages/core/src/lib/services/list.service.ts | 7 ++++--- .../proxy/src/lib/proxy/identity/identity-user.service.ts | 7 +++---- .../identity/src/lib/components/users/users.component.ts | 5 +---- .../extensible-table/extensible-table.component.ts | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/list.service.ts b/npm/ng-packs/packages/core/src/lib/services/list.service.ts index 9395f87d5a..aff51daa1c 100644 --- a/npm/ng-packs/packages/core/src/lib/services/list.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/list.service.ts @@ -132,15 +132,16 @@ export class ListService implements } private resetPageWhenUnchanged() { - const skipCount = this._page * this._maxResultCount; // 10 + const maxPage = Number(Number(this._totalCount / this._maxResultCount).toFixed()) // 2 + const skipCount = this._page * this._maxResultCount; // 20 if(skipCount === this._totalCount){ - if(this.page > 0){ + if(this.page === maxPage && this.page > 0){ + this._skipCount = skipCount - this._maxResultCount this.page = this.page - 1; } }else{ this._skipCount = skipCount; } - } private next() { diff --git a/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts b/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts index b7951bca10..c3b6f203f2 100644 --- a/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts +++ b/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts @@ -52,15 +52,14 @@ export class IdentityUserService { }, { apiName: this.apiName }); - getList = (input: GetIdentityUsersInput) => { - console.log({input}); - return this.restService.request>({ + getList = (input: GetIdentityUsersInput) => + this.restService.request>({ method: 'GET', url: '/api/identity/users', params: { filter: input.filter, sorting: input.sorting, skipCount: input.skipCount, maxResultCount: input.maxResultCount }, }, { apiName: this.apiName }); - } + getRoles = (id: string) => diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts index 447a2a4d92..6dd1ab9f17 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts @@ -184,10 +184,7 @@ export class UsersComponent implements OnInit { } private hookToQuery() { - this.list.hookToQuery(query => this.service.getList(query)).subscribe(res => { - this.data = res; - this.list.totalCount = res.totalCount - }); + this.list.hookToQuery(query => this.service.getList(query)).subscribe(res => (this.data = res)); } openPermissionsModal(providerKey: string, entityDisplayName?: string) { diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts index 21dec03838..ae76565aa8 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts @@ -150,7 +150,7 @@ export class ExtensibleTableComponent implements OnChanges { ngOnChanges({ data }: SimpleChanges) { if (!data?.currentValue) return; - + this.list.totalCount = this.recordsTotal this.data = data.currentValue.map((record: any, index: number) => { this.propList.forEach(prop => { const propData = { getInjected: this.getInjected, record, index } as any; From 8c57631766a4dcf1411d65246162cad00ce21195 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 11 Aug 2023 13:51:19 +0300 Subject: [PATCH 165/165] fix --- .../core/src/lib/services/list.service.ts | 18 ++++++++++-------- .../extensible-table.component.ts | 6 +++++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/list.service.ts b/npm/ng-packs/packages/core/src/lib/services/list.service.ts index aff51daa1c..76dac87b5a 100644 --- a/npm/ng-packs/packages/core/src/lib/services/list.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/list.service.ts @@ -132,15 +132,17 @@ export class ListService implements } private resetPageWhenUnchanged() { - const maxPage = Number(Number(this._totalCount / this._maxResultCount).toFixed()) // 2 - const skipCount = this._page * this._maxResultCount; // 20 - if(skipCount === this._totalCount){ - if(this.page === maxPage && this.page > 0){ - this._skipCount = skipCount - this._maxResultCount - this.page = this.page - 1; - } - }else{ + const maxPage = Number(Number(this.totalCount / this._maxResultCount).toFixed()); + const skipCount = this._page * this._maxResultCount; + + if (skipCount !== this._totalCount) { this._skipCount = skipCount; + return; + } + + if (this.page === maxPage && this.page > 0) { + this._skipCount = skipCount - this._maxResultCount; + this.page = this.page - 1; } } diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts index ae76565aa8..aa264385be 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts @@ -150,7 +150,11 @@ export class ExtensibleTableComponent implements OnChanges { ngOnChanges({ data }: SimpleChanges) { if (!data?.currentValue) return; - this.list.totalCount = this.recordsTotal + + if (data.currentValue.length < 1) { + this.list.totalCount = this.recordsTotal + } + this.data = data.currentValue.map((record: any, index: number) => { this.propList.forEach(prop => { const propData = { getInjected: this.getInjected, record, index } as any;