Browse Source

Merge pull request #9070 from abpframework/auto-merge/rel-4-3/391

Merge branch dev with rel-4.3
pull/9072/head
Halil İbrahim Kalkan 5 years ago
committed by GitHub
parent
commit
67932648b5
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 60
      docs/en/JSON.md
  2. 77
      docs/en/Modules/Cms-Kit.md
  3. 3
      docs/en/Modules/cms-kit/Pages.md
  4. 125
      docs/en/UI/Angular/Component-Replacement.md
  5. 4
      docs/en/docs-nav.json
  6. 7
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs
  7. 5
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs
  8. 8
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs
  9. 19
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs
  10. 3
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Pages/PagePublicAppService.cs
  11. 10
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Ratings/RatingPublicAppService.cs
  12. 7
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Reactions/ReactionPublicAppService.cs
  13. 2
      npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts
  14. 11
      npm/ng-packs/packages/theme-shared/src/lib/handlers/datepicker-config.ts
  15. 1
      npm/ng-packs/packages/theme-shared/src/lib/handlers/index.ts
  16. 1
      npm/ng-packs/packages/theme-shared/src/lib/providers/index.ts
  17. 21
      npm/ng-packs/packages/theme-shared/src/lib/providers/ng-bootstrap-config.provider.ts
  18. 13
      npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts

60
docs/en/JSON.md

@ -0,0 +1,60 @@
# JSON
The ABP Framework provides an abstraction to work with JSON. Having such an abstraction has some benefits;
* You can write library independent code. Therefore, you can change the underlying library with the minimum effort and code change.
* You can use the predefined converters defined in the ABP without worrying about the underlying library's internal details.
> The JSON serialization system is implemented with the [Volo.Abp.Json](https://www.nuget.org/packages/Volo.Abp.Json) NuGet package. Most of the time, you don't need to manually [install it](https://abp.io/package-detail/Volo.Abp.Json) since it comes pre-installed with the [application startup template](Startup-Templates/Application.md).
## IJsonSerializer
You can inject `IJsonSerializer` and use it for JSON operations. Here is the available operations in the `IJsonSerializer` interface.
```csharp
public interface IJsonSerializer
{
string Serialize(object obj, bool camelCase = true, bool indented = false);
T Deserialize<T>(string jsonString, bool camelCase = true);
object Deserialize(Type type, string jsonString, bool camelCase = true);
}
```
Usage Example:
```csharp
public class ProductManager
{
public IJsonSerializer JsonSerializer { get; }
public ProductManager(IJsonSerializer jsonSerializer)
{
JsonSerializer = jsonSerializer;
}
public void SendRequest(Product product)
{
var json= JsonSerializer.Serialize(product);
// Left blank intentionally for demo purposes...
}
}
```
## Configuration
### AbpJsonOptions
`AbpJsonOptions` type provides options for the JSON operations in the ABP Framework.
Properties:
* **DefaultDateTimeFormat(`string`)**: Default `DateTime` format.
* **UseHybridSerializer(`bool`)**: True by default. Boolean field indicating whether the ABP Framework uses the hybrid approach or not. If the field is true, it will try to use `System.Json.Text` to handle JSON if it can otherwise use the `Newtonsoft.Json.`
* **Providers(`ITypeList<IJsonSerializerProvider>`)**: List of JSON serializer providers implementing the `IJsonSerializerProvider` interface. You can create and add custom serializers to the list, and the ABP Framework uses them automatically. When the `Serialize` or `Deserialize` method is called on the `IJsonSerializer` interface, the ABP Framework calls the `CanHandle` methods of the given providers in reverse order and uses the first provider that returns `true` to do the JSON operation.
### AbpSystemTextJsonSerializerOptions
`AbpSystemTextJsonSerializerOptions` provides options for `System.Text.Json` usage.
Properties:
- **JsonSerializerOptions(`System.Text.Json.JsonSerializerOptions`)**: Global options for System.Text.Json library operations. See [here](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions) for reference.
- **UnsupportedTypes(`ITypeList`)**: List of the unsupported types. You can add types of the unsupported types to the list and, the hybrid JSON serializer automatically uses the `Newtonsoft.Json` library instead of `System.Text.Json`.

77
docs/en/Modules/Cms-Kit.md

@ -1,70 +1,61 @@
# CMS Kit Module # CMS Kit Module
This module provides CMS(Content Management System) capabilities for your application. This module provides CMS (Content Management System) capabilities for your application. It provides **core building blocks** and fully working **sub-systems** to create your own website with CMS features enabled, or use the building blocks in your web sites with any purpose.
* Provides a **page** management system to manage dynamic pages. > **This module currently available only for the MVC UI**. While there is no official Blazor package, it can also work in a Blazor Server UI since a Blazor Server UI application is actually a hybrid application that runs within the MVC UI.
* Provides a [**blog**](cms-kit/Blog-System.md) system to create blogs and publish posts.
* Provides a [**tag**](cms-kit/Tag-Management.md) system to tag any kind of resources, like blog posts. The following features are currently available:
* Provides a [**comment**](cms-kit/Comment-System.md) system to add comments feature to any kind of resource, like blog posts, products, etc.
* Provides a [**reaction**](cms-kit/Reaction-System.md) system to add reactions feature to any kind of resource, like blog posts or comments. * Provides a [**page**](cms-kit/Pages.md) management system to manage dynamic pages with dynamic URLs.
* Provides a [**blog**](cms-kit/Blog-System.md) system to create publish blog posts with multiple blog support.
* Provides a [**tagging**](cms-kit/Tag-Management.md) system to tag any kind of resource, like a blog post.
* Provides a [**comment**](cms-kit/Comment-System.md) system to add comments feature to any kind of resource, like blog post or a product review page.
* Provides a [**reaction**](cms-kit/Reaction-System.md) system to add reactions (smileys) feature to any kind of resource, like a blog post or a comment.
* Provides a [**rating**](cms-kit/Rating-System.md) system to add rating feature to any kind of resource. * Provides a [**rating**](cms-kit/Rating-System.md) system to add rating feature to any kind of resource.
## How to install Click to a feature to understand and learn how to use it.
All features are individually usable. If you disable a feature, it completely disappears from your application, even from the database tables, by the help of the [Global Features](../Global-Features.md) system.
## How to Install
The ABP CLI allows adding a module to a solution using `add-module` command. CMS kit module can be added using the command below; [ABP CLI](../CLI.md) allows installing a module to a solution using the `add-module` command. You can install the CMS Kit module in a command-line terminal with the following command:
```bash ```bash
abp add-module Volo.CmsKit abp add-module Volo.CmsKit
``` ```
Open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project and place the following code to the `Configure` method to enable all features in the CMS kit module. After the installation process, open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project of your solution and place the following code into the `Configure` method to enable all the features in the CMS Kit module.
```csharp ```csharp
GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit => GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit =>
{ {
cmsKit.EnableAll(); cmsKit.EnableAll();
}); });
``` ```
> If you are using EntityFrameworkCore, do not forget to add a new migration and update your database. Instead of enabling all, you may prefer to enable the features one by one. The following example enables only the [tags](cms-kit/Tag-Management.md) and [comments](cms-kit/Comment-System.md) features:
## Packages
This module follows the [module development best practices guide](https://docs.abp.io/en/abp/latest/Best-Practices/Index) and consists of several NuGet and NPM packages. See the guide if you want to understand the packages and relations between them.
CMS kit packages are designed for various usage scenarios. When you visit the [CMS kit package list page](https://www.nuget.org/packages?q=Volo.CmsKit), you will see that packages have admin, public and unified versions.
For example,
- `Volo.CmsKit.Admin.Application`: Contains functionality required by admin websites.
- `Volo.CmsKit.Public.Application`: Contains functionality required by public websites.
- `Volo.CmsKit.Application` : Unified package dependent on both public and admin packages.
If you want to separate admin and public website codes, you can use the admin and public packages. However, if you want to keep admin and public website codes in a shared project, you can use the unified packages to include admin and public packages.
It is recommended to use the unified packages instead of adding both admin and public packages.
## Feature System
CMS kit uses the [global feature](https://docs.abp.io/en/abp/latest/Global-Features) system for all implemented features. You can use the global feature system to enable all features or only enabled specific features easily.
To enable all features in the CMS kit, open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project. ````csharp
```csharp
GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit => GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit =>
{ {
cmsKit.EnableAll(); cmsKit.Tags.Enable();
cmsKit.Comments.Enable();
}); });
``` ````
You can only enable specific features such as pages, like below. > If you are using Entity Framework Core, do not forget to add a new migration and update your database.
```csharp ## The Packages
GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit =>
{ This module follows the [module development best practices guide](https://docs.abp.io/en/abp/latest/Best-Practices/Index) and consists of several NuGet and NPM packages. See the guide if you want to understand the packages and relations between them.
cmsKit.Pages.Enable();
}); CMS kit packages are designed for various usage scenarios. When you visit the [CMS kit package list page](https://www.nuget.org/packages?q=Volo.CmsKit), you will see that packages have admin, public and unified versions:
```
- `Volo.CmsKit.Admin.*` packages contain the functionalities required by admin (back office) applications.
- `Volo.CmsKit.Public.*` packages contain the functionalities used in public websites where users read blog posts or leave comments.
- `Volo.CmsKit.*` (without Admin/Public suffix) packages are called as unified packages. Unified packages are shortcuts for adding Admin & Public packages (of the related layer) separately. If you have a single application for administration and public web site, you can use these packages.
## User interface ## The User Interface
### Menu items ### Menu items
@ -156,4 +147,4 @@ You can also customize the reaction icons shown in the reaction component.
You can use the rating component to add rating a mechanism to your content. Here how the rating component looks on a sample page. You can use the rating component to add rating a mechanism to your content. Here how the rating component looks on a sample page.
![ratings](../images/cmskit-module-ratings.png) ![ratings](../images/cmskit-module-ratings.png)

3
docs/en/Modules/cms-kit/Pages.md

@ -0,0 +1,3 @@
# CMS Kit: Pages
This document is in progress...

125
docs/en/UI/Angular/Component-Replacement.md

@ -84,11 +84,10 @@ export class AppComponent {
Run the following command in `angular` folder to create a new component called `LogoComponent`. Run the following command in `angular` folder to create a new component called `LogoComponent`.
```bash ```bash
yarn ng generate component logo --inlineTemplate --inlineStyle --entryComponent yarn ng generate component logo --inlineTemplate --inlineStyle
# You don't need the --entryComponent option in Angular 9
``` ```
Open the generated `logo.component.ts` in `src/app/logo` folder and replace its content with the following: Open the generated `logo.component.ts` in `src/app/logo` folder and replace its content with the following:
```js ```js
@ -115,7 +114,7 @@ Open `app.component.ts` in `src/app` folder and modify it as shown below:
```js ```js
import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService
import { LogoComponent } from './logo/logo.component'; // imported NavItemsComponent import { LogoComponent } from './logo/logo.component'; // imported LogoComponent
import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents
//... //...
@ -151,36 +150,18 @@ yarn ng generate component routes
Open the generated `routes.component.ts` in `src/app/routes` folder and replace its content with the following: Open the generated `routes.component.ts` in `src/app/routes` folder and replace its content with the following:
```js ```js
import { ABP } from '@abp/ng.core'; import { Component, HostBinding } from '@angular/core';
import {
Component,
HostBinding,
Inject,
Renderer2,
TrackByFunction,
AfterViewInit,
} from '@angular/core';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
@Component({ @Component({
selector: 'app-routes', selector: 'app-routes',
templateUrl: 'routes.component.html', templateUrl: 'routes.component.html',
}) })
export class RoutesComponent implements AfterViewInit { export class RoutesComponent {
@HostBinding('class.mx-auto') @HostBinding('class.mx-auto')
marginAuto = true; marginAuto = true;
smallScreen = window.innerWidth < 992; get smallScreen() {
return window.innerWidth < 992;
constructor(private renderer: Renderer2) {}
ngAfterViewInit() {
fromEvent(window, 'resize')
.pipe(debounceTime(150))
.subscribe(() => {
this.smallScreen = window.innerWidth < 992;
});
} }
} }
``` ```
@ -310,7 +291,7 @@ Open `app.component.ts` in `src/app` folder and modify it as shown below:
```js ```js
import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService
import { RoutesComponent } from './routes/routes.component'; // imported NavItemsComponent import { RoutesComponent } from './routes/routes.component'; // imported RoutesComponent
import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents
//... //...
@ -347,51 +328,51 @@ Open the generated `nav-items.component.ts` in `src/app/nav-items` folder and re
```js ```js
import { import {
ApplicationConfiguration,
AuthService, AuthService,
ConfigState, ConfigStateService,
CurrentUserDto,
LanguageInfo,
NAVIGATE_TO_MANAGE_PROFILE,
SessionStateService, SessionStateService,
SetLanguage,
} from '@abp/ng.core'; } from '@abp/ng.core';
import { Component, AfterViewInit } from '@angular/core'; import { Component, Inject } from '@angular/core';
import { Navigate, RouterState } from '@ngxs/router-plugin'; import { Observable } from 'rxjs';
import { Select, Store } from '@ngxs/store'; import { map } from 'rxjs/operators';
import { Observable, fromEvent } from 'rxjs';
import { map, debounceTime } from 'rxjs/operators';
import snq from 'snq'; import snq from 'snq';
@Component({ @Component({
selector: 'app-nav-items', selector: 'app-nav-items',
templateUrl: 'nav-items.component.html', templateUrl: 'nav-items.component.html',
}) })
export class NavItemsComponent implements AfterViewInit { export class NavItemsComponent {
@Select(ConfigState.getOne('currentUser')) currentUser$: Observable<CurrentUserDto> = this.configState.getOne$('currentUser');
currentUser$: Observable<ApplicationConfiguration.CurrentUser>; selectedTenant$ = this.sessionState.getTenant$();
@Select(ConfigState.getDeep('localization.languages')) languages$: Observable<LanguageInfo[]> = this.configState.getDeep$('localization.languages');
languages$: Observable<ApplicationConfiguration.Language[]>;
smallScreen = window.innerWidth < 992; get smallScreen(): boolean {
return window.innerWidth < 992;
}
get defaultLanguage$(): Observable<string> { get defaultLanguage$(): Observable<string> {
return this.languages$.pipe( return this.languages$.pipe(
map( map(
languages => languages =>
snq( snq(
() => languages.find(lang => lang.cultureName === this.selectedLangCulture).displayName, () => languages.find(lang => lang.cultureName === this.selectedLangCulture).displayName
), ),
'', ''
), )
); );
} }
get dropdownLanguages$(): Observable<ApplicationConfiguration.Language[]> { get dropdownLanguages$(): Observable<LanguageInfo[]> {
return this.languages$.pipe( return this.languages$.pipe(
map( map(
languages => languages =>
snq(() => languages.filter(lang => lang.cultureName !== this.selectedLangCulture)), snq(() => languages.filter(lang => lang.cultureName !== this.selectedLangCulture)),
[], []
), )
); );
} }
@ -399,28 +380,23 @@ export class NavItemsComponent implements AfterViewInit {
return this.sessionState.getLanguage(); return this.sessionState.getLanguage();
} }
constructor(private store: Store, private authService: AuthService, private sessionState: SessionStateService) {} constructor(
@Inject(NAVIGATE_TO_MANAGE_PROFILE) public navigateToManageProfile,
private configState: ConfigStateService,
private authService: AuthService,
private sessionState: SessionStateService
) {}
ngAfterViewInit() { onChangeLang(cultureName: string) {
fromEvent(window, 'resize') this.sessionState.setLanguage(cultureName);
.pipe(debounceTime(150))
.subscribe(() => {
this.smallScreen = window.innerWidth < 992;
});
} }
onChangeLang(cultureName: string) { navigateToLogin() {
this.store.dispatch(new SetLanguage(cultureName)); this.authService.navigateToLogin();
} }
logout() { logout() {
this.authService.logout().subscribe(() => { this.authService.logout().subscribe();
this.store.dispatch(
new Navigate(['/'], null, {
state: { redirectUrl: this.store.selectSnapshot(RouterState).state.url },
}),
);
});
} }
} }
``` ```
@ -445,8 +421,14 @@ Open the generated `nav-items.component.html` in `src/app/nav-items` folder and
```html ```html
<ul class="navbar-nav"> <ul class="navbar-nav">
<input type="search" placeholder="Search" class="bg-transparent border-0 text-white" /> <input type="search" placeholder="Search" class="bg-transparent border-0 text-white" />
<li *ngIf="(dropdownLanguages$ | async)?.length > 0" class="nav-item"> <li class="nav-item d-flex align-items-center">
<div class="dropdown" ngbDropdown #languageDropdown="ngbDropdown" display="static"> <div
*ngIf="(dropdownLanguages$ | async)?.length > 0"
class="dropdown"
ngbDropdown
#languageDropdown="ngbDropdown"
display="static"
>
<a <a
ngbDropdownToggle ngbDropdownToggle
class="nav-link" class="nav-link"
@ -474,10 +456,9 @@ Open the generated `nav-items.component.html` in `src/app/nav-items` folder and
</div> </div>
</div> </div>
</li> </li>
<li class="nav-item d-flex align-items-center">
<li class="nav-item">
<ng-template #loginBtn> <ng-template #loginBtn>
<a role="button" class="nav-link" routerLink="/account/login">{%{{{ <a role="button" class="nav-link pointer" (click)="navigateToLogin()">{%{{{
'AbpAccount::Login' | abpLocalization 'AbpAccount::Login' | abpLocalization
}}}%}</a> }}}%}</a>
</ng-template> </ng-template>
@ -498,14 +479,18 @@ Open the generated `nav-items.component.html` in `src/app/nav-items` folder and
aria-haspopup="true" aria-haspopup="true"
aria-expanded="false" aria-expanded="false"
> >
{%{{{ (currentUser$ | async)?.userName }}}%} <small *ngIf="(selectedTenant$ | async)?.name as tenantName"
><i>{%{{{ tenantName }}}%}</i
>\</small
>
<strong>{%{{{ (currentUser$ | async)?.userName }}}%}</strong>
</a> </a>
<div <div
class="dropdown-menu dropdown-menu-right border-0 shadow-sm" class="dropdown-menu dropdown-menu-right border-0 shadow-sm"
aria-labelledby="dropdownMenuLink" aria-labelledby="dropdownMenuLink"
[class.d-block]="smallScreen && currentUserDropdown.isOpen()" [class.d-block]="smallScreen && currentUserDropdown.isOpen()"
> >
<a class="dropdown-item" routerLink="/account/manage-profile" <a class="dropdown-item pointer" (click)="navigateToManageProfile()"
><i class="fa fa-cog mr-1"></i>{%{{{ 'AbpAccount::ManageYourProfile' | abpLocalization }}}%}</a ><i class="fa fa-cog mr-1"></i>{%{{{ 'AbpAccount::ManageYourProfile' | abpLocalization }}}%}</a
> >
<a class="dropdown-item" href="javascript:void(0)" (click)="logout()" <a class="dropdown-item" href="javascript:void(0)" (click)="logout()"

4
docs/en/docs-nav.json

@ -348,6 +348,10 @@
} }
] ]
}, },
{
"text": "JSON",
"path": "JSON.md"
},
{ {
"text": "Features", "text": "Features",
"path": "Features.md" "path": "Features.md"

7
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs

@ -1,10 +1,11 @@
using System.Linq; using System.Threading.Tasks;
using System.Linq; using Volo.Abp.GlobalFeatures;
using System.Threading.Tasks; using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Tags; using Volo.CmsKit.Tags;
namespace Volo.CmsKit.Admin.Tags namespace Volo.CmsKit.Admin.Tags
{ {
[RequiresGlobalFeature(typeof(TagsFeature))]
public class EntityTagAdminAppService : CmsKitAdminAppServiceBase, IEntityTagAdminAppService public class EntityTagAdminAppService : CmsKitAdminAppServiceBase, IEntityTagAdminAppService
{ {
protected ITagDefinitionStore TagDefinitionStore { get; } protected ITagDefinitionStore TagDefinitionStore { get; }

5
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs

@ -5,14 +5,15 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.GlobalFeatures;
using Volo.Abp.Domain.Repositories; using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Permissions; using Volo.CmsKit.Permissions;
using Volo.CmsKit.Tags; using Volo.CmsKit.Tags;
namespace Volo.CmsKit.Admin.Tags namespace Volo.CmsKit.Admin.Tags
{ {
[Authorize(CmsKitAdminPermissions.Tags.Default)] [Authorize(CmsKitAdminPermissions.Tags.Default)]
[RequiresGlobalFeature(typeof(TagsFeature))]
public class TagAdminAppService : CmsKitAppServiceBase, ITagAdminAppService public class TagAdminAppService : CmsKitAppServiceBase, ITagAdminAppService
{ {
protected ITagRepository Repository { get; } protected ITagRepository Repository { get; }

8
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs

@ -1,14 +1,14 @@
using JetBrains.Annotations; using JetBrains.Annotations;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.BlobStoring; using Volo.Abp.GlobalFeatures;
using Volo.Abp.Content;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
using Volo.CmsKit.GlobalFeatures;
namespace Volo.CmsKit.Public.Blogs namespace Volo.CmsKit.Public.Blogs
{ {
[RequiresGlobalFeature(typeof(BlogsFeature))]
public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPublicAppService public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPublicAppService
{ {
protected IBlogRepository BlogRepository { get; } protected IBlogRepository BlogRepository { get; }
@ -36,7 +36,7 @@ namespace Volo.CmsKit.Public.Blogs
{ {
var blog = await BlogRepository.GetBySlugAsync(blogSlug); var blog = await BlogRepository.GetBySlugAsync(blogSlug);
var blogPosts = await BlogPostRepository.GetListAsync(null, blog.Id,input.MaxResultCount, input.SkipCount, input.Sorting); var blogPosts = await BlogPostRepository.GetListAsync(null, blog.Id, input.MaxResultCount, input.SkipCount, input.Sorting);
return new PagedResultDto<BlogPostPublicDto>( return new PagedResultDto<BlogPostPublicDto>(
await BlogPostRepository.GetCountAsync(blogId: blog.Id), await BlogPostRepository.GetCountAsync(blogId: blog.Id),

19
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs

@ -1,22 +1,21 @@
using System; using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Authorization; using Volo.Abp.Authorization;
using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Uow; using Volo.Abp.GlobalFeatures;
using Volo.Abp.Users; using Volo.Abp.Users;
using Volo.CmsKit.Comments; using Volo.CmsKit.Comments;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Users; using Volo.CmsKit.Users;
namespace Volo.CmsKit.Public.Comments namespace Volo.CmsKit.Public.Comments
{ {
public class CommentPublicAppService : ApplicationService, ICommentPublicAppService [RequiresGlobalFeature(typeof(CommentsFeature))]
public class CommentPublicAppService : CmsKitPublicAppServiceBase, ICommentPublicAppService
{ {
protected ICommentRepository CommentRepository { get; } protected ICommentRepository CommentRepository { get; }
protected ICmsUserLookupService CmsUserLookupService { get; } protected ICmsUserLookupService CmsUserLookupService { get; }
@ -50,7 +49,7 @@ namespace Volo.CmsKit.Public.Comments
{ {
var user = await CmsUserLookupService.GetByIdAsync(CurrentUser.GetId()); var user = await CmsUserLookupService.GetByIdAsync(CurrentUser.GetId());
if(input.RepliedCommentId.HasValue) if (input.RepliedCommentId.HasValue)
{ {
await CommentRepository.GetAsync(input.RepliedCommentId.Value); await CommentRepository.GetAsync(input.RepliedCommentId.Value);
} }
@ -111,8 +110,8 @@ namespace Volo.CmsKit.Public.Comments
//TODO: I think this method can be optimized if you use dictionaries instead of straight search //TODO: I think this method can be optimized if you use dictionaries instead of straight search
var parentComments = comments var parentComments = comments
.Where(c=> c.Comment.RepliedCommentId == null) .Where(c => c.Comment.RepliedCommentId == null)
.Select(c=> ObjectMapper.Map<Comment, CommentWithDetailsDto>(c.Comment)) .Select(c => ObjectMapper.Map<Comment, CommentWithDetailsDto>(c.Comment))
.ToList(); .ToList();
foreach (var parentComment in parentComments) foreach (var parentComment in parentComments)

3
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Pages/PagePublicAppService.cs

@ -1,8 +1,11 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.GlobalFeatures;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Pages; using Volo.CmsKit.Pages;
namespace Volo.CmsKit.Public.Pages namespace Volo.CmsKit.Public.Pages
{ {
[RequiresGlobalFeature(typeof(PagesFeature))]
public class PagePublicAppService : CmsKitPublicAppServiceBase, IPagePublicAppService public class PagePublicAppService : CmsKitPublicAppServiceBase, IPagePublicAppService
{ {
protected IPageRepository PageRepository { get; } protected IPageRepository PageRepository { get; }

10
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Ratings/RatingPublicAppService.cs

@ -1,15 +1,17 @@
using System.Collections.Generic; using Microsoft.AspNetCore.Authorization;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Services;
using Volo.Abp.Authorization; using Volo.Abp.Authorization;
using Volo.Abp.GlobalFeatures;
using Volo.Abp.Users; using Volo.Abp.Users;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Ratings; using Volo.CmsKit.Ratings;
using Volo.CmsKit.Users; using Volo.CmsKit.Users;
namespace Volo.CmsKit.Public.Ratings namespace Volo.CmsKit.Public.Ratings
{ {
public class RatingPublicAppService : ApplicationService, IRatingPublicAppService [RequiresGlobalFeature(typeof(RatingsFeature))]
public class RatingPublicAppService : CmsKitPublicAppServiceBase, IRatingPublicAppService
{ {
protected IRatingRepository RatingRepository { get; } protected IRatingRepository RatingRepository { get; }
public ICmsUserLookupService CmsUserLookupService { get; } public ICmsUserLookupService CmsUserLookupService { get; }

7
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Reactions/ReactionPublicAppService.cs

@ -1,13 +1,16 @@
using System.Collections.Generic; using Microsoft.AspNetCore.Authorization;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.GlobalFeatures;
using Volo.Abp.Users; using Volo.Abp.Users;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Reactions; using Volo.CmsKit.Reactions;
namespace Volo.CmsKit.Public.Reactions namespace Volo.CmsKit.Public.Reactions
{ {
[RequiresGlobalFeature(typeof(ReactionsFeature))]
public class ReactionPublicAppService : CmsKitPublicAppServiceBase, IReactionPublicAppService public class ReactionPublicAppService : CmsKitPublicAppServiceBase, IReactionPublicAppService
{ {
protected IReactionDefinitionStore ReactionDefinitionStore { get; } protected IReactionDefinitionStore ReactionDefinitionStore { get; }

2
npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts

@ -150,9 +150,9 @@ export default `
box-shadow: none; box-shadow: none;
} }
ngb-typeahead-window { ngb-typeahead-window {
width: 100%;
max-height: 25em; max-height: 25em;
overflow-y: scroll !important; overflow-y: scroll !important;
z-index: 1050;
} }
@keyframes fadeInTop { @keyframes fadeInTop {

11
npm/ng-packs/packages/theme-shared/src/lib/handlers/datepicker-config.ts

@ -1,11 +0,0 @@
import { Injector } from '@angular/core';
import { NgbInputDatepickerConfig } from '@ng-bootstrap/ng-bootstrap';
export function initDatepickerConfig(injector: Injector) {
const datepickerConfig = injector.get(NgbInputDatepickerConfig, null);
if (datepickerConfig) {
datepickerConfig.container = 'body';
}
return () => {};
}

1
npm/ng-packs/packages/theme-shared/src/lib/handlers/index.ts

@ -1,3 +1,2 @@
export * from './error.handler'; export * from './error.handler';
export * from './lazy-style.handler'; export * from './lazy-style.handler';
export * from './datepicker-config';

1
npm/ng-packs/packages/theme-shared/src/lib/providers/index.ts

@ -1 +1,2 @@
export * from './ng-bootstrap-config.provider';
export * from './route.provider'; export * from './route.provider';

21
npm/ng-packs/packages/theme-shared/src/lib/providers/ng-bootstrap-config.provider.ts

@ -0,0 +1,21 @@
import { APP_INITIALIZER } from '@angular/core';
import { NgbInputDatepickerConfig, NgbTypeaheadConfig } from '@ng-bootstrap/ng-bootstrap';
export const NG_BOOTSTRAP_CONFIG_PROVIDERS = [
{
provide: APP_INITIALIZER,
useFactory: configureNgBootstrap,
deps: [NgbInputDatepickerConfig, NgbTypeaheadConfig],
multi: true,
},
];
export function configureNgBootstrap(
datepicker: NgbInputDatepickerConfig,
typeahead: NgbTypeaheadConfig,
) {
return () => {
datepicker.container = 'body';
typeahead.container = 'body';
};
}

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

@ -17,6 +17,7 @@ import { ConfirmationComponent } from './components/confirmation/confirmation.co
import { HttpErrorWrapperComponent } from './components/http-error-wrapper/http-error-wrapper.component'; import { HttpErrorWrapperComponent } from './components/http-error-wrapper/http-error-wrapper.component';
import { LoaderBarComponent } from './components/loader-bar/loader-bar.component'; import { LoaderBarComponent } from './components/loader-bar/loader-bar.component';
import { LoadingComponent } from './components/loading/loading.component'; import { LoadingComponent } from './components/loading/loading.component';
import { ModalCloseDirective } from './components/modal/modal-close.directive';
import { ModalContainerComponent } from './components/modal/modal-container.component'; import { ModalContainerComponent } from './components/modal/modal-container.component';
import { ModalComponent } from './components/modal/modal.component'; import { ModalComponent } from './components/modal/modal.component';
import { SortOrderIconComponent } from './components/sort-order-icon/sort-order-icon.component'; import { SortOrderIconComponent } from './components/sort-order-icon/sort-order-icon.component';
@ -33,12 +34,11 @@ import { TableSortDirective } from './directives/table-sort.directive';
import { ErrorHandler } from './handlers/error.handler'; import { ErrorHandler } from './handlers/error.handler';
import { initLazyStyleHandler } from './handlers/lazy-style.handler'; import { initLazyStyleHandler } from './handlers/lazy-style.handler';
import { RootParams } from './models/common'; import { RootParams } from './models/common';
import { NG_BOOTSTRAP_CONFIG_PROVIDERS } from './providers';
import { THEME_SHARED_ROUTE_PROVIDERS } from './providers/route.provider'; import { THEME_SHARED_ROUTE_PROVIDERS } from './providers/route.provider';
import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token'; import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token';
import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/http-error.token'; import { httpErrorConfigFactory, HTTP_ERROR_CONFIG } from './tokens/http-error.token';
import { DateParserFormatter } from './utils/date-parser-formatter'; import { DateParserFormatter } from './utils/date-parser-formatter';
import { ModalCloseDirective } from './components/modal/modal-close.directive';
import { initDatepickerConfig } from './handlers/datepicker-config';
const declarationsWithExports = [ const declarationsWithExports = [
BreadcrumbComponent, BreadcrumbComponent,
@ -111,12 +111,6 @@ export class ThemeSharedModule {
deps: [Injector], deps: [Injector],
useFactory: initLazyStyleHandler, useFactory: initLazyStyleHandler,
}, },
{
provide: APP_INITIALIZER,
multi: true,
deps: [Injector],
useFactory: initDatepickerConfig,
},
{ provide: HTTP_ERROR_CONFIG, useValue: httpErrorConfig }, { provide: HTTP_ERROR_CONFIG, useValue: httpErrorConfig },
{ {
provide: 'HTTP_ERROR_CONFIG', provide: 'HTTP_ERROR_CONFIG',
@ -124,6 +118,7 @@ export class ThemeSharedModule {
deps: [HTTP_ERROR_CONFIG], deps: [HTTP_ERROR_CONFIG],
}, },
{ provide: NgbDateParserFormatter, useClass: DateParserFormatter }, { provide: NgbDateParserFormatter, useClass: DateParserFormatter },
NG_BOOTSTRAP_CONFIG_PROVIDERS,
{ {
provide: VALIDATION_BLUEPRINTS, provide: VALIDATION_BLUEPRINTS,
useValue: { useValue: {

Loading…
Cancel
Save