diff --git a/docs/en/Themes/LeptonXLite/Angular.md b/docs/en/Themes/LeptonXLite/Angular.md index 7ebb649aca..56b003e606 100644 --- a/docs/en/Themes/LeptonXLite/Angular.md +++ b/docs/en/Themes/LeptonXLite/Angular.md @@ -14,11 +14,15 @@ To add `LeptonX-lite` into your project, - Install `@abp/ng.theme.lepton-x` -`yarn add @abp/ng.theme.lepton-x@preview` +```bash +yarn add @abp/ng.theme.lepton-x +``` - Install `bootstrap-icons` -`yarn add bootstrap-icons` +```bash +yarn add bootstrap-icons +``` - Then, we need to edit the styles array in `angular.json` to replace the existing style with the new one in the following link : diff --git a/docs/en/Tutorials/Todo/Single-Layer/Index.md b/docs/en/Tutorials/Todo/Single-Layer/Index.md index 744aff88ad..fe09c57e3f 100644 --- a/docs/en/Tutorials/Todo/Single-Layer/Index.md +++ b/docs/en/Tutorials/Todo/Single-Layer/Index.md @@ -255,7 +255,7 @@ Before starting to implement these use cases, first we need to create a DTO clas [Application services](../../../Application-Services.md) typically get and return DTOs ([Data Transfer Objects](../../../Data-Transfer-Objects.md)) instead of entities. So, create a new `TodoItemDto` class under the `Services/Dtos` folder{{if UI=="Blazor"}} of your `TodoApp.Contracts` project{{end}}: ```csharp -namespace TodoApp{{if UI=="Blazor"}}.Contracts{{end}}.Services.Dtos; +namespace TodoApp.Services.Dtos; public class TodoItemDto { @@ -273,10 +273,10 @@ This is a very simple DTO class that has the same properties as the `TodoItem` e Create a `ITodoAppService` interface under the `Services` folder of the `TodoApp.Contracts` project, as shown below: ```csharp -using TodoApp.Contracts.Services.Dtos; +using TodoApp.Services.Dtos; using Volo.Abp.Application.Services; -namespace TodoApp.Contracts.Services; +namespace TodoApp.Services; public interface ITodoAppService : IApplicationService { @@ -296,17 +296,18 @@ Create a `TodoAppService` class under the `Services` folder of {{if UI=="Blazor" ```csharp {{if UI=="Blazor"}} -using TodoApp.Contracts.Services; -using TodoApp.Contracts.Services.Dtos; -using TodoApp.Host.Entities; +using TodoApp.Services; +using TodoApp.Services.Dtos; +using TodoApp.Entities; using Volo.Abp.Application.Services; +using Volo.Abp.Domain.Repositories; {{else}} using TodoApp.Entities; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories; {{end}} -namespace TodoApp{{if UI=="Blazor"}}.Host{{end}}.Services; +namespace TodoApp.Services; public class TodoAppService : ApplicationService{{if UI=="Blazor"}}, ITodoAppService{{end}} { @@ -562,8 +563,8 @@ Open the `Index.razor.cs` file in the `Pages` folder{{if UI=="Blazor"}} in your ```csharp {{if UI=="Blazor"}} using Microsoft.AspNetCore.Components; -using TodoApp.Contracts.Services; -using TodoApp.Contracts.Services.Dtos; +using TodoApp.Services; +using TodoApp.Services.Dtos; {{else}} using Microsoft.AspNetCore.Components; using TodoApp.Services; diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs index 14cd0d405b..1a1e2ece3b 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs @@ -124,7 +124,7 @@ public class FeatureDefinition : ICanCreateChildFeature } /// - /// Sets a property in the dictionary. + /// Adds one or more providers to the list. /// This is a shortcut for nested calls on this object. /// public virtual FeatureDefinition WithProviders(params string[] providers) diff --git a/npm/ng-packs/angular.json b/npm/ng-packs/angular.json index 01e482cd85..7138cb5a38 100644 --- a/npm/ng-packs/angular.json +++ b/npm/ng-packs/angular.json @@ -195,15 +195,55 @@ "assets": ["apps/dev-app/src/favicon.ico", "apps/dev-app/src/assets"], "styles": [ { - "input": "node_modules/bootstrap/dist/css/bootstrap.rtl.min.css", + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.css", "inject": false, - "bundleName": "bootstrap-rtl.min" + "bundleName": "bootstrap-dim" }, { - "input": "node_modules/bootstrap/dist/css/bootstrap.min.css", - "inject": true, - "bundleName": "bootstrap-ltr.min" + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.css", + "inject": false, + "bundleName": "ng-bundle" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.css", + "inject": false, + "bundleName": "layout-bundle" + }, + { + "input": "node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.css", + "inject": false, + "bundleName": "abp-bundle" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.rtl.css", + "inject": false, + "bundleName": "bootstrap-dim.rtl" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.rtl.css", + "inject": false, + "bundleName": "ng-bundle.rtl" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.rtl.css", + "inject": false, + "bundleName": "layout-bundle.rtl" + }, + { + "input": "node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.rtl.css", + "inject": false, + "bundleName": "abp-bundle.rtl" + }, + { + "input":"node_modules/@volo/ngx-lepton-x.lite/assets/css/font-bundle.rtl.css", + "inject":false, + "bundleName":"font-bundle.rtl" }, + { + "input":"node_modules/@volo/ngx-lepton-x.lite/assets/css/font-bundle.css", + "inject":false, + "bundleName":"font-bundle" + }, { "input": "node_modules/@fortawesome/fontawesome-free/css/all.min.css", "inject": true, @@ -234,6 +274,7 @@ "inject": false, "bundleName": "ng-zorro-antd-tree" }, + "node_modules/bootstrap-icons/font/bootstrap-icons.css", "apps/dev-app/src/styles.scss" ], "scripts": [] diff --git a/npm/ng-packs/apps/dev-app/src/app/app.module.ts b/npm/ng-packs/apps/dev-app/src/app/app.module.ts index 52ebd38362..56e38b40ee 100644 --- a/npm/ng-packs/apps/dev-app/src/app/app.module.ts +++ b/npm/ng-packs/apps/dev-app/src/app/app.module.ts @@ -4,7 +4,8 @@ import { registerLocale } from '@abp/ng.core/locale'; import { IdentityConfigModule } from '@abp/ng.identity/config'; import { SettingManagementConfigModule } from '@abp/ng.setting-management/config'; import { TenantManagementConfigModule } from '@abp/ng.tenant-management/config'; -import { ThemeBasicModule } from '@abp/ng.theme.basic'; +import { ThemeLeptonXModule } from '@abp/ng.theme.lepton-x'; +import { SideMenuLayoutModule } from '@abp/ng.theme.lepton-x/layouts'; import { ThemeSharedModule } from '@abp/ng.theme.shared'; import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; @@ -34,7 +35,8 @@ import { AbpOAuthModule } from '@abp/ng.oauth'; TenantManagementConfigModule.forRoot(), FeatureManagementModule.forRoot(), SettingManagementConfigModule.forRoot(), - ThemeBasicModule.forRoot(), + ThemeLeptonXModule.forRoot(), + SideMenuLayoutModule.forRoot(), ], providers: [APP_ROUTE_PROVIDER], declarations: [AppComponent], diff --git a/npm/ng-packs/apps/dev-app/src/app/home/home.component.html b/npm/ng-packs/apps/dev-app/src/app/home/home.component.html index 2d249da3d8..7024ab69e5 100644 --- a/npm/ng-packs/apps/dev-app/src/app/home/home.component.html +++ b/npm/ng-packs/apps/dev-app/src/app/home/home.component.html @@ -26,8 +26,8 @@

Let's improve your application!

Here are some links to help you get started:

-
-
+ +
-
-
+ +

Meet the ABP Commercial

A Complete Web Application Platform Built on the ABP Framework

- -
-
+ +

ABP Commercial is a platform based on the open source ABP framework. It provides pre-built application modules, rapid @@ -271,8 +270,9 @@ " >

-
- + + +

{ provide: AbpApplicationConfigurationService, useValue: { get: () => of(CONFIG_STATE_DATA) }, }, + { + provide: AbpApplicationLocalizationService, + useValue: { get: () => APPLICATION_LOCALIZATION_DATA }, + }, + IncludeLocalizationResourcesProvider, ], }); diff --git a/npm/ng-packs/packages/core/src/lib/tests/date-utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/date-utils.spec.ts index 20ef2e4a48..33f02dfb4f 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/date-utils.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/date-utils.spec.ts @@ -15,7 +15,7 @@ describe('Date Utils', () => { let config: ConfigStateService; beforeEach(() => { - config = new ConfigStateService(null); + config = new ConfigStateService(null, null, null); }); describe('#getShortDateFormat', () => { diff --git a/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts index c12b7b61ce..4af0755d6c 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts @@ -57,6 +57,7 @@ describe('Localization Utils', () => { languages: [], languageFilesMap: null, languagesMap: null, + resources: {}, }); test.each` @@ -100,6 +101,7 @@ describe('Localization Utils', () => { languages: [], languageFilesMap: null, languagesMap: null, + resources: {}, }); test.each` @@ -148,6 +150,7 @@ describe('Localization Utils', () => { languages: [], languageFilesMap: null, languagesMap: null, + resources: {}, }); test.each` diff --git a/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts index 5aedd28f6e..d2eb653a85 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts @@ -8,8 +8,12 @@ import { SessionStateService } from '../services/session-state.service'; import { LocalizationService } from '../services/localization.service'; import { CORE_OPTIONS } from '../tokens/options.token'; import { CONFIG_STATE_DATA } from './config-state.service.spec'; +import { AbpApplicationLocalizationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service'; +import { APPLICATION_LOCALIZATION_DATA } from './application-localization.service.spec'; +import { IncludeLocalizationResourcesProvider } from '../providers'; const appConfigData$ = new BehaviorSubject(CONFIG_STATE_DATA); +const appLocalizationData$ = new BehaviorSubject(APPLICATION_LOCALIZATION_DATA); describe('LocalizationService', () => { let spectator: SpectatorService; @@ -22,6 +26,7 @@ describe('LocalizationService', () => { entryComponents: [], mocks: [Router], providers: [ + IncludeLocalizationResourcesProvider, { provide: CORE_OPTIONS, useValue: { registerLocaleFn: () => Promise.resolve(), cultureNameLocaleFileMap: {} }, @@ -30,6 +35,10 @@ describe('LocalizationService', () => { provide: AbpApplicationConfigurationService, useValue: { get: () => appConfigData$ }, }, + { + provide: AbpApplicationLocalizationService, + useValue: { get: () => appLocalizationData$ }, + }, ], }); diff --git a/npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts index 4369b8434f..372f3434f3 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts @@ -9,6 +9,7 @@ import { HttpErrorReporterService } from '../services/http-error-reporter.servic import { PermissionService } from '../services/permission.service'; import { RoutesService } from '../services/routes.service'; import { CORE_OPTIONS } from '../tokens/options.token'; +import { IncludeLocalizationResourcesProvider } from '../providers'; describe('PermissionGuard', () => { let spectator: SpectatorService; @@ -36,7 +37,7 @@ describe('PermissionGuard', () => { }, }, ], - { relativeLinkResolution: 'legacy' }, + {}, ), ], providers: [ @@ -45,6 +46,7 @@ describe('PermissionGuard', () => { useValue: '/', }, { provide: CORE_OPTIONS, useValue: { skipGetAppConfiguration: true } }, + IncludeLocalizationResourcesProvider, ], }); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/card/card-body.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/card/card-body.component.ts new file mode 100644 index 0000000000..b7efd90236 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/card/card-body.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'abp-card-body', + template: `

+ +
`, +}) +export class CardBodyComponent {} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/card/card-title.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/card/card-title.component.ts new file mode 100644 index 0000000000..f629636854 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/card/card-title.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'abp-card-title', + template: `
+ +
`, +}) +export class CardTitleComponent {} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/card/card.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/card/card.component.ts new file mode 100644 index 0000000000..317e5800b9 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/card/card.component.ts @@ -0,0 +1,22 @@ +import { Component, ContentChild, Input } from '@angular/core'; +import { CardBodyComponent } from './card-body.component'; +import { CardTitleComponent } from './card-title.component'; + +@Component({ + selector: 'abp-card', + template: `
+ + +
`, +}) +export class CardComponent { + @Input() cardClass: string; + + @Input() cardStyle: string; + + @ContentChild(CardBodyComponent) + cardBodyTemplate?: CardBodyComponent; + + @ContentChild(CardTitleComponent) + cardTitleTemplate?: CardTitleComponent; +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/card/card.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/card/card.module.ts new file mode 100644 index 0000000000..d8050a40cd --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/card/card.module.ts @@ -0,0 +1,14 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { CardBodyComponent } from './card-body.component'; +import { CardTitleComponent } from './card-title.component'; +import { CardComponent } from './card.component'; + +const declarationsWithExports = [CardComponent, CardBodyComponent, CardTitleComponent]; + +@NgModule({ + declarations: [...declarationsWithExports], + imports: [CommonModule], + exports: [...declarationsWithExports], +}) +export class CardModule {} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/card/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/card/index.ts new file mode 100644 index 0000000000..8d6bbd86d8 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/card/index.ts @@ -0,0 +1,4 @@ +export * from './card.module'; +export * from './card.component'; +export * from './card-body.component'; +export * from './card-title.component'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/index.ts index 810d5a991a..095af5ef26 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/index.ts @@ -11,3 +11,4 @@ export * from './modal/modal.component'; export * from './toast-container/toast-container.component'; export * from './toast/toast.component'; export * from './password/password.component'; +export * from './card/index'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/visible.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/visible.directive.ts index 9c2c408d0e..9613779472 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/directives/visible.directive.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/visible.directive.ts @@ -8,7 +8,7 @@ export class AbpVisibleDirective implements OnDestroy, OnInit { conditionSubscription: Subscription | undefined; isVisible: boolean | undefined; - @Input('abpVisible') set abpVisible( + @Input() set abpVisible( value: boolean | Promise | Observable | undefined | null, ) { this.condition$ = checkType(value); 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 765403f2bd..8a7cf9f851 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 @@ -36,8 +36,8 @@ import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/http-error.t import { DateParserFormatter } from './utils/date-parser-formatter'; import { CONFIRMATION_ICONS, DEFAULT_CONFIRMATION_ICONS } from './tokens/confirmation-icons.token'; import { PasswordComponent } from './components/password/password.component'; +import { CardModule } from './components/card/card.module'; import { AbpVisibleDirective } from './directives'; -import { FormInputComponent } from './components/form-input/form-input.component'; const declarationsWithExports = [ BreadcrumbComponent, @@ -64,9 +64,16 @@ const declarationsWithExports = [ NgxValidateCoreModule, NgbPaginationModule, EllipsisModule, + CardModule, + ], + declarations: [...declarationsWithExports, HttpErrorWrapperComponent], + exports: [ + NgxDatatableModule, + EllipsisModule, + NgxValidateCoreModule, + ...declarationsWithExports, + CardModule, ], - declarations: [...declarationsWithExports, HttpErrorWrapperComponent, FormInputComponent], - exports: [NgxDatatableModule, EllipsisModule, NgxValidateCoreModule, ...declarationsWithExports], providers: [DatePipe], }) export class BaseThemeSharedModule {}