mirror of https://github.com/abpframework/abp.git
78 changed files with 7215 additions and 6742 deletions
@ -1,51 +1,61 @@ |
|||
import { IDENTITY_ROUTES } from '@abp/ng.identity'; |
|||
import { ACCOUNT_ROUTES } from '@abp/ng.account'; |
|||
import { NgModule } from '@angular/core'; |
|||
import { Routes, RouterModule } from '@angular/router'; |
|||
import { ABP } from '@abp/ng.core'; |
|||
import { TENANT_MANAGEMENT_ROUTES } from '@abp/ng.tenant-management'; |
|||
import { ApplicationLayoutComponent } from '@abp/ng.theme.basic'; |
|||
import { ABP } from "@abp/ng.core"; |
|||
import { NgModule } from "@angular/core"; |
|||
import { RouterModule, Routes } from "@angular/router"; |
|||
import { ApplicationLayoutComponent } from "@abp/ng.theme.basic"; |
|||
|
|||
const routes: Routes = [ |
|||
{ |
|||
path: '', |
|||
loadChildren: () => import('./home/home.module').then(m => m.HomeModule), |
|||
path: "", |
|||
loadChildren: () => import("./home/home.module").then(m => m.HomeModule), |
|||
data: { |
|||
routes: { |
|||
name: '::Menu:Home', |
|||
} as ABP.Route, |
|||
}, |
|||
name: "::Menu:Home" |
|||
} as ABP.Route |
|||
} |
|||
}, |
|||
{ |
|||
path: 'account', |
|||
loadChildren: () => import('./lazy-libs/account-wrapper.module').then(m => m.AccountWrapperModule), |
|||
data: { routes: ACCOUNT_ROUTES }, |
|||
path: "account", |
|||
loadChildren: () => |
|||
import("./lazy-libs/account-wrapper.module").then( |
|||
m => m.AccountWrapperModule |
|||
) |
|||
}, |
|||
{ |
|||
path: "identity", |
|||
loadChildren: () => |
|||
import("./lazy-libs/identity-wrapper.module").then( |
|||
m => m.IdentityWrapperModule |
|||
) |
|||
}, |
|||
{ |
|||
path: 'identity', |
|||
loadChildren: () => import('./lazy-libs/identity-wrapper.module').then(m => m.IdentityWrapperModule), |
|||
data: { routes: IDENTITY_ROUTES }, |
|||
path: "tenant-management", |
|||
loadChildren: () => |
|||
import("./lazy-libs/tenant-management-wrapper.module").then( |
|||
m => m.TenantManagementWrapperModule |
|||
) |
|||
}, |
|||
{ |
|||
path: 'tenant-management', |
|||
path: "setting-management", |
|||
loadChildren: () => |
|||
import('./lazy-libs/tenant-management-wrapper.module').then(m => m.TenantManagementWrapperModule), |
|||
data: { routes: TENANT_MANAGEMENT_ROUTES }, |
|||
import("./lazy-libs/setting-management-wrapper.module").then( |
|||
m => m.SettingManagementWrapperModule |
|||
) |
|||
}, |
|||
{ |
|||
path: 'books', |
|||
path: "books", |
|||
component: ApplicationLayoutComponent, |
|||
loadChildren: () => import('./books/books.module').then(m => m.BooksModule), |
|||
loadChildren: () => import("./books/books.module").then(m => m.BooksModule), |
|||
data: { |
|||
routes: { |
|||
name: 'Books', |
|||
} as ABP.Route, |
|||
}, |
|||
}, |
|||
name: "::Menu:Books", |
|||
iconClass: "fas fa-book" |
|||
} as ABP.Route |
|||
} |
|||
} |
|||
]; |
|||
|
|||
@NgModule({ |
|||
imports: [RouterModule.forRoot(routes)], |
|||
exports: [RouterModule], |
|||
exports: [RouterModule] |
|||
}) |
|||
export class AppRoutingModule {} |
|||
|
|||
@ -0,0 +1,68 @@ |
|||
import { LazyLoadService } from '@abp/ng.core'; |
|||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|||
import { RouterTestingModule } from '@angular/router/testing'; |
|||
import { NgxsModule } from '@ngxs/store'; |
|||
import { OAuthService } from 'angular-oauth2-oidc'; |
|||
import { AppComponent } from './app.component'; |
|||
import { LoaderBarComponent } from '@abp/ng.theme.shared'; |
|||
import { Subject, Observable } from 'rxjs'; |
|||
import { Component } from '@angular/core'; |
|||
import { By } from '@angular/platform-browser'; |
|||
|
|||
@Component({ |
|||
template: '', |
|||
selector: 'abp-loader-bar', |
|||
}) |
|||
class DummyLoaderBarComponent {} |
|||
|
|||
describe('AppComponent', () => { |
|||
let component: AppComponent; |
|||
let fixture: ComponentFixture<AppComponent>; |
|||
let mockLazyLoadService: { load: () => Observable<void> }; |
|||
let loadResponse$: Subject<void>; |
|||
let spy: jasmine.Spy<() => Observable<void>>; |
|||
|
|||
beforeEach(() => { |
|||
TestBed.configureTestingModule({ |
|||
imports: [RouterTestingModule], |
|||
declarations: [AppComponent, DummyLoaderBarComponent], |
|||
providers: [{ provide: LazyLoadService, useValue: { load: () => loadResponse$ } }], |
|||
}); |
|||
loadResponse$ = new Subject(); |
|||
fixture = TestBed.createComponent(AppComponent); |
|||
component = fixture.componentInstance; |
|||
mockLazyLoadService = TestBed.get(LazyLoadService); |
|||
spy = spyOn(mockLazyLoadService, 'load'); |
|||
spy.and.returnValue(loadResponse$); |
|||
fixture.detectChanges(); |
|||
}); |
|||
|
|||
describe('LazyLoadService load method', () => { |
|||
it('should call', () => { |
|||
expect(spy).toHaveBeenCalledWith( |
|||
[ |
|||
'primeng.min.css', |
|||
'primeicons.css', |
|||
'primeng-nova-light-theme.css', |
|||
'fontawesome-all.min.css', |
|||
'fontawesome-v4-shims.min.css', |
|||
], |
|||
'style', |
|||
null, |
|||
'head', |
|||
); |
|||
}); |
|||
}); |
|||
|
|||
describe('template', () => { |
|||
it('should have the abp-loader-bar', () => { |
|||
const abpLoader = fixture.debugElement.query(By.css('abp-loader-bar')); |
|||
expect(abpLoader).toBeTruthy(); |
|||
}); |
|||
|
|||
it('should have router-outlet', () => { |
|||
const abpLoader = fixture.debugElement.query(By.css('router-outlet')); |
|||
expect(abpLoader).toBeTruthy(); |
|||
}); |
|||
}); |
|||
}); |
|||
@ -1,41 +1,44 @@ |
|||
import { AccountConfigModule } from '@abp/ng.account.config'; |
|||
import { CoreModule } from '@abp/ng.core'; |
|||
import { IdentityConfigModule } from '@abp/ng.identity.config'; |
|||
import { SettingManagementConfigModule } from '@abp/ng.setting-management.config'; |
|||
import { TenantManagementConfigModule } from '@abp/ng.tenant-management.config'; |
|||
import { LAYOUTS } from '@abp/ng.theme.basic'; |
|||
import { ThemeSharedModule } from '@abp/ng.theme.shared'; |
|||
import { NgModule } from '@angular/core'; |
|||
import { BrowserModule } from '@angular/platform-browser'; |
|||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; |
|||
import { NgxsReduxDevtoolsPluginModule } from '@ngxs/devtools-plugin'; |
|||
import { NgxsLoggerPluginModule } from '@ngxs/logger-plugin'; |
|||
import { NgxsModule } from '@ngxs/store'; |
|||
import { OAuthModule } from 'angular-oauth2-oidc'; |
|||
import { environment } from '../environments/environment'; |
|||
import { AppRoutingModule } from './app-routing.module'; |
|||
import { AppComponent } from './app.component'; |
|||
import { SharedModule } from './shared/shared.module'; |
|||
import { ThemeSharedModule } from '@abp/ng.theme.shared'; |
|||
import { AccountProviders } from '@abp/ng.account'; |
|||
import { IdentityProviders } from '@abp/ng.identity'; |
|||
import { TenantManagementProviders } from '@abp/ng.tenant-management'; |
|||
import { BooksState } from './store/states/books.state'; |
|||
|
|||
const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })]; |
|||
|
|||
@NgModule({ |
|||
declarations: [AppComponent], |
|||
imports: [ |
|||
ThemeSharedModule.forRoot(), |
|||
CoreModule.forRoot({ |
|||
environment, |
|||
requirements: { |
|||
layouts: LAYOUTS, |
|||
}, |
|||
}), |
|||
OAuthModule.forRoot(), |
|||
NgxsModule.forRoot([]), |
|||
ThemeSharedModule.forRoot(), |
|||
AccountConfigModule.forRoot({ redirectUrl: '/' }), |
|||
IdentityConfigModule, |
|||
TenantManagementConfigModule, |
|||
SettingManagementConfigModule, |
|||
NgxsModule.forRoot([BooksState]), |
|||
BrowserModule, |
|||
BrowserAnimationsModule, |
|||
AppRoutingModule, |
|||
SharedModule, |
|||
NgxsModule.forRoot([BooksState, ]), |
|||
NgxsReduxDevtoolsPluginModule.forRoot({ disabled: environment.production }), |
|||
...(environment.production ? [] : LOGGERS), |
|||
], |
|||
providers: [...AccountProviders({ redirectUrl: '/' }), ...IdentityProviders(), ...TenantManagementProviders()], |
|||
declarations: [AppComponent], |
|||
bootstrap: [AppComponent], |
|||
}) |
|||
export class AppModule {} |
|||
|
|||
@ -1,18 +1,19 @@ |
|||
import { NgModule } from '@angular/core'; |
|||
import { RouterModule, Routes } from '@angular/router'; |
|||
import { BooksComponent } from './books.component'; |
|||
import { BookListComponent } from './book-list/book-list.component'; |
|||
import { NgModule } from "@angular/core"; |
|||
import { Routes, RouterModule } from "@angular/router"; |
|||
|
|||
import { BooksComponent } from "./books.component"; |
|||
import { BookListComponent } from "./book-list/book-list.component"; |
|||
|
|||
const routes: Routes = [ |
|||
{ |
|||
path: '', |
|||
path: "", |
|||
component: BooksComponent, |
|||
children: [{ path: '', component: BookListComponent }], |
|||
}, |
|||
children: [{ path: "", component: BookListComponent }] |
|||
} |
|||
]; |
|||
|
|||
@NgModule({ |
|||
imports: [RouterModule.forChild(routes)], |
|||
exports: [RouterModule], |
|||
exports: [RouterModule] |
|||
}) |
|||
export class BooksRoutingModule {} |
|||
|
|||
@ -1,8 +1,15 @@ |
|||
import { Component } from '@angular/core'; |
|||
import { Component, OnInit } from '@angular/core'; |
|||
|
|||
@Component({ |
|||
selector: 'app-books', |
|||
templateUrl: './books.component.html', |
|||
styleUrls: ['./books.component.scss'], |
|||
styleUrls: ['./books.component.scss'] |
|||
}) |
|||
export class BooksComponent {} |
|||
export class BooksComponent implements OnInit { |
|||
|
|||
constructor() { } |
|||
|
|||
ngOnInit() { |
|||
} |
|||
|
|||
} |
|||
|
|||
@ -1,14 +1,14 @@ |
|||
import { NgModule } from '@angular/core'; |
|||
import { CommonModule } from '@angular/common'; |
|||
import { NgModule } from "@angular/core"; |
|||
import { CommonModule } from "@angular/common"; |
|||
|
|||
import { BooksRoutingModule } from './books-routing.module'; |
|||
import { BooksComponent } from './books.component'; |
|||
import { SharedModule } from '../shared/shared.module'; |
|||
import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap'; |
|||
import { BookListComponent } from './book-list/book-list.component'; |
|||
import { BooksRoutingModule } from "./books-routing.module"; |
|||
import { BooksComponent } from "./books.component"; |
|||
import { BookListComponent } from "./book-list/book-list.component"; |
|||
import { SharedModule } from "../shared/shared.module"; |
|||
import { NgbDatepickerModule } from "@ng-bootstrap/ng-bootstrap"; |
|||
|
|||
@NgModule({ |
|||
declarations: [BooksComponent, BookListComponent], |
|||
imports: [CommonModule, BooksRoutingModule, SharedModule, NgbDatepickerModule], |
|||
imports: [CommonModule, BooksRoutingModule, SharedModule, NgbDatepickerModule] |
|||
}) |
|||
export class BooksModule {} |
|||
|
|||
@ -1,15 +1,20 @@ |
|||
<div class="card"> |
|||
<div class="card-header">{{ '::Welcome' | abpLocalization }}</div> |
|||
<div class="card-body"> |
|||
<p> |
|||
{{ '::LongWelcomeMessage' | abpLocalization }} |
|||
</p> |
|||
<p *ngIf="!hasLoggedIn"> |
|||
<a routerLink="/account/login" [state]="{ redirectUrl: '/' }" class="btn btn-primary" role="button" |
|||
><i class="fa fa-sign-in"></i>{{ 'AbpIdentity::Login' | abpLocalization }}</a |
|||
> |
|||
</p> |
|||
<hr /> |
|||
<p class="text-right"><a href="https://abp.io?ref=tmpl" target="_blank">abp.io</a></p> |
|||
<div id="AbpContentToolbar"></div> |
|||
<div class="jumbotron text-center"> |
|||
<h1>{{ '::Welcome' | abpLocalization }}</h1> |
|||
<div class="row"> |
|||
<div class="col-md-6 mx-auto"> |
|||
<p>{{ '::LongWelcomeMessage' | abpLocalization }}</p> |
|||
<hr class="my-4" /> |
|||
</div> |
|||
</div> |
|||
<a href="https://abp.io?ref=tmpl" target="_blank" class="btn btn-primary px-4">abp.io</a> |
|||
<a |
|||
*ngIf="!hasLoggedIn" |
|||
routerLink="/account/login" |
|||
[state]="{ redirectUrl: '/' }" |
|||
class="px-4 btn btn-primary ml-1" |
|||
role="button" |
|||
id="login-button" |
|||
><i class="fa fa-sign-in"></i> {{ 'AbpAccount::Login' | abpLocalization }}</a |
|||
> |
|||
</div> |
|||
|
|||
@ -0,0 +1,51 @@ |
|||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|||
import { OAuthService } from 'angular-oauth2-oidc'; |
|||
import { HomeComponent } from './home.component'; |
|||
import { HomeModule } from './home.module'; |
|||
import { RouterTestingModule } from '@angular/router/testing'; |
|||
import { NgxsModule } from '@ngxs/store'; |
|||
import { By } from '@angular/platform-browser'; |
|||
|
|||
describe('HomeComponent', () => { |
|||
let component: HomeComponent; |
|||
let fixture: ComponentFixture<HomeComponent>; |
|||
let mockOAuthService: { hasValidAccessToken: () => boolean }; |
|||
|
|||
beforeEach(() => { |
|||
TestBed.configureTestingModule({ |
|||
imports: [ NgxsModule.forRoot(), HomeModule, RouterTestingModule], |
|||
providers: [{ provide: OAuthService, useValue: { hasValidAccessToken: () => false } }], |
|||
}); |
|||
fixture = TestBed.createComponent(HomeComponent); |
|||
component = fixture.componentInstance; |
|||
mockOAuthService = TestBed.get(OAuthService); |
|||
fixture.detectChanges(); |
|||
}); |
|||
|
|||
describe('#hasLoggedIn', () => { |
|||
it('should return the hasValidAccessToken method of oAuthService', () => { |
|||
const spy = spyOn(mockOAuthService, 'hasValidAccessToken'); |
|||
spy.and.returnValue(false); |
|||
|
|||
expect(component.hasLoggedIn).toBe(false); |
|||
expect(spy).toHaveBeenCalled(); |
|||
}); |
|||
}); |
|||
|
|||
describe('login button', () => { |
|||
it('should display', () => { |
|||
const button = fixture.debugElement.query(By.css('[routerLink="/account/login"]')); |
|||
expect(button).toBeTruthy(); |
|||
expect(button.nativeElement.textContent).toContain('AbpAccount::Login'); |
|||
}); |
|||
|
|||
it('should not display when user logged in', () => { |
|||
const spy = spyOn(mockOAuthService, 'hasValidAccessToken'); |
|||
spy.and.returnValue(true); |
|||
fixture.detectChanges(); |
|||
|
|||
const button = fixture.debugElement.query(By.css('#login-button')); |
|||
expect(button).toBeFalsy(); |
|||
}); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,7 @@ |
|||
import { NgModule } from '@angular/core'; |
|||
import { SettingManagementModule } from '@abp/ng.setting-management'; |
|||
|
|||
@NgModule({ |
|||
imports: [SettingManagementModule], |
|||
}) |
|||
export class SettingManagementWrapperModule {} |
|||
@ -1,15 +1,18 @@ |
|||
import { Books } from '../models'; |
|||
import { Books } from "../models"; |
|||
|
|||
export class GetBooks { |
|||
static readonly type = '[Books] Get'; |
|||
static readonly type = "[Books] Get"; |
|||
} |
|||
|
|||
export class CreateUpdateBook { |
|||
static readonly type = '[Books] Create Update Book'; |
|||
constructor(public payload: Books.CreateUpdateBookInput, public id?: string) {} |
|||
static readonly type = "[Books] Create Update Book"; |
|||
constructor( |
|||
public payload: Books.CreateUpdateBookInput, |
|||
public id?: string |
|||
) {} |
|||
} |
|||
|
|||
export class DeleteBook { |
|||
static readonly type = '[Books] Delete'; |
|||
static readonly type = "[Books] Delete"; |
|||
constructor(public id: string) {} |
|||
} |
|||
|
|||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 101 KiB |
@ -1,16 +1,16 @@ |
|||
using System; |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Acme.BookStore |
|||
{ |
|||
public class BookAppService : |
|||
public class BookAppService : |
|||
CrudAppService<Book, BookDto, Guid, PagedAndSortedResultRequestDto, |
|||
CreateUpdateBookDto, CreateUpdateBookDto>, |
|||
CreateUpdateBookDto, CreateUpdateBookDto>, |
|||
IBookAppService |
|||
{ |
|||
public BookAppService(IRepository<Book, Guid> repository) |
|||
public BookAppService(IRepository<Book, Guid> repository) |
|||
: base(repository) |
|||
{ |
|||
|
|||
@ -0,0 +1,10 @@ |
|||
2020-02-28 10:50:32.009 +03:00 [INF] Started database migrations... |
|||
2020-02-28 10:50:32.039 +03:00 [INF] Migrating host database schema... |
|||
2020-02-28 10:50:32.040 +03:00 [INF] Executing host database seed... |
|||
2020-02-28 10:50:34.397 +03:00 [INF] Successfully completed host database migrations. |
|||
2020-02-28 10:50:34.567 +03:00 [INF] Successfully completed database migrations. |
|||
2020-02-28 14:38:28.119 +03:00 [INF] Started database migrations... |
|||
2020-02-28 14:38:28.145 +03:00 [INF] Migrating host database schema... |
|||
2020-02-28 14:38:28.146 +03:00 [INF] Executing host database seed... |
|||
2020-02-28 14:38:29.427 +03:00 [INF] Successfully completed host database migrations. |
|||
2020-02-28 14:38:29.584 +03:00 [INF] Successfully completed database migrations. |
|||
@ -0,0 +1 @@ |
|||
{"KeyId":"uJGOjuG6IaY44NtDmqRybg","Parameters":{"D":"MneJN4+n7rLDTJ015kE8QUHUJvHOEt+HtpMZU/m/cQ5p1wLLKqZyml6q/RFXwtfczSXDh+ThyZ6czEHyPFdOvByVEJxdky8r27TPdKv+dGsKXmwoHOqdf9eAR3aTMmS4D8ljPIwc/3/PdE/SrMc2uRTzYBcNHmMpUC0cOQ+OXrfrGwfgyNKTFCrNKEnkn5uFF2Q2tCMAfi2kGdLJZldFW8Bb522rl+lUoEgrnWE6OX2FqYhVD2JxfbMjrSfHf4snwdde0Vc9ee/avtXk4wHTYl1E/xJ6HDRA4UDI+dcIEQ0b1xHGSruy+0LBark+tjumQExDSiK4YbTtGUCwfvksgQ==","DP":"SJps1XBF8F3/BeJihJA0pw43Xus2keWqZSwcCjr3c0GA/dxpdIXwZlSvoa8F0uVCtSXa7n8efBTbsICKNctV+pueeSbv3rgaYiFO39Fnq3mO3uvo9VOuOJhOMc/kNNpKJT5qHaqdl1pL6NIP4Hx4GdG12d6+qka8u6D9iBydxIE=","DQ":"Lf2dO5CGcX0xs2rRVUruBozLCnhwWRIWEeTAV1FxpAH8clFcmARblMtzYh0Q9UbH/2jUPJo3W1LBOW7SSgrLVHvytc8oSqbYc1l8QXsY8eQqQKz4Ey+huJU4iZgfme7a8lwf6hsJsuigLWgQ67DyKSTHiIINzXfO+phfUEnszF0=","Exponent":"AQAB","InverseQ":"z5fhltiEYkrWSCaBAFcmXBMtreVEaNl7kpFQvHS8FR+QFwqwMOhLGdTTArp+XmdOSYq5xsTpN87iDORIdURjwkGFBNSeoABaS/WbS75mBAHc4fy0RmzoSpnVVJt9LILtIJmNqxAH+HqsiIxE1MhL89mQhZEcqRMN1mOyr0RCSqY=","Modulus":"vEFGJZO6rP+bRnzpPyc34y32mSvFm9yK3UJ8kdB15F781GXaznAg4mU7FQB2umrcAm1SilgfGiHAtzpkxy44f5MkSO9KJVeSs0N+6+X+DbCC7aIrd3quKSJgAjK3lMFdihUdJ+acSMA0+3yrmSfJVV4QMGlWcTjACab57SRJ0kHxzfXrYYexpbxejGMoT3sU6rpLq7DBqWOO+6mv5v00V6IfnYio56smpBVLviNxDs5gOa4x6idiUm4crMwg9BlfGUhWJagd+XAcnNpZL1DNP2pfD17YoT5AAkI8YICiH2iNoiZZFSx81jNLQ91VzyXzFixGb7z4y83wv6UlcVdCDw==","P":"59As5b9v7n0PvPfZLI8YAwdwSXef+sPDkjpViYD00++XByBkyQp2iYE1lZJ9ZHAeQxs3AX9NJEkIeRS2XptZJijFnaN4eaBg6QXTEKQf/Ti6Foi9ygd6QPxRcYvJSD5yfK1NgH7bFSBLEgJaeodz/joD/F2Ysd42qCTU730q18E=","Q":"z+WkIXBxm/scuNlX1LVL2Q/QYdBfzTBm6H6b9AY7fxfGcQpmFddzdz4NTl9VrkanJnkN53bDrGktqneknpWeloAuFQKdd5jvMYLD6Rq0sKqTNWsNvYgV5jOCZe5vI1LCU2Xsr8fYaSOd7iKCPPytgVdGnitoayzAlLx5x04+Dc8="}} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "zh-Hant", |
|||
"texts": { |
|||
"Menu:Home": "首頁", |
|||
"Welcome": "歡迎", |
|||
"LongWelcomeMessage": "歡迎來到此應用程式. 這是一個基於ABP框架的起始專案. 有關更多訊息, 請瀏覽 abp.io." |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Guids; |
|||
|
|||
namespace Acme.BookStore |
|||
{ |
|||
public class BookStoreDataSeederContributor |
|||
: IDataSeedContributor, ITransientDependency |
|||
{ |
|||
private readonly IRepository<Book, Guid> _bookRepository; |
|||
private readonly IGuidGenerator _guidGenerator; |
|||
|
|||
public BookStoreDataSeederContributor( |
|||
IRepository<Book, Guid> bookRepository, |
|||
IGuidGenerator guidGenerator) |
|||
{ |
|||
_bookRepository = bookRepository; |
|||
_guidGenerator = guidGenerator; |
|||
} |
|||
|
|||
public async Task SeedAsync(DataSeedContext context) |
|||
{ |
|||
if (await _bookRepository.GetCountAsync() > 0) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
await _bookRepository.InsertAsync( |
|||
new Book( |
|||
id: _guidGenerator.Create(), |
|||
name: "1984", |
|||
type: BookType.Dystopia, |
|||
publishDate: new DateTime(1949, 6, 8), |
|||
price: 19.84f |
|||
) |
|||
); |
|||
|
|||
await _bookRepository.InsertAsync( |
|||
new Book( |
|||
id: _guidGenerator.Create(), |
|||
name: "The Hitchhiker's Guide to the Galaxy", |
|||
type: BookType.ScienceFiction, |
|||
publishDate: new DateTime(1995, 9, 27), |
|||
price: 42.0f |
|||
) |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +1,12 @@ |
|||
{ |
|||
"App": { |
|||
"SelfUrl": "https://localhost:44341", |
|||
"SelfUrl": "https://localhost:44317", |
|||
"CorsOrigins": "https://*.BookStore.com,http://localhost:4200" |
|||
}, |
|||
"ConnectionStrings": { |
|||
"Default": "mongodb://localhost:27017/BookStore" |
|||
}, |
|||
"AuthServer": { |
|||
"Authority": "https://localhost:44341" |
|||
"Authority": "https://localhost:44317" |
|||
} |
|||
} |
|||
|
|||
@ -1,56 +1,56 @@ |
|||
@keyframes spin { |
|||
0% { |
|||
transform: translateZ(0) rotate(0deg); |
|||
} |
|||
|
|||
100% { |
|||
transform: translateZ(0) rotate(360deg); |
|||
} |
|||
} |
|||
|
|||
.abp-block-area { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
z-index: 102; |
|||
background-color: #fff; |
|||
opacity: .8; |
|||
transition: opacity .25s; |
|||
} |
|||
|
|||
.abp-block-area.abp-block-area-disappearing { |
|||
opacity: 0; |
|||
} |
|||
|
|||
.abp-block-area.abp-block-area-busy:after { |
|||
content: attr(data-text); |
|||
display: block; |
|||
max-width: 125px; |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate(-50%, -50%); |
|||
font-size: 20px; |
|||
font-family: sans-serif; |
|||
color: #343a40; |
|||
text-align: center; |
|||
text-transform: uppercase; |
|||
} |
|||
|
|||
.abp-block-area.abp-block-area-busy:before { |
|||
content: ""; |
|||
display: block; |
|||
width: 150px; |
|||
height: 150px; |
|||
border-radius: 50%; |
|||
border-width: 2px; |
|||
border-style: solid; |
|||
border-color: transparent #228ae6 #228ae6 #228ae6; |
|||
position: absolute; |
|||
top: calc(50% - 75px); |
|||
left: calc(50% - 75px); |
|||
will-change: transform; |
|||
animation: spin .75s infinite ease-in-out; |
|||
} |
|||
@keyframes spin { |
|||
0% { |
|||
transform: translateZ(0) rotate(0deg); |
|||
} |
|||
|
|||
100% { |
|||
transform: translateZ(0) rotate(360deg); |
|||
} |
|||
} |
|||
|
|||
.abp-block-area { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
z-index: 102; |
|||
background-color: #fff; |
|||
opacity: .8; |
|||
transition: opacity .25s; |
|||
} |
|||
|
|||
.abp-block-area.abp-block-area-disappearing { |
|||
opacity: 0; |
|||
} |
|||
|
|||
.abp-block-area.abp-block-area-busy:after { |
|||
content: attr(data-text); |
|||
display: block; |
|||
max-width: 125px; |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate(-50%, -50%); |
|||
font-size: 20px; |
|||
font-family: sans-serif; |
|||
color: #343a40; |
|||
text-align: center; |
|||
text-transform: uppercase; |
|||
} |
|||
|
|||
.abp-block-area.abp-block-area-busy:before { |
|||
content: ""; |
|||
display: block; |
|||
width: 150px; |
|||
height: 150px; |
|||
border-radius: 50%; |
|||
border-width: 2px; |
|||
border-style: solid; |
|||
border-color: transparent #228ae6 #228ae6 #228ae6; |
|||
position: absolute; |
|||
top: calc(50% - 75px); |
|||
left: calc(50% - 75px); |
|||
will-change: transform; |
|||
animation: spin .75s infinite ease-in-out; |
|||
} |
|||
|
|||
File diff suppressed because it is too large
@ -1,389 +1,393 @@ |
|||
var abp = abp || {}; |
|||
(function($) { |
|||
|
|||
if (!$) { |
|||
throw "abp/jquery library requires the jquery library included to the page!"; |
|||
} |
|||
|
|||
// ABP CORE OVERRIDES /////////////////////////////////////////////////////
|
|||
|
|||
abp.message._showMessage = function (message, title) { |
|||
alert((title || '') + ' ' + message); |
|||
|
|||
return $.Deferred(function ($dfd) { |
|||
$dfd.resolve(); |
|||
}); |
|||
}; |
|||
|
|||
abp.message.confirm = function (message, titleOrCallback, callback) { |
|||
if (titleOrCallback && !(typeof titleOrCallback == 'string')) { |
|||
callback = titleOrCallback; |
|||
} |
|||
|
|||
var result = confirm(message); |
|||
callback && callback(result); |
|||
|
|||
return $.Deferred(function ($dfd) { |
|||
$dfd.resolve(result); |
|||
}); |
|||
}; |
|||
|
|||
abp.utils.isFunction = function (obj) { |
|||
return $.isFunction(obj); |
|||
}; |
|||
|
|||
// JQUERY EXTENSIONS //////////////////////////////////////////////////////
|
|||
|
|||
$.fn.findWithSelf = function (selector) { |
|||
return this.filter(selector).add(this.find(selector)); |
|||
}; |
|||
|
|||
// DOM ////////////////////////////////////////////////////////////////////
|
|||
|
|||
abp.dom = abp.dom || {}; |
|||
|
|||
abp.dom.onNodeAdded = function (callback) { |
|||
abp.event.on('abp.dom.nodeAdded', callback); |
|||
}; |
|||
|
|||
abp.dom.onNodeRemoved = function (callback) { |
|||
abp.event.on('abp.dom.nodeRemoved', callback); |
|||
}; |
|||
|
|||
var mutationObserverCallback = function (mutationsList) { |
|||
for (var i = 0; i < mutationsList.length; i++) { |
|||
var mutation = mutationsList[i]; |
|||
if (mutation.type === 'childList') { |
|||
if (mutation.addedNodes && mutation.removedNodes.length) { |
|||
for (var k = 0; k < mutation.removedNodes.length; k++) { |
|||
abp.event.trigger( |
|||
'abp.dom.nodeRemoved', |
|||
{ |
|||
$el: $(mutation.removedNodes[k]) |
|||
} |
|||
); |
|||
} |
|||
} |
|||
|
|||
if (mutation.addedNodes && mutation.addedNodes.length) { |
|||
for (var j = 0; j < mutation.addedNodes.length; j++) { |
|||
abp.event.trigger( |
|||
'abp.dom.nodeAdded', |
|||
{ |
|||
$el: $(mutation.addedNodes[j]) |
|||
} |
|||
); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
new MutationObserver(mutationObserverCallback).observe( |
|||
$('body')[0], |
|||
{ |
|||
subtree: true, |
|||
childList: true |
|||
} |
|||
); |
|||
|
|||
// AJAX ///////////////////////////////////////////////////////////////////
|
|||
|
|||
abp.ajax = function (userOptions) { |
|||
userOptions = userOptions || {}; |
|||
|
|||
var options = $.extend(true, {}, abp.ajax.defaultOpts, userOptions); |
|||
|
|||
options.success = undefined; |
|||
options.error = undefined; |
|||
|
|||
return $.Deferred(function ($dfd) { |
|||
$.ajax(options) |
|||
.done(function (data, textStatus, jqXHR) { |
|||
$dfd.resolve(data); |
|||
userOptions.success && userOptions.success(data); |
|||
}).fail(function (jqXHR) { |
|||
if (jqXHR.getResponseHeader('_AbpErrorFormat') === 'true') { |
|||
abp.ajax.handleAbpErrorResponse(jqXHR, userOptions, $dfd); |
|||
} else { |
|||
abp.ajax.handleNonAbpErrorResponse(jqXHR, userOptions, $dfd); |
|||
} |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
$.extend(abp.ajax, { |
|||
defaultOpts: { |
|||
dataType: 'json', |
|||
type: 'POST', |
|||
contentType: 'application/json', |
|||
headers: { |
|||
'X-Requested-With': 'XMLHttpRequest' |
|||
} |
|||
}, |
|||
|
|||
defaultError: { |
|||
message: 'An error has occurred!', |
|||
details: 'Error detail not sent by server.' |
|||
}, |
|||
|
|||
defaultError401: { |
|||
message: 'You are not authenticated!', |
|||
details: 'You should be authenticated (sign in) in order to perform this operation.' |
|||
}, |
|||
|
|||
defaultError403: { |
|||
message: 'You are not authorized!', |
|||
details: 'You are not allowed to perform this operation.' |
|||
}, |
|||
|
|||
defaultError404: { |
|||
message: 'Resource not found!', |
|||
details: 'The resource requested could not found on the server.' |
|||
}, |
|||
|
|||
logError: function (error) { |
|||
abp.log.error(error); |
|||
}, |
|||
|
|||
showError: function (error) { |
|||
if (error.details) { |
|||
return abp.message.error(error.details, error.message); |
|||
} else { |
|||
return abp.message.error(error.message || abp.ajax.defaultError.message); |
|||
} |
|||
}, |
|||
|
|||
handleTargetUrl: function (targetUrl) { |
|||
if (!targetUrl) { |
|||
location.href = abp.appPath; |
|||
} else { |
|||
location.href = targetUrl; |
|||
} |
|||
}, |
|||
|
|||
handleErrorStatusCode: function (status) { |
|||
switch (status) { |
|||
case 401: |
|||
abp.ajax.handleUnAuthorizedRequest( |
|||
abp.ajax.showError(abp.ajax.defaultError401), |
|||
abp.appPath |
|||
); |
|||
break; |
|||
case 403: |
|||
abp.ajax.showError(abp.ajax.defaultError403); |
|||
break; |
|||
case 404: |
|||
abp.ajax.showError(abp.ajax.defaultError404); |
|||
break; |
|||
default: |
|||
abp.ajax.showError(abp.ajax.defaultError); |
|||
break; |
|||
} |
|||
}, |
|||
|
|||
handleNonAbpErrorResponse: function (jqXHR, userOptions, $dfd) { |
|||
if (userOptions.abpHandleError !== false) { |
|||
abp.ajax.handleErrorStatusCode(jqXHR.status); |
|||
} |
|||
|
|||
$dfd.reject.apply(this, arguments); |
|||
userOptions.error && userOptions.error.apply(this, arguments); |
|||
}, |
|||
|
|||
handleAbpErrorResponse: function (jqXHR, userOptions, $dfd) { |
|||
var messagePromise = null; |
|||
|
|||
if (userOptions.abpHandleError !== false) { |
|||
messagePromise = abp.ajax.showError(jqXHR.responseJSON.error); |
|||
} |
|||
|
|||
abp.ajax.logError(jqXHR.responseJSON.error); |
|||
|
|||
$dfd && $dfd.reject(jqXHR.responseJSON.error, jqXHR); |
|||
userOptions.error && userOptions.error(jqXHR.responseJSON.error, jqXHR); |
|||
|
|||
if (jqXHR.status === 401 && userOptions.abpHandleError !== false) { |
|||
abp.ajax.handleUnAuthorizedRequest(messagePromise); |
|||
} |
|||
}, |
|||
|
|||
handleUnAuthorizedRequest: function (messagePromise, targetUrl) { |
|||
if (messagePromise) { |
|||
messagePromise.done(function () { |
|||
abp.ajax.handleTargetUrl(targetUrl); |
|||
}); |
|||
} else { |
|||
abp.ajax.handleTargetUrl(targetUrl); |
|||
} |
|||
}, |
|||
|
|||
blockUI: function (options) { |
|||
if (options.blockUI) { |
|||
if (options.blockUI === true) { //block whole page
|
|||
abp.ui.setBusy(); |
|||
} else { //block an element
|
|||
abp.ui.setBusy(options.blockUI); |
|||
} |
|||
} |
|||
}, |
|||
|
|||
unblockUI: function (options) { |
|||
if (options.blockUI) { |
|||
if (options.blockUI === true) { //unblock whole page
|
|||
abp.ui.clearBusy(); |
|||
} else { //unblock an element
|
|||
abp.ui.clearBusy(options.blockUI); |
|||
} |
|||
} |
|||
}, |
|||
|
|||
ajaxSendHandler: function (event, request, settings) { |
|||
var token = abp.security.antiForgery.getToken(); |
|||
if (!token) { |
|||
return; |
|||
} |
|||
|
|||
if (!settings.headers || settings.headers[abp.security.antiForgery.tokenHeaderName] === undefined) { |
|||
request.setRequestHeader(abp.security.antiForgery.tokenHeaderName, token); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
$(document).ajaxSend(function (event, request, settings) { |
|||
return abp.ajax.ajaxSendHandler(event, request, settings); |
|||
}); |
|||
|
|||
abp.event.on('abp.configurationInitialized', function () { |
|||
var l = abp.localization.getResource('AbpUi'); |
|||
|
|||
abp.ajax.defaultError.message = l('DefaultErrorMessage'); |
|||
abp.ajax.defaultError.details = l('DefaultErrorMessageDetail'); |
|||
abp.ajax.defaultError401.message = l('DefaultErrorMessage401'); |
|||
abp.ajax.defaultError401.details = l('DefaultErrorMessage401Detail'); |
|||
abp.ajax.defaultError403.message = l('DefaultErrorMessage403'); |
|||
abp.ajax.defaultError403.details = l('DefaultErrorMessage403Detail'); |
|||
abp.ajax.defaultError404.message = l('DefaultErrorMessage404'); |
|||
abp.ajax.defaultError404.details = l('DefaultErrorMessage404Detail'); |
|||
}); |
|||
|
|||
// RESOURCE LOADER ////////////////////////////////////////////////////////
|
|||
|
|||
/* UrlStates enum */ |
|||
var UrlStates = { |
|||
LOADING: 'LOADING', |
|||
LOADED: 'LOADED', |
|||
FAILED: 'FAILED' |
|||
}; |
|||
|
|||
/* UrlInfo class */ |
|||
function UrlInfo(url) { |
|||
this.url = url; |
|||
this.state = UrlStates.LOADING; |
|||
this.loadCallbacks = []; |
|||
this.failCallbacks = []; |
|||
} |
|||
|
|||
UrlInfo.prototype.succeed = function () { |
|||
this.state = UrlStates.LOADED; |
|||
for (var i = 0; i < this.loadCallbacks.length; i++) { |
|||
this.loadCallbacks[i](); |
|||
} |
|||
}; |
|||
|
|||
UrlInfo.prototype.failed = function () { |
|||
this.state = UrlStates.FAILED; |
|||
for (var i = 0; i < this.failCallbacks.length; i++) { |
|||
this.failCallbacks[i](); |
|||
} |
|||
}; |
|||
|
|||
UrlInfo.prototype.handleCallbacks = function (loadCallback, failCallback) { |
|||
switch (this.state) { |
|||
case UrlStates.LOADED: |
|||
loadCallback && loadCallback(); |
|||
break; |
|||
case UrlStates.FAILED: |
|||
failCallback && failCallback(); |
|||
break; |
|||
case UrlStates.LOADING: |
|||
this.addCallbacks(loadCallback, failCallback); |
|||
break; |
|||
} |
|||
}; |
|||
|
|||
UrlInfo.prototype.addCallbacks = function (loadCallback, failCallback) { |
|||
loadCallback && this.loadCallbacks.push(loadCallback); |
|||
failCallback && this.failCallbacks.push(failCallback); |
|||
}; |
|||
|
|||
/* ResourceLoader API */ |
|||
|
|||
abp.ResourceLoader = (function () { |
|||
|
|||
var _urlInfos = {}; |
|||
|
|||
function getCacheKey(url) { |
|||
return url; |
|||
} |
|||
|
|||
function appendTimeToUrl(url) { |
|||
|
|||
if (url.indexOf('?') < 0) { |
|||
url += '?'; |
|||
} else { |
|||
url += '&'; |
|||
} |
|||
|
|||
url += '_=' + new Date().getTime(); |
|||
|
|||
return url; |
|||
} |
|||
|
|||
var _loadFromUrl = function (url, loadCallback, failCallback, serverLoader) { |
|||
|
|||
var cacheKey = getCacheKey(url); |
|||
|
|||
var urlInfo = _urlInfos[cacheKey]; |
|||
|
|||
if (urlInfo) { |
|||
urlInfo.handleCallbacks(loadCallback, failCallback); |
|||
return; |
|||
} |
|||
|
|||
_urlInfos[cacheKey] = urlInfo = new UrlInfo(url); |
|||
urlInfo.addCallbacks(loadCallback, failCallback); |
|||
|
|||
serverLoader(urlInfo); |
|||
}; |
|||
|
|||
var _loadScript = function (url, loadCallback, failCallback) { |
|||
_loadFromUrl(url, loadCallback, failCallback, function (urlInfo) { |
|||
$.getScript(url) |
|||
.done(function () { |
|||
urlInfo.succeed(); |
|||
}) |
|||
.fail(function () { |
|||
urlInfo.failed(); |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
var _loadStyle = function (url) { |
|||
_loadFromUrl(url, undefined, undefined, function (urlInfo) { |
|||
|
|||
$('<link/>', { |
|||
rel: 'stylesheet', |
|||
type: 'text/css', |
|||
href: appendTimeToUrl(url) |
|||
}).appendTo('head'); |
|||
}); |
|||
}; |
|||
|
|||
return { |
|||
loadScript: _loadScript, |
|||
loadStyle: _loadStyle |
|||
} |
|||
})(); |
|||
|
|||
var abp = abp || {}; |
|||
(function($) { |
|||
|
|||
if (!$) { |
|||
throw "abp/jquery library requires the jquery library included to the page!"; |
|||
} |
|||
|
|||
// ABP CORE OVERRIDES /////////////////////////////////////////////////////
|
|||
|
|||
abp.message._showMessage = function (message, title) { |
|||
alert((title || '') + ' ' + message); |
|||
|
|||
return $.Deferred(function ($dfd) { |
|||
$dfd.resolve(); |
|||
}); |
|||
}; |
|||
|
|||
abp.message.confirm = function (message, titleOrCallback, callback) { |
|||
if (titleOrCallback && !(typeof titleOrCallback == 'string')) { |
|||
callback = titleOrCallback; |
|||
} |
|||
|
|||
var result = confirm(message); |
|||
callback && callback(result); |
|||
|
|||
return $.Deferred(function ($dfd) { |
|||
$dfd.resolve(result); |
|||
}); |
|||
}; |
|||
|
|||
abp.utils.isFunction = function (obj) { |
|||
return $.isFunction(obj); |
|||
}; |
|||
|
|||
// JQUERY EXTENSIONS //////////////////////////////////////////////////////
|
|||
|
|||
$.fn.findWithSelf = function (selector) { |
|||
return this.filter(selector).add(this.find(selector)); |
|||
}; |
|||
|
|||
// DOM ////////////////////////////////////////////////////////////////////
|
|||
|
|||
abp.dom = abp.dom || {}; |
|||
|
|||
abp.dom.onNodeAdded = function (callback) { |
|||
abp.event.on('abp.dom.nodeAdded', callback); |
|||
}; |
|||
|
|||
abp.dom.onNodeRemoved = function (callback) { |
|||
abp.event.on('abp.dom.nodeRemoved', callback); |
|||
}; |
|||
|
|||
var mutationObserverCallback = function (mutationsList) { |
|||
for (var i = 0; i < mutationsList.length; i++) { |
|||
var mutation = mutationsList[i]; |
|||
if (mutation.type === 'childList') { |
|||
if (mutation.addedNodes && mutation.removedNodes.length) { |
|||
for (var k = 0; k < mutation.removedNodes.length; k++) { |
|||
abp.event.trigger( |
|||
'abp.dom.nodeRemoved', |
|||
{ |
|||
$el: $(mutation.removedNodes[k]) |
|||
} |
|||
); |
|||
} |
|||
} |
|||
|
|||
if (mutation.addedNodes && mutation.addedNodes.length) { |
|||
for (var j = 0; j < mutation.addedNodes.length; j++) { |
|||
abp.event.trigger( |
|||
'abp.dom.nodeAdded', |
|||
{ |
|||
$el: $(mutation.addedNodes[j]) |
|||
} |
|||
); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
new MutationObserver(mutationObserverCallback).observe( |
|||
$('body')[0], |
|||
{ |
|||
subtree: true, |
|||
childList: true |
|||
} |
|||
); |
|||
|
|||
// AJAX ///////////////////////////////////////////////////////////////////
|
|||
|
|||
abp.ajax = function (userOptions) { |
|||
userOptions = userOptions || {}; |
|||
|
|||
var options = $.extend(true, {}, abp.ajax.defaultOpts, userOptions); |
|||
|
|||
options.success = undefined; |
|||
options.error = undefined; |
|||
|
|||
return $.Deferred(function ($dfd) { |
|||
$.ajax(options) |
|||
.done(function (data, textStatus, jqXHR) { |
|||
$dfd.resolve(data); |
|||
userOptions.success && userOptions.success(data); |
|||
}).fail(function (jqXHR) { |
|||
if (jqXHR.getResponseHeader('_AbpErrorFormat') === 'true') { |
|||
abp.ajax.handleAbpErrorResponse(jqXHR, userOptions, $dfd); |
|||
} else { |
|||
abp.ajax.handleNonAbpErrorResponse(jqXHR, userOptions, $dfd); |
|||
} |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
$.extend(abp.ajax, { |
|||
defaultOpts: { |
|||
dataType: 'json', |
|||
type: 'POST', |
|||
contentType: 'application/json', |
|||
headers: { |
|||
'X-Requested-With': 'XMLHttpRequest' |
|||
} |
|||
}, |
|||
|
|||
defaultError: { |
|||
message: 'An error has occurred!', |
|||
details: 'Error detail not sent by server.' |
|||
}, |
|||
|
|||
defaultError401: { |
|||
message: 'You are not authenticated!', |
|||
details: 'You should be authenticated (sign in) in order to perform this operation.' |
|||
}, |
|||
|
|||
defaultError403: { |
|||
message: 'You are not authorized!', |
|||
details: 'You are not allowed to perform this operation.' |
|||
}, |
|||
|
|||
defaultError404: { |
|||
message: 'Resource not found!', |
|||
details: 'The resource requested could not found on the server.' |
|||
}, |
|||
|
|||
logError: function (error) { |
|||
abp.log.error(error); |
|||
}, |
|||
|
|||
showError: function (error) { |
|||
if (error.details) { |
|||
return abp.message.error(error.details, error.message); |
|||
} else { |
|||
return abp.message.error(error.message || abp.ajax.defaultError.message); |
|||
} |
|||
}, |
|||
|
|||
handleTargetUrl: function (targetUrl) { |
|||
if (!targetUrl) { |
|||
location.href = abp.appPath; |
|||
} else { |
|||
location.href = targetUrl; |
|||
} |
|||
}, |
|||
|
|||
handleErrorStatusCode: function (status) { |
|||
switch (status) { |
|||
case 401: |
|||
abp.ajax.handleUnAuthorizedRequest( |
|||
abp.ajax.showError(abp.ajax.defaultError401), |
|||
abp.appPath |
|||
); |
|||
break; |
|||
case 403: |
|||
abp.ajax.showError(abp.ajax.defaultError403); |
|||
break; |
|||
case 404: |
|||
abp.ajax.showError(abp.ajax.defaultError404); |
|||
break; |
|||
default: |
|||
abp.ajax.showError(abp.ajax.defaultError); |
|||
break; |
|||
} |
|||
}, |
|||
|
|||
handleNonAbpErrorResponse: function (jqXHR, userOptions, $dfd) { |
|||
if (userOptions.abpHandleError !== false) { |
|||
abp.ajax.handleErrorStatusCode(jqXHR.status); |
|||
} |
|||
|
|||
$dfd.reject.apply(this, arguments); |
|||
userOptions.error && userOptions.error.apply(this, arguments); |
|||
}, |
|||
|
|||
handleAbpErrorResponse: function (jqXHR, userOptions, $dfd) { |
|||
var messagePromise = null; |
|||
|
|||
if (userOptions.abpHandleError !== false) { |
|||
messagePromise = abp.ajax.showError(jqXHR.responseJSON.error); |
|||
} |
|||
|
|||
abp.ajax.logError(jqXHR.responseJSON.error); |
|||
|
|||
$dfd && $dfd.reject(jqXHR.responseJSON.error, jqXHR); |
|||
userOptions.error && userOptions.error(jqXHR.responseJSON.error, jqXHR); |
|||
|
|||
if (jqXHR.status === 401 && userOptions.abpHandleError !== false) { |
|||
abp.ajax.handleUnAuthorizedRequest(messagePromise); |
|||
} |
|||
}, |
|||
|
|||
handleUnAuthorizedRequest: function (messagePromise, targetUrl) { |
|||
if (messagePromise) { |
|||
messagePromise.done(function () { |
|||
abp.ajax.handleTargetUrl(targetUrl); |
|||
}); |
|||
} else { |
|||
abp.ajax.handleTargetUrl(targetUrl); |
|||
} |
|||
}, |
|||
|
|||
blockUI: function (options) { |
|||
if (options.blockUI) { |
|||
if (options.blockUI === true) { //block whole page
|
|||
abp.ui.setBusy(); |
|||
} else { //block an element
|
|||
abp.ui.setBusy(options.blockUI); |
|||
} |
|||
} |
|||
}, |
|||
|
|||
unblockUI: function (options) { |
|||
if (options.blockUI) { |
|||
if (options.blockUI === true) { //unblock whole page
|
|||
abp.ui.clearBusy(); |
|||
} else { //unblock an element
|
|||
abp.ui.clearBusy(options.blockUI); |
|||
} |
|||
} |
|||
}, |
|||
|
|||
ajaxSendHandler: function (event, request, settings) { |
|||
var token = abp.security.antiForgery.getToken(); |
|||
if (!token) { |
|||
return; |
|||
} |
|||
|
|||
if (!settings.headers || settings.headers[abp.security.antiForgery.tokenHeaderName] === undefined) { |
|||
request.setRequestHeader(abp.security.antiForgery.tokenHeaderName, token); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
$(document).ajaxSend(function (event, request, settings) { |
|||
return abp.ajax.ajaxSendHandler(event, request, settings); |
|||
}); |
|||
|
|||
abp.event.on('abp.configurationInitialized', function () { |
|||
var l = abp.localization.getResource('AbpUi'); |
|||
|
|||
abp.ajax.defaultError.message = l('DefaultErrorMessage'); |
|||
abp.ajax.defaultError.details = l('DefaultErrorMessageDetail'); |
|||
abp.ajax.defaultError401.message = l('DefaultErrorMessage401'); |
|||
abp.ajax.defaultError401.details = l('DefaultErrorMessage401Detail'); |
|||
abp.ajax.defaultError403.message = l('DefaultErrorMessage403'); |
|||
abp.ajax.defaultError403.details = l('DefaultErrorMessage403Detail'); |
|||
abp.ajax.defaultError404.message = l('DefaultErrorMessage404'); |
|||
abp.ajax.defaultError404.details = l('DefaultErrorMessage404Detail'); |
|||
}); |
|||
|
|||
// RESOURCE LOADER ////////////////////////////////////////////////////////
|
|||
|
|||
/* UrlStates enum */ |
|||
var UrlStates = { |
|||
LOADING: 'LOADING', |
|||
LOADED: 'LOADED', |
|||
FAILED: 'FAILED' |
|||
}; |
|||
|
|||
/* UrlInfo class */ |
|||
function UrlInfo(url) { |
|||
this.url = url; |
|||
this.state = UrlStates.LOADING; |
|||
this.loadCallbacks = []; |
|||
this.failCallbacks = []; |
|||
} |
|||
|
|||
UrlInfo.prototype.succeed = function () { |
|||
this.state = UrlStates.LOADED; |
|||
for (var i = 0; i < this.loadCallbacks.length; i++) { |
|||
this.loadCallbacks[i](); |
|||
} |
|||
}; |
|||
|
|||
UrlInfo.prototype.failed = function () { |
|||
this.state = UrlStates.FAILED; |
|||
for (var i = 0; i < this.failCallbacks.length; i++) { |
|||
this.failCallbacks[i](); |
|||
} |
|||
}; |
|||
|
|||
UrlInfo.prototype.handleCallbacks = function (loadCallback, failCallback) { |
|||
switch (this.state) { |
|||
case UrlStates.LOADED: |
|||
loadCallback && loadCallback(); |
|||
break; |
|||
case UrlStates.FAILED: |
|||
failCallback && failCallback(); |
|||
break; |
|||
case UrlStates.LOADING: |
|||
this.addCallbacks(loadCallback, failCallback); |
|||
break; |
|||
} |
|||
}; |
|||
|
|||
UrlInfo.prototype.addCallbacks = function (loadCallback, failCallback) { |
|||
loadCallback && this.loadCallbacks.push(loadCallback); |
|||
failCallback && this.failCallbacks.push(failCallback); |
|||
}; |
|||
|
|||
/* ResourceLoader API */ |
|||
|
|||
abp.ResourceLoader = (function () { |
|||
|
|||
var _urlInfos = {}; |
|||
|
|||
function getCacheKey(url) { |
|||
return url; |
|||
} |
|||
|
|||
function appendTimeToUrl(url) { |
|||
|
|||
if (url.indexOf('?') < 0) { |
|||
url += '?'; |
|||
} else { |
|||
url += '&'; |
|||
} |
|||
|
|||
url += '_=' + new Date().getTime(); |
|||
|
|||
return url; |
|||
} |
|||
|
|||
var _loadFromUrl = function (url, loadCallback, failCallback, serverLoader) { |
|||
|
|||
var cacheKey = getCacheKey(url); |
|||
|
|||
var urlInfo = _urlInfos[cacheKey]; |
|||
|
|||
if (urlInfo) { |
|||
urlInfo.handleCallbacks(loadCallback, failCallback); |
|||
return; |
|||
} |
|||
|
|||
_urlInfos[cacheKey] = urlInfo = new UrlInfo(url); |
|||
urlInfo.addCallbacks(loadCallback, failCallback); |
|||
|
|||
serverLoader(urlInfo); |
|||
}; |
|||
|
|||
var _loadScript = function (url, loadCallback, failCallback) { |
|||
_loadFromUrl(url, loadCallback, failCallback, function (urlInfo) { |
|||
$.get({ |
|||
url: url, |
|||
dataType: 'text' |
|||
}) |
|||
.done(function (script) { |
|||
$.globalEval(script); |
|||
urlInfo.succeed(); |
|||
}) |
|||
.fail(function () { |
|||
urlInfo.failed(); |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
var _loadStyle = function (url) { |
|||
_loadFromUrl(url, undefined, undefined, function (urlInfo) { |
|||
|
|||
$('<link/>', { |
|||
rel: 'stylesheet', |
|||
type: 'text/css', |
|||
href: appendTimeToUrl(url) |
|||
}).appendTo('head'); |
|||
}); |
|||
}; |
|||
|
|||
return { |
|||
loadScript: _loadScript, |
|||
loadStyle: _loadStyle |
|||
} |
|||
})(); |
|||
|
|||
})(jQuery); |
|||
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -1,37 +1,37 @@ |
|||
{ |
|||
"name": "malihu-custom-scrollbar-plugin", |
|||
"version": "3.1.5", |
|||
"author": "malihu (http://manos.malihu.gr)", |
|||
"description": "Highly customizable custom scrollbar jQuery plugin, featuring vertical/horizontal scrollbars, scrolling momentum, mouse-wheel, keyboard and touch support user defined callbacks etc.", |
|||
"license": "MIT", |
|||
"homepage": "http://manos.malihu.gr/jquery-custom-content-scroller", |
|||
"main": "./jquery.mCustomScrollbar.js", |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "https://github.com/malihu/malihu-custom-scrollbar-plugin.git" |
|||
}, |
|||
"bugs": { |
|||
"url": "https://github.com/malihu/malihu-custom-scrollbar-plugin/issues" |
|||
}, |
|||
"keywords": [ |
|||
"jquery-plugin", |
|||
"custom-scrollbar", |
|||
"scrollbar" |
|||
], |
|||
"files": [ |
|||
"jquery.mCustomScrollbar.js", |
|||
"jquery.mCustomScrollbar.concat.min.js", |
|||
"jquery.mCustomScrollbar.css", |
|||
"mCSB_buttons.png", |
|||
"readme.md" |
|||
], |
|||
"jam": { |
|||
"dependencies": { |
|||
"jquery": ">=1.6", |
|||
"jquery-mousewheel": ">=3.0.6" |
|||
} |
|||
}, |
|||
"dependencies": { |
|||
"jquery-mousewheel": ">=3.0.6" |
|||
} |
|||
{ |
|||
"name": "malihu-custom-scrollbar-plugin", |
|||
"version": "3.1.5", |
|||
"author": "malihu (http://manos.malihu.gr)", |
|||
"description": "Highly customizable custom scrollbar jQuery plugin, featuring vertical/horizontal scrollbars, scrolling momentum, mouse-wheel, keyboard and touch support user defined callbacks etc.", |
|||
"license": "MIT", |
|||
"homepage": "http://manos.malihu.gr/jquery-custom-content-scroller", |
|||
"main": "./jquery.mCustomScrollbar.js", |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "https://github.com/malihu/malihu-custom-scrollbar-plugin.git" |
|||
}, |
|||
"bugs": { |
|||
"url": "https://github.com/malihu/malihu-custom-scrollbar-plugin/issues" |
|||
}, |
|||
"keywords": [ |
|||
"jquery-plugin", |
|||
"custom-scrollbar", |
|||
"scrollbar" |
|||
], |
|||
"files": [ |
|||
"jquery.mCustomScrollbar.js", |
|||
"jquery.mCustomScrollbar.concat.min.js", |
|||
"jquery.mCustomScrollbar.css", |
|||
"mCSB_buttons.png", |
|||
"readme.md" |
|||
], |
|||
"jam": { |
|||
"dependencies": { |
|||
"jquery": ">=1.6", |
|||
"jquery-mousewheel": ">=3.0.6" |
|||
} |
|||
}, |
|||
"dependencies": { |
|||
"jquery-mousewheel": ">=3.0.6" |
|||
} |
|||
} |
|||
@ -1,82 +1,82 @@ |
|||
malihu custom scrollbar plugin |
|||
================================ |
|||
|
|||
Highly customizable custom scrollbar jQuery plugin ([Demo](http://manos.malihu.gr/repository/custom-scrollbar/demo/examples/complete_examples.html)). Features include: |
|||
|
|||
* Vertical and/or horizontal scrollbar(s) |
|||
* Adjustable scrolling momentum |
|||
* Mouse-wheel, keyboard and touch support |
|||
* Ready-to-use themes and customization via CSS |
|||
* RTL direction support |
|||
* Option parameters for full control of scrollbar functionality |
|||
* Methods for triggering actions like scroll-to, update, destroy etc. |
|||
* User-defined callbacks |
|||
* Selectable/searchable content |
|||
|
|||
**[Plugin homepage and documentation](http://manos.malihu.gr/jquery-custom-content-scroller/)** ([Changelog](http://manos.malihu.gr/jquery-custom-content-scroller/2/)) |
|||
|
|||
#### Installation |
|||
|
|||
npm: `npm install malihu-custom-scrollbar-plugin` |
|||
|
|||
Bower: `bower install malihu-custom-scrollbar-plugin` |
|||
|
|||
[Manual](http://manos.malihu.gr/jquery-custom-content-scroller/#get-started-section) |
|||
|
|||
#### Usage |
|||
|
|||
Manual: `$(selector).mCustomScrollbar();` |
|||
|
|||
[Browserify](http://browserify.org/): |
|||
|
|||
var $ = require('jquery'); |
|||
require('malihu-custom-scrollbar-plugin')($); |
|||
|
|||
[webpack](https://webpack.github.io/): |
|||
|
|||
npm install imports-loader |
|||
npm install jquery-mousewheel |
|||
npm install malihu-custom-scrollbar-plugin |
|||
|
|||
module.exports = { |
|||
module: { |
|||
loaders: [ |
|||
{ test: /jquery-mousewheel/, loader: "imports?define=>false&this=>window" }, |
|||
{ test: /malihu-custom-scrollbar-plugin/, loader: "imports?define=>false&this=>window" } |
|||
] |
|||
} |
|||
}; |
|||
|
|||
var $ = require('jquery'); |
|||
require("jquery-mousewheel")($); |
|||
require('malihu-custom-scrollbar-plugin')($); |
|||
|
|||
|
|||
Requirements |
|||
------------------------- |
|||
|
|||
jQuery version **1.6.0** or higher |
|||
|
|||
Browser compatibility |
|||
------------------------- |
|||
|
|||
* Internet Explorer 8+ |
|||
* Firefox |
|||
* Chrome |
|||
* Opera |
|||
* Safari |
|||
* iOS |
|||
* Android |
|||
* Windows Phone |
|||
|
|||
License |
|||
------------------------- |
|||
|
|||
MIT License (MIT) |
|||
|
|||
http://opensource.org/licenses/MIT |
|||
|
|||
Donate |
|||
------------------------- |
|||
|
|||
malihu custom scrollbar plugin |
|||
================================ |
|||
|
|||
Highly customizable custom scrollbar jQuery plugin ([Demo](http://manos.malihu.gr/repository/custom-scrollbar/demo/examples/complete_examples.html)). Features include: |
|||
|
|||
* Vertical and/or horizontal scrollbar(s) |
|||
* Adjustable scrolling momentum |
|||
* Mouse-wheel, keyboard and touch support |
|||
* Ready-to-use themes and customization via CSS |
|||
* RTL direction support |
|||
* Option parameters for full control of scrollbar functionality |
|||
* Methods for triggering actions like scroll-to, update, destroy etc. |
|||
* User-defined callbacks |
|||
* Selectable/searchable content |
|||
|
|||
**[Plugin homepage and documentation](http://manos.malihu.gr/jquery-custom-content-scroller/)** ([Changelog](http://manos.malihu.gr/jquery-custom-content-scroller/2/)) |
|||
|
|||
#### Installation |
|||
|
|||
npm: `npm install malihu-custom-scrollbar-plugin` |
|||
|
|||
Bower: `bower install malihu-custom-scrollbar-plugin` |
|||
|
|||
[Manual](http://manos.malihu.gr/jquery-custom-content-scroller/#get-started-section) |
|||
|
|||
#### Usage |
|||
|
|||
Manual: `$(selector).mCustomScrollbar();` |
|||
|
|||
[Browserify](http://browserify.org/): |
|||
|
|||
var $ = require('jquery'); |
|||
require('malihu-custom-scrollbar-plugin')($); |
|||
|
|||
[webpack](https://webpack.github.io/): |
|||
|
|||
npm install imports-loader |
|||
npm install jquery-mousewheel |
|||
npm install malihu-custom-scrollbar-plugin |
|||
|
|||
module.exports = { |
|||
module: { |
|||
loaders: [ |
|||
{ test: /jquery-mousewheel/, loader: "imports?define=>false&this=>window" }, |
|||
{ test: /malihu-custom-scrollbar-plugin/, loader: "imports?define=>false&this=>window" } |
|||
] |
|||
} |
|||
}; |
|||
|
|||
var $ = require('jquery'); |
|||
require("jquery-mousewheel")($); |
|||
require('malihu-custom-scrollbar-plugin')($); |
|||
|
|||
|
|||
Requirements |
|||
------------------------- |
|||
|
|||
jQuery version **1.6.0** or higher |
|||
|
|||
Browser compatibility |
|||
------------------------- |
|||
|
|||
* Internet Explorer 8+ |
|||
* Firefox |
|||
* Chrome |
|||
* Opera |
|||
* Safari |
|||
* iOS |
|||
* Android |
|||
* Windows Phone |
|||
|
|||
License |
|||
------------------------- |
|||
|
|||
MIT License (MIT) |
|||
|
|||
http://opensource.org/licenses/MIT |
|||
|
|||
Donate |
|||
------------------------- |
|||
|
|||
https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UYJ5G65M6ZA28 |
|||
Loading…
Reference in new issue