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 { ABP } from "@abp/ng.core"; |
||||
import { ACCOUNT_ROUTES } from '@abp/ng.account'; |
import { NgModule } from "@angular/core"; |
||||
import { NgModule } from '@angular/core'; |
import { RouterModule, Routes } from "@angular/router"; |
||||
import { Routes, RouterModule } from '@angular/router'; |
import { ApplicationLayoutComponent } from "@abp/ng.theme.basic"; |
||||
import { ABP } from '@abp/ng.core'; |
|
||||
import { TENANT_MANAGEMENT_ROUTES } from '@abp/ng.tenant-management'; |
|
||||
import { ApplicationLayoutComponent } from '@abp/ng.theme.basic'; |
|
||||
|
|
||||
const routes: Routes = [ |
const routes: Routes = [ |
||||
{ |
{ |
||||
path: '', |
path: "", |
||||
loadChildren: () => import('./home/home.module').then(m => m.HomeModule), |
loadChildren: () => import("./home/home.module").then(m => m.HomeModule), |
||||
data: { |
data: { |
||||
routes: { |
routes: { |
||||
name: '::Menu:Home', |
name: "::Menu:Home" |
||||
} as ABP.Route, |
} as ABP.Route |
||||
}, |
} |
||||
}, |
}, |
||||
{ |
{ |
||||
path: 'account', |
path: "account", |
||||
loadChildren: () => import('./lazy-libs/account-wrapper.module').then(m => m.AccountWrapperModule), |
loadChildren: () => |
||||
data: { routes: ACCOUNT_ROUTES }, |
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', |
path: "tenant-management", |
||||
loadChildren: () => import('./lazy-libs/identity-wrapper.module').then(m => m.IdentityWrapperModule), |
loadChildren: () => |
||||
data: { routes: IDENTITY_ROUTES }, |
import("./lazy-libs/tenant-management-wrapper.module").then( |
||||
|
m => m.TenantManagementWrapperModule |
||||
|
) |
||||
}, |
}, |
||||
{ |
{ |
||||
path: 'tenant-management', |
path: "setting-management", |
||||
loadChildren: () => |
loadChildren: () => |
||||
import('./lazy-libs/tenant-management-wrapper.module').then(m => m.TenantManagementWrapperModule), |
import("./lazy-libs/setting-management-wrapper.module").then( |
||||
data: { routes: TENANT_MANAGEMENT_ROUTES }, |
m => m.SettingManagementWrapperModule |
||||
|
) |
||||
}, |
}, |
||||
{ |
{ |
||||
path: 'books', |
path: "books", |
||||
component: ApplicationLayoutComponent, |
component: ApplicationLayoutComponent, |
||||
loadChildren: () => import('./books/books.module').then(m => m.BooksModule), |
loadChildren: () => import("./books/books.module").then(m => m.BooksModule), |
||||
data: { |
data: { |
||||
routes: { |
routes: { |
||||
name: 'Books', |
name: "::Menu:Books", |
||||
} as ABP.Route, |
iconClass: "fas fa-book" |
||||
}, |
} as ABP.Route |
||||
}, |
} |
||||
|
} |
||||
]; |
]; |
||||
|
|
||||
@NgModule({ |
@NgModule({ |
||||
imports: [RouterModule.forRoot(routes)], |
imports: [RouterModule.forRoot(routes)], |
||||
exports: [RouterModule], |
exports: [RouterModule] |
||||
}) |
}) |
||||
export class AppRoutingModule {} |
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 { 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 { LAYOUTS } from '@abp/ng.theme.basic'; |
||||
|
import { ThemeSharedModule } from '@abp/ng.theme.shared'; |
||||
import { NgModule } from '@angular/core'; |
import { NgModule } from '@angular/core'; |
||||
import { BrowserModule } from '@angular/platform-browser'; |
import { BrowserModule } from '@angular/platform-browser'; |
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; |
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 { NgxsModule } from '@ngxs/store'; |
||||
import { OAuthModule } from 'angular-oauth2-oidc'; |
|
||||
import { environment } from '../environments/environment'; |
import { environment } from '../environments/environment'; |
||||
import { AppRoutingModule } from './app-routing.module'; |
import { AppRoutingModule } from './app-routing.module'; |
||||
import { AppComponent } from './app.component'; |
import { AppComponent } from './app.component'; |
||||
import { SharedModule } from './shared/shared.module'; |
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'; |
import { BooksState } from './store/states/books.state'; |
||||
|
|
||||
|
const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })]; |
||||
|
|
||||
@NgModule({ |
@NgModule({ |
||||
declarations: [AppComponent], |
|
||||
imports: [ |
imports: [ |
||||
ThemeSharedModule.forRoot(), |
|
||||
CoreModule.forRoot({ |
CoreModule.forRoot({ |
||||
environment, |
environment, |
||||
requirements: { |
requirements: { |
||||
layouts: LAYOUTS, |
layouts: LAYOUTS, |
||||
}, |
}, |
||||
}), |
}), |
||||
OAuthModule.forRoot(), |
ThemeSharedModule.forRoot(), |
||||
NgxsModule.forRoot([]), |
AccountConfigModule.forRoot({ redirectUrl: '/' }), |
||||
|
IdentityConfigModule, |
||||
|
TenantManagementConfigModule, |
||||
|
SettingManagementConfigModule, |
||||
|
NgxsModule.forRoot([BooksState]), |
||||
BrowserModule, |
BrowserModule, |
||||
BrowserAnimationsModule, |
BrowserAnimationsModule, |
||||
AppRoutingModule, |
AppRoutingModule, |
||||
SharedModule, |
SharedModule, |
||||
NgxsModule.forRoot([BooksState, ]), |
...(environment.production ? [] : LOGGERS), |
||||
NgxsReduxDevtoolsPluginModule.forRoot({ disabled: environment.production }), |
|
||||
], |
], |
||||
providers: [...AccountProviders({ redirectUrl: '/' }), ...IdentityProviders(), ...TenantManagementProviders()], |
declarations: [AppComponent], |
||||
bootstrap: [AppComponent], |
bootstrap: [AppComponent], |
||||
}) |
}) |
||||
export class AppModule {} |
export class AppModule {} |
||||
|
|||||
@ -1,18 +1,19 @@ |
|||||
import { NgModule } from '@angular/core'; |
import { NgModule } from "@angular/core"; |
||||
import { RouterModule, Routes } from '@angular/router'; |
import { Routes, RouterModule } from "@angular/router"; |
||||
import { BooksComponent } from './books.component'; |
|
||||
import { BookListComponent } from './book-list/book-list.component'; |
import { BooksComponent } from "./books.component"; |
||||
|
import { BookListComponent } from "./book-list/book-list.component"; |
||||
|
|
||||
const routes: Routes = [ |
const routes: Routes = [ |
||||
{ |
{ |
||||
path: '', |
path: "", |
||||
component: BooksComponent, |
component: BooksComponent, |
||||
children: [{ path: '', component: BookListComponent }], |
children: [{ path: "", component: BookListComponent }] |
||||
}, |
} |
||||
]; |
]; |
||||
|
|
||||
@NgModule({ |
@NgModule({ |
||||
imports: [RouterModule.forChild(routes)], |
imports: [RouterModule.forChild(routes)], |
||||
exports: [RouterModule], |
exports: [RouterModule] |
||||
}) |
}) |
||||
export class BooksRoutingModule {} |
export class BooksRoutingModule {} |
||||
|
|||||
@ -1,8 +1,15 @@ |
|||||
import { Component } from '@angular/core'; |
import { Component, OnInit } from '@angular/core'; |
||||
|
|
||||
@Component({ |
@Component({ |
||||
selector: 'app-books', |
selector: 'app-books', |
||||
templateUrl: './books.component.html', |
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 { NgModule } from "@angular/core"; |
||||
import { CommonModule } from '@angular/common'; |
import { CommonModule } from "@angular/common"; |
||||
|
|
||||
import { BooksRoutingModule } from './books-routing.module'; |
import { BooksRoutingModule } from "./books-routing.module"; |
||||
import { BooksComponent } from './books.component'; |
import { BooksComponent } from "./books.component"; |
||||
import { SharedModule } from '../shared/shared.module'; |
import { BookListComponent } from "./book-list/book-list.component"; |
||||
import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap'; |
import { SharedModule } from "../shared/shared.module"; |
||||
import { BookListComponent } from './book-list/book-list.component'; |
import { NgbDatepickerModule } from "@ng-bootstrap/ng-bootstrap"; |
||||
|
|
||||
@NgModule({ |
@NgModule({ |
||||
declarations: [BooksComponent, BookListComponent], |
declarations: [BooksComponent, BookListComponent], |
||||
imports: [CommonModule, BooksRoutingModule, SharedModule, NgbDatepickerModule], |
imports: [CommonModule, BooksRoutingModule, SharedModule, NgbDatepickerModule] |
||||
}) |
}) |
||||
export class BooksModule {} |
export class BooksModule {} |
||||
|
|||||
@ -1,15 +1,20 @@ |
|||||
<div class="card"> |
<div id="AbpContentToolbar"></div> |
||||
<div class="card-header">{{ '::Welcome' | abpLocalization }}</div> |
<div class="jumbotron text-center"> |
||||
<div class="card-body"> |
<h1>{{ '::Welcome' | abpLocalization }}</h1> |
||||
<p> |
<div class="row"> |
||||
{{ '::LongWelcomeMessage' | abpLocalization }} |
<div class="col-md-6 mx-auto"> |
||||
</p> |
<p>{{ '::LongWelcomeMessage' | abpLocalization }}</p> |
||||
<p *ngIf="!hasLoggedIn"> |
<hr class="my-4" /> |
||||
<a routerLink="/account/login" [state]="{ redirectUrl: '/' }" class="btn btn-primary" role="button" |
</div> |
||||
><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> |
</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> |
</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 { |
export class GetBooks { |
||||
static readonly type = '[Books] Get'; |
static readonly type = "[Books] Get"; |
||||
} |
} |
||||
|
|
||||
export class CreateUpdateBook { |
export class CreateUpdateBook { |
||||
static readonly type = '[Books] Create Update Book'; |
static readonly type = "[Books] Create Update Book"; |
||||
constructor(public payload: Books.CreateUpdateBookInput, public id?: string) {} |
constructor( |
||||
|
public payload: Books.CreateUpdateBookInput, |
||||
|
public id?: string |
||||
|
) {} |
||||
} |
} |
||||
|
|
||||
export class DeleteBook { |
export class DeleteBook { |
||||
static readonly type = '[Books] Delete'; |
static readonly type = "[Books] Delete"; |
||||
constructor(public id: string) {} |
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.Dtos; |
||||
using Volo.Abp.Application.Services; |
using Volo.Abp.Application.Services; |
||||
using Volo.Abp.Domain.Repositories; |
using Volo.Abp.Domain.Repositories; |
||||
|
|
||||
namespace Acme.BookStore |
namespace Acme.BookStore |
||||
{ |
{ |
||||
public class BookAppService : |
public class BookAppService : |
||||
CrudAppService<Book, BookDto, Guid, PagedAndSortedResultRequestDto, |
CrudAppService<Book, BookDto, Guid, PagedAndSortedResultRequestDto, |
||||
CreateUpdateBookDto, CreateUpdateBookDto>, |
CreateUpdateBookDto, CreateUpdateBookDto>, |
||||
IBookAppService |
IBookAppService |
||||
{ |
{ |
||||
public BookAppService(IRepository<Book, Guid> repository) |
public BookAppService(IRepository<Book, Guid> repository) |
||||
: base(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": { |
"App": { |
||||
"SelfUrl": "https://localhost:44341", |
"SelfUrl": "https://localhost:44317", |
||||
"CorsOrigins": "https://*.BookStore.com,http://localhost:4200" |
"CorsOrigins": "https://*.BookStore.com,http://localhost:4200" |
||||
}, |
}, |
||||
"ConnectionStrings": { |
"ConnectionStrings": { |
||||
"Default": "mongodb://localhost:27017/BookStore" |
"Default": "mongodb://localhost:27017/BookStore" |
||||
}, |
}, |
||||
"AuthServer": { |
"AuthServer": { |
||||
"Authority": "https://localhost:44341" |
"Authority": "https://localhost:44317" |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -1,56 +1,56 @@ |
|||||
@keyframes spin { |
@keyframes spin { |
||||
0% { |
0% { |
||||
transform: translateZ(0) rotate(0deg); |
transform: translateZ(0) rotate(0deg); |
||||
} |
} |
||||
|
|
||||
100% { |
100% { |
||||
transform: translateZ(0) rotate(360deg); |
transform: translateZ(0) rotate(360deg); |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
.abp-block-area { |
.abp-block-area { |
||||
position: fixed; |
position: fixed; |
||||
top: 0; |
top: 0; |
||||
left: 0; |
left: 0; |
||||
width: 100%; |
width: 100%; |
||||
height: 100%; |
height: 100%; |
||||
z-index: 102; |
z-index: 102; |
||||
background-color: #fff; |
background-color: #fff; |
||||
opacity: .8; |
opacity: .8; |
||||
transition: opacity .25s; |
transition: opacity .25s; |
||||
} |
} |
||||
|
|
||||
.abp-block-area.abp-block-area-disappearing { |
.abp-block-area.abp-block-area-disappearing { |
||||
opacity: 0; |
opacity: 0; |
||||
} |
} |
||||
|
|
||||
.abp-block-area.abp-block-area-busy:after { |
.abp-block-area.abp-block-area-busy:after { |
||||
content: attr(data-text); |
content: attr(data-text); |
||||
display: block; |
display: block; |
||||
max-width: 125px; |
max-width: 125px; |
||||
position: absolute; |
position: absolute; |
||||
top: 50%; |
top: 50%; |
||||
left: 50%; |
left: 50%; |
||||
transform: translate(-50%, -50%); |
transform: translate(-50%, -50%); |
||||
font-size: 20px; |
font-size: 20px; |
||||
font-family: sans-serif; |
font-family: sans-serif; |
||||
color: #343a40; |
color: #343a40; |
||||
text-align: center; |
text-align: center; |
||||
text-transform: uppercase; |
text-transform: uppercase; |
||||
} |
} |
||||
|
|
||||
.abp-block-area.abp-block-area-busy:before { |
.abp-block-area.abp-block-area-busy:before { |
||||
content: ""; |
content: ""; |
||||
display: block; |
display: block; |
||||
width: 150px; |
width: 150px; |
||||
height: 150px; |
height: 150px; |
||||
border-radius: 50%; |
border-radius: 50%; |
||||
border-width: 2px; |
border-width: 2px; |
||||
border-style: solid; |
border-style: solid; |
||||
border-color: transparent #228ae6 #228ae6 #228ae6; |
border-color: transparent #228ae6 #228ae6 #228ae6; |
||||
position: absolute; |
position: absolute; |
||||
top: calc(50% - 75px); |
top: calc(50% - 75px); |
||||
left: calc(50% - 75px); |
left: calc(50% - 75px); |
||||
will-change: transform; |
will-change: transform; |
||||
animation: spin .75s infinite ease-in-out; |
animation: spin .75s infinite ease-in-out; |
||||
} |
} |
||||
|
|||||
File diff suppressed because it is too large
@ -1,389 +1,393 @@ |
|||||
var abp = abp || {}; |
var abp = abp || {}; |
||||
(function($) { |
(function($) { |
||||
|
|
||||
if (!$) { |
if (!$) { |
||||
throw "abp/jquery library requires the jquery library included to the page!"; |
throw "abp/jquery library requires the jquery library included to the page!"; |
||||
} |
} |
||||
|
|
||||
// ABP CORE OVERRIDES /////////////////////////////////////////////////////
|
// ABP CORE OVERRIDES /////////////////////////////////////////////////////
|
||||
|
|
||||
abp.message._showMessage = function (message, title) { |
abp.message._showMessage = function (message, title) { |
||||
alert((title || '') + ' ' + message); |
alert((title || '') + ' ' + message); |
||||
|
|
||||
return $.Deferred(function ($dfd) { |
return $.Deferred(function ($dfd) { |
||||
$dfd.resolve(); |
$dfd.resolve(); |
||||
}); |
}); |
||||
}; |
}; |
||||
|
|
||||
abp.message.confirm = function (message, titleOrCallback, callback) { |
abp.message.confirm = function (message, titleOrCallback, callback) { |
||||
if (titleOrCallback && !(typeof titleOrCallback == 'string')) { |
if (titleOrCallback && !(typeof titleOrCallback == 'string')) { |
||||
callback = titleOrCallback; |
callback = titleOrCallback; |
||||
} |
} |
||||
|
|
||||
var result = confirm(message); |
var result = confirm(message); |
||||
callback && callback(result); |
callback && callback(result); |
||||
|
|
||||
return $.Deferred(function ($dfd) { |
return $.Deferred(function ($dfd) { |
||||
$dfd.resolve(result); |
$dfd.resolve(result); |
||||
}); |
}); |
||||
}; |
}; |
||||
|
|
||||
abp.utils.isFunction = function (obj) { |
abp.utils.isFunction = function (obj) { |
||||
return $.isFunction(obj); |
return $.isFunction(obj); |
||||
}; |
}; |
||||
|
|
||||
// JQUERY EXTENSIONS //////////////////////////////////////////////////////
|
// JQUERY EXTENSIONS //////////////////////////////////////////////////////
|
||||
|
|
||||
$.fn.findWithSelf = function (selector) { |
$.fn.findWithSelf = function (selector) { |
||||
return this.filter(selector).add(this.find(selector)); |
return this.filter(selector).add(this.find(selector)); |
||||
}; |
}; |
||||
|
|
||||
// DOM ////////////////////////////////////////////////////////////////////
|
// DOM ////////////////////////////////////////////////////////////////////
|
||||
|
|
||||
abp.dom = abp.dom || {}; |
abp.dom = abp.dom || {}; |
||||
|
|
||||
abp.dom.onNodeAdded = function (callback) { |
abp.dom.onNodeAdded = function (callback) { |
||||
abp.event.on('abp.dom.nodeAdded', callback); |
abp.event.on('abp.dom.nodeAdded', callback); |
||||
}; |
}; |
||||
|
|
||||
abp.dom.onNodeRemoved = function (callback) { |
abp.dom.onNodeRemoved = function (callback) { |
||||
abp.event.on('abp.dom.nodeRemoved', callback); |
abp.event.on('abp.dom.nodeRemoved', callback); |
||||
}; |
}; |
||||
|
|
||||
var mutationObserverCallback = function (mutationsList) { |
var mutationObserverCallback = function (mutationsList) { |
||||
for (var i = 0; i < mutationsList.length; i++) { |
for (var i = 0; i < mutationsList.length; i++) { |
||||
var mutation = mutationsList[i]; |
var mutation = mutationsList[i]; |
||||
if (mutation.type === 'childList') { |
if (mutation.type === 'childList') { |
||||
if (mutation.addedNodes && mutation.removedNodes.length) { |
if (mutation.addedNodes && mutation.removedNodes.length) { |
||||
for (var k = 0; k < mutation.removedNodes.length; k++) { |
for (var k = 0; k < mutation.removedNodes.length; k++) { |
||||
abp.event.trigger( |
abp.event.trigger( |
||||
'abp.dom.nodeRemoved', |
'abp.dom.nodeRemoved', |
||||
{ |
{ |
||||
$el: $(mutation.removedNodes[k]) |
$el: $(mutation.removedNodes[k]) |
||||
} |
} |
||||
); |
); |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
if (mutation.addedNodes && mutation.addedNodes.length) { |
if (mutation.addedNodes && mutation.addedNodes.length) { |
||||
for (var j = 0; j < mutation.addedNodes.length; j++) { |
for (var j = 0; j < mutation.addedNodes.length; j++) { |
||||
abp.event.trigger( |
abp.event.trigger( |
||||
'abp.dom.nodeAdded', |
'abp.dom.nodeAdded', |
||||
{ |
{ |
||||
$el: $(mutation.addedNodes[j]) |
$el: $(mutation.addedNodes[j]) |
||||
} |
} |
||||
); |
); |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
}; |
}; |
||||
|
|
||||
new MutationObserver(mutationObserverCallback).observe( |
new MutationObserver(mutationObserverCallback).observe( |
||||
$('body')[0], |
$('body')[0], |
||||
{ |
{ |
||||
subtree: true, |
subtree: true, |
||||
childList: true |
childList: true |
||||
} |
} |
||||
); |
); |
||||
|
|
||||
// AJAX ///////////////////////////////////////////////////////////////////
|
// AJAX ///////////////////////////////////////////////////////////////////
|
||||
|
|
||||
abp.ajax = function (userOptions) { |
abp.ajax = function (userOptions) { |
||||
userOptions = userOptions || {}; |
userOptions = userOptions || {}; |
||||
|
|
||||
var options = $.extend(true, {}, abp.ajax.defaultOpts, userOptions); |
var options = $.extend(true, {}, abp.ajax.defaultOpts, userOptions); |
||||
|
|
||||
options.success = undefined; |
options.success = undefined; |
||||
options.error = undefined; |
options.error = undefined; |
||||
|
|
||||
return $.Deferred(function ($dfd) { |
return $.Deferred(function ($dfd) { |
||||
$.ajax(options) |
$.ajax(options) |
||||
.done(function (data, textStatus, jqXHR) { |
.done(function (data, textStatus, jqXHR) { |
||||
$dfd.resolve(data); |
$dfd.resolve(data); |
||||
userOptions.success && userOptions.success(data); |
userOptions.success && userOptions.success(data); |
||||
}).fail(function (jqXHR) { |
}).fail(function (jqXHR) { |
||||
if (jqXHR.getResponseHeader('_AbpErrorFormat') === 'true') { |
if (jqXHR.getResponseHeader('_AbpErrorFormat') === 'true') { |
||||
abp.ajax.handleAbpErrorResponse(jqXHR, userOptions, $dfd); |
abp.ajax.handleAbpErrorResponse(jqXHR, userOptions, $dfd); |
||||
} else { |
} else { |
||||
abp.ajax.handleNonAbpErrorResponse(jqXHR, userOptions, $dfd); |
abp.ajax.handleNonAbpErrorResponse(jqXHR, userOptions, $dfd); |
||||
} |
} |
||||
}); |
}); |
||||
}); |
}); |
||||
}; |
}; |
||||
|
|
||||
$.extend(abp.ajax, { |
$.extend(abp.ajax, { |
||||
defaultOpts: { |
defaultOpts: { |
||||
dataType: 'json', |
dataType: 'json', |
||||
type: 'POST', |
type: 'POST', |
||||
contentType: 'application/json', |
contentType: 'application/json', |
||||
headers: { |
headers: { |
||||
'X-Requested-With': 'XMLHttpRequest' |
'X-Requested-With': 'XMLHttpRequest' |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
defaultError: { |
defaultError: { |
||||
message: 'An error has occurred!', |
message: 'An error has occurred!', |
||||
details: 'Error detail not sent by server.' |
details: 'Error detail not sent by server.' |
||||
}, |
}, |
||||
|
|
||||
defaultError401: { |
defaultError401: { |
||||
message: 'You are not authenticated!', |
message: 'You are not authenticated!', |
||||
details: 'You should be authenticated (sign in) in order to perform this operation.' |
details: 'You should be authenticated (sign in) in order to perform this operation.' |
||||
}, |
}, |
||||
|
|
||||
defaultError403: { |
defaultError403: { |
||||
message: 'You are not authorized!', |
message: 'You are not authorized!', |
||||
details: 'You are not allowed to perform this operation.' |
details: 'You are not allowed to perform this operation.' |
||||
}, |
}, |
||||
|
|
||||
defaultError404: { |
defaultError404: { |
||||
message: 'Resource not found!', |
message: 'Resource not found!', |
||||
details: 'The resource requested could not found on the server.' |
details: 'The resource requested could not found on the server.' |
||||
}, |
}, |
||||
|
|
||||
logError: function (error) { |
logError: function (error) { |
||||
abp.log.error(error); |
abp.log.error(error); |
||||
}, |
}, |
||||
|
|
||||
showError: function (error) { |
showError: function (error) { |
||||
if (error.details) { |
if (error.details) { |
||||
return abp.message.error(error.details, error.message); |
return abp.message.error(error.details, error.message); |
||||
} else { |
} else { |
||||
return abp.message.error(error.message || abp.ajax.defaultError.message); |
return abp.message.error(error.message || abp.ajax.defaultError.message); |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
handleTargetUrl: function (targetUrl) { |
handleTargetUrl: function (targetUrl) { |
||||
if (!targetUrl) { |
if (!targetUrl) { |
||||
location.href = abp.appPath; |
location.href = abp.appPath; |
||||
} else { |
} else { |
||||
location.href = targetUrl; |
location.href = targetUrl; |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
handleErrorStatusCode: function (status) { |
handleErrorStatusCode: function (status) { |
||||
switch (status) { |
switch (status) { |
||||
case 401: |
case 401: |
||||
abp.ajax.handleUnAuthorizedRequest( |
abp.ajax.handleUnAuthorizedRequest( |
||||
abp.ajax.showError(abp.ajax.defaultError401), |
abp.ajax.showError(abp.ajax.defaultError401), |
||||
abp.appPath |
abp.appPath |
||||
); |
); |
||||
break; |
break; |
||||
case 403: |
case 403: |
||||
abp.ajax.showError(abp.ajax.defaultError403); |
abp.ajax.showError(abp.ajax.defaultError403); |
||||
break; |
break; |
||||
case 404: |
case 404: |
||||
abp.ajax.showError(abp.ajax.defaultError404); |
abp.ajax.showError(abp.ajax.defaultError404); |
||||
break; |
break; |
||||
default: |
default: |
||||
abp.ajax.showError(abp.ajax.defaultError); |
abp.ajax.showError(abp.ajax.defaultError); |
||||
break; |
break; |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
handleNonAbpErrorResponse: function (jqXHR, userOptions, $dfd) { |
handleNonAbpErrorResponse: function (jqXHR, userOptions, $dfd) { |
||||
if (userOptions.abpHandleError !== false) { |
if (userOptions.abpHandleError !== false) { |
||||
abp.ajax.handleErrorStatusCode(jqXHR.status); |
abp.ajax.handleErrorStatusCode(jqXHR.status); |
||||
} |
} |
||||
|
|
||||
$dfd.reject.apply(this, arguments); |
$dfd.reject.apply(this, arguments); |
||||
userOptions.error && userOptions.error.apply(this, arguments); |
userOptions.error && userOptions.error.apply(this, arguments); |
||||
}, |
}, |
||||
|
|
||||
handleAbpErrorResponse: function (jqXHR, userOptions, $dfd) { |
handleAbpErrorResponse: function (jqXHR, userOptions, $dfd) { |
||||
var messagePromise = null; |
var messagePromise = null; |
||||
|
|
||||
if (userOptions.abpHandleError !== false) { |
if (userOptions.abpHandleError !== false) { |
||||
messagePromise = abp.ajax.showError(jqXHR.responseJSON.error); |
messagePromise = abp.ajax.showError(jqXHR.responseJSON.error); |
||||
} |
} |
||||
|
|
||||
abp.ajax.logError(jqXHR.responseJSON.error); |
abp.ajax.logError(jqXHR.responseJSON.error); |
||||
|
|
||||
$dfd && $dfd.reject(jqXHR.responseJSON.error, jqXHR); |
$dfd && $dfd.reject(jqXHR.responseJSON.error, jqXHR); |
||||
userOptions.error && userOptions.error(jqXHR.responseJSON.error, jqXHR); |
userOptions.error && userOptions.error(jqXHR.responseJSON.error, jqXHR); |
||||
|
|
||||
if (jqXHR.status === 401 && userOptions.abpHandleError !== false) { |
if (jqXHR.status === 401 && userOptions.abpHandleError !== false) { |
||||
abp.ajax.handleUnAuthorizedRequest(messagePromise); |
abp.ajax.handleUnAuthorizedRequest(messagePromise); |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
handleUnAuthorizedRequest: function (messagePromise, targetUrl) { |
handleUnAuthorizedRequest: function (messagePromise, targetUrl) { |
||||
if (messagePromise) { |
if (messagePromise) { |
||||
messagePromise.done(function () { |
messagePromise.done(function () { |
||||
abp.ajax.handleTargetUrl(targetUrl); |
abp.ajax.handleTargetUrl(targetUrl); |
||||
}); |
}); |
||||
} else { |
} else { |
||||
abp.ajax.handleTargetUrl(targetUrl); |
abp.ajax.handleTargetUrl(targetUrl); |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
blockUI: function (options) { |
blockUI: function (options) { |
||||
if (options.blockUI) { |
if (options.blockUI) { |
||||
if (options.blockUI === true) { //block whole page
|
if (options.blockUI === true) { //block whole page
|
||||
abp.ui.setBusy(); |
abp.ui.setBusy(); |
||||
} else { //block an element
|
} else { //block an element
|
||||
abp.ui.setBusy(options.blockUI); |
abp.ui.setBusy(options.blockUI); |
||||
} |
} |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
unblockUI: function (options) { |
unblockUI: function (options) { |
||||
if (options.blockUI) { |
if (options.blockUI) { |
||||
if (options.blockUI === true) { //unblock whole page
|
if (options.blockUI === true) { //unblock whole page
|
||||
abp.ui.clearBusy(); |
abp.ui.clearBusy(); |
||||
} else { //unblock an element
|
} else { //unblock an element
|
||||
abp.ui.clearBusy(options.blockUI); |
abp.ui.clearBusy(options.blockUI); |
||||
} |
} |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
ajaxSendHandler: function (event, request, settings) { |
ajaxSendHandler: function (event, request, settings) { |
||||
var token = abp.security.antiForgery.getToken(); |
var token = abp.security.antiForgery.getToken(); |
||||
if (!token) { |
if (!token) { |
||||
return; |
return; |
||||
} |
} |
||||
|
|
||||
if (!settings.headers || settings.headers[abp.security.antiForgery.tokenHeaderName] === undefined) { |
if (!settings.headers || settings.headers[abp.security.antiForgery.tokenHeaderName] === undefined) { |
||||
request.setRequestHeader(abp.security.antiForgery.tokenHeaderName, token); |
request.setRequestHeader(abp.security.antiForgery.tokenHeaderName, token); |
||||
} |
} |
||||
} |
} |
||||
}); |
}); |
||||
|
|
||||
$(document).ajaxSend(function (event, request, settings) { |
$(document).ajaxSend(function (event, request, settings) { |
||||
return abp.ajax.ajaxSendHandler(event, request, settings); |
return abp.ajax.ajaxSendHandler(event, request, settings); |
||||
}); |
}); |
||||
|
|
||||
abp.event.on('abp.configurationInitialized', function () { |
abp.event.on('abp.configurationInitialized', function () { |
||||
var l = abp.localization.getResource('AbpUi'); |
var l = abp.localization.getResource('AbpUi'); |
||||
|
|
||||
abp.ajax.defaultError.message = l('DefaultErrorMessage'); |
abp.ajax.defaultError.message = l('DefaultErrorMessage'); |
||||
abp.ajax.defaultError.details = l('DefaultErrorMessageDetail'); |
abp.ajax.defaultError.details = l('DefaultErrorMessageDetail'); |
||||
abp.ajax.defaultError401.message = l('DefaultErrorMessage401'); |
abp.ajax.defaultError401.message = l('DefaultErrorMessage401'); |
||||
abp.ajax.defaultError401.details = l('DefaultErrorMessage401Detail'); |
abp.ajax.defaultError401.details = l('DefaultErrorMessage401Detail'); |
||||
abp.ajax.defaultError403.message = l('DefaultErrorMessage403'); |
abp.ajax.defaultError403.message = l('DefaultErrorMessage403'); |
||||
abp.ajax.defaultError403.details = l('DefaultErrorMessage403Detail'); |
abp.ajax.defaultError403.details = l('DefaultErrorMessage403Detail'); |
||||
abp.ajax.defaultError404.message = l('DefaultErrorMessage404'); |
abp.ajax.defaultError404.message = l('DefaultErrorMessage404'); |
||||
abp.ajax.defaultError404.details = l('DefaultErrorMessage404Detail'); |
abp.ajax.defaultError404.details = l('DefaultErrorMessage404Detail'); |
||||
}); |
}); |
||||
|
|
||||
// RESOURCE LOADER ////////////////////////////////////////////////////////
|
// RESOURCE LOADER ////////////////////////////////////////////////////////
|
||||
|
|
||||
/* UrlStates enum */ |
/* UrlStates enum */ |
||||
var UrlStates = { |
var UrlStates = { |
||||
LOADING: 'LOADING', |
LOADING: 'LOADING', |
||||
LOADED: 'LOADED', |
LOADED: 'LOADED', |
||||
FAILED: 'FAILED' |
FAILED: 'FAILED' |
||||
}; |
}; |
||||
|
|
||||
/* UrlInfo class */ |
/* UrlInfo class */ |
||||
function UrlInfo(url) { |
function UrlInfo(url) { |
||||
this.url = url; |
this.url = url; |
||||
this.state = UrlStates.LOADING; |
this.state = UrlStates.LOADING; |
||||
this.loadCallbacks = []; |
this.loadCallbacks = []; |
||||
this.failCallbacks = []; |
this.failCallbacks = []; |
||||
} |
} |
||||
|
|
||||
UrlInfo.prototype.succeed = function () { |
UrlInfo.prototype.succeed = function () { |
||||
this.state = UrlStates.LOADED; |
this.state = UrlStates.LOADED; |
||||
for (var i = 0; i < this.loadCallbacks.length; i++) { |
for (var i = 0; i < this.loadCallbacks.length; i++) { |
||||
this.loadCallbacks[i](); |
this.loadCallbacks[i](); |
||||
} |
} |
||||
}; |
}; |
||||
|
|
||||
UrlInfo.prototype.failed = function () { |
UrlInfo.prototype.failed = function () { |
||||
this.state = UrlStates.FAILED; |
this.state = UrlStates.FAILED; |
||||
for (var i = 0; i < this.failCallbacks.length; i++) { |
for (var i = 0; i < this.failCallbacks.length; i++) { |
||||
this.failCallbacks[i](); |
this.failCallbacks[i](); |
||||
} |
} |
||||
}; |
}; |
||||
|
|
||||
UrlInfo.prototype.handleCallbacks = function (loadCallback, failCallback) { |
UrlInfo.prototype.handleCallbacks = function (loadCallback, failCallback) { |
||||
switch (this.state) { |
switch (this.state) { |
||||
case UrlStates.LOADED: |
case UrlStates.LOADED: |
||||
loadCallback && loadCallback(); |
loadCallback && loadCallback(); |
||||
break; |
break; |
||||
case UrlStates.FAILED: |
case UrlStates.FAILED: |
||||
failCallback && failCallback(); |
failCallback && failCallback(); |
||||
break; |
break; |
||||
case UrlStates.LOADING: |
case UrlStates.LOADING: |
||||
this.addCallbacks(loadCallback, failCallback); |
this.addCallbacks(loadCallback, failCallback); |
||||
break; |
break; |
||||
} |
} |
||||
}; |
}; |
||||
|
|
||||
UrlInfo.prototype.addCallbacks = function (loadCallback, failCallback) { |
UrlInfo.prototype.addCallbacks = function (loadCallback, failCallback) { |
||||
loadCallback && this.loadCallbacks.push(loadCallback); |
loadCallback && this.loadCallbacks.push(loadCallback); |
||||
failCallback && this.failCallbacks.push(failCallback); |
failCallback && this.failCallbacks.push(failCallback); |
||||
}; |
}; |
||||
|
|
||||
/* ResourceLoader API */ |
/* ResourceLoader API */ |
||||
|
|
||||
abp.ResourceLoader = (function () { |
abp.ResourceLoader = (function () { |
||||
|
|
||||
var _urlInfos = {}; |
var _urlInfos = {}; |
||||
|
|
||||
function getCacheKey(url) { |
function getCacheKey(url) { |
||||
return url; |
return url; |
||||
} |
} |
||||
|
|
||||
function appendTimeToUrl(url) { |
function appendTimeToUrl(url) { |
||||
|
|
||||
if (url.indexOf('?') < 0) { |
if (url.indexOf('?') < 0) { |
||||
url += '?'; |
url += '?'; |
||||
} else { |
} else { |
||||
url += '&'; |
url += '&'; |
||||
} |
} |
||||
|
|
||||
url += '_=' + new Date().getTime(); |
url += '_=' + new Date().getTime(); |
||||
|
|
||||
return url; |
return url; |
||||
} |
} |
||||
|
|
||||
var _loadFromUrl = function (url, loadCallback, failCallback, serverLoader) { |
var _loadFromUrl = function (url, loadCallback, failCallback, serverLoader) { |
||||
|
|
||||
var cacheKey = getCacheKey(url); |
var cacheKey = getCacheKey(url); |
||||
|
|
||||
var urlInfo = _urlInfos[cacheKey]; |
var urlInfo = _urlInfos[cacheKey]; |
||||
|
|
||||
if (urlInfo) { |
if (urlInfo) { |
||||
urlInfo.handleCallbacks(loadCallback, failCallback); |
urlInfo.handleCallbacks(loadCallback, failCallback); |
||||
return; |
return; |
||||
} |
} |
||||
|
|
||||
_urlInfos[cacheKey] = urlInfo = new UrlInfo(url); |
_urlInfos[cacheKey] = urlInfo = new UrlInfo(url); |
||||
urlInfo.addCallbacks(loadCallback, failCallback); |
urlInfo.addCallbacks(loadCallback, failCallback); |
||||
|
|
||||
serverLoader(urlInfo); |
serverLoader(urlInfo); |
||||
}; |
}; |
||||
|
|
||||
var _loadScript = function (url, loadCallback, failCallback) { |
var _loadScript = function (url, loadCallback, failCallback) { |
||||
_loadFromUrl(url, loadCallback, failCallback, function (urlInfo) { |
_loadFromUrl(url, loadCallback, failCallback, function (urlInfo) { |
||||
$.getScript(url) |
$.get({ |
||||
.done(function () { |
url: url, |
||||
urlInfo.succeed(); |
dataType: 'text' |
||||
}) |
}) |
||||
.fail(function () { |
.done(function (script) { |
||||
urlInfo.failed(); |
$.globalEval(script); |
||||
}); |
urlInfo.succeed(); |
||||
}); |
}) |
||||
}; |
.fail(function () { |
||||
|
urlInfo.failed(); |
||||
var _loadStyle = function (url) { |
}); |
||||
_loadFromUrl(url, undefined, undefined, function (urlInfo) { |
}); |
||||
|
}; |
||||
$('<link/>', { |
|
||||
rel: 'stylesheet', |
var _loadStyle = function (url) { |
||||
type: 'text/css', |
_loadFromUrl(url, undefined, undefined, function (urlInfo) { |
||||
href: appendTimeToUrl(url) |
|
||||
}).appendTo('head'); |
$('<link/>', { |
||||
}); |
rel: 'stylesheet', |
||||
}; |
type: 'text/css', |
||||
|
href: appendTimeToUrl(url) |
||||
return { |
}).appendTo('head'); |
||||
loadScript: _loadScript, |
}); |
||||
loadStyle: _loadStyle |
}; |
||||
} |
|
||||
})(); |
return { |
||||
|
loadScript: _loadScript, |
||||
|
loadStyle: _loadStyle |
||||
|
} |
||||
|
})(); |
||||
|
|
||||
})(jQuery); |
})(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", |
"name": "malihu-custom-scrollbar-plugin", |
||||
"version": "3.1.5", |
"version": "3.1.5", |
||||
"author": "malihu (http://manos.malihu.gr)", |
"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.", |
"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", |
"license": "MIT", |
||||
"homepage": "http://manos.malihu.gr/jquery-custom-content-scroller", |
"homepage": "http://manos.malihu.gr/jquery-custom-content-scroller", |
||||
"main": "./jquery.mCustomScrollbar.js", |
"main": "./jquery.mCustomScrollbar.js", |
||||
"repository": { |
"repository": { |
||||
"type": "git", |
"type": "git", |
||||
"url": "https://github.com/malihu/malihu-custom-scrollbar-plugin.git" |
"url": "https://github.com/malihu/malihu-custom-scrollbar-plugin.git" |
||||
}, |
}, |
||||
"bugs": { |
"bugs": { |
||||
"url": "https://github.com/malihu/malihu-custom-scrollbar-plugin/issues" |
"url": "https://github.com/malihu/malihu-custom-scrollbar-plugin/issues" |
||||
}, |
}, |
||||
"keywords": [ |
"keywords": [ |
||||
"jquery-plugin", |
"jquery-plugin", |
||||
"custom-scrollbar", |
"custom-scrollbar", |
||||
"scrollbar" |
"scrollbar" |
||||
], |
], |
||||
"files": [ |
"files": [ |
||||
"jquery.mCustomScrollbar.js", |
"jquery.mCustomScrollbar.js", |
||||
"jquery.mCustomScrollbar.concat.min.js", |
"jquery.mCustomScrollbar.concat.min.js", |
||||
"jquery.mCustomScrollbar.css", |
"jquery.mCustomScrollbar.css", |
||||
"mCSB_buttons.png", |
"mCSB_buttons.png", |
||||
"readme.md" |
"readme.md" |
||||
], |
], |
||||
"jam": { |
"jam": { |
||||
"dependencies": { |
"dependencies": { |
||||
"jquery": ">=1.6", |
"jquery": ">=1.6", |
||||
"jquery-mousewheel": ">=3.0.6" |
"jquery-mousewheel": ">=3.0.6" |
||||
} |
} |
||||
}, |
}, |
||||
"dependencies": { |
"dependencies": { |
||||
"jquery-mousewheel": ">=3.0.6" |
"jquery-mousewheel": ">=3.0.6" |
||||
} |
} |
||||
} |
} |
||||
@ -1,82 +1,82 @@ |
|||||
malihu custom scrollbar plugin |
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: |
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) |
* Vertical and/or horizontal scrollbar(s) |
||||
* Adjustable scrolling momentum |
* Adjustable scrolling momentum |
||||
* Mouse-wheel, keyboard and touch support |
* Mouse-wheel, keyboard and touch support |
||||
* Ready-to-use themes and customization via CSS |
* Ready-to-use themes and customization via CSS |
||||
* RTL direction support |
* RTL direction support |
||||
* Option parameters for full control of scrollbar functionality |
* Option parameters for full control of scrollbar functionality |
||||
* Methods for triggering actions like scroll-to, update, destroy etc. |
* Methods for triggering actions like scroll-to, update, destroy etc. |
||||
* User-defined callbacks |
* User-defined callbacks |
||||
* Selectable/searchable content |
* 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/)) |
**[Plugin homepage and documentation](http://manos.malihu.gr/jquery-custom-content-scroller/)** ([Changelog](http://manos.malihu.gr/jquery-custom-content-scroller/2/)) |
||||
|
|
||||
#### Installation |
#### Installation |
||||
|
|
||||
npm: `npm install malihu-custom-scrollbar-plugin` |
npm: `npm install malihu-custom-scrollbar-plugin` |
||||
|
|
||||
Bower: `bower install malihu-custom-scrollbar-plugin` |
Bower: `bower install malihu-custom-scrollbar-plugin` |
||||
|
|
||||
[Manual](http://manos.malihu.gr/jquery-custom-content-scroller/#get-started-section) |
[Manual](http://manos.malihu.gr/jquery-custom-content-scroller/#get-started-section) |
||||
|
|
||||
#### Usage |
#### Usage |
||||
|
|
||||
Manual: `$(selector).mCustomScrollbar();` |
Manual: `$(selector).mCustomScrollbar();` |
||||
|
|
||||
[Browserify](http://browserify.org/): |
[Browserify](http://browserify.org/): |
||||
|
|
||||
var $ = require('jquery'); |
var $ = require('jquery'); |
||||
require('malihu-custom-scrollbar-plugin')($); |
require('malihu-custom-scrollbar-plugin')($); |
||||
|
|
||||
[webpack](https://webpack.github.io/): |
[webpack](https://webpack.github.io/): |
||||
|
|
||||
npm install imports-loader |
npm install imports-loader |
||||
npm install jquery-mousewheel |
npm install jquery-mousewheel |
||||
npm install malihu-custom-scrollbar-plugin |
npm install malihu-custom-scrollbar-plugin |
||||
|
|
||||
module.exports = { |
module.exports = { |
||||
module: { |
module: { |
||||
loaders: [ |
loaders: [ |
||||
{ test: /jquery-mousewheel/, loader: "imports?define=>false&this=>window" }, |
{ test: /jquery-mousewheel/, loader: "imports?define=>false&this=>window" }, |
||||
{ test: /malihu-custom-scrollbar-plugin/, loader: "imports?define=>false&this=>window" } |
{ test: /malihu-custom-scrollbar-plugin/, loader: "imports?define=>false&this=>window" } |
||||
] |
] |
||||
} |
} |
||||
}; |
}; |
||||
|
|
||||
var $ = require('jquery'); |
var $ = require('jquery'); |
||||
require("jquery-mousewheel")($); |
require("jquery-mousewheel")($); |
||||
require('malihu-custom-scrollbar-plugin')($); |
require('malihu-custom-scrollbar-plugin')($); |
||||
|
|
||||
|
|
||||
Requirements |
Requirements |
||||
------------------------- |
------------------------- |
||||
|
|
||||
jQuery version **1.6.0** or higher |
jQuery version **1.6.0** or higher |
||||
|
|
||||
Browser compatibility |
Browser compatibility |
||||
------------------------- |
------------------------- |
||||
|
|
||||
* Internet Explorer 8+ |
* Internet Explorer 8+ |
||||
* Firefox |
* Firefox |
||||
* Chrome |
* Chrome |
||||
* Opera |
* Opera |
||||
* Safari |
* Safari |
||||
* iOS |
* iOS |
||||
* Android |
* Android |
||||
* Windows Phone |
* Windows Phone |
||||
|
|
||||
License |
License |
||||
------------------------- |
------------------------- |
||||
|
|
||||
MIT License (MIT) |
MIT License (MIT) |
||||
|
|
||||
http://opensource.org/licenses/MIT |
http://opensource.org/licenses/MIT |
||||
|
|
||||
Donate |
Donate |
||||
------------------------- |
------------------------- |
||||
|
|
||||
https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UYJ5G65M6ZA28 |
https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UYJ5G65M6ZA28 |
||||
Loading…
Reference in new issue