mirror of https://github.com/abpframework/abp.git
340 changed files with 64605 additions and 0 deletions
@ -0,0 +1,13 @@ |
|||||
|
# Editor configuration, see https://editorconfig.org |
||||
|
root = true |
||||
|
|
||||
|
[*] |
||||
|
charset = utf-8 |
||||
|
indent_style = space |
||||
|
indent_size = 2 |
||||
|
insert_final_newline = true |
||||
|
trim_trailing_whitespace = true |
||||
|
|
||||
|
[*.md] |
||||
|
max_line_length = off |
||||
|
trim_trailing_whitespace = false |
||||
@ -0,0 +1,48 @@ |
|||||
|
# See http://help.github.com/ignore-files/ for more about ignoring files. |
||||
|
|
||||
|
# compiled output |
||||
|
/dist |
||||
|
/tmp |
||||
|
/out-tsc |
||||
|
# Only exists if Bazel was run |
||||
|
/bazel-out |
||||
|
|
||||
|
# dependencies |
||||
|
/node_modules |
||||
|
|
||||
|
# profiling files |
||||
|
chrome-profiler-events.json |
||||
|
speed-measure-plugin.json |
||||
|
|
||||
|
# IDEs and editors |
||||
|
/.idea |
||||
|
.project |
||||
|
.classpath |
||||
|
.c9/ |
||||
|
*.launch |
||||
|
.settings/ |
||||
|
*.sublime-workspace |
||||
|
|
||||
|
# IDE - VSCode |
||||
|
.vscode/* |
||||
|
!.vscode/settings.json |
||||
|
!.vscode/tasks.json |
||||
|
!.vscode/launch.json |
||||
|
!.vscode/extensions.json |
||||
|
.history/* |
||||
|
|
||||
|
# misc |
||||
|
/.sass-cache |
||||
|
/connect.lock |
||||
|
/coverage |
||||
|
/libpeerconnection.log |
||||
|
npm-debug.log |
||||
|
yarn-error.log |
||||
|
testem.log |
||||
|
/typings |
||||
|
|
||||
|
# System Files |
||||
|
.DS_Store |
||||
|
Thumbs.db |
||||
|
|
||||
|
yarn.lock* |
||||
@ -0,0 +1 @@ |
|||||
|
@volo:registry=http://192.168.1.45:4873/ |
||||
@ -0,0 +1,27 @@ |
|||||
|
# BookStore |
||||
|
|
||||
|
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.0.3. |
||||
|
|
||||
|
## Development server |
||||
|
|
||||
|
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. |
||||
|
|
||||
|
## Code scaffolding |
||||
|
|
||||
|
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. |
||||
|
|
||||
|
## Build |
||||
|
|
||||
|
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. |
||||
|
|
||||
|
## Running unit tests |
||||
|
|
||||
|
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). |
||||
|
|
||||
|
## Running end-to-end tests |
||||
|
|
||||
|
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). |
||||
|
|
||||
|
## Further help |
||||
|
|
||||
|
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). |
||||
@ -0,0 +1,135 @@ |
|||||
|
{ |
||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json", |
||||
|
"version": 1, |
||||
|
"newProjectRoot": "projects", |
||||
|
"projects": { |
||||
|
"myProjectName": { |
||||
|
"projectType": "application", |
||||
|
"schematics": { |
||||
|
"@schematics/angular:component": { |
||||
|
"style": "scss" |
||||
|
} |
||||
|
}, |
||||
|
"root": "", |
||||
|
"sourceRoot": "src", |
||||
|
"prefix": "app", |
||||
|
"architect": { |
||||
|
"build": { |
||||
|
"builder": "@angular-devkit/build-angular:browser", |
||||
|
"options": { |
||||
|
"outputPath": "dist/myProjectName", |
||||
|
"index": "src/index.html", |
||||
|
"main": "src/main.ts", |
||||
|
"polyfills": "src/polyfills.ts", |
||||
|
"tsConfig": "tsconfig.app.json", |
||||
|
"aot": false, |
||||
|
"assets": ["src/favicon.ico", "src/assets"], |
||||
|
"styles": [ |
||||
|
"src/styles.scss", |
||||
|
"node_modules/bootstrap/dist/css/bootstrap.min.css", |
||||
|
"node_modules/font-awesome/css/font-awesome.min.css", |
||||
|
"node_modules/primeng/resources/themes/nova-light/theme.css", |
||||
|
"node_modules/primeicons/primeicons.css", |
||||
|
"node_modules/primeng/resources/primeng.min.css" |
||||
|
], |
||||
|
"scripts": [] |
||||
|
}, |
||||
|
"configurations": { |
||||
|
"production": { |
||||
|
"fileReplacements": [ |
||||
|
{ |
||||
|
"replace": "src/environments/environment.ts", |
||||
|
"with": "src/environments/environment.prod.ts" |
||||
|
} |
||||
|
], |
||||
|
"optimization": true, |
||||
|
"outputHashing": "all", |
||||
|
"sourceMap": false, |
||||
|
"extractCss": true, |
||||
|
"namedChunks": false, |
||||
|
"aot": true, |
||||
|
"extractLicenses": true, |
||||
|
"vendorChunk": false, |
||||
|
"buildOptimizer": true, |
||||
|
"budgets": [ |
||||
|
{ |
||||
|
"type": "initial", |
||||
|
"maximumWarning": "2mb", |
||||
|
"maximumError": "5mb" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
"hmr": { |
||||
|
"fileReplacements": [ |
||||
|
{ |
||||
|
"replace": "src/environments/environment.ts", |
||||
|
"with": "src/environments/environment.hmr.ts" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"serve": { |
||||
|
"builder": "@angular-devkit/build-angular:dev-server", |
||||
|
"options": { |
||||
|
"browserTarget": "myProjectName:build" |
||||
|
}, |
||||
|
"configurations": { |
||||
|
"production": { |
||||
|
"browserTarget": "myProjectName:build:production" |
||||
|
}, |
||||
|
"hmr": { |
||||
|
"hmr": true, |
||||
|
"browserTarget": "myProjectName:build:hmr" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"extract-i18n": { |
||||
|
"builder": "@angular-devkit/build-angular:extract-i18n", |
||||
|
"options": { |
||||
|
"browserTarget": "myProjectName:build" |
||||
|
} |
||||
|
}, |
||||
|
"test": { |
||||
|
"builder": "@angular-devkit/build-angular:karma", |
||||
|
"options": { |
||||
|
"main": "src/test.ts", |
||||
|
"polyfills": "src/polyfills.ts", |
||||
|
"tsConfig": "tsconfig.spec.json", |
||||
|
"karmaConfig": "karma.conf.js", |
||||
|
"assets": ["src/favicon.ico", "src/assets"], |
||||
|
"styles": [ |
||||
|
"src/styles.scss", |
||||
|
"node_modules/bootstrap/dist/css/bootstrap.min.css", |
||||
|
"node_modules/font-awesome/css/font-awesome.min.css", |
||||
|
"node_modules/primeng/resources/themes/nova-light/theme.css", |
||||
|
"node_modules/primeicons/primeicons.css", |
||||
|
"node_modules/primeng/resources/primeng.min.css" |
||||
|
], |
||||
|
"scripts": [] |
||||
|
} |
||||
|
}, |
||||
|
"lint": { |
||||
|
"builder": "@angular-devkit/build-angular:tslint", |
||||
|
"options": { |
||||
|
"tsConfig": ["tsconfig.app.json", "tsconfig.spec.json", "e2e/tsconfig.json"], |
||||
|
"exclude": ["**/node_modules/**"] |
||||
|
} |
||||
|
}, |
||||
|
"e2e": { |
||||
|
"builder": "@angular-devkit/build-angular:protractor", |
||||
|
"options": { |
||||
|
"protractorConfig": "e2e/protractor.conf.js", |
||||
|
"devServerTarget": "myProjectName:serve" |
||||
|
}, |
||||
|
"configurations": { |
||||
|
"production": { |
||||
|
"devServerTarget": "myProjectName:serve:production" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"defaultProject": "myProjectName" |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. |
||||
|
# For additional information regarding the format and rule options, please see: |
||||
|
# https://github.com/browserslist/browserslist#queries |
||||
|
|
||||
|
# You can see what browsers were selected by your queries by running: |
||||
|
# npx browserslist |
||||
|
|
||||
|
> 0.5% |
||||
|
last 2 versions |
||||
|
Firefox ESR |
||||
|
not dead |
||||
|
not IE 9-11 # For IE 9-11 support, remove 'not'. |
||||
@ -0,0 +1,32 @@ |
|||||
|
// @ts-check
|
||||
|
// Protractor configuration file, see link for more information
|
||||
|
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
|
||||
|
const { SpecReporter } = require('jasmine-spec-reporter'); |
||||
|
|
||||
|
/** |
||||
|
* @type { import("protractor").Config } |
||||
|
*/ |
||||
|
exports.config = { |
||||
|
allScriptsTimeout: 11000, |
||||
|
specs: [ |
||||
|
'./src/**/*.e2e-spec.ts' |
||||
|
], |
||||
|
capabilities: { |
||||
|
'browserName': 'chrome' |
||||
|
}, |
||||
|
directConnect: true, |
||||
|
baseUrl: 'http://localhost:4200/', |
||||
|
framework: 'jasmine', |
||||
|
jasmineNodeOpts: { |
||||
|
showColors: true, |
||||
|
defaultTimeoutInterval: 30000, |
||||
|
print: function() {} |
||||
|
}, |
||||
|
onPrepare() { |
||||
|
require('ts-node').register({ |
||||
|
project: require('path').join(__dirname, './tsconfig.json') |
||||
|
}); |
||||
|
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); |
||||
|
} |
||||
|
}; |
||||
@ -0,0 +1,23 @@ |
|||||
|
import { AppPage } from './app.po'; |
||||
|
import { browser, logging } from 'protractor'; |
||||
|
|
||||
|
describe('workspace-project App', () => { |
||||
|
let page: AppPage; |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
page = new AppPage(); |
||||
|
}); |
||||
|
|
||||
|
it('should display welcome message', () => { |
||||
|
page.navigateTo(); |
||||
|
expect(page.getTitleText()).toEqual('Welcome to myProjectName!'); |
||||
|
}); |
||||
|
|
||||
|
afterEach(async () => { |
||||
|
// Assert that there are no errors emitted from the browser
|
||||
|
const logs = await browser.manage().logs().get(logging.Type.BROWSER); |
||||
|
expect(logs).not.toContain(jasmine.objectContaining({ |
||||
|
level: logging.Level.SEVERE, |
||||
|
} as logging.Entry)); |
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,11 @@ |
|||||
|
import { browser, by, element } from 'protractor'; |
||||
|
|
||||
|
export class AppPage { |
||||
|
navigateTo() { |
||||
|
return browser.get(browser.baseUrl) as Promise<any>; |
||||
|
} |
||||
|
|
||||
|
getTitleText() { |
||||
|
return element(by.css('app-root h1')).getText() as Promise<string>; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
{ |
||||
|
"extends": "../tsconfig.json", |
||||
|
"compilerOptions": { |
||||
|
"outDir": "../out-tsc/e2e", |
||||
|
"module": "commonjs", |
||||
|
"target": "es5", |
||||
|
"types": [ |
||||
|
"jasmine", |
||||
|
"jasminewd2", |
||||
|
"node" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
// Karma configuration file, see link for more information
|
||||
|
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
|
||||
|
module.exports = function (config) { |
||||
|
config.set({ |
||||
|
basePath: '', |
||||
|
frameworks: ['jasmine', '@angular-devkit/build-angular'], |
||||
|
plugins: [ |
||||
|
require('karma-jasmine'), |
||||
|
require('karma-chrome-launcher'), |
||||
|
require('karma-jasmine-html-reporter'), |
||||
|
require('karma-coverage-istanbul-reporter'), |
||||
|
require('@angular-devkit/build-angular/plugins/karma') |
||||
|
], |
||||
|
client: { |
||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
|
}, |
||||
|
coverageIstanbulReporter: { |
||||
|
dir: require('path').join(__dirname, './coverage/myProjectName'), |
||||
|
reports: ['html', 'lcovonly', 'text-summary'], |
||||
|
fixWebpackSourcePaths: true |
||||
|
}, |
||||
|
reporters: ['progress', 'kjhtml'], |
||||
|
port: 9876, |
||||
|
colors: true, |
||||
|
logLevel: config.LOG_INFO, |
||||
|
autoWatch: true, |
||||
|
browsers: ['Chrome'], |
||||
|
singleRun: false, |
||||
|
restartOnFileChange: true |
||||
|
}); |
||||
|
}; |
||||
@ -0,0 +1,56 @@ |
|||||
|
{ |
||||
|
"name": "my-project-name", |
||||
|
"version": "0.0.0", |
||||
|
"scripts": { |
||||
|
"ng": "ng", |
||||
|
"start": "ng serve", |
||||
|
"start:hmr": "ng serve --configuration hmr", |
||||
|
"build": "ng build", |
||||
|
"build:prod": "ng build --configuration production", |
||||
|
"test": "ng test", |
||||
|
"lint": "ng lint", |
||||
|
"e2e": "ng e2e" |
||||
|
}, |
||||
|
"private": true, |
||||
|
"dependencies": { |
||||
|
"@abp/ng.account": "^0.8.0", |
||||
|
"@abp/ng.identity": "^0.8.0", |
||||
|
"@abp/ng.tenant-management": "^0.8.0", |
||||
|
"@abp/ng.theme.basic": "^0.8.0", |
||||
|
"@angular/animations": "~8.1.2", |
||||
|
"@angular/common": "~8.1.2", |
||||
|
"@angular/compiler": "~8.1.2", |
||||
|
"@angular/core": "~8.1.2", |
||||
|
"@angular/forms": "~8.1.2", |
||||
|
"@angular/platform-browser": "~8.1.2", |
||||
|
"@angular/platform-browser-dynamic": "~8.1.2", |
||||
|
"@angular/router": "~8.1.2", |
||||
|
"@angularclass/hmr": "^2.1.3", |
||||
|
"@ngxs/devtools-plugin": "^3.5.0", |
||||
|
"@ngxs/hmr-plugin": "^3.5.0", |
||||
|
"rxjs": "^6.4.0", |
||||
|
"tslib": "^1.9.0", |
||||
|
"zone.js": "~0.9.1" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"@angular-devkit/build-angular": "~0.801.2", |
||||
|
"@angular/cli": "~8.1.2", |
||||
|
"@angular/compiler-cli": "~8.1.2", |
||||
|
"@angular/language-service": "~8.1.2", |
||||
|
"@types/jasmine": "~3.3.8", |
||||
|
"@types/jasminewd2": "~2.0.3", |
||||
|
"@types/node": "~8.9.4", |
||||
|
"codelyzer": "^5.0.0", |
||||
|
"jasmine-core": "~3.4.0", |
||||
|
"jasmine-spec-reporter": "~4.2.1", |
||||
|
"karma": "~4.1.0", |
||||
|
"karma-chrome-launcher": "~2.2.0", |
||||
|
"karma-coverage-istanbul-reporter": "~2.0.1", |
||||
|
"karma-jasmine": "~2.0.1", |
||||
|
"karma-jasmine-html-reporter": "^1.4.0", |
||||
|
"protractor": "~5.4.0", |
||||
|
"ts-node": "~7.0.0", |
||||
|
"tslint": "~5.15.0", |
||||
|
"typescript": "~3.4.3" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
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'; |
||||
|
|
||||
|
const routes: Routes = [ |
||||
|
{ path: '', redirectTo: '/home', pathMatch: 'full' }, |
||||
|
{ |
||||
|
path: 'home', |
||||
|
loadChildren: () => import('./home/home.module').then(m => m.HomeModule), |
||||
|
data: { |
||||
|
routes: { |
||||
|
name: 'Home', |
||||
|
} as ABP.Route, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
path: 'account', |
||||
|
loadChildren: () => import('./lazy-libs/account-wrapper.module').then(m => m.AccountWrapperModule), |
||||
|
data: { routes: ACCOUNT_ROUTES }, |
||||
|
}, |
||||
|
{ |
||||
|
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), |
||||
|
data: { routes: TENANT_MANAGEMENT_ROUTES }, |
||||
|
}, |
||||
|
{ path: '**', redirectTo: '/' }, |
||||
|
]; |
||||
|
|
||||
|
@NgModule({ |
||||
|
imports: [RouterModule.forRoot(routes)], |
||||
|
exports: [RouterModule], |
||||
|
}) |
||||
|
export class AppRoutingModule {} |
||||
@ -0,0 +1,12 @@ |
|||||
|
import { Component } from '@angular/core'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'app-root', |
||||
|
template: ` |
||||
|
<abp-loader-bar></abp-loader-bar> |
||||
|
<router-outlet></router-outlet> |
||||
|
`,
|
||||
|
}) |
||||
|
export class AppComponent { |
||||
|
title = 'myProjectName'; |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
import { CoreModule } from '@abp/ng.core'; |
||||
|
import { LAYOUTS } from '@abp/ng.theme.basic'; |
||||
|
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 { 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'; |
||||
|
|
||||
|
@NgModule({ |
||||
|
declarations: [AppComponent], |
||||
|
imports: [ |
||||
|
BrowserModule, |
||||
|
BrowserAnimationsModule, |
||||
|
AppRoutingModule, |
||||
|
SharedModule, |
||||
|
ThemeSharedModule.forRoot(), |
||||
|
CoreModule.forRoot({ |
||||
|
environment, |
||||
|
requirements: { |
||||
|
layouts: LAYOUTS, |
||||
|
}, |
||||
|
}), |
||||
|
OAuthModule.forRoot(), |
||||
|
NgxsModule.forRoot([]), |
||||
|
NgxsReduxDevtoolsPluginModule.forRoot({ disabled: environment.production }), |
||||
|
], |
||||
|
providers: [], |
||||
|
bootstrap: [AppComponent], |
||||
|
}) |
||||
|
export class AppModule {} |
||||
@ -0,0 +1,18 @@ |
|||||
|
import { NgModule } from '@angular/core'; |
||||
|
import { Routes, RouterModule } from '@angular/router'; |
||||
|
import { HomeComponent } from './home.component'; |
||||
|
import { LayoutApplicationComponent } from '@abp/ng.theme.basic'; |
||||
|
|
||||
|
const routes: Routes = [ |
||||
|
{ |
||||
|
path: '', |
||||
|
component: LayoutApplicationComponent, |
||||
|
children: [{ path: '', component: HomeComponent }], |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
@NgModule({ |
||||
|
imports: [RouterModule.forChild(routes)], |
||||
|
exports: [RouterModule], |
||||
|
}) |
||||
|
export class HomeRoutingModule {} |
||||
@ -0,0 +1,16 @@ |
|||||
|
<div class="card"> |
||||
|
<div class="card-header">Welcome</div> |
||||
|
<div class="card-body"> |
||||
|
<p> |
||||
|
Welcome to the application. This is a startup project based on the ABP framework. For more information, visit |
||||
|
abp.io. |
||||
|
</p> |
||||
|
<p *ngIf="!hasLoggedIn"> |
||||
|
<a routerLink="/account/login" [state]="{ redirectUrl: '/home' }" 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> |
||||
|
</div> |
||||
@ -0,0 +1,14 @@ |
|||||
|
import { Component } from '@angular/core'; |
||||
|
import { OAuthService } from 'angular-oauth2-oidc'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'abp-home', |
||||
|
templateUrl: './home.component.html', |
||||
|
}) |
||||
|
export class HomeComponent { |
||||
|
get hasLoggedIn(): boolean { |
||||
|
return this.oAuthService.hasValidAccessToken(); |
||||
|
} |
||||
|
|
||||
|
constructor(private oAuthService: OAuthService) {} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
import { NgModule } from '@angular/core'; |
||||
|
import { SharedModule } from '../shared/shared.module'; |
||||
|
import { HomeRoutingModule } from './home-routing.module'; |
||||
|
import { HomeComponent } from './home.component'; |
||||
|
|
||||
|
@NgModule({ |
||||
|
declarations: [HomeComponent], |
||||
|
imports: [SharedModule, HomeRoutingModule], |
||||
|
}) |
||||
|
export class HomeModule {} |
||||
@ -0,0 +1,7 @@ |
|||||
|
import { NgModule } from '@angular/core'; |
||||
|
import { AccountModule } from '@abp/ng.account'; |
||||
|
|
||||
|
@NgModule({ |
||||
|
imports: [AccountModule], |
||||
|
}) |
||||
|
export class AccountWrapperModule {} |
||||
@ -0,0 +1,7 @@ |
|||||
|
import { NgModule } from '@angular/core'; |
||||
|
import { IdentityModule } from '@abp/ng.identity'; |
||||
|
|
||||
|
@NgModule({ |
||||
|
imports: [IdentityModule], |
||||
|
}) |
||||
|
export class IdentityWrapperModule {} |
||||
@ -0,0 +1,7 @@ |
|||||
|
import { NgModule } from '@angular/core'; |
||||
|
import { TenantManagementModule } from '@abp/ng.tenant-management'; |
||||
|
|
||||
|
@NgModule({ |
||||
|
imports: [TenantManagementModule], |
||||
|
}) |
||||
|
export class TenantManagementWrapperModule {} |
||||
@ -0,0 +1,12 @@ |
|||||
|
import { NgModule } from '@angular/core'; |
||||
|
import { ThemeSharedModule } from '@abp/ng.theme.shared'; |
||||
|
import { CoreModule } from '@abp/ng.core'; |
||||
|
import { ThemeBasicModule } from '@abp/ng.theme.basic'; |
||||
|
|
||||
|
@NgModule({ |
||||
|
declarations: [], |
||||
|
imports: [CoreModule, ThemeSharedModule, ThemeBasicModule], |
||||
|
exports: [CoreModule, ThemeSharedModule, ThemeBasicModule], |
||||
|
providers: [], |
||||
|
}) |
||||
|
export class SharedModule {} |
||||
@ -0,0 +1,21 @@ |
|||||
|
export const environment = { |
||||
|
production: false, |
||||
|
hmr: true, |
||||
|
oAuthConfig: { |
||||
|
issuer: 'https://localhost:44359', |
||||
|
clientId: 'BookStore_ConsoleTestApp', |
||||
|
dummyClientSecret: '1q2w3e*', |
||||
|
scope: 'BookStore', |
||||
|
showDebugInformation: true, |
||||
|
oidc: false, |
||||
|
requireHttps: true, |
||||
|
}, |
||||
|
apis: { |
||||
|
default: { |
||||
|
url: 'https://localhost:44359', |
||||
|
}, |
||||
|
}, |
||||
|
localization: { |
||||
|
defaultResourceName: 'BookStore', |
||||
|
}, |
||||
|
}; |
||||
@ -0,0 +1,21 @@ |
|||||
|
export const environment = { |
||||
|
production: true, |
||||
|
hmr: false, |
||||
|
oAuthConfig: { |
||||
|
issuer: 'https://localhost:44359', |
||||
|
clientId: 'BookStore_ConsoleTestApp', |
||||
|
dummyClientSecret: '1q2w3e*', |
||||
|
scope: 'BookStore', |
||||
|
showDebugInformation: true, |
||||
|
oidc: false, |
||||
|
requireHttps: true, |
||||
|
}, |
||||
|
apis: { |
||||
|
default: { |
||||
|
url: 'https://localhost:44359', |
||||
|
}, |
||||
|
}, |
||||
|
localization: { |
||||
|
defaultResourceName: 'BookStore', |
||||
|
}, |
||||
|
}; |
||||
@ -0,0 +1,21 @@ |
|||||
|
export const environment = { |
||||
|
production: false, |
||||
|
hmr: false, |
||||
|
oAuthConfig: { |
||||
|
issuer: 'https://localhost:44359', |
||||
|
clientId: 'BookStore_ConsoleTestApp', |
||||
|
dummyClientSecret: '1q2w3e*', |
||||
|
scope: 'BookStore', |
||||
|
showDebugInformation: true, |
||||
|
oidc: false, |
||||
|
requireHttps: true, |
||||
|
}, |
||||
|
apis: { |
||||
|
default: { |
||||
|
url: 'https://localhost:44359', |
||||
|
}, |
||||
|
}, |
||||
|
localization: { |
||||
|
defaultResourceName: 'BookStore', |
||||
|
}, |
||||
|
}; |
||||
|
After Width: | Height: | Size: 5.3 KiB |
@ -0,0 +1,16 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="utf-8" /> |
||||
|
<title>BookStore</title> |
||||
|
<base href="/" /> |
||||
|
|
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico" /> |
||||
|
</head> |
||||
|
<body> |
||||
|
<app-root> |
||||
|
<div class="donut centered"></div> |
||||
|
</app-root> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,20 @@ |
|||||
|
import { enableProdMode } from '@angular/core'; |
||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; |
||||
|
import { BootstrapModuleFn as Bootstrap, hmr, WebpackModule } from '@ngxs/hmr-plugin'; |
||||
|
|
||||
|
import { AppModule } from './app/app.module'; |
||||
|
import { environment } from './environments/environment'; |
||||
|
|
||||
|
declare const module: WebpackModule; |
||||
|
|
||||
|
if (environment.production) { |
||||
|
enableProdMode(); |
||||
|
} |
||||
|
|
||||
|
const bootstrap: Bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule); |
||||
|
|
||||
|
if (environment.hmr) { |
||||
|
hmr(module, bootstrap).catch(err => console.error(err)); |
||||
|
} else { |
||||
|
bootstrap().catch(err => console.log(err)); |
||||
|
} |
||||
@ -0,0 +1,63 @@ |
|||||
|
/** |
||||
|
* This file includes polyfills needed by Angular and is loaded before the app. |
||||
|
* You can add your own extra polyfills to this file. |
||||
|
* |
||||
|
* This file is divided into 2 sections: |
||||
|
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. |
||||
|
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main |
||||
|
* file. |
||||
|
* |
||||
|
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that |
||||
|
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), |
||||
|
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. |
||||
|
* |
||||
|
* Learn more in https://angular.io/guide/browser-support
|
||||
|
*/ |
||||
|
|
||||
|
/*************************************************************************************************** |
||||
|
* BROWSER POLYFILLS |
||||
|
*/ |
||||
|
|
||||
|
/** IE10 and IE11 requires the following for NgClass support on SVG elements */ |
||||
|
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||
|
|
||||
|
/** |
||||
|
* Web Animations `@angular/platform-browser/animations` |
||||
|
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. |
||||
|
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). |
||||
|
*/ |
||||
|
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||
|
|
||||
|
/** |
||||
|
* By default, zone.js will patch all possible macroTask and DomEvents |
||||
|
* user can disable parts of macroTask/DomEvents patch by setting following flags |
||||
|
* because those flags need to be set before `zone.js` being loaded, and webpack |
||||
|
* will put import in the top of bundle, so user need to create a separate file |
||||
|
* in this directory (for example: zone-flags.ts), and put the following flags |
||||
|
* into that file, and then add the following code before importing zone.js. |
||||
|
* import './zone-flags.ts'; |
||||
|
* |
||||
|
* The flags allowed in zone-flags.ts are listed here. |
||||
|
* |
||||
|
* The following flags will work for all browsers. |
||||
|
* |
||||
|
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
||||
|
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
||||
|
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||
|
* |
||||
|
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js |
||||
|
* with the following flag, it will bypass `zone.js` patch for IE/Edge |
||||
|
* |
||||
|
* (window as any).__Zone_enable_cross_context_check = true; |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
/*************************************************************************************************** |
||||
|
* Zone JS is required by default for Angular itself. |
||||
|
*/ |
||||
|
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||
|
|
||||
|
|
||||
|
/*************************************************************************************************** |
||||
|
* APPLICATION IMPORTS |
||||
|
*/ |
||||
@ -0,0 +1,27 @@ |
|||||
|
/* You can add global styles to this file, and also import other style files */ |
||||
|
|
||||
|
@keyframes donut-spin { |
||||
|
0% { |
||||
|
transform: rotate(0deg); |
||||
|
} |
||||
|
100% { |
||||
|
transform: rotate(360deg); |
||||
|
} |
||||
|
} |
||||
|
.donut { |
||||
|
display: inline-block; |
||||
|
border: 4px solid rgba(0, 0, 0, 0.1); |
||||
|
border-left-color: #7983ff; |
||||
|
border-radius: 50%; |
||||
|
width: 30px; |
||||
|
height: 30px; |
||||
|
animation: donut-spin 1.2s linear infinite; |
||||
|
|
||||
|
&.centered { |
||||
|
position: fixed; |
||||
|
top: 50%; |
||||
|
left: 50%; |
||||
|
/* bring your own prefixes */ |
||||
|
transform: translate(-50%, -50%); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
|
||||
|
import 'zone.js/dist/zone-testing'; |
||||
|
import { getTestBed } from '@angular/core/testing'; |
||||
|
import { |
||||
|
BrowserDynamicTestingModule, |
||||
|
platformBrowserDynamicTesting |
||||
|
} from '@angular/platform-browser-dynamic/testing'; |
||||
|
|
||||
|
declare const require: any; |
||||
|
|
||||
|
// First, initialize the Angular testing environment.
|
||||
|
getTestBed().initTestEnvironment( |
||||
|
BrowserDynamicTestingModule, |
||||
|
platformBrowserDynamicTesting() |
||||
|
); |
||||
|
// Then we find all the tests.
|
||||
|
const context = require.context('./', true, /\.spec\.ts$/); |
||||
|
// And load the modules.
|
||||
|
context.keys().map(context); |
||||
@ -0,0 +1,9 @@ |
|||||
|
{ |
||||
|
"extends": "./tsconfig.json", |
||||
|
"compilerOptions": { |
||||
|
"outDir": "./out-tsc/app", |
||||
|
"types": ["node"] |
||||
|
}, |
||||
|
"include": ["src/**/*.ts"], |
||||
|
"exclude": ["src/test.ts", "src/**/*.spec.ts"] |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
{ |
||||
|
"compileOnSave": false, |
||||
|
"compilerOptions": { |
||||
|
"baseUrl": "./", |
||||
|
"outDir": "./dist/out-tsc", |
||||
|
"sourceMap": true, |
||||
|
"declaration": false, |
||||
|
"downlevelIteration": true, |
||||
|
"emitDecoratorMetadata": true, |
||||
|
"experimentalDecorators": true, |
||||
|
"module": "esnext", |
||||
|
"moduleResolution": "node", |
||||
|
"importHelpers": true, |
||||
|
"target": "es2015", |
||||
|
"typeRoots": [ |
||||
|
"node_modules/@types" |
||||
|
], |
||||
|
"lib": [ |
||||
|
"es2018", |
||||
|
"dom" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
{ |
||||
|
"extends": "./tsconfig.json", |
||||
|
"compilerOptions": { |
||||
|
"outDir": "./out-tsc/spec", |
||||
|
"types": [ |
||||
|
"jasmine", |
||||
|
"node" |
||||
|
] |
||||
|
}, |
||||
|
"files": [ |
||||
|
"src/test.ts", |
||||
|
"src/polyfills.ts" |
||||
|
], |
||||
|
"include": [ |
||||
|
"src/**/*.spec.ts", |
||||
|
"src/**/*.d.ts" |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,92 @@ |
|||||
|
{ |
||||
|
"extends": "tslint:recommended", |
||||
|
"rules": { |
||||
|
"array-type": false, |
||||
|
"arrow-parens": false, |
||||
|
"deprecation": { |
||||
|
"severity": "warn" |
||||
|
}, |
||||
|
"component-class-suffix": true, |
||||
|
"contextual-lifecycle": true, |
||||
|
"directive-class-suffix": true, |
||||
|
"directive-selector": [ |
||||
|
true, |
||||
|
"attribute", |
||||
|
"app", |
||||
|
"camelCase" |
||||
|
], |
||||
|
"component-selector": [ |
||||
|
true, |
||||
|
"element", |
||||
|
"app", |
||||
|
"kebab-case" |
||||
|
], |
||||
|
"import-blacklist": [ |
||||
|
true, |
||||
|
"rxjs/Rx" |
||||
|
], |
||||
|
"interface-name": false, |
||||
|
"max-classes-per-file": false, |
||||
|
"max-line-length": [ |
||||
|
true, |
||||
|
140 |
||||
|
], |
||||
|
"member-access": false, |
||||
|
"member-ordering": [ |
||||
|
true, |
||||
|
{ |
||||
|
"order": [ |
||||
|
"static-field", |
||||
|
"instance-field", |
||||
|
"static-method", |
||||
|
"instance-method" |
||||
|
] |
||||
|
} |
||||
|
], |
||||
|
"no-consecutive-blank-lines": false, |
||||
|
"no-console": [ |
||||
|
true, |
||||
|
"debug", |
||||
|
"info", |
||||
|
"time", |
||||
|
"timeEnd", |
||||
|
"trace" |
||||
|
], |
||||
|
"no-empty": false, |
||||
|
"no-inferrable-types": [ |
||||
|
true, |
||||
|
"ignore-params" |
||||
|
], |
||||
|
"no-non-null-assertion": true, |
||||
|
"no-redundant-jsdoc": true, |
||||
|
"no-switch-case-fall-through": true, |
||||
|
"no-use-before-declare": true, |
||||
|
"no-var-requires": false, |
||||
|
"object-literal-key-quotes": [ |
||||
|
true, |
||||
|
"as-needed" |
||||
|
], |
||||
|
"object-literal-sort-keys": false, |
||||
|
"ordered-imports": false, |
||||
|
"quotemark": [ |
||||
|
true, |
||||
|
"single" |
||||
|
], |
||||
|
"trailing-comma": false, |
||||
|
"no-conflicting-lifecycle": true, |
||||
|
"no-host-metadata-property": true, |
||||
|
"no-input-rename": true, |
||||
|
"no-inputs-metadata-property": true, |
||||
|
"no-output-native": true, |
||||
|
"no-output-on-prefix": true, |
||||
|
"no-output-rename": true, |
||||
|
"no-outputs-metadata-property": true, |
||||
|
"template-banana-in-box": true, |
||||
|
"template-no-negated-async": true, |
||||
|
"use-lifecycle-interface": true, |
||||
|
"use-pipe-transform-interface": true |
||||
|
}, |
||||
|
"rulesDirectory": [ |
||||
|
"codelyzer" |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1 @@ |
|||||
|
**/wwwroot/libs/** linguist-vendored |
||||
@ -0,0 +1,259 @@ |
|||||
|
## Ignore Visual Studio temporary files, build results, and |
||||
|
## files generated by popular Visual Studio add-ons. |
||||
|
|
||||
|
# User-specific files |
||||
|
*.suo |
||||
|
*.user |
||||
|
*.userosscache |
||||
|
*.sln.docstates |
||||
|
|
||||
|
# User-specific files (MonoDevelop/Xamarin Studio) |
||||
|
*.userprefs |
||||
|
|
||||
|
# Build results |
||||
|
[Dd]ebug/ |
||||
|
[Dd]ebugPublic/ |
||||
|
[Rr]elease/ |
||||
|
[Rr]eleases/ |
||||
|
x64/ |
||||
|
x86/ |
||||
|
bld/ |
||||
|
[Bb]in/ |
||||
|
[Oo]bj/ |
||||
|
[Ll]og/ |
||||
|
|
||||
|
# Visual Studio 2015 cache/options directory |
||||
|
.vs/ |
||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot |
||||
|
#wwwroot/ |
||||
|
|
||||
|
# MSTest test Results |
||||
|
[Tt]est[Rr]esult*/ |
||||
|
[Bb]uild[Ll]og.* |
||||
|
|
||||
|
# NUNIT |
||||
|
*.VisualState.xml |
||||
|
TestResult.xml |
||||
|
|
||||
|
# Build Results of an ATL Project |
||||
|
[Dd]ebugPS/ |
||||
|
[Rr]eleasePS/ |
||||
|
dlldata.c |
||||
|
|
||||
|
# DNX |
||||
|
project.lock.json |
||||
|
artifacts/ |
||||
|
|
||||
|
*_i.c |
||||
|
*_p.c |
||||
|
*_i.h |
||||
|
*.ilk |
||||
|
*.meta |
||||
|
*.obj |
||||
|
*.pch |
||||
|
*.pdb |
||||
|
*.pgc |
||||
|
*.pgd |
||||
|
*.rsp |
||||
|
*.sbr |
||||
|
*.tlb |
||||
|
*.tli |
||||
|
*.tlh |
||||
|
*.tmp |
||||
|
*.tmp_proj |
||||
|
*.log |
||||
|
*.vspscc |
||||
|
*.vssscc |
||||
|
.builds |
||||
|
*.pidb |
||||
|
*.svclog |
||||
|
*.scc |
||||
|
|
||||
|
# Chutzpah Test files |
||||
|
_Chutzpah* |
||||
|
|
||||
|
# Visual C++ cache files |
||||
|
ipch/ |
||||
|
*.aps |
||||
|
*.ncb |
||||
|
*.opendb |
||||
|
*.opensdf |
||||
|
*.sdf |
||||
|
*.cachefile |
||||
|
*.VC.db |
||||
|
*.VC.VC.opendb |
||||
|
|
||||
|
# Visual Studio profiler |
||||
|
*.psess |
||||
|
*.vsp |
||||
|
*.vspx |
||||
|
*.sap |
||||
|
|
||||
|
# TFS 2012 Local Workspace |
||||
|
$tf/ |
||||
|
|
||||
|
# Guidance Automation Toolkit |
||||
|
*.gpState |
||||
|
|
||||
|
# ReSharper is a .NET coding add-in |
||||
|
_ReSharper*/ |
||||
|
*.[Rr]e[Ss]harper |
||||
|
*.DotSettings.user |
||||
|
|
||||
|
# JustCode is a .NET coding add-in |
||||
|
.JustCode |
||||
|
|
||||
|
# TeamCity is a build add-in |
||||
|
_TeamCity* |
||||
|
|
||||
|
# DotCover is a Code Coverage Tool |
||||
|
*.dotCover |
||||
|
|
||||
|
# NCrunch |
||||
|
_NCrunch_* |
||||
|
.*crunch*.local.xml |
||||
|
nCrunchTemp_* |
||||
|
|
||||
|
# MightyMoose |
||||
|
*.mm.* |
||||
|
AutoTest.Net/ |
||||
|
|
||||
|
# Web workbench (sass) |
||||
|
.sass-cache/ |
||||
|
|
||||
|
# Installshield output folder |
||||
|
[Ee]xpress/ |
||||
|
|
||||
|
# DocProject is a documentation generator add-in |
||||
|
DocProject/buildhelp/ |
||||
|
DocProject/Help/*.HxT |
||||
|
DocProject/Help/*.HxC |
||||
|
DocProject/Help/*.hhc |
||||
|
DocProject/Help/*.hhk |
||||
|
DocProject/Help/*.hhp |
||||
|
DocProject/Help/Html2 |
||||
|
DocProject/Help/html |
||||
|
|
||||
|
# Click-Once directory |
||||
|
publish/ |
||||
|
|
||||
|
# Publish Web Output |
||||
|
*.[Pp]ublish.xml |
||||
|
*.azurePubxml |
||||
|
# TODO: Comment the next line if you want to checkin your web deploy settings |
||||
|
# but database connection strings (with potential passwords) will be unencrypted |
||||
|
*.pubxml |
||||
|
*.publishproj |
||||
|
|
||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to |
||||
|
# checkin your Azure Web App publish settings, but sensitive information contained |
||||
|
# in these scripts will be unencrypted |
||||
|
PublishScripts/ |
||||
|
|
||||
|
# NuGet Packages |
||||
|
*.nupkg |
||||
|
# The packages folder can be ignored because of Package Restore |
||||
|
**/packages/* |
||||
|
# except build/, which is used as an MSBuild target. |
||||
|
!**/packages/build/ |
||||
|
# Uncomment if necessary however generally it will be regenerated when needed |
||||
|
#!**/packages/repositories.config |
||||
|
# NuGet v3's project.json files produces more ignoreable files |
||||
|
*.nuget.props |
||||
|
*.nuget.targets |
||||
|
|
||||
|
# Microsoft Azure Build Output |
||||
|
csx/ |
||||
|
*.build.csdef |
||||
|
|
||||
|
# Microsoft Azure Emulator |
||||
|
ecf/ |
||||
|
rcf/ |
||||
|
|
||||
|
# Windows Store app package directories and files |
||||
|
AppPackages/ |
||||
|
BundleArtifacts/ |
||||
|
Package.StoreAssociation.xml |
||||
|
_pkginfo.txt |
||||
|
|
||||
|
# Visual Studio cache files |
||||
|
# files ending in .cache can be ignored |
||||
|
*.[Cc]ache |
||||
|
# but keep track of directories ending in .cache |
||||
|
!*.[Cc]ache/ |
||||
|
|
||||
|
# Others |
||||
|
ClientBin/ |
||||
|
~$* |
||||
|
*~ |
||||
|
*.dbmdl |
||||
|
*.dbproj.schemaview |
||||
|
*.pfx |
||||
|
*.publishsettings |
||||
|
node_modules/ |
||||
|
orleans.codegen.cs |
||||
|
|
||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components |
||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) |
||||
|
#bower_components/ |
||||
|
|
||||
|
# RIA/Silverlight projects |
||||
|
Generated_Code/ |
||||
|
|
||||
|
# Backup & report files from converting an old project file |
||||
|
# to a newer Visual Studio version. Backup files are not needed, |
||||
|
# because we have git ;-) |
||||
|
_UpgradeReport_Files/ |
||||
|
Backup*/ |
||||
|
UpgradeLog*.XML |
||||
|
UpgradeLog*.htm |
||||
|
|
||||
|
# SQL Server files |
||||
|
*.mdf |
||||
|
*.ldf |
||||
|
|
||||
|
# Business Intelligence projects |
||||
|
*.rdl.data |
||||
|
*.bim.layout |
||||
|
*.bim_*.settings |
||||
|
|
||||
|
# Microsoft Fakes |
||||
|
FakesAssemblies/ |
||||
|
|
||||
|
# GhostDoc plugin setting file |
||||
|
*.GhostDoc.xml |
||||
|
|
||||
|
# Node.js Tools for Visual Studio |
||||
|
.ntvs_analysis.dat |
||||
|
|
||||
|
# Visual Studio 6 build log |
||||
|
*.plg |
||||
|
|
||||
|
# Visual Studio 6 workspace options file |
||||
|
*.opt |
||||
|
|
||||
|
# Visual Studio LightSwitch build output |
||||
|
**/*.HTMLClient/GeneratedArtifacts |
||||
|
**/*.DesktopClient/GeneratedArtifacts |
||||
|
**/*.DesktopClient/ModelManifest.xml |
||||
|
**/*.Server/GeneratedArtifacts |
||||
|
**/*.Server/ModelManifest.xml |
||||
|
_Pvt_Extensions |
||||
|
|
||||
|
# Paket dependency manager |
||||
|
.paket/paket.exe |
||||
|
paket-files/ |
||||
|
|
||||
|
# FAKE - F# Make |
||||
|
.fake/ |
||||
|
|
||||
|
# JetBrains Rider |
||||
|
.idea/ |
||||
|
*.sln.iml |
||||
|
|
||||
|
# BookStore |
||||
|
src/Acme.BookStore.Web/Logs/* |
||||
|
src/Acme.BookStore.Web.Host/Logs/* |
||||
|
src/Acme.BookStore.IdentityServer/Logs/* |
||||
|
src/Acme.BookStore.HttpApi.Host/Logs/* |
||||
|
src/Acme.BookStore.HttpApi.Host/Logs/* |
||||
@ -0,0 +1,123 @@ |
|||||
|
|
||||
|
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||
|
# Visual Studio Version 16 |
||||
|
VisualStudioVersion = 16.0.29020.237 |
||||
|
MinimumVisualStudioVersion = 10.0.40219.1 |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Domain", "src\Acme.BookStore.Domain\Acme.BookStore.Domain.csproj", "{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Application", "src\Acme.BookStore.Application\Acme.BookStore.Application.csproj", "{1A94A50E-06DC-43C1-80B5-B662820EC3EB}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CA9AC87F-097E-4F15-8393-4BC07735A5B0}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{04DBDB01-70F4-4E06-B468-8F87850B22BE}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Application.Tests", "test\Acme.BookStore.Application.Tests\Acme.BookStore.Application.Tests.csproj", "{50B2631D-129C-47B3-A587-029CCD6099BC}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.MongoDB", "src\Acme.BookStore.MongoDB\Acme.BookStore.MongoDB.csproj", "{E3444355-D47E-431E-BDD0-DD3A7113B2AE}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Domain.Shared", "src\Acme.BookStore.Domain.Shared\Acme.BookStore.Domain.Shared.csproj", "{42F719ED-8413-4895-B5B4-5AB56079BC66}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Application.Contracts", "src\Acme.BookStore.Application.Contracts\Acme.BookStore.Application.Contracts.csproj", "{520659C8-C734-4298-A3DA-B539DB9DFC0B}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.HttpApi", "src\Acme.BookStore.HttpApi\Acme.BookStore.HttpApi.csproj", "{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.HttpApi.Client", "src\Acme.BookStore.HttpApi.Client\Acme.BookStore.HttpApi.Client.csproj", "{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.TestBase", "test\Acme.BookStore.TestBase\Acme.BookStore.TestBase.csproj", "{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Domain.Tests", "test\Acme.BookStore.Domain.Tests\Acme.BookStore.Domain.Tests.csproj", "{E512F4D9-9375-480F-A2F6-A46509F9D824}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.MongoDB.Tests", "test\Acme.BookStore.MongoDB.Tests\Acme.BookStore.MongoDB.Tests.csproj", "{6015D17B-104B-4EC2-A9B7-D8A40C891458}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.HttpApi.Client.ConsoleTestApp", "test\Acme.BookStore.HttpApi.Client.ConsoleTestApp\Acme.BookStore.HttpApi.Client.ConsoleTestApp.csproj", "{EF480016-9127-4916-8735-D2466BDBC582}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.DbMigrator", "src\Acme.BookStore.DbMigrator\Acme.BookStore.DbMigrator.csproj", "{AA94D832-1CCC-4715-95A9-A483F23A1A5D}" |
||||
|
EndProject |
||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Acme.BookStore.HttpApi.Host", "src\Acme.BookStore.HttpApi.Host\Acme.BookStore.HttpApi.Host.csproj", "{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}" |
||||
|
EndProject |
||||
|
Global |
||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
|
Debug|Any CPU = Debug|Any CPU |
||||
|
Release|Any CPU = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
|
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{6015D17B-104B-4EC2-A9B7-D8A40C891458}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{6015D17B-104B-4EC2-A9B7-D8A40C891458}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{6015D17B-104B-4EC2-A9B7-D8A40C891458}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{6015D17B-104B-4EC2-A9B7-D8A40C891458}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
GlobalSection(SolutionProperties) = preSolution |
||||
|
HideSolutionNode = FALSE |
||||
|
EndGlobalSection |
||||
|
GlobalSection(NestedProjects) = preSolution |
||||
|
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{1A94A50E-06DC-43C1-80B5-B662820EC3EB} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{50B2631D-129C-47B3-A587-029CCD6099BC} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
||||
|
{E3444355-D47E-431E-BDD0-DD3A7113B2AE} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{42F719ED-8413-4895-B5B4-5AB56079BC66} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{520659C8-C734-4298-A3DA-B539DB9DFC0B} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
||||
|
{E512F4D9-9375-480F-A2F6-A46509F9D824} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
||||
|
{6015D17B-104B-4EC2-A9B7-D8A40C891458} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
||||
|
{EF480016-9127-4916-8735-D2466BDBC582} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
||||
|
{AA94D832-1CCC-4715-95A9-A483F23A1A5D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ExtensibilityGlobals) = postSolution |
||||
|
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} |
||||
|
EndGlobalSection |
||||
|
EndGlobal |
||||
@ -0,0 +1,7 @@ |
|||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> |
||||
|
<s:Boolean x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=59923913AE66194DB837F628B1FC08BE/@KeyIndexDefined">True</s:Boolean> |
||||
|
<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=59923913AE66194DB837F628B1FC08BE/AbsolutePath/@EntryValue">D:\github\abp\common.DotSettings</s:String> |
||||
|
<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=59923913AE66194DB837F628B1FC08BE/RelativePath/@EntryValue">..\..\..\common.DotSettings</s:String> |
||||
|
<s:Boolean x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=File59923913AE66194DB837F628B1FC08BE/@KeyIndexDefined">True</s:Boolean> |
||||
|
<s:Double x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=File59923913AE66194DB837F628B1FC08BE/RelativePriority/@EntryValue">1</s:Double> |
||||
|
</wpf:ResourceDictionary> |
||||
@ -0,0 +1,7 @@ |
|||||
|
<Project> |
||||
|
<PropertyGroup> |
||||
|
<LangVersion>latest</LangVersion> |
||||
|
<Version>1.0.0</Version> |
||||
|
<NoWarn>$(NoWarn);CS1591</NoWarn> |
||||
|
</PropertyGroup> |
||||
|
</Project> |
||||
@ -0,0 +1,22 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<RootNamespace>Acme.BookStore</RootNamespace> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Acme.BookStore.Domain.Shared\Acme.BookStore.Domain.Shared.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\account\src\Volo.Abp.Account.Application.Contracts\Volo.Abp.Account.Application.Contracts.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.Application.Contracts\Volo.Abp.Identity.Application.Contracts.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.Application.Contracts\Volo.Abp.PermissionManagement.Application.Contracts.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\tenant-management\src\Volo.Abp.TenantManagement.Application.Contracts\Volo.Abp.TenantManagement.Application.Contracts.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\feature-management\src\Volo.Abp.FeatureManagement.Application.Contracts\Volo.Abp.FeatureManagement.Application.Contracts.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,22 @@ |
|||||
|
using Volo.Abp.Account; |
||||
|
using Volo.Abp.FeatureManagement; |
||||
|
using Volo.Abp.Identity; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.PermissionManagement; |
||||
|
using Volo.Abp.TenantManagement; |
||||
|
|
||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(BookStoreDomainSharedModule), |
||||
|
typeof(AbpAccountApplicationContractsModule), |
||||
|
typeof(AbpFeatureManagementApplicationContractsModule), |
||||
|
typeof(AbpIdentityApplicationContractsModule), |
||||
|
typeof(AbpPermissionManagementApplicationContractsModule), |
||||
|
typeof(AbpTenantManagementApplicationContractsModule) |
||||
|
)] |
||||
|
public class BookStoreApplicationContractsModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netcoreapp2.2</TargetFramework> |
||||
|
<RootNamespace>Acme.BookStore</RootNamespace> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Acme.BookStore.Domain\Acme.BookStore.Domain.csproj" /> |
||||
|
<ProjectReference Include="..\Acme.BookStore.Application.Contracts\Acme.BookStore.Application.Contracts.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\account\src\Volo.Abp.Account.Application\Volo.Abp.Account.Application.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.Application\Volo.Abp.Identity.Application.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.Application\Volo.Abp.PermissionManagement.Application.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\tenant-management\src\Volo.Abp.TenantManagement.Application\Volo.Abp.TenantManagement.Application.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\feature-management\src\Volo.Abp.FeatureManagement.Application\Volo.Abp.FeatureManagement.Application.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text; |
||||
|
using Acme.BookStore.Localization; |
||||
|
using Volo.Abp.Application.Services; |
||||
|
|
||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
/* Inherit your application services from this class. |
||||
|
*/ |
||||
|
public abstract class BookStoreAppService : ApplicationService |
||||
|
{ |
||||
|
protected BookStoreAppService() |
||||
|
{ |
||||
|
LocalizationResource = typeof(BookStoreResource); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using AutoMapper; |
||||
|
|
||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
public class BookStoreApplicationAutoMapperProfile : Profile |
||||
|
{ |
||||
|
public BookStoreApplicationAutoMapperProfile() |
||||
|
{ |
||||
|
/* You can configure your AutoMapper mapping configuration here. |
||||
|
* Alternatively, you can split your mapping configurations |
||||
|
* into multiple profile classes for a better organization. */ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,34 @@ |
|||||
|
using Volo.Abp.Account; |
||||
|
using Volo.Abp.AutoMapper; |
||||
|
using Volo.Abp.FeatureManagement; |
||||
|
using Volo.Abp.Identity; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.PermissionManagement; |
||||
|
using Volo.Abp.TenantManagement; |
||||
|
|
||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(BookStoreDomainModule), |
||||
|
typeof(AbpAccountApplicationModule), |
||||
|
typeof(BookStoreApplicationContractsModule), |
||||
|
typeof(AbpIdentityApplicationModule), |
||||
|
typeof(AbpPermissionManagementApplicationModule), |
||||
|
typeof(AbpTenantManagementApplicationModule), |
||||
|
typeof(AbpFeatureManagementApplicationModule) |
||||
|
)] |
||||
|
public class BookStoreApplicationModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<AbpAutoMapperOptions>(options => |
||||
|
{ |
||||
|
/* Use `true` for the `validate` parameter if you want to |
||||
|
* validate the profile on application startup. |
||||
|
* See http://docs.automapper.org/en/stable/Configuration-validation.html for more info
|
||||
|
* about the configuration validation. */ |
||||
|
options.AddProfile<BookStoreApplicationAutoMapperProfile>(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using Acme.BookStore.Localization; |
||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.Localization; |
||||
|
|
||||
|
namespace Acme.BookStore.Permissions |
||||
|
{ |
||||
|
public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvider |
||||
|
{ |
||||
|
public override void Define(IPermissionDefinitionContext context) |
||||
|
{ |
||||
|
var myGroup = context.AddGroup(BookStorePermissions.GroupName); |
||||
|
|
||||
|
//Define your own permissions here. Example:
|
||||
|
//myGroup.AddPermission(BookStorePermissions.MyPermission1, L("Permission:MyPermission1"));
|
||||
|
} |
||||
|
|
||||
|
private static LocalizableString L(string name) |
||||
|
{ |
||||
|
return LocalizableString.Create<BookStoreResource>(name); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
namespace Acme.BookStore.Permissions |
||||
|
{ |
||||
|
public static class BookStorePermissions |
||||
|
{ |
||||
|
public const string GroupName = "BookStore"; |
||||
|
|
||||
|
//Add your own permission names. Example:
|
||||
|
//public const string MyPermission1 = GroupName + ".MyPermission1";
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<OutputType>Exe</OutputType> |
||||
|
<TargetFramework>netcoreapp2.2</TargetFramework> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<None Remove="appsettings.json" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<Content Include="appsettings.json"> |
||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> |
||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
|
</Content> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.4" /> |
||||
|
<PackageReference Include="Serilog.Sinks.File" Version="4.0.0" /> |
||||
|
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
||||
|
<ProjectReference Include="..\Acme.BookStore.Application.Contracts\Acme.BookStore.Application.Contracts.csproj" /> |
||||
|
<ProjectReference Include="..\Acme.BookStore.MongoDB\Acme.BookStore.MongoDB.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,16 @@ |
|||||
|
using Acme.BookStore.MongoDB; |
||||
|
using Volo.Abp.Autofac; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Acme.BookStore.DbMigrator |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAutofacModule), |
||||
|
typeof(BookStoreMongoDbModule), |
||||
|
typeof(BookStoreApplicationContractsModule) |
||||
|
)] |
||||
|
public class BookStoreDbMigratorModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
using System.IO; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Acme.BookStore.Data; |
||||
|
using Serilog; |
||||
|
using Serilog.Events; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Threading; |
||||
|
|
||||
|
namespace Acme.BookStore.DbMigrator |
||||
|
{ |
||||
|
class Program |
||||
|
{ |
||||
|
static void Main(string[] args) |
||||
|
{ |
||||
|
ConfigureLogging(); |
||||
|
|
||||
|
using (var application = AbpApplicationFactory.Create<BookStoreDbMigratorModule>(options => |
||||
|
{ |
||||
|
options.UseAutofac(); |
||||
|
options.Services.AddLogging(c => c.AddSerilog()); |
||||
|
})) |
||||
|
{ |
||||
|
application.Initialize(); |
||||
|
|
||||
|
AsyncHelper.RunSync( |
||||
|
() => application |
||||
|
.ServiceProvider |
||||
|
.GetRequiredService<BookStoreDbMigrationService>() |
||||
|
.MigrateAsync() |
||||
|
); |
||||
|
|
||||
|
application.Shutdown(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static void ConfigureLogging() |
||||
|
{ |
||||
|
Log.Logger = new LoggerConfiguration() |
||||
|
.MinimumLevel.Information() |
||||
|
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning) |
||||
|
.MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning) |
||||
|
#if DEBUG
|
||||
|
.MinimumLevel.Override("Acme.BookStore", LogEventLevel.Debug) |
||||
|
#else
|
||||
|
.MinimumLevel.Override("Acme.BookStore", LogEventLevel.Information) |
||||
|
#endif
|
||||
|
.Enrich.FromLogContext() |
||||
|
.WriteTo.File(Path.Combine(Directory.GetCurrentDirectory(), "Logs/logs.txt")) |
||||
|
.WriteTo.Console() |
||||
|
.CreateLogger(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
{ |
||||
|
"ConnectionStrings": { |
||||
|
"Default": "mongodb://localhost:27017|BookStore" |
||||
|
}, |
||||
|
"IdentityServer": { |
||||
|
"Clients": { |
||||
|
"BookStore_Web": { |
||||
|
"ClientId": "BookStore_Web", |
||||
|
"ClientSecret": "1q2w3e*", |
||||
|
"RootUrl": "https://localhost:44335" |
||||
|
}, |
||||
|
"BookStore_ConsoleTestApp": { |
||||
|
"ClientId": "BookStore_ConsoleTestApp", |
||||
|
"ClientSecret": "1q2w3e*" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<RootNamespace>Acme.BookStore</RootNamespace> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.Domain.Shared\Volo.Abp.Identity.Domain.Shared.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\identityserver\src\Volo.Abp.IdentityServer.Domain.Shared\Volo.Abp.IdentityServer.Domain.Shared.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\background-jobs\src\Volo.Abp.BackgroundJobs.Domain.Shared\Volo.Abp.BackgroundJobs.Domain.Shared.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\audit-logging\src\Volo.Abp.AuditLogging.Domain.Shared\Volo.Abp.AuditLogging.Domain.Shared.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\tenant-management\src\Volo.Abp.TenantManagement.Domain.Shared\Volo.Abp.TenantManagement.Domain.Shared.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\feature-management\src\Volo.Abp.FeatureManagement.Domain.Shared\Volo.Abp.FeatureManagement.Domain.Shared.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.Domain.Shared\Volo.Abp.PermissionManagement.Domain.Shared.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\setting-management\src\Volo.Abp.SettingManagement.Domain.Shared\Volo.Abp.SettingManagement.Domain.Shared.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<EmbeddedResource Include="Localization\BookStore\*.json" /> |
||||
|
<Content Remove="Localization\BookStore\*.json" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
public static class BookStoreDomainErrorCodes |
||||
|
{ |
||||
|
/* You can add your business exception error codes here, as constants */ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
using Acme.BookStore.Localization; |
||||
|
using Volo.Abp.AuditLogging; |
||||
|
using Volo.Abp.BackgroundJobs; |
||||
|
using Volo.Abp.FeatureManagement; |
||||
|
using Volo.Abp.Identity; |
||||
|
using Volo.Abp.IdentityServer; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Localization.Resources.AbpValidation; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.PermissionManagement; |
||||
|
using Volo.Abp.SettingManagement; |
||||
|
using Volo.Abp.TenantManagement; |
||||
|
using Volo.Abp.VirtualFileSystem; |
||||
|
|
||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAuditLoggingDomainSharedModule), |
||||
|
typeof(BackgroundJobsDomainSharedModule), |
||||
|
typeof(AbpFeatureManagementDomainSharedModule), |
||||
|
typeof(AbpIdentityDomainSharedModule), |
||||
|
typeof(AbpIdentityServerDomainSharedModule), |
||||
|
typeof(AbpPermissionManagementDomainSharedModule), |
||||
|
typeof(AbpSettingManagementDomainSharedModule), |
||||
|
typeof(AbpTenantManagementDomainSharedModule) |
||||
|
)] |
||||
|
public class BookStoreDomainSharedModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<VirtualFileSystemOptions>(options => |
||||
|
{ |
||||
|
options.FileSets.AddEmbedded<BookStoreDomainSharedModule>("Acme.BookStore"); |
||||
|
}); |
||||
|
|
||||
|
Configure<AbpLocalizationOptions>(options => |
||||
|
{ |
||||
|
options.Resources |
||||
|
.Add<BookStoreResource>("en") |
||||
|
.AddBaseTypes(typeof(AbpValidationResource)) |
||||
|
.AddVirtualJson("/Localization/BookStore"); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"culture": "cs", |
||||
|
"texts": { |
||||
|
"Menu:Home": "Úvod", |
||||
|
"Welcome": "Vítejte", |
||||
|
"LongWelcomeMessage": "Vítejte v aplikaci. Toto je startovací projekt založený na ABP frameworku. Pro více informací, navštivte abp.io." |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"culture": "en", |
||||
|
"texts": { |
||||
|
"Menu:Home": "Home", |
||||
|
"Welcome": "Welcome", |
||||
|
"LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io." |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"culture": "pl", |
||||
|
"texts": { |
||||
|
"Menu:Home": "Home", |
||||
|
"Welcome": "Witaj", |
||||
|
"LongWelcomeMessage": "Witaj w aplikacji. To jest inicjalny projekt bazujący na ABP framework. Po więcej informacji odwiedź stronę abp.io." |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"culture": "pt-BR", |
||||
|
"texts": { |
||||
|
"Menu:Home": "Principal", |
||||
|
"Welcome": "Seja bem-vindo!", |
||||
|
"LongWelcomeMessage": "Bem-vindo a esta aplicação. Este é um projeto inicial baseado no ABP framework. Para mais informações, visite abp.io." |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"culture": "tr", |
||||
|
"texts": { |
||||
|
"Menu:Home": "Ana sayfa", |
||||
|
"Welcome": "Hoşgeldiniz", |
||||
|
"LongWelcomeMessage": "Uygulamaya hoşgeldiniz. Bu, ABP framework'ü üzerine bina edilmiş bir başlangıç projesidir. Daha fazla bilgi için abp.io adresini ziyaret edebilirsiniz." |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"culture": "vi", |
||||
|
"texts": { |
||||
|
"Menu:Home": "Trang chủ", |
||||
|
"Welcome": "Chào mừng bạn", |
||||
|
"LongWelcomeMessage": "Chào mừng bạn đến ứng dụng. Đây là một dự án khởi nghiệp dựa trên khung ABP. Để biết thêm thông tin, hãy truy cập abp.io." |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"culture": "zh-Hans", |
||||
|
"texts": { |
||||
|
"Menu:Home": "首页", |
||||
|
"Welcome": "欢迎", |
||||
|
"LongWelcomeMessage": "欢迎来到该应用程序. 这是一个基于ABP框架的启动项目. 有关更多信息, 请访问 cn.abp.io." |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using Volo.Abp.Localization; |
||||
|
|
||||
|
namespace Acme.BookStore.Localization |
||||
|
{ |
||||
|
[LocalizationResourceName("BookStore")] |
||||
|
public class BookStoreResource |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
namespace Acme.BookStore.MultiTenancy |
||||
|
{ |
||||
|
public static class MultiTenancyConsts |
||||
|
{ |
||||
|
/* Enable/disable multi-tenancy easily in a single point. |
||||
|
* If you will never need to multi-tenancy, you can remove |
||||
|
* related modules and code parts, including this file. |
||||
|
*/ |
||||
|
public const bool IsEnabled = true; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netcoreapp2.2</TargetFramework> |
||||
|
<RootNamespace>Acme.BookStore</RootNamespace> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Acme.BookStore.Domain.Shared\Acme.BookStore.Domain.Shared.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.DataAnnotations" Version="2.2.0" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.Domain\Volo.Abp.Identity.Domain.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.PermissionManagement.Domain.Identity\Volo.Abp.PermissionManagement.Domain.Identity.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\identityserver\src\Volo.Abp.IdentityServer.Domain\Volo.Abp.IdentityServer.Domain.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\identityserver\src\Volo.Abp.PermissionManagement.Domain.IdentityServer\Volo.Abp.PermissionManagement.Domain.IdentityServer.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\background-jobs\src\Volo.Abp.BackgroundJobs.Domain\Volo.Abp.BackgroundJobs.Domain.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\audit-logging\src\Volo.Abp.AuditLogging.Domain\Volo.Abp.AuditLogging.Domain.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\tenant-management\src\Volo.Abp.TenantManagement.Domain\Volo.Abp.TenantManagement.Domain.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\feature-management\src\Volo.Abp.FeatureManagement.Domain\Volo.Abp.FeatureManagement.Domain.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\setting-management\src\Volo.Abp.SettingManagement.Domain\Volo.Abp.SettingManagement.Domain.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,9 @@ |
|||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
public static class BookStoreConsts |
||||
|
{ |
||||
|
public const string DbTablePrefix = "App"; |
||||
|
|
||||
|
public const string DbSchema = null; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
using Acme.BookStore.MultiTenancy; |
||||
|
using Volo.Abp.AuditLogging; |
||||
|
using Volo.Abp.BackgroundJobs; |
||||
|
using Volo.Abp.FeatureManagement; |
||||
|
using Volo.Abp.Identity; |
||||
|
using Volo.Abp.IdentityServer; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using Volo.Abp.PermissionManagement.Identity; |
||||
|
using Volo.Abp.PermissionManagement.IdentityServer; |
||||
|
using Volo.Abp.SettingManagement; |
||||
|
using Volo.Abp.TenantManagement; |
||||
|
|
||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(BookStoreDomainSharedModule), |
||||
|
typeof(AbpAuditLoggingDomainModule), |
||||
|
typeof(BackgroundJobsDomainModule), |
||||
|
typeof(AbpFeatureManagementDomainModule), |
||||
|
typeof(AbpIdentityDomainModule), |
||||
|
typeof(AbpPermissionManagementDomainIdentityModule), |
||||
|
typeof(AbpIdentityServerDomainModule), |
||||
|
typeof(AbpPermissionManagementDomainIdentityServerModule), |
||||
|
typeof(AbpSettingManagementDomainModule), |
||||
|
typeof(AbpTenantManagementDomainModule) |
||||
|
)] |
||||
|
public class BookStoreDomainModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<MultiTenancyOptions>(options => |
||||
|
{ |
||||
|
options.IsEnabled = MultiTenancyConsts.IsEnabled; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Acme.BookStore.Data |
||||
|
{ |
||||
|
public class BookStoreDbMigrationService : ITransientDependency |
||||
|
{ |
||||
|
public ILogger<BookStoreDbMigrationService> Logger { get; set; } |
||||
|
|
||||
|
private readonly IDataSeeder _dataSeeder; |
||||
|
private readonly IBookStoreDbSchemaMigrator _dbSchemaMigrator; |
||||
|
|
||||
|
public BookStoreDbMigrationService( |
||||
|
IDataSeeder dataSeeder, |
||||
|
IBookStoreDbSchemaMigrator dbSchemaMigrator) |
||||
|
{ |
||||
|
_dataSeeder = dataSeeder; |
||||
|
_dbSchemaMigrator = dbSchemaMigrator; |
||||
|
|
||||
|
Logger = NullLogger<BookStoreDbMigrationService>.Instance; |
||||
|
} |
||||
|
|
||||
|
public async Task MigrateAsync() |
||||
|
{ |
||||
|
Logger.LogInformation("Started database migrations..."); |
||||
|
|
||||
|
Logger.LogInformation("Migrating database schema..."); |
||||
|
await _dbSchemaMigrator.MigrateAsync(); |
||||
|
|
||||
|
Logger.LogInformation("Executing database seed..."); |
||||
|
await _dataSeeder.SeedAsync(); |
||||
|
|
||||
|
Logger.LogInformation("Successfully completed database migrations."); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Acme.BookStore.Data |
||||
|
{ |
||||
|
public interface IBookStoreDbSchemaMigrator |
||||
|
{ |
||||
|
Task MigrateAsync(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Acme.BookStore.Data |
||||
|
{ |
||||
|
/* This is used if database provider does't define |
||||
|
* IBookStoreDbSchemaMigrator implementation. |
||||
|
*/ |
||||
|
public class NullBookStoreDbSchemaMigrator : IBookStoreDbSchemaMigrator, ITransientDependency |
||||
|
{ |
||||
|
public Task MigrateAsync() |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,223 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using IdentityServer4.Models; |
||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.Configuration; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Guids; |
||||
|
using Volo.Abp.IdentityServer.ApiResources; |
||||
|
using Volo.Abp.IdentityServer.Clients; |
||||
|
using Volo.Abp.IdentityServer.IdentityResources; |
||||
|
using Volo.Abp.PermissionManagement; |
||||
|
using Volo.Abp.Uow; |
||||
|
using ApiResource = Volo.Abp.IdentityServer.ApiResources.ApiResource; |
||||
|
using Client = Volo.Abp.IdentityServer.Clients.Client; |
||||
|
|
||||
|
namespace Acme.BookStore.IdentityServer |
||||
|
{ |
||||
|
public class IdentityServerDataSeedContributor : IDataSeedContributor, ITransientDependency |
||||
|
{ |
||||
|
private readonly IApiResourceRepository _apiResourceRepository; |
||||
|
private readonly IClientRepository _clientRepository; |
||||
|
private readonly IIdentityResourceDataSeeder _identityResourceDataSeeder; |
||||
|
private readonly IGuidGenerator _guidGenerator; |
||||
|
private readonly IPermissionDataSeeder _permissionDataSeeder; |
||||
|
private readonly IConfigurationAccessor _configurationAccessor; |
||||
|
|
||||
|
public IdentityServerDataSeedContributor( |
||||
|
IClientRepository clientRepository, |
||||
|
IApiResourceRepository apiResourceRepository, |
||||
|
IIdentityResourceDataSeeder identityResourceDataSeeder, |
||||
|
IGuidGenerator guidGenerator, |
||||
|
IPermissionDataSeeder permissionDataSeeder, |
||||
|
IConfigurationAccessor configurationAccessor) |
||||
|
{ |
||||
|
_clientRepository = clientRepository; |
||||
|
_apiResourceRepository = apiResourceRepository; |
||||
|
_identityResourceDataSeeder = identityResourceDataSeeder; |
||||
|
_guidGenerator = guidGenerator; |
||||
|
_permissionDataSeeder = permissionDataSeeder; |
||||
|
_configurationAccessor = configurationAccessor; |
||||
|
} |
||||
|
|
||||
|
[UnitOfWork] |
||||
|
public virtual async Task SeedAsync(DataSeedContext context) |
||||
|
{ |
||||
|
await _identityResourceDataSeeder.CreateStandardResourcesAsync(); |
||||
|
await CreateApiResourcesAsync(); |
||||
|
await CreateClientsAsync(); |
||||
|
} |
||||
|
|
||||
|
private async Task CreateApiResourcesAsync() |
||||
|
{ |
||||
|
var commonApiUserClaims = new[] |
||||
|
{ |
||||
|
"email", |
||||
|
"email_verified", |
||||
|
"name", |
||||
|
"phone_number", |
||||
|
"phone_number_verified", |
||||
|
"role" |
||||
|
}; |
||||
|
|
||||
|
await CreateApiResourceAsync("BookStore", commonApiUserClaims); |
||||
|
} |
||||
|
|
||||
|
private async Task<ApiResource> CreateApiResourceAsync(string name, IEnumerable<string> claims) |
||||
|
{ |
||||
|
var apiResource = await _apiResourceRepository.FindByNameAsync(name); |
||||
|
if (apiResource == null) |
||||
|
{ |
||||
|
apiResource = await _apiResourceRepository.InsertAsync( |
||||
|
new ApiResource( |
||||
|
_guidGenerator.Create(), |
||||
|
name, |
||||
|
name + " API" |
||||
|
), |
||||
|
autoSave: true |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
foreach (var claim in claims) |
||||
|
{ |
||||
|
if (apiResource.FindClaim(claim) == null) |
||||
|
{ |
||||
|
apiResource.AddUserClaim(claim); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return await _apiResourceRepository.UpdateAsync(apiResource); |
||||
|
} |
||||
|
|
||||
|
private async Task CreateClientsAsync() |
||||
|
{ |
||||
|
var commonScopes = new[] |
||||
|
{ |
||||
|
"email", |
||||
|
"openid", |
||||
|
"profile", |
||||
|
"role", |
||||
|
"phone", |
||||
|
"address", |
||||
|
"BookStore" |
||||
|
}; |
||||
|
|
||||
|
var configurationSection = _configurationAccessor.Configuration.GetSection("IdentityServer:Clients"); |
||||
|
|
||||
|
//Web Client
|
||||
|
var webClientId = configurationSection["BookStore_Web:ClientId"]; |
||||
|
if (!webClientId.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
var webClientRootUrl = configurationSection["BookStore_Web:RootUrl"].EnsureEndsWith('/'); |
||||
|
|
||||
|
/* BookStore_Web client is only needed if you created a tiered |
||||
|
* solution. Otherwise, you can delete this client. */ |
||||
|
|
||||
|
await CreateClientAsync( |
||||
|
webClientId, |
||||
|
commonScopes, |
||||
|
new[] { "hybrid" }, |
||||
|
(configurationSection["BookStore_Web:ClientSecret"] ?? "1q2w3e*").Sha256(), |
||||
|
redirectUri: $"{webClientRootUrl}signin-oidc", |
||||
|
postLogoutRedirectUri: $"{webClientRootUrl}signout-callback-oidc" |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
//Console Test Client
|
||||
|
var consoleClientId = configurationSection["BookStore_ConsoleTestApp:ClientId"]; |
||||
|
if (!consoleClientId.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
await CreateClientAsync( |
||||
|
consoleClientId, |
||||
|
commonScopes, |
||||
|
new[] { "password", "client_credentials" }, |
||||
|
(configurationSection["BookStore_ConsoleTestApp:ClientSecret"] ?? "1q2w3e*").Sha256() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private async Task<Client> CreateClientAsync( |
||||
|
string name, |
||||
|
IEnumerable<string> scopes, |
||||
|
IEnumerable<string> grantTypes, |
||||
|
string secret, |
||||
|
string redirectUri = null, |
||||
|
string postLogoutRedirectUri = null, |
||||
|
IEnumerable<string> permissions = null) |
||||
|
{ |
||||
|
var client = await _clientRepository.FindByCliendIdAsync(name); |
||||
|
if (client == null) |
||||
|
{ |
||||
|
client = await _clientRepository.InsertAsync( |
||||
|
new Client( |
||||
|
_guidGenerator.Create(), |
||||
|
name |
||||
|
) |
||||
|
{ |
||||
|
ClientName = name, |
||||
|
ProtocolType = "oidc", |
||||
|
Description = name, |
||||
|
AlwaysIncludeUserClaimsInIdToken = true, |
||||
|
AllowOfflineAccess = true, |
||||
|
AbsoluteRefreshTokenLifetime = 31536000, //365 days
|
||||
|
AccessTokenLifetime = 31536000, //365 days
|
||||
|
AuthorizationCodeLifetime = 300, |
||||
|
IdentityTokenLifetime = 300, |
||||
|
RequireConsent = false |
||||
|
}, |
||||
|
autoSave: true |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
foreach (var scope in scopes) |
||||
|
{ |
||||
|
if (client.FindScope(scope) == null) |
||||
|
{ |
||||
|
client.AddScope(scope); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
foreach (var grantType in grantTypes) |
||||
|
{ |
||||
|
if (client.FindGrantType(grantType) == null) |
||||
|
{ |
||||
|
client.AddGrantType(grantType); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (client.FindSecret(secret) == null) |
||||
|
{ |
||||
|
client.AddSecret(secret); |
||||
|
} |
||||
|
|
||||
|
if (redirectUri != null) |
||||
|
{ |
||||
|
if (client.FindRedirectUri(redirectUri) == null) |
||||
|
{ |
||||
|
client.AddRedirectUri(redirectUri); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (postLogoutRedirectUri != null) |
||||
|
{ |
||||
|
if (client.FindPostLogoutRedirectUri(postLogoutRedirectUri) == null) |
||||
|
{ |
||||
|
client.AddPostLogoutRedirectUri(postLogoutRedirectUri); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (permissions != null) |
||||
|
{ |
||||
|
await _permissionDataSeeder.SeedAsync( |
||||
|
ClientPermissionValueProvider.ProviderName, |
||||
|
name, |
||||
|
permissions |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
return await _clientRepository.UpdateAsync(client); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
using Volo.Abp.Settings; |
||||
|
|
||||
|
namespace Acme.BookStore.Settings |
||||
|
{ |
||||
|
public class BookStoreSettingDefinitionProvider : SettingDefinitionProvider |
||||
|
{ |
||||
|
public override void Define(ISettingDefinitionContext context) |
||||
|
{ |
||||
|
//Define your own settings here. Example:
|
||||
|
//context.Add(new SettingDefinition(BookStoreSettings.MySetting1));
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
namespace Acme.BookStore.Settings |
||||
|
{ |
||||
|
public static class BookStoreSettings |
||||
|
{ |
||||
|
private const string Prefix = "BookStore"; |
||||
|
|
||||
|
//Add your own setting names here. Example:
|
||||
|
//public const string MySetting1 = Prefix + ".MySetting1";
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.Domain.Entities.Auditing; |
||||
|
using Volo.Abp.Users; |
||||
|
|
||||
|
namespace Acme.BookStore.Users |
||||
|
{ |
||||
|
/* This entity shares the same table/collection ("AbpUsers" by default) with the |
||||
|
* IdentityUser entity of the Identity module. |
||||
|
* |
||||
|
* - You can define your custom properties into this class. |
||||
|
* - You never create or delete this entity, because it is Identity module's job. |
||||
|
* - You can query users from database with this entity. |
||||
|
* - You can update values of your custom properties. |
||||
|
*/ |
||||
|
public class AppUser : FullAuditedAggregateRoot<Guid>, IUser |
||||
|
{ |
||||
|
#region Base properties
|
||||
|
|
||||
|
/* These properties are shared with the IdentityUser entity of the Identity module. |
||||
|
* Do not change these properties through this class. Instead, use Identity module |
||||
|
* services (like IdentityUserManager) to change them. |
||||
|
* So, this properties are designed as read only! |
||||
|
*/ |
||||
|
|
||||
|
public virtual Guid? TenantId { get; private set; } |
||||
|
|
||||
|
public virtual string UserName { get; private set; } |
||||
|
|
||||
|
public virtual string Name { get; private set; } |
||||
|
|
||||
|
public virtual string Surname { get; private set; } |
||||
|
|
||||
|
public virtual string Email { get; private set; } |
||||
|
|
||||
|
public virtual bool EmailConfirmed { get; private set; } |
||||
|
|
||||
|
public virtual string PhoneNumber { get; private set; } |
||||
|
|
||||
|
public virtual bool PhoneNumberConfirmed { get; private set; } |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
/* Add your own properties here. Example: |
||||
|
* |
||||
|
* public virtual string MyProperty { get; set; } |
||||
|
*/ |
||||
|
|
||||
|
private AppUser() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<RootNamespace>Acme.BookStore</RootNamespace> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Acme.BookStore.Application.Contracts\Acme.BookStore.Application.Contracts.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\account\src\Volo.Abp.Account.HttpApi.Client\Volo.Abp.Account.HttpApi.Client.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.HttpApi.Client\Volo.Abp.Identity.HttpApi.Client.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.HttpApi.Client\Volo.Abp.PermissionManagement.HttpApi.Client.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\tenant-management\src\Volo.Abp.TenantManagement.HttpApi.Client\Volo.Abp.TenantManagement.HttpApi.Client.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\feature-management\src\Volo.Abp.FeatureManagement.HttpApi.Client\Volo.Abp.FeatureManagement.HttpApi.Client.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,31 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Account; |
||||
|
using Volo.Abp.FeatureManagement; |
||||
|
using Volo.Abp.Identity; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.PermissionManagement; |
||||
|
using Volo.Abp.TenantManagement; |
||||
|
|
||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(BookStoreApplicationContractsModule), |
||||
|
typeof(AbpAccountHttpApiClientModule), |
||||
|
typeof(AbpIdentityHttpApiClientModule), |
||||
|
typeof(AbpPermissionManagementHttpApiClientModule), |
||||
|
typeof(AbpTenantManagementHttpApiClientModule), |
||||
|
typeof(AbpFeatureManagementHttpApiClientModule) |
||||
|
)] |
||||
|
public class BookStoreHttpApiClientModule : AbpModule |
||||
|
{ |
||||
|
public const string RemoteServiceName = "Default"; |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddHttpClientProxies( |
||||
|
typeof(BookStoreApplicationContractsModule).Assembly, |
||||
|
RemoteServiceName |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk.Web"> |
||||
|
|
||||
|
<Import Project="..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netcoreapp2.2</TargetFramework> |
||||
|
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> |
||||
|
<RootNamespace>Acme.BookStore</RootNamespace> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.App" /> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" /> |
||||
|
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> |
||||
|
<PackageReference Include="Serilog.Sinks.File" Version="4.0.0" /> |
||||
|
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" /> |
||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" /> |
||||
|
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.MultiTenancy\Volo.Abp.AspNetCore.MultiTenancy.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Authentication.JwtBearer\Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\..\modules\account\src\Volo.Abp.Account.Web.IdentityServer\Volo.Abp.Account.Web.IdentityServer.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Acme.BookStore.Application\Acme.BookStore.Application.csproj" /> |
||||
|
<ProjectReference Include="..\Acme.BookStore.MongoDB\Acme.BookStore.MongoDB.csproj" /> |
||||
|
<ProjectReference Include="..\Acme.BookStore.HttpApi\Acme.BookStore.HttpApi.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<Compile Remove="Logs\**" /> |
||||
|
<Content Remove="Logs\**" /> |
||||
|
<EmbeddedResource Remove="Logs\**" /> |
||||
|
<None Remove="Logs\**" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,170 @@ |
|||||
|
using System; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Net.Http; |
||||
|
using Acme.BookStore.MongoDB; |
||||
|
using Microsoft.AspNetCore.Builder; |
||||
|
using Microsoft.AspNetCore.Hosting; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Acme.BookStore.MultiTenancy; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; |
||||
|
using Swashbuckle.AspNetCore.Swagger; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Account.Web; |
||||
|
using Volo.Abp.AspNetCore.Authentication.JwtBearer; |
||||
|
using Volo.Abp.AspNetCore.MultiTenancy; |
||||
|
using Volo.Abp.AspNetCore.Mvc; |
||||
|
using Volo.Abp.Autofac; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.UI.Navigation.Urls; |
||||
|
using Volo.Abp.VirtualFileSystem; |
||||
|
|
||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(BookStoreHttpApiModule), |
||||
|
typeof(AbpAutofacModule), |
||||
|
typeof(AbpAspNetCoreMultiTenancyModule), |
||||
|
typeof(BookStoreApplicationModule), |
||||
|
typeof(BookStoreMongoDbModule), |
||||
|
typeof(AbpAspNetCoreMvcUiBasicThemeModule), |
||||
|
typeof(AbpAspNetCoreAuthenticationJwtBearerModule), |
||||
|
typeof(AbpAccountWebIdentityServerModule) |
||||
|
)] |
||||
|
public class BookStoreHttpApiHostModule : AbpModule |
||||
|
{ |
||||
|
private const string DefaultCorsPolicyName = "Default"; |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
var configuration = context.Services.GetConfiguration(); |
||||
|
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
||||
|
|
||||
|
ConfigureUrls(configuration); |
||||
|
ConfigureConventionalControllers(); |
||||
|
ConfigureAuthentication(context, configuration); |
||||
|
ConfigureSwagger(context); |
||||
|
ConfigureLocalization(); |
||||
|
ConfigureVirtualFileSystem(context); |
||||
|
ConfigureCors(context, configuration); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureUrls(IConfigurationRoot configuration) |
||||
|
{ |
||||
|
Configure<AppUrlOptions>(options => |
||||
|
{ |
||||
|
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
||||
|
|
||||
|
if (hostingEnvironment.IsDevelopment()) |
||||
|
{ |
||||
|
Configure<VirtualFileSystemOptions>(options => |
||||
|
{ |
||||
|
options.FileSets.ReplaceEmbeddedByPhysical<BookStoreDomainSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Acme.BookStore.Domain.Shared")); |
||||
|
options.FileSets.ReplaceEmbeddedByPhysical<BookStoreDomainModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Acme.BookStore.Domain")); |
||||
|
options.FileSets.ReplaceEmbeddedByPhysical<BookStoreApplicationContractsModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Acme.BookStore.Application.Contracts")); |
||||
|
options.FileSets.ReplaceEmbeddedByPhysical<BookStoreApplicationModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Acme.BookStore.Application")); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void ConfigureConventionalControllers() |
||||
|
{ |
||||
|
Configure<AbpAspNetCoreMvcOptions>(options => |
||||
|
{ |
||||
|
options.ConventionalControllers.Create(typeof(BookStoreApplicationModule).Assembly); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfigurationRoot configuration) |
||||
|
{ |
||||
|
context.Services.AddAuthentication() |
||||
|
.AddIdentityServerAuthentication(options => |
||||
|
{ |
||||
|
options.Authority = configuration["AuthServer:Authority"]; |
||||
|
options.RequireHttpsMetadata = false; |
||||
|
options.ApiName = "BookStore"; |
||||
|
options.JwtBackChannelHandler = new HttpClientHandler() |
||||
|
{ |
||||
|
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator |
||||
|
}; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private static void ConfigureSwagger(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddSwaggerGen( |
||||
|
options => |
||||
|
{ |
||||
|
options.SwaggerDoc("v1", new Info {Title = "BookStore API", Version = "v1"}); |
||||
|
options.DocInclusionPredicate((docName, description) => true); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureLocalization() |
||||
|
{ |
||||
|
Configure<AbpLocalizationOptions>(options => |
||||
|
{ |
||||
|
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); |
||||
|
options.Languages.Add(new LanguageInfo("en", "en", "English")); |
||||
|
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); |
||||
|
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); |
||||
|
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureCors(ServiceConfigurationContext context, IConfigurationRoot configuration) |
||||
|
{ |
||||
|
context.Services.AddCors(options => |
||||
|
{ |
||||
|
options.AddPolicy(DefaultCorsPolicyName, builder => |
||||
|
{ |
||||
|
builder |
||||
|
.WithOrigins( |
||||
|
configuration["App:CorsOrigins"] |
||||
|
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
||||
|
.Select(o => o.RemovePostFix("/")) |
||||
|
.ToArray() |
||||
|
) |
||||
|
.SetIsOriginAllowedToAllowWildcardSubdomains() |
||||
|
.AllowAnyHeader() |
||||
|
.AllowAnyMethod() |
||||
|
.AllowCredentials(); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
||||
|
{ |
||||
|
var app = context.GetApplicationBuilder(); |
||||
|
|
||||
|
app.UseCors(DefaultCorsPolicyName); |
||||
|
|
||||
|
app.UseVirtualFiles(); |
||||
|
app.UseAuthentication(); |
||||
|
app.UseJwtTokenMiddleware(); |
||||
|
|
||||
|
if (MultiTenancyConsts.IsEnabled) |
||||
|
{ |
||||
|
app.UseMultiTenancy(); |
||||
|
} |
||||
|
|
||||
|
app.UseIdentityServer(); |
||||
|
app.UseAbpRequestLocalization(); |
||||
|
app.UseSwagger(); |
||||
|
app.UseSwaggerUI(options => |
||||
|
{ |
||||
|
options.SwaggerEndpoint("/swagger/v1/swagger.json", "BookStore API"); |
||||
|
}); |
||||
|
app.UseAuditing(); |
||||
|
app.UseMvcWithDefaultRouteAndArea(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp.AspNetCore.Mvc; |
||||
|
|
||||
|
namespace Acme.BookStore.Controllers |
||||
|
{ |
||||
|
public class HomeController : AbpController |
||||
|
{ |
||||
|
public ActionResult Index() |
||||
|
{ |
||||
|
return Redirect("/swagger"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,54 @@ |
|||||
|
using System; |
||||
|
using System.IO; |
||||
|
using Microsoft.AspNetCore.Hosting; |
||||
|
using Microsoft.AspNetCore.InProcess; |
||||
|
using Serilog; |
||||
|
using Serilog.Events; |
||||
|
|
||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
public class Program |
||||
|
{ |
||||
|
public static int Main(string[] args) |
||||
|
{ |
||||
|
CurrentDirectoryHelpers.SetCurrentDirectory(); |
||||
|
|
||||
|
Log.Logger = new LoggerConfiguration() |
||||
|
#if DEBUG
|
||||
|
.MinimumLevel.Debug() |
||||
|
#else
|
||||
|
.MinimumLevel.Information() |
||||
|
#endif
|
||||
|
.MinimumLevel.Override("Microsoft", LogEventLevel.Information) |
||||
|
.Enrich.FromLogContext() |
||||
|
.WriteTo.Async(c => c.File("Logs/logs.txt")) |
||||
|
.CreateLogger(); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
Log.Information("Starting Acme.BookStore.HttpApi.Host."); |
||||
|
BuildWebHostInternal(args).Run(); |
||||
|
return 0; |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Log.Fatal(ex, "Host terminated unexpectedly!"); |
||||
|
return 1; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
Log.CloseAndFlush(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static IWebHost BuildWebHostInternal(string[] args) => |
||||
|
new WebHostBuilder() |
||||
|
.UseKestrel() |
||||
|
.UseContentRoot(Directory.GetCurrentDirectory()) |
||||
|
.UseIIS() |
||||
|
.UseIISIntegration() |
||||
|
.UseStartup<Startup>() |
||||
|
.UseSerilog() |
||||
|
.Build(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
{ |
||||
|
"iisSettings": { |
||||
|
"windowsAuthentication": false, |
||||
|
"anonymousAuthentication": true, |
||||
|
"iisExpress": { |
||||
|
"applicationUrl": "https://localhost:44359", |
||||
|
"sslPort": 44359 |
||||
|
} |
||||
|
}, |
||||
|
"profiles": { |
||||
|
"IIS Express": { |
||||
|
"commandName": "IISExpress", |
||||
|
"launchBrowser": true, |
||||
|
"environmentVariables": { |
||||
|
"ASPNETCORE_ENVIRONMENT": "Development" |
||||
|
} |
||||
|
}, |
||||
|
"Acme.BookStore.HttpApi.Host": { |
||||
|
"commandName": "Project", |
||||
|
"launchBrowser": true, |
||||
|
"applicationUrl": "https://localhost:44359", |
||||
|
"environmentVariables": { |
||||
|
"ASPNETCORE_ENVIRONMENT": "Development" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
using System; |
||||
|
using Microsoft.AspNetCore.Builder; |
||||
|
using Microsoft.AspNetCore.Hosting; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Volo.Abp; |
||||
|
|
||||
|
namespace Acme.BookStore |
||||
|
{ |
||||
|
public class Startup |
||||
|
{ |
||||
|
public IServiceProvider ConfigureServices(IServiceCollection services) |
||||
|
{ |
||||
|
services.AddApplication<BookStoreHttpApiHostModule>(options => |
||||
|
{ |
||||
|
options.UseAutofac(); |
||||
|
}); |
||||
|
|
||||
|
return services.BuildServiceProviderFromFactory(); |
||||
|
} |
||||
|
|
||||
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) |
||||
|
{ |
||||
|
app.InitializeApplication(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
module.exports = { |
||||
|
aliases: { |
||||
|
|
||||
|
}, |
||||
|
mappings: { |
||||
|
|
||||
|
} |
||||
|
}; |
||||
@ -0,0 +1,2 @@ |
|||||
|
{ |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
{ |
||||
|
"App": { |
||||
|
"SelfUrl": "https://localhost:44359", |
||||
|
"CorsOrigins": "https://*.BookStore.com,http://localhost:4200" |
||||
|
}, |
||||
|
"ConnectionStrings": { |
||||
|
"Default": "Server=localhost;Database=BookStore;Trusted_Connection=True;MultipleActiveResultSets=true" |
||||
|
}, |
||||
|
"Redis": { |
||||
|
"Configuration": "127.0.0.1" |
||||
|
}, |
||||
|
"AuthServer": { |
||||
|
"Authority": "https://localhost:44359" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
"use strict"; |
||||
|
|
||||
|
var gulp = require("gulp"), |
||||
|
path = require('path'), |
||||
|
copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js'); |
||||
|
|
||||
|
exports.default = function(){ |
||||
|
return copyResources(path.resolve('./')); |
||||
|
}; |
||||
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"version": "1.0.0", |
||||
|
"name": "my-app", |
||||
|
"private": true, |
||||
|
"dependencies": { |
||||
|
"@abp/aspnetcore.mvc.ui.theme.basic": "^0.6.6" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1 @@ |
|||||
|
{"KeyId":"5eb863b25811a7099f9bc925c0fdf680","Parameters":{"D":"gqn7NAeMkug4twJJHFz/qPseDzQCx7R+6Maj649xrG4vPsMANV9mfR78Er2SuHUS0ZihM2MQEILI5Sf41Uuubv8swCNSE3Dw7GQrBIbTAJ7BZKbQMVgtGkMDtHrtri6d9cOi3EOTSJINICk9r80M49oBMOZihEKascfBSIUYVQvWLEMYfryEiDeFUPbobr10OxF5tZ1unvEKgZe190BdNKWQuFhJelcgsZumjEYNsOz5DHrK73WLhfTy01DmsTKx8i1XVnLtq6W89MqAhMZP9QO9Vj8lR0ANnmdOsY6hJfwUbXiI36t4V9rAZvXR5ESorjb4mnXzT6QPuOfy1fbdSQ==","DP":"ItYIpEqw6aDjDc/swDifUe0Dq6yl4yim3UyQ4B9NBPQR5M6b7D3vbCnvwql4zJK4s+0N4lRViBtkF+20Td1yc2v8S+THCYZCVxCf2e9Q7Ff/sKecJ9/JmdzHkztCfs0xb+4X3CPEQP+JIYtMGmwOLQgE5XgmUYKr0ahZDhYTCwE=","DQ":"v35mgxfyF/nwnWwWlR9cF3mg0v7SyPfKkwdxGaVnGH6G8nPWpPlO+zueflA5QDXEwGtk/1k3PAzI/OLUwJiKBubx/UMhsqt5+/bKTrFDNHxLANCvGNZggMZIzFZBYRucuXRZbiBe5qpCkKkniUct7w6jd/V1mnsESiJZ7btcxU0=","Exponent":"AQAB","InverseQ":"Vbg2a+wtaYvhTV8AzqJsVvaz0kfC4HFbmwEgA8+BAbS3GEoS3RHFSfB3DHndpnNihIg72DctDNLmV2GMMiTu18uyI+7AUaYNR836fByxptfyhPtSQfw4kINZ3V0GWKJGzzZ5NAOct4/FpRl8xliHetayCfUIuK9jwk0z9i6V6bA=","Modulus":"xlzmN1sBi2V1971MsPD5MTND9dAGncIzYqxa3H+9jx1mNDivY6JgKijUWm5a3D2Y1UPMB3kx6qUf3iH6pZHjq5bk938qRhxrPy9muW55U03HTiW4V5/ga0+OqXj5Tj4lz+29OiQHPErxLRgfXT+WBgrGb75ElzkHajKpJnPgzAZuarlUCwupJNQlav/crwOFrgkhGsnaOW13M8htiSLZozw5lxkbhYIei7YTTQZ3l6rVH1dPL8CvzRJJOTwbnU8k0sUmWiuOhrLzuinlr6uuOTocAVgbj943/witVFtN5B0yhetxEVgFCwxRDTOO1EKVHFtCiAyZBUOlK4gwZ+SbGQ==","P":"7dFfbAkZSdx/ieSMYJHoY1DKC4dLg80RObEEmuJ72MaVJLTtFuBPoRpYOrMUNuupIyPjZZsW8fHRlPRhKW7xFv+Q2aDudh1UaJzFZs3xYKoiXTU/j0B3TB3nrifVLMqsS+8kHOWOojwA4dMjI6GCYCpKmYVvMOE1cuJrQ9EYxoM=","Q":"1YdN8mLchLVoTEwD34Pi3T2U7EjjBDgDCzhjl7x5FBG73TyKMz1n7/KXkXcJ2rqIAsnLqCWpYUeRcWl+IQEQxFKoMwkvmQ33lRkOE0SBZ+FnUAMivRyxOD5qM9z4ccqx0ga4ZRgb1lR85f7VYtMSfIosOuSFxWAbV1e29utxhTM="}} |
||||
@ -0,0 +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: 999999999; |
||||
|
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; |
||||
|
} |
||||
@ -0,0 +1,636 @@ |
|||||
|
var abp = abp || {}; |
||||
|
(function () { |
||||
|
|
||||
|
/* Application paths *****************************************/ |
||||
|
|
||||
|
//Current application root path (including virtual directory if exists).
|
||||
|
abp.appPath = abp.appPath || '/'; |
||||
|
|
||||
|
abp.pageLoadTime = new Date(); |
||||
|
|
||||
|
//Converts given path to absolute path using abp.appPath variable.
|
||||
|
abp.toAbsAppPath = function (path) { |
||||
|
if (path.indexOf('/') == 0) { |
||||
|
path = path.substring(1); |
||||
|
} |
||||
|
|
||||
|
return abp.appPath + path; |
||||
|
}; |
||||
|
|
||||
|
/* LOGGING ***************************************************/ |
||||
|
//Implements Logging API that provides secure & controlled usage of console.log
|
||||
|
|
||||
|
abp.log = abp.log || {}; |
||||
|
|
||||
|
abp.log.levels = { |
||||
|
DEBUG: 1, |
||||
|
INFO: 2, |
||||
|
WARN: 3, |
||||
|
ERROR: 4, |
||||
|
FATAL: 5 |
||||
|
}; |
||||
|
|
||||
|
abp.log.level = abp.log.levels.DEBUG; |
||||
|
|
||||
|
abp.log.log = function (logObject, logLevel) { |
||||
|
if (!window.console || !window.console.log) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (logLevel != undefined && logLevel < abp.log.level) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
console.log(logObject); |
||||
|
}; |
||||
|
|
||||
|
abp.log.debug = function (logObject) { |
||||
|
abp.log.log("DEBUG: ", abp.log.levels.DEBUG); |
||||
|
abp.log.log(logObject, abp.log.levels.DEBUG); |
||||
|
}; |
||||
|
|
||||
|
abp.log.info = function (logObject) { |
||||
|
abp.log.log("INFO: ", abp.log.levels.INFO); |
||||
|
abp.log.log(logObject, abp.log.levels.INFO); |
||||
|
}; |
||||
|
|
||||
|
abp.log.warn = function (logObject) { |
||||
|
abp.log.log("WARN: ", abp.log.levels.WARN); |
||||
|
abp.log.log(logObject, abp.log.levels.WARN); |
||||
|
}; |
||||
|
|
||||
|
abp.log.error = function (logObject) { |
||||
|
abp.log.log("ERROR: ", abp.log.levels.ERROR); |
||||
|
abp.log.log(logObject, abp.log.levels.ERROR); |
||||
|
}; |
||||
|
|
||||
|
abp.log.fatal = function (logObject) { |
||||
|
abp.log.log("FATAL: ", abp.log.levels.FATAL); |
||||
|
abp.log.log(logObject, abp.log.levels.FATAL); |
||||
|
}; |
||||
|
|
||||
|
/* LOCALIZATION ***********************************************/ |
||||
|
|
||||
|
abp.localization = abp.localization || {}; |
||||
|
|
||||
|
abp.localization.values = {}; |
||||
|
|
||||
|
abp.localization.localize = function (key, sourceName) { |
||||
|
sourceName = sourceName || abp.localization.defaultResourceName; |
||||
|
|
||||
|
var source = abp.localization.values[sourceName]; |
||||
|
|
||||
|
if (!source) { |
||||
|
abp.log.warn('Could not find localization source: ' + sourceName); |
||||
|
return key; |
||||
|
} |
||||
|
|
||||
|
var value = source[key]; |
||||
|
if (value == undefined) { |
||||
|
return key; |
||||
|
} |
||||
|
|
||||
|
var copiedArguments = Array.prototype.slice.call(arguments, 0); |
||||
|
copiedArguments.splice(1, 1); |
||||
|
copiedArguments[0] = value; |
||||
|
|
||||
|
return abp.utils.formatString.apply(this, copiedArguments); |
||||
|
}; |
||||
|
|
||||
|
abp.localization.getResource = function (name) { |
||||
|
return function () { |
||||
|
var copiedArguments = Array.prototype.slice.call(arguments, 0); |
||||
|
copiedArguments.splice(1, 0, name); |
||||
|
return abp.localization.localize.apply(this, copiedArguments); |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
abp.localization.defaultResourceName = undefined; |
||||
|
|
||||
|
/* AUTHORIZATION **********************************************/ |
||||
|
|
||||
|
abp.auth = abp.auth || {}; |
||||
|
|
||||
|
abp.auth.policies = abp.auth.policies || {}; |
||||
|
|
||||
|
abp.auth.grantedPolicies = abp.auth.grantedPolicies || {}; |
||||
|
|
||||
|
abp.auth.isGranted = function (policyName) { |
||||
|
return abp.auth.policies[policyName] != undefined && abp.auth.grantedPolicies[policyName] != undefined; |
||||
|
}; |
||||
|
|
||||
|
abp.auth.isAnyGranted = function () { |
||||
|
if (!arguments || arguments.length <= 0) { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
for (var i = 0; i < arguments.length; i++) { |
||||
|
if (abp.auth.isGranted(arguments[i])) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
}; |
||||
|
|
||||
|
abp.auth.areAllGranted = function () { |
||||
|
if (!arguments || arguments.length <= 0) { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
for (var i = 0; i < arguments.length; i++) { |
||||
|
if (!abp.auth.isGranted(arguments[i])) { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
}; |
||||
|
|
||||
|
abp.auth.tokenCookieName = 'Abp.AuthToken'; |
||||
|
|
||||
|
abp.auth.setToken = function (authToken, expireDate) { |
||||
|
abp.utils.setCookieValue(abp.auth.tokenCookieName, authToken, expireDate, abp.appPath, abp.domain); |
||||
|
}; |
||||
|
|
||||
|
abp.auth.getToken = function () { |
||||
|
return abp.utils.getCookieValue(abp.auth.tokenCookieName); |
||||
|
} |
||||
|
|
||||
|
abp.auth.clearToken = function () { |
||||
|
abp.auth.setToken(); |
||||
|
} |
||||
|
|
||||
|
/* SETTINGS *************************************************/ |
||||
|
|
||||
|
abp.setting = abp.setting || {}; |
||||
|
|
||||
|
abp.setting.values = abp.setting.values || {}; |
||||
|
|
||||
|
abp.setting.get = function (name) { |
||||
|
return abp.setting.values[name]; |
||||
|
}; |
||||
|
|
||||
|
abp.setting.getBoolean = function (name) { |
||||
|
var value = abp.setting.get(name); |
||||
|
return value == 'true' || value == 'True'; |
||||
|
}; |
||||
|
|
||||
|
abp.setting.getInt = function (name) { |
||||
|
return parseInt(abp.setting.values[name]); |
||||
|
}; |
||||
|
|
||||
|
/* NOTIFICATION *********************************************/ |
||||
|
//Defines Notification API, not implements it
|
||||
|
|
||||
|
abp.notify = abp.notify || {}; |
||||
|
|
||||
|
abp.notify.success = function (message, title, options) { |
||||
|
abp.log.warn('abp.notify.success is not implemented!'); |
||||
|
}; |
||||
|
|
||||
|
abp.notify.info = function (message, title, options) { |
||||
|
abp.log.warn('abp.notify.info is not implemented!'); |
||||
|
}; |
||||
|
|
||||
|
abp.notify.warn = function (message, title, options) { |
||||
|
abp.log.warn('abp.notify.warn is not implemented!'); |
||||
|
}; |
||||
|
|
||||
|
abp.notify.error = function (message, title, options) { |
||||
|
abp.log.warn('abp.notify.error is not implemented!'); |
||||
|
}; |
||||
|
|
||||
|
/* MESSAGE **************************************************/ |
||||
|
//Defines Message API, not implements it
|
||||
|
|
||||
|
abp.message = abp.message || {}; |
||||
|
|
||||
|
abp.message._showMessage = function (message, title) { |
||||
|
alert((title || '') + ' ' + message); |
||||
|
}; |
||||
|
|
||||
|
abp.message.info = function (message, title) { |
||||
|
abp.log.warn('abp.message.info is not implemented!'); |
||||
|
return abp.message._showMessage(message, title); |
||||
|
}; |
||||
|
|
||||
|
abp.message.success = function (message, title) { |
||||
|
abp.log.warn('abp.message.success is not implemented!'); |
||||
|
return abp.message._showMessage(message, title); |
||||
|
}; |
||||
|
|
||||
|
abp.message.warn = function (message, title) { |
||||
|
abp.log.warn('abp.message.warn is not implemented!'); |
||||
|
return abp.message._showMessage(message, title); |
||||
|
}; |
||||
|
|
||||
|
abp.message.error = function (message, title) { |
||||
|
abp.log.warn('abp.message.error is not implemented!'); |
||||
|
return abp.message._showMessage(message, title); |
||||
|
}; |
||||
|
|
||||
|
abp.message.confirm = function (message, titleOrCallback, callback) { |
||||
|
abp.log.warn('abp.message.confirm is not properly implemented!'); |
||||
|
|
||||
|
if (titleOrCallback && !(typeof titleOrCallback == 'string')) { |
||||
|
callback = titleOrCallback; |
||||
|
} |
||||
|
|
||||
|
var result = confirm(message); |
||||
|
callback && callback(result); |
||||
|
}; |
||||
|
|
||||
|
/* UI *******************************************************/ |
||||
|
|
||||
|
abp.ui = abp.ui || {}; |
||||
|
|
||||
|
/* UI BLOCK */ |
||||
|
//Defines UI Block API and implements basically
|
||||
|
|
||||
|
var $abpBlockArea = document.createElement('div'); |
||||
|
$abpBlockArea.classList.add('abp-block-area'); |
||||
|
|
||||
|
/* opts: { //Can be an object with options or a string for query a selector |
||||
|
* elm: a query selector (optional - default: document.body) |
||||
|
* busy: boolean (optional - default: false) |
||||
|
* promise: A promise with always or finally handler (optional - auto unblocks the ui if provided) |
||||
|
* } |
||||
|
*/ |
||||
|
abp.ui.block = function (opts) { |
||||
|
if (!opts) { |
||||
|
opts = {}; |
||||
|
} else if (typeof opts == 'string') { |
||||
|
opts = { |
||||
|
elm: opts |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
var $elm = document.querySelector(opts.elm) || document.body; |
||||
|
|
||||
|
if (opts.busy) { |
||||
|
$abpBlockArea.classList.add('abp-block-area-busy'); |
||||
|
} else { |
||||
|
$abpBlockArea.classList.remove('abp-block-area-busy'); |
||||
|
} |
||||
|
|
||||
|
if (document.querySelector(opts.elm)) { |
||||
|
$abpBlockArea.style.position = 'absolute'; |
||||
|
} else { |
||||
|
$abpBlockArea.style.position = 'fixed'; |
||||
|
} |
||||
|
|
||||
|
$elm.appendChild($abpBlockArea); |
||||
|
|
||||
|
if (opts.promise) { |
||||
|
if (opts.promise.always) { //jQuery.Deferred style
|
||||
|
opts.promise.always(function () { |
||||
|
abp.ui.unblock({ |
||||
|
$elm: opts.elm |
||||
|
}); |
||||
|
}); |
||||
|
} else if (opts.promise['finally']) { //Q style
|
||||
|
opts.promise['finally'](function () { |
||||
|
abp.ui.unblock({ |
||||
|
$elm: opts.elm |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
/* opts: { |
||||
|
* |
||||
|
* } |
||||
|
*/ |
||||
|
abp.ui.unblock = function (opts) { |
||||
|
var element = document.querySelector('.abp-block-area'); |
||||
|
if (element) { |
||||
|
element.classList.add('abp-block-area-disappearing'); |
||||
|
setTimeout(function () { |
||||
|
if (element) { |
||||
|
element.classList.remove('abp-block-area-disappearing'); |
||||
|
element.parentElement.removeChild(element); |
||||
|
} |
||||
|
}, 250); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
/* UI BUSY */ |
||||
|
//Defines UI Busy API, not implements it
|
||||
|
|
||||
|
abp.ui.setBusy = function (opts) { |
||||
|
if (!opts) { |
||||
|
opts = { |
||||
|
busy: true |
||||
|
}; |
||||
|
} else if (typeof opts == 'string') { |
||||
|
opts = { |
||||
|
elm: opts, |
||||
|
busy: true |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
abp.ui.block(opts); |
||||
|
}; |
||||
|
|
||||
|
abp.ui.clearBusy = function (opts) { |
||||
|
abp.ui.unblock(opts); |
||||
|
}; |
||||
|
|
||||
|
/* SIMPLE EVENT BUS *****************************************/ |
||||
|
|
||||
|
abp.event = (function () { |
||||
|
|
||||
|
var _callbacks = {}; |
||||
|
|
||||
|
var on = function (eventName, callback) { |
||||
|
if (!_callbacks[eventName]) { |
||||
|
_callbacks[eventName] = []; |
||||
|
} |
||||
|
|
||||
|
_callbacks[eventName].push(callback); |
||||
|
}; |
||||
|
|
||||
|
var off = function (eventName, callback) { |
||||
|
var callbacks = _callbacks[eventName]; |
||||
|
if (!callbacks) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var index = -1; |
||||
|
for (var i = 0; i < callbacks.length; i++) { |
||||
|
if (callbacks[i] === callback) { |
||||
|
index = i; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (index < 0) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
_callbacks[eventName].splice(index, 1); |
||||
|
}; |
||||
|
|
||||
|
var trigger = function (eventName) { |
||||
|
var callbacks = _callbacks[eventName]; |
||||
|
if (!callbacks || !callbacks.length) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var args = Array.prototype.slice.call(arguments, 1); |
||||
|
for (var i = 0; i < callbacks.length; i++) { |
||||
|
callbacks[i].apply(this, args); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// Public interface ///////////////////////////////////////////////////
|
||||
|
|
||||
|
return { |
||||
|
on: on, |
||||
|
off: off, |
||||
|
trigger: trigger |
||||
|
}; |
||||
|
})(); |
||||
|
|
||||
|
|
||||
|
/* UTILS ***************************************************/ |
||||
|
|
||||
|
abp.utils = abp.utils || {}; |
||||
|
|
||||
|
/* Creates a name namespace. |
||||
|
* Example: |
||||
|
* var taskService = abp.utils.createNamespace(abp, 'services.task'); |
||||
|
* taskService will be equal to abp.services.task |
||||
|
* first argument (root) must be defined first |
||||
|
************************************************************/ |
||||
|
abp.utils.createNamespace = function (root, ns) { |
||||
|
var parts = ns.split('.'); |
||||
|
for (var i = 0; i < parts.length; i++) { |
||||
|
if (typeof root[parts[i]] == 'undefined') { |
||||
|
root[parts[i]] = {}; |
||||
|
} |
||||
|
|
||||
|
root = root[parts[i]]; |
||||
|
} |
||||
|
|
||||
|
return root; |
||||
|
}; |
||||
|
|
||||
|
/* Find and replaces a string (search) to another string (replacement) in |
||||
|
* given string (str). |
||||
|
* Example: |
||||
|
* abp.utils.replaceAll('This is a test string', 'is', 'X') = 'ThX X a test string' |
||||
|
************************************************************/ |
||||
|
abp.utils.replaceAll = function (str, search, replacement) { |
||||
|
var fix = search.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); |
||||
|
return str.replace(new RegExp(fix, 'g'), replacement); |
||||
|
}; |
||||
|
|
||||
|
/* Formats a string just like string.format in C#. |
||||
|
* Example: |
||||
|
* abp.utils.formatString('Hello {0}','Tuana') = 'Hello Tuana' |
||||
|
************************************************************/ |
||||
|
abp.utils.formatString = function () { |
||||
|
if (arguments.length < 1) { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
var str = arguments[0]; |
||||
|
|
||||
|
for (var i = 1; i < arguments.length; i++) { |
||||
|
var placeHolder = '{' + (i - 1) + '}'; |
||||
|
str = abp.utils.replaceAll(str, placeHolder, arguments[i]); |
||||
|
} |
||||
|
|
||||
|
return str; |
||||
|
}; |
||||
|
|
||||
|
abp.utils.toPascalCase = function (str) { |
||||
|
if (!str || !str.length) { |
||||
|
return str; |
||||
|
} |
||||
|
|
||||
|
if (str.length === 1) { |
||||
|
return str.charAt(0).toUpperCase(); |
||||
|
} |
||||
|
|
||||
|
return str.charAt(0).toUpperCase() + str.substr(1); |
||||
|
} |
||||
|
|
||||
|
abp.utils.toCamelCase = function (str) { |
||||
|
if (!str || !str.length) { |
||||
|
return str; |
||||
|
} |
||||
|
|
||||
|
if (str.length === 1) { |
||||
|
return str.charAt(0).toLowerCase(); |
||||
|
} |
||||
|
|
||||
|
return str.charAt(0).toLowerCase() + str.substr(1); |
||||
|
} |
||||
|
|
||||
|
abp.utils.truncateString = function (str, maxLength) { |
||||
|
if (!str || !str.length || str.length <= maxLength) { |
||||
|
return str; |
||||
|
} |
||||
|
|
||||
|
return str.substr(0, maxLength); |
||||
|
}; |
||||
|
|
||||
|
abp.utils.truncateStringWithPostfix = function (str, maxLength, postfix) { |
||||
|
postfix = postfix || '...'; |
||||
|
|
||||
|
if (!str || !str.length || str.length <= maxLength) { |
||||
|
return str; |
||||
|
} |
||||
|
|
||||
|
if (maxLength <= postfix.length) { |
||||
|
return postfix.substr(0, maxLength); |
||||
|
} |
||||
|
|
||||
|
return str.substr(0, maxLength - postfix.length) + postfix; |
||||
|
}; |
||||
|
|
||||
|
abp.utils.isFunction = function (obj) { |
||||
|
return !!(obj && obj.constructor && obj.call && obj.apply); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* parameterInfos should be an array of { name, value } objects |
||||
|
* where name is query string parameter name and value is it's value. |
||||
|
* includeQuestionMark is true by default. |
||||
|
*/ |
||||
|
abp.utils.buildQueryString = function (parameterInfos, includeQuestionMark) { |
||||
|
if (includeQuestionMark === undefined) { |
||||
|
includeQuestionMark = true; |
||||
|
} |
||||
|
|
||||
|
var qs = ''; |
||||
|
|
||||
|
function addSeperator() { |
||||
|
if (!qs.length) { |
||||
|
if (includeQuestionMark) { |
||||
|
qs = qs + '?'; |
||||
|
} |
||||
|
} else { |
||||
|
qs = qs + '&'; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for (var i = 0; i < parameterInfos.length; ++i) { |
||||
|
var parameterInfo = parameterInfos[i]; |
||||
|
if (parameterInfo.value === undefined) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (parameterInfo.value === null) { |
||||
|
parameterInfo.value = ''; |
||||
|
} |
||||
|
|
||||
|
addSeperator(); |
||||
|
|
||||
|
if (parameterInfo.value.toJSON && typeof parameterInfo.value.toJSON === "function") { |
||||
|
qs = qs + parameterInfo.name + '=' + encodeURIComponent(parameterInfo.value.toJSON()); |
||||
|
} else if (Array.isArray(parameterInfo.value) && parameterInfo.value.length) { |
||||
|
for (var j = 0; j < parameterInfo.value.length; j++) { |
||||
|
if (j > 0) { |
||||
|
addSeperator(); |
||||
|
} |
||||
|
|
||||
|
qs = qs + parameterInfo.name + '[' + j + ']=' + encodeURIComponent(parameterInfo.value[j]); |
||||
|
} |
||||
|
} else { |
||||
|
qs = qs + parameterInfo.name + '=' + encodeURIComponent(parameterInfo.value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return qs; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets a cookie value for given key. |
||||
|
* This is a simple implementation created to be used by ABP. |
||||
|
* Please use a complete cookie library if you need. |
||||
|
* @param {string} key |
||||
|
* @param {string} value |
||||
|
* @param {Date} expireDate (optional). If not specified the cookie will expire at the end of session. |
||||
|
* @param {string} path (optional) |
||||
|
*/ |
||||
|
abp.utils.setCookieValue = function (key, value, expireDate, path) { |
||||
|
var cookieValue = encodeURIComponent(key) + '='; |
||||
|
|
||||
|
if (value) { |
||||
|
cookieValue = cookieValue + encodeURIComponent(value); |
||||
|
} |
||||
|
|
||||
|
if (expireDate) { |
||||
|
cookieValue = cookieValue + "; expires=" + expireDate.toUTCString(); |
||||
|
} |
||||
|
|
||||
|
if (path) { |
||||
|
cookieValue = cookieValue + "; path=" + path; |
||||
|
} |
||||
|
|
||||
|
document.cookie = cookieValue; |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Gets a cookie with given key. |
||||
|
* This is a simple implementation created to be used by ABP. |
||||
|
* Please use a complete cookie library if you need. |
||||
|
* @param {string} key |
||||
|
* @returns {string} Cookie value or null |
||||
|
*/ |
||||
|
abp.utils.getCookieValue = function (key) { |
||||
|
var equalities = document.cookie.split('; '); |
||||
|
for (var i = 0; i < equalities.length; i++) { |
||||
|
if (!equalities[i]) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
var splitted = equalities[i].split('='); |
||||
|
if (splitted.length != 2) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (decodeURIComponent(splitted[0]) === key) { |
||||
|
return decodeURIComponent(splitted[1] || ''); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Deletes cookie for given key. |
||||
|
* This is a simple implementation created to be used by ABP. |
||||
|
* Please use a complete cookie library if you need. |
||||
|
* @param {string} key |
||||
|
* @param {string} path (optional) |
||||
|
*/ |
||||
|
abp.utils.deleteCookie = function (key, path) { |
||||
|
var cookieValue = encodeURIComponent(key) + '='; |
||||
|
|
||||
|
cookieValue = cookieValue + "; expires=" + (new Date(new Date().getTime() - 86400000)).toUTCString(); |
||||
|
|
||||
|
if (path) { |
||||
|
cookieValue = cookieValue + "; path=" + path; |
||||
|
} |
||||
|
|
||||
|
document.cookie = cookieValue; |
||||
|
} |
||||
|
|
||||
|
/* SECURITY ***************************************/ |
||||
|
abp.security = abp.security || {}; |
||||
|
abp.security.antiForgery = abp.security.antiForgery || {}; |
||||
|
|
||||
|
abp.security.antiForgery.tokenCookieName = 'XSRF-TOKEN'; |
||||
|
abp.security.antiForgery.tokenHeaderName = 'X-XSRF-TOKEN'; |
||||
|
|
||||
|
abp.security.antiForgery.getToken = function () { |
||||
|
return abp.utils.getCookieValue(abp.security.antiForgery.tokenCookieName); |
||||
|
}; |
||||
|
|
||||
|
})(); |
||||
@ -0,0 +1,389 @@ |
|||||
|
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 |
||||
|
} |
||||
|
})(); |
||||
|
|
||||
|
})(jQuery); |
||||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,202 @@ |
|||||
|
table.dataTable { |
||||
|
clear: both; |
||||
|
margin-top: 6px !important; |
||||
|
margin-bottom: 6px !important; |
||||
|
max-width: none !important; |
||||
|
border-collapse: separate !important; |
||||
|
} |
||||
|
table.dataTable td, |
||||
|
table.dataTable th { |
||||
|
-webkit-box-sizing: content-box; |
||||
|
box-sizing: content-box; |
||||
|
} |
||||
|
table.dataTable td.dataTables_empty, |
||||
|
table.dataTable th.dataTables_empty { |
||||
|
text-align: center; |
||||
|
} |
||||
|
table.dataTable.nowrap th, |
||||
|
table.dataTable.nowrap td { |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
div.dataTables_wrapper div.dataTables_length label { |
||||
|
font-weight: normal; |
||||
|
text-align: left; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
div.dataTables_wrapper div.dataTables_length select { |
||||
|
width: 75px; |
||||
|
display: inline-block; |
||||
|
} |
||||
|
div.dataTables_wrapper div.dataTables_filter { |
||||
|
text-align: right; |
||||
|
} |
||||
|
div.dataTables_wrapper div.dataTables_filter label { |
||||
|
font-weight: normal; |
||||
|
white-space: nowrap; |
||||
|
text-align: left; |
||||
|
} |
||||
|
div.dataTables_wrapper div.dataTables_filter input { |
||||
|
margin-left: 0.5em; |
||||
|
display: inline-block; |
||||
|
width: auto; |
||||
|
} |
||||
|
div.dataTables_wrapper div.dataTables_info { |
||||
|
padding-top: 0.85em; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
div.dataTables_wrapper div.dataTables_paginate { |
||||
|
margin: 0; |
||||
|
white-space: nowrap; |
||||
|
text-align: right; |
||||
|
} |
||||
|
div.dataTables_wrapper div.dataTables_paginate ul.pagination { |
||||
|
margin: 2px 0; |
||||
|
white-space: nowrap; |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
div.dataTables_wrapper div.dataTables_processing { |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
left: 50%; |
||||
|
width: 200px; |
||||
|
margin-left: -100px; |
||||
|
margin-top: -26px; |
||||
|
text-align: center; |
||||
|
padding: 1em 0; |
||||
|
} |
||||
|
|
||||
|
table.dataTable thead > tr > th.sorting_asc, table.dataTable thead > tr > th.sorting_desc, table.dataTable thead > tr > th.sorting, |
||||
|
table.dataTable thead > tr > td.sorting_asc, |
||||
|
table.dataTable thead > tr > td.sorting_desc, |
||||
|
table.dataTable thead > tr > td.sorting { |
||||
|
padding-right: 30px; |
||||
|
} |
||||
|
table.dataTable thead > tr > th:active, |
||||
|
table.dataTable thead > tr > td:active { |
||||
|
outline: none; |
||||
|
} |
||||
|
table.dataTable thead .sorting, |
||||
|
table.dataTable thead .sorting_asc, |
||||
|
table.dataTable thead .sorting_desc, |
||||
|
table.dataTable thead .sorting_asc_disabled, |
||||
|
table.dataTable thead .sorting_desc_disabled { |
||||
|
cursor: pointer; |
||||
|
position: relative; |
||||
|
} |
||||
|
table.dataTable thead .sorting:before, table.dataTable thead .sorting:after, |
||||
|
table.dataTable thead .sorting_asc:before, |
||||
|
table.dataTable thead .sorting_asc:after, |
||||
|
table.dataTable thead .sorting_desc:before, |
||||
|
table.dataTable thead .sorting_desc:after, |
||||
|
table.dataTable thead .sorting_asc_disabled:before, |
||||
|
table.dataTable thead .sorting_asc_disabled:after, |
||||
|
table.dataTable thead .sorting_desc_disabled:before, |
||||
|
table.dataTable thead .sorting_desc_disabled:after { |
||||
|
position: absolute; |
||||
|
bottom: 0.9em; |
||||
|
display: block; |
||||
|
opacity: 0.3; |
||||
|
} |
||||
|
table.dataTable thead .sorting:before, |
||||
|
table.dataTable thead .sorting_asc:before, |
||||
|
table.dataTable thead .sorting_desc:before, |
||||
|
table.dataTable thead .sorting_asc_disabled:before, |
||||
|
table.dataTable thead .sorting_desc_disabled:before { |
||||
|
right: 1em; |
||||
|
content: "\2191"; |
||||
|
} |
||||
|
table.dataTable thead .sorting:after, |
||||
|
table.dataTable thead .sorting_asc:after, |
||||
|
table.dataTable thead .sorting_desc:after, |
||||
|
table.dataTable thead .sorting_asc_disabled:after, |
||||
|
table.dataTable thead .sorting_desc_disabled:after { |
||||
|
right: 0.5em; |
||||
|
content: "\2193"; |
||||
|
} |
||||
|
table.dataTable thead .sorting_asc:before, |
||||
|
table.dataTable thead .sorting_desc:after { |
||||
|
opacity: 1; |
||||
|
} |
||||
|
table.dataTable thead .sorting_asc_disabled:before, |
||||
|
table.dataTable thead .sorting_desc_disabled:after { |
||||
|
opacity: 0; |
||||
|
} |
||||
|
|
||||
|
div.dataTables_scrollHead table.dataTable { |
||||
|
margin-bottom: 0 !important; |
||||
|
} |
||||
|
|
||||
|
div.dataTables_scrollBody table { |
||||
|
border-top: none; |
||||
|
margin-top: 0 !important; |
||||
|
margin-bottom: 0 !important; |
||||
|
} |
||||
|
div.dataTables_scrollBody table thead .sorting:after, |
||||
|
div.dataTables_scrollBody table thead .sorting_asc:after, |
||||
|
div.dataTables_scrollBody table thead .sorting_desc:after { |
||||
|
display: none; |
||||
|
} |
||||
|
div.dataTables_scrollBody table tbody tr:first-child th, |
||||
|
div.dataTables_scrollBody table tbody tr:first-child td { |
||||
|
border-top: none; |
||||
|
} |
||||
|
|
||||
|
div.dataTables_scrollFoot > .dataTables_scrollFootInner { |
||||
|
box-sizing: content-box; |
||||
|
} |
||||
|
div.dataTables_scrollFoot > .dataTables_scrollFootInner > table { |
||||
|
margin-top: 0 !important; |
||||
|
border-top: none; |
||||
|
} |
||||
|
|
||||
|
@media screen and (max-width: 767px) { |
||||
|
div.dataTables_wrapper div.dataTables_length, |
||||
|
div.dataTables_wrapper div.dataTables_filter, |
||||
|
div.dataTables_wrapper div.dataTables_info, |
||||
|
div.dataTables_wrapper div.dataTables_paginate { |
||||
|
text-align: center; |
||||
|
} |
||||
|
} |
||||
|
table.dataTable.table-sm > thead > tr > th { |
||||
|
padding-right: 20px; |
||||
|
} |
||||
|
table.dataTable.table-sm .sorting:before, |
||||
|
table.dataTable.table-sm .sorting_asc:before, |
||||
|
table.dataTable.table-sm .sorting_desc:before { |
||||
|
top: 5px; |
||||
|
right: 0.85em; |
||||
|
} |
||||
|
table.dataTable.table-sm .sorting:after, |
||||
|
table.dataTable.table-sm .sorting_asc:after, |
||||
|
table.dataTable.table-sm .sorting_desc:after { |
||||
|
top: 5px; |
||||
|
} |
||||
|
|
||||
|
table.table-bordered.dataTable th, |
||||
|
table.table-bordered.dataTable td { |
||||
|
border-left-width: 0; |
||||
|
} |
||||
|
table.table-bordered.dataTable th:last-child, table.table-bordered.dataTable th:last-child, |
||||
|
table.table-bordered.dataTable td:last-child, |
||||
|
table.table-bordered.dataTable td:last-child { |
||||
|
border-right-width: 0; |
||||
|
} |
||||
|
table.table-bordered.dataTable tbody th, |
||||
|
table.table-bordered.dataTable tbody td { |
||||
|
border-bottom-width: 0; |
||||
|
} |
||||
|
|
||||
|
div.dataTables_scrollHead table.table-bordered { |
||||
|
border-bottom-width: 0; |
||||
|
} |
||||
|
|
||||
|
div.table-responsive > div.dataTables_wrapper > div.row { |
||||
|
margin: 0; |
||||
|
} |
||||
|
div.table-responsive > div.dataTables_wrapper > div.row > div[class^="col-"]:first-child { |
||||
|
padding-left: 0; |
||||
|
} |
||||
|
div.table-responsive > div.dataTables_wrapper > div.row > div[class^="col-"]:last-child { |
||||
|
padding-right: 0; |
||||
|
} |
||||
@ -0,0 +1,184 @@ |
|||||
|
/*! DataTables Bootstrap 3 integration |
||||
|
* ©2011-2015 SpryMedia Ltd - datatables.net/license |
||||
|
*/ |
||||
|
|
||||
|
/** |
||||
|
* DataTables integration for Bootstrap 3. This requires Bootstrap 3 and |
||||
|
* DataTables 1.10 or newer. |
||||
|
* |
||||
|
* This file sets the defaults and adds options to DataTables to style its |
||||
|
* controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap
|
||||
|
* for further information. |
||||
|
*/ |
||||
|
(function( factory ){ |
||||
|
if ( typeof define === 'function' && define.amd ) { |
||||
|
// AMD
|
||||
|
define( ['jquery', 'datatables.net'], function ( $ ) { |
||||
|
return factory( $, window, document ); |
||||
|
} ); |
||||
|
} |
||||
|
else if ( typeof exports === 'object' ) { |
||||
|
// CommonJS
|
||||
|
module.exports = function (root, $) { |
||||
|
if ( ! root ) { |
||||
|
root = window; |
||||
|
} |
||||
|
|
||||
|
if ( ! $ || ! $.fn.dataTable ) { |
||||
|
// Require DataTables, which attaches to jQuery, including
|
||||
|
// jQuery if needed and have a $ property so we can access the
|
||||
|
// jQuery object that is used
|
||||
|
$ = require('datatables.net')(root, $).$; |
||||
|
} |
||||
|
|
||||
|
return factory( $, root, root.document ); |
||||
|
}; |
||||
|
} |
||||
|
else { |
||||
|
// Browser
|
||||
|
factory( jQuery, window, document ); |
||||
|
} |
||||
|
}(function( $, window, document, undefined ) { |
||||
|
'use strict'; |
||||
|
var DataTable = $.fn.dataTable; |
||||
|
|
||||
|
|
||||
|
/* Set the defaults for DataTables initialisation */ |
||||
|
$.extend( true, DataTable.defaults, { |
||||
|
dom: |
||||
|
"<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>>" + |
||||
|
"<'row'<'col-sm-12'tr>>" + |
||||
|
"<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", |
||||
|
renderer: 'bootstrap' |
||||
|
} ); |
||||
|
|
||||
|
|
||||
|
/* Default class modification */ |
||||
|
$.extend( DataTable.ext.classes, { |
||||
|
sWrapper: "dataTables_wrapper container-fluid dt-bootstrap4", |
||||
|
sFilterInput: "form-control form-control-sm", |
||||
|
sLengthSelect: "form-control form-control-sm", |
||||
|
sProcessing: "dataTables_processing card", |
||||
|
sPageButton: "paginate_button page-item" |
||||
|
} ); |
||||
|
|
||||
|
|
||||
|
/* Bootstrap paging button renderer */ |
||||
|
DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) { |
||||
|
var api = new DataTable.Api( settings ); |
||||
|
var classes = settings.oClasses; |
||||
|
var lang = settings.oLanguage.oPaginate; |
||||
|
var aria = settings.oLanguage.oAria.paginate || {}; |
||||
|
var btnDisplay, btnClass, counter=0; |
||||
|
|
||||
|
var attach = function( container, buttons ) { |
||||
|
var i, ien, node, button; |
||||
|
var clickHandler = function ( e ) { |
||||
|
e.preventDefault(); |
||||
|
if ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) { |
||||
|
api.page( e.data.action ).draw( 'page' ); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
for ( i=0, ien=buttons.length ; i<ien ; i++ ) { |
||||
|
button = buttons[i]; |
||||
|
|
||||
|
if ( $.isArray( button ) ) { |
||||
|
attach( container, button ); |
||||
|
} |
||||
|
else { |
||||
|
btnDisplay = ''; |
||||
|
btnClass = ''; |
||||
|
|
||||
|
switch ( button ) { |
||||
|
case 'ellipsis': |
||||
|
btnDisplay = '…'; |
||||
|
btnClass = 'disabled'; |
||||
|
break; |
||||
|
|
||||
|
case 'first': |
||||
|
btnDisplay = lang.sFirst; |
||||
|
btnClass = button + (page > 0 ? |
||||
|
'' : ' disabled'); |
||||
|
break; |
||||
|
|
||||
|
case 'previous': |
||||
|
btnDisplay = lang.sPrevious; |
||||
|
btnClass = button + (page > 0 ? |
||||
|
'' : ' disabled'); |
||||
|
break; |
||||
|
|
||||
|
case 'next': |
||||
|
btnDisplay = lang.sNext; |
||||
|
btnClass = button + (page < pages-1 ? |
||||
|
'' : ' disabled'); |
||||
|
break; |
||||
|
|
||||
|
case 'last': |
||||
|
btnDisplay = lang.sLast; |
||||
|
btnClass = button + (page < pages-1 ? |
||||
|
'' : ' disabled'); |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
btnDisplay = button + 1; |
||||
|
btnClass = page === button ? |
||||
|
'active' : ''; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
if ( btnDisplay ) { |
||||
|
node = $('<li>', { |
||||
|
'class': classes.sPageButton+' '+btnClass, |
||||
|
'id': idx === 0 && typeof button === 'string' ? |
||||
|
settings.sTableId +'_'+ button : |
||||
|
null |
||||
|
} ) |
||||
|
.append( $('<a>', { |
||||
|
'href': '#', |
||||
|
'aria-controls': settings.sTableId, |
||||
|
'aria-label': aria[ button ], |
||||
|
'data-dt-idx': counter, |
||||
|
'tabindex': settings.iTabIndex, |
||||
|
'class': 'page-link' |
||||
|
} ) |
||||
|
.html( btnDisplay ) |
||||
|
) |
||||
|
.appendTo( container ); |
||||
|
|
||||
|
settings.oApi._fnBindAction( |
||||
|
node, {action: button}, clickHandler |
||||
|
); |
||||
|
|
||||
|
counter++; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// IE9 throws an 'unknown error' if document.activeElement is used
|
||||
|
// inside an iframe or frame.
|
||||
|
var activeEl; |
||||
|
|
||||
|
try { |
||||
|
// Because this approach is destroying and recreating the paging
|
||||
|
// elements, focus is lost on the select button which is bad for
|
||||
|
// accessibility. So we want to restore focus once the draw has
|
||||
|
// completed
|
||||
|
activeEl = $(host).find(document.activeElement).data('dt-idx'); |
||||
|
} |
||||
|
catch (e) {} |
||||
|
|
||||
|
attach( |
||||
|
$(host).empty().html('<ul class="pagination"/>').children('ul'), |
||||
|
buttons |
||||
|
); |
||||
|
|
||||
|
if ( activeEl !== undefined ) { |
||||
|
$(host).find( '[data-dt-idx='+activeEl+']' ).focus(); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
return DataTable; |
||||
|
})); |
||||
File diff suppressed because it is too large
File diff suppressed because it is too large
Binary file not shown.
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue