Browse Source

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

pull/1746/head
Yunus Emre Kalkan 7 years ago
parent
commit
8a2babb6dc
  1. 6
      docs/en/Multi-Tenancy.md
  2. 6
      docs/zh-Hans/Multi-Tenancy.md
  3. 21
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs
  4. 168
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.html
  5. 2
      npm/ng-packs/packages/identity/src/lib/identity.module.ts
  6. 66
      npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html
  7. 3
      npm/ng-packs/packages/permission-management/src/lib/permission-management.module.ts
  8. 17
      npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts
  9. 7
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html
  10. 15
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts
  11. 2
      npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.ts
  12. 105
      npm/ng-packs/packages/theme-shared/src/lib/contants/styles.ts
  13. 32
      npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts

6
docs/en/Multi-Tenancy.md

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

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

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

21
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs

@ -171,31 +171,32 @@ namespace Volo.Abp.Cli
private void LogNewVersionInfo(UpdateChannel updateChannel, SemanticVersion latestVersion, string toolPath)
{
Logger.LogWarning(
$"ABP CLI has a newer {updateChannel.ToString().ToLowerInvariant()} version {latestVersion}, please update to get the latest features and fixes.");
Logger.LogWarning("");
Logger.LogWarning($"ABP CLI has a newer {updateChannel.ToString().ToLowerInvariant()} version {latestVersion}, please update to get the latest features and fixes.");
Logger.LogWarning(string.Empty);
Logger.LogWarning("Update Command: ");
// Update command doesn't support prerelease versions https://github.com/dotnet/sdk/issues/2551 workaround is to uninstall & install
switch (updateChannel)
{
case UpdateChannel.Stable:
Logger.LogWarning($" dotnet tool update --tool-path {toolPath} Volo.Abp.Cli");
Logger.LogWarning("dotnet tool update -g Volo.Abp.Cli");
break;
case UpdateChannel.Prerelease:
Logger.LogWarning($" dotnet tool uninstall --tool-path {toolPath} Volo.Abp.Cli");
Logger.LogWarning($" dotnet tool install --tool-path {toolPath} --version {latestVersion} Volo.Abp.Cli");
Logger.LogWarning("dotnet tool uninstall -g Volo.Abp.Cli");
Logger.LogWarning($"dotnet tool install -g Volo.Abp.Cli --version {latestVersion}");
break;
case UpdateChannel.Nightly:
Logger.LogWarning($" dotnet tool uninstall --tool-path {toolPath} Volo.Abp.Cli");
Logger.LogWarning(
$" dotnet tool install --tool-path {toolPath} --add-source https://www.myget.org/F/abp-nightly/api/v3/index.json --version {latestVersion} Volo.Abp.Cli");
case UpdateChannel.Development:
Logger.LogWarning("dotnet tool uninstall -g Volo.Abp.Cli");
Logger.LogWarning($"dotnet tool install -g Volo.Abp.Cli --add-source https://www.myget.org/F/abp-nightly/api/v3/index.json --version {latestVersion}");
break;
default:
throw new ArgumentOutOfRangeException(nameof(updateChannel), updateChannel, null);
}
Logger.LogWarning("");
Logger.LogWarning(string.Empty);
}
protected enum UpdateChannel

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

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

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

@ -10,7 +10,6 @@ import { UsersComponent } from './components/users/users.component';
import { PermissionManagementModule } from '@abp/ng.permission-management';
import { TableModule } from 'primeng/table';
import { NgxValidateCoreModule } from '@ngx-validate/core';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
@NgModule({
declarations: [RolesComponent, UsersComponent],
@ -24,7 +23,6 @@ import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
NgbDropdownModule,
PermissionManagementModule,
NgxValidateCoreModule,
PerfectScrollbarModule,
],
})
export class IdentityModule {}

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

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

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

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

17
npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts

@ -11,26 +11,25 @@ import { Toaster } from '../../models/toaster';
(onClose)="close(dismiss)"
[modal]="true"
[baseZIndex]="1000"
styleClass=""
styleClass="abp-confirm"
>
<ng-template let-message pTemplate="message">
<div *ngIf="message.summary" class="modal-header">
<h4 class="modal-title">
{{ message.summary | abpLocalization: message.titleLocalizationParams }}
</h4>
<i class="fa fa-exclamation-circle abp-confirm-icon"></i>
<div *ngIf="message.summary" class="abp-confirm-summary">
{{ message.summary | abpLocalization: message.titleLocalizationParams }}
</div>
<div class="modal-body">
<div class="abp-confirm-body">
{{ message.detail | abpLocalization: message.messageLocalizationParams }}
</div>
<div class="modal-footer justify-content-center">
<button *ngIf="!message.hideCancelBtn" type="button" class="btn btn-secondary" (click)="close(reject)">
<div class="abp-confirm-footer justify-content-center">
<button *ngIf="!message.hideCancelBtn" type="button" class="btn btn-sm btn-primary" (click)="close(reject)">
{{ message.cancelCopy || 'AbpIdentity::Cancel' | abpLocalization }}
</button>
<button
*ngIf="!message.hideYesBtn"
type="button"
class="btn btn-secondary"
class="btn btn-sm btn-primary"
(click)="close(confirm)"
autofocus
>

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

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

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

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

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

@ -3,7 +3,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'abp-toast',
template: `
<p-toast position="bottom-right" key="abpToast" [baseZIndex]="1000">
<p-toast position="bottom-right" key="abpToast" styleClass="abp-toast" [baseZIndex]="1000">
<ng-template let-message pTemplate="message">
<span
class="ui-toast-icon pi"

105
npm/ng-packs/packages/theme-shared/src/lib/contants/styles.ts

@ -45,6 +45,111 @@ export default `
white-space: nowrap;
}
.abp-toast .ui-toast-message {
box-sizing: border-box !important;
border: 2px solid transparent !important;
border-radius: 4px !important;
background-color: #f4f4f7 !important;
color: #1b1d29 !important;
}
.abp-toast .ui-toast-message-content {
padding: 10px !important;
}
.abp-toast .ui-toast-message-content .ui-toast-icon {
top: 0 !important;
left: 0 !important;
padding: 10px !important;
}
.abp-toast .ui-toast-summary {
margin: 0 !important;
font-weight: 700 !important;
}
.abp-toast .ui-toast-message.ui-toast-message-error {
border-color: #ba1659 !important;
}
.abp-toast .ui-toast-message.ui-toast-message-error .ui-toast-message-content .ui-toast-icon {
color: #ba1659 !important;
}
.abp-toast .ui-toast-message.ui-toast-message-warning {
border-color: #ed5d98 !important;
}
.abp-toast .ui-toast-message.ui-toast-message-warning .ui-toast-message-content .ui-toast-icon {
color: #ed5d98 !important;
}
.abp-toast .ui-toast-message.ui-toast-message-success {
border-color: #1c9174 !important;
}
.abp-toast .ui-toast-message.ui-toast-message-success .ui-toast-message-content .ui-toast-icon {
color: #1c9174 !important;
}
.abp-toast .ui-toast-message.ui-toast-message-info {
border-color: #fccb31 !important;
}
.abp-toast .ui-toast-message.ui-toast-message-info .ui-toast-message-content .ui-toast-icon {
color: #fccb31 !important;
}
.abp-confirm .ui-toast-message {
box-sizing: border-box !important;
padding: 0px !important;
border:0 none !important;
border-radius: 4px !important;
background-color: #fff !important;
color: rgba(0, 0, 0, .65) !important;
font-family: "Poppins", sans-serif;
text-align: center !important;
}
.abp-confirm .ui-toast-message-content {
padding: 0px !important;
}
.abp-confirm .abp-confirm-icon {
margin: 32px 50px 5px !important;
color: #f8bb86 !important;
font-size: 52px !important;
}
.abp-confirm .ui-toast-close-icon {
display: none !important;
}
.abp-confirm .abp-confirm-summary {
display: block !important;
margin-bottom: 13px !important;
padding: 13px 16px 0px !important;
font-weight: 600 !important;
font-size: 18px !important;
}
.abp-confirm .abp-confirm-body {
display: inline-block !important;
padding: 0px 10px !important;
}
.abp-confirm .abp-confirm-footer {
display: block !important;
margin-top: 30px !important;
padding: 16px !important;
background-color: #f4f4f7 !important;
text-align: right !important;
}
.abp-confirm .abp-confirm-footer .btn {
margin-left: 10px !important;
}
/* <animations */
.fade-in-top {

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

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

Loading…
Cancel
Save