This commit is contained in:
Przemysław Stawujak 2018-11-27 17:46:25 +01:00
parent 5e6f7ea90a
commit 23a46d9f28
354 changed files with 49307 additions and 0 deletions

9
SystemKonkursow/4.2.1/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# IDEs and editors
.vs/
obj/
bin/
aspnet-core/src/SystemKonkursow.Web.Host/App_Data/Logs/
aspnet-core/src/SystemKonkursow.Web.Mvc/App_Data/Logs/
aspnet-core/src/SystemKonkursow.Migrator/Logs/Logs.txt

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 ASP.NET Boilerplate
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,33 @@
# Introduction
This is a template to create **ASP.NET Core MVC / Angular** based startup projects for [ASP.NET Boilerplate](https://aspnetboilerplate.com/Pages/Documents). It has 2 different versions:
1. [ASP.NET Core MVC & jQuery](https://aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template-Core) (server rendered multi-page application).
2. [ASP.NET Core & Angular](https://aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template-Angular) (single page application).
User Interface is based on [BSB Admin theme](https://github.com/gurayyarar/AdminBSBMaterialDesign).
# Download
Create & download your project from https://aspnetboilerplate.com/Templates
# Screenshots
#### Sample Dashboard Page
![](_screenshots/module-zero-core-template-ui-home.png)
#### User Creation Modal
![](_screenshots/module-zero-core-template-ui-user-create-modal.png)
#### Login Page
![](_screenshots/module-zero-core-template-ui-login.png)
# Documentation
* [ASP.NET Core MVC & jQuery version.](https://aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template-Core)
* [ASP.NET Core & Angular version.](https://aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template-Angular)
# License
[MIT](LICENSE).

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

View File

@ -0,0 +1,12 @@
# Editor configuration, see http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false

View File

@ -0,0 +1,43 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
# dependencies
/node_modules
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
.vs/
[Oo]bj/
bin/
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# misc
/.sass-cache
/connect.lock
/coverage/*
/libpeerconnection.log
npm-debug.log
testem.log
/typings
# e2e
/e2e/*.js
/e2e/*.map
#System Files
.DS_Store
Thumbs.db

View File

@ -0,0 +1,3 @@
FROM nginx
COPY . /usr/share/nginx/html

View File

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:14424/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"SystemKonkursow.AngularUI": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,27 @@
# SystemKonkursowTemplate
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.0-beta.31.
## 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/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/).
Before running the tests make sure you are serving the app via `ng serve`.
## 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).

View File

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<AssemblyName>angular</AssemblyName>
<PackageId>angular</PackageId>
</PropertyGroup>
<ItemGroup>
<Compile Remove="node_modules\**" />
<EmbeddedResource Remove="node_modules\**" />
<None Remove="node_modules\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="dist" />
<None Include="App.config" />
<None Update="wwwroot\**\*;web.config">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Update="Dockerfile">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,33 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SystemKonkursow.AngularUI", "SystemKonkursow.AngularUI.csproj", "{11BD8782-23F0-45A0-9A00-A213373B0F5D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Debug|x64.ActiveCfg = Debug|Any CPU
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Debug|x64.Build.0 = Debug|Any CPU
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Debug|x86.ActiveCfg = Debug|Any CPU
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Debug|x86.Build.0 = Debug|Any CPU
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Release|Any CPU.Build.0 = Release|Any CPU
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Release|x64.ActiveCfg = Release|Any CPU
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Release|x64.Build.0 = Release|Any CPU
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Release|x86.ActiveCfg = Release|Any CPU
{11BD8782-23F0-45A0-9A00-A213373B0F5D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,249 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"SystemKonkursow": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"tsConfig": "src/tsconfig.json",
"polyfills": "src/polyfills.ts",
"assets": [
"src/assets",
"src/favicon.ico",
{
"glob": "abp.signalr.js",
"input": "node_modules/abp-web-resources/Abp/Framework/scripts/libs",
"output": "/assets/abp"
},
{
"glob": "abp.signalr-client.js",
"input": "node_modules/abp-web-resources/Abp/Framework/scripts/libs",
"output": "/assets/abp"
}
],
"styles": [
"src/assets/fonts/roboto/roboto.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/simple-line-icons/css/simple-line-icons.css",
"node_modules/font-awesome/css/font-awesome.css",
"node_modules/famfamfam-flags/dist/sprite/famfamfam-flags.css",
"node_modules/toastr/build/toastr.css",
"node_modules/node-waves/dist/waves.css",
"src/bsb-theme/css/materialize.css",
"src/bsb-theme/css/style.css",
"src/bsb-theme/css/themes/all-themes.css",
"src/shared/core.less"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/jquery-migrate/dist/jquery-migrate.min.js",
"node_modules/js-cookie/src/js.cookie.js",
"node_modules/bootstrap/dist/js/bootstrap.js",
"node_modules/lodash/lodash.min.js",
"node_modules/moment/min/moment.min.js",
"node_modules/@aspnet/signalr/dist/browser/signalr.min.js",
"node_modules/toastr/toastr.js",
"node_modules/sweetalert/dist/sweetalert.min.js",
"node_modules/block-ui/jquery.blockUI.js",
"node_modules/spin.js/spin.min.js",
"node_modules/spin.js/jquery.spin.js",
"node_modules/push.js/bin/push.min.js",
"node_modules/jquery-slimscroll/jquery.slimscroll.min.js",
"node_modules/node-waves/dist/waves.min.js",
"node_modules/jquery-countto/jquery.countTo.js",
"node_modules/raphael/raphael.min.js",
"node_modules/morris.js/morris.min.js",
"node_modules/chart.js/dist/Chart.bundle.min.js",
"node_modules/flot/jquery.flot.js",
"node_modules/flot/jquery.flot.resize.js",
"node_modules/flot/jquery.flot.pie.js",
"node_modules/flot/jquery.flot.categories.js",
"node_modules/flot/jquery.flot.time.js",
"node_modules/jquery-sparkline/jquery.sparkline.min.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/abp.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.jquery.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.toastr.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.blockUI.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.spin.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.sweet-alert.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.moment.js",
"src/bsb-theme/js/admin.js",
"src/bsb-theme/js/demo.js",
"src/bsb-theme/js/jquery.validate.js"
]
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
},
"hmr": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.hmr.ts"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "SystemKonkursow:build"
},
"configurations": {
"production": {
"browserTarget": "SystemKonkursow:build:production"
},
"hmr": {
"browserTarget": "SystemKonkursow:build:hmr"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "SystemKonkursow:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"karmaConfig": "./karma.conf.js",
"polyfills": "src/polyfills.ts",
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/jquery-migrate/dist/jquery-migrate.min.js",
"node_modules/js-cookie/src/js.cookie.js",
"node_modules/bootstrap/dist/js/bootstrap.js",
"node_modules/lodash/lodash.min.js",
"node_modules/moment/min/moment.min.js",
"node_modules/@aspnet/signalr/dist/browser/signalr.min.js",
"node_modules/toastr/toastr.js",
"node_modules/sweetalert/dist/sweetalert.min.js",
"node_modules/block-ui/jquery.blockUI.js",
"node_modules/spin.js/spin.min.js",
"node_modules/spin.js/jquery.spin.js",
"node_modules/push.js/bin/push.min.js",
"node_modules/jquery-slimscroll/jquery.slimscroll.min.js",
"node_modules/node-waves/dist/waves.min.js",
"node_modules/jquery-countto/jquery.countTo.js",
"node_modules/raphael/raphael.min.js",
"node_modules/morris.js/morris.min.js",
"node_modules/chart.js/dist/Chart.bundle.min.js",
"node_modules/flot/jquery.flot.js",
"node_modules/flot/jquery.flot.resize.js",
"node_modules/flot/jquery.flot.pie.js",
"node_modules/flot/jquery.flot.categories.js",
"node_modules/flot/jquery.flot.time.js",
"node_modules/jquery-sparkline/jquery.sparkline.min.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/abp.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.jquery.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.toastr.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.blockUI.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.spin.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.sweet-alert.js",
"node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.moment.js",
"src/bsb-theme/js/admin.js",
"src/bsb-theme/js/demo.js",
"src/bsb-theme/js/jquery.validate.js"
],
"styles": [
"src/assets/fonts/roboto/roboto.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/simple-line-icons/css/simple-line-icons.css",
"node_modules/font-awesome/css/font-awesome.css",
"node_modules/famfamfam-flags/dist/sprite/famfamfam-flags.css",
"node_modules/toastr/build/toastr.css",
"node_modules/node-waves/dist/waves.css",
"src/bsb-theme/css/materialize.css",
"src/bsb-theme/css/style.css",
"src/bsb-theme/css/themes/all-themes.css",
"src/shared/core.less"
],
"assets": [
"src/assets",
"src/favicon.ico",
{
"glob": "abp.signalr.js",
"input": "node_modules/abp-web-resources/Abp/Framework/scripts/libs",
"output": "/assets/abp"
},
{
"glob": "abp.signalr-client.js",
"input": "node_modules/abp-web-resources/Abp/Framework/scripts/libs",
"output": "/assets/abp"
}
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.json"
],
"exclude": []
}
}
}
},
"SystemKonkursow-e2e": {
"root": "",
"sourceRoot": "",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "./protractor.conf.js",
"devServerTarget": "SystemKonkursow:serve"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"e2e/tsconfig.json"
],
"exclude": []
}
}
}
}
},
"defaultProject": "SystemKonkursow",
"schematics": {
"@schematics/angular:component": {
"prefix": "app",
"styleext": "css"
},
"@schematics/angular:directive": {
"prefix": "app"
}
}
}

View File

@ -0,0 +1,5 @@
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>

View File

@ -0,0 +1,14 @@
import { SystemKonkursowTemplatePage } from './app.po';
describe('SystemKonkursow App', function() {
let page: SystemKonkursowTemplatePage;
beforeEach(() => {
page = new SystemKonkursowTemplatePage();
});
it('should display message saying app works', () => {
page.navigateTo();
expect(page.getParagraphText()).toEqual('app works!');
});
});

View File

@ -0,0 +1,11 @@
import { browser, element, by } from 'protractor';
export class SystemKonkursowTemplatePage {
navigateTo() {
return browser.get('/');
}
getParagraphText() {
return element(by.css('app-root h1')).getText();
}
}

View File

@ -0,0 +1,19 @@
{
"compileOnSave": false,
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"es2016"
],
"module": "commonjs",
"moduleResolution": "node",
"outDir": "../dist/out-tsc-e2e",
"sourceMap": true,
"target": "es6",
"typeRoots": [
"../node_modules/@types"
]
}
}

View File

@ -0,0 +1,41 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/0.13/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-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
files: [
],
preprocessors: {
},
mime: {
'text/x-typescript': ['ts','tsx']
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
config: './.angular-cli.json',
environment: 'dev'
},
reporters: config.angularCli && config.angularCli.codeCoverage
? ['progress', 'coverage-istanbul']
: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};

View File

@ -0,0 +1 @@
"..\node_modules\.bin\nswag" run

View File

@ -0,0 +1,139 @@
{
"runtime": "Default",
"swaggerGenerator": {
"fromSwagger": {
"url": "http://localhost:21021/swagger/v1/swagger.json",
"output": null
}
},
"codeGenerators": {
"swaggerToTypeScriptClient": {
"className": "{controller}ServiceProxy",
"moduleName": "",
"namespace": "",
"typeScriptVersion": 2.0,
"template": "Angular",
"promiseType": "Promise",
"httpClass": "HttpClient",
"useSingletonProvider": false,
"injectionTokenType": "InjectionToken",
"rxJsVersion": 6.0,
"dateTimeType": "MomentJS",
"nullValue": "Undefined",
"generateClientClasses": true,
"generateClientInterfaces": false,
"generateOptionalParameters": false,
"wrapDtoExceptions": false,
"wrapResponses": false,
"generateResponseClasses": true,
"responseClass": "SwaggerResponse",
"useTransformOptionsMethod": false,
"useTransformResultMethod": false,
"generateDtoTypes": true,
"operationGenerationMode": "MultipleClientsFromPathSegments",
"markOptionalProperties": false,
"generateCloneMethod": true,
"typeStyle": "Class",
"generateDefaultValues": true,
"excludedTypeNames": [],
"handleReferences": false,
"generateConstructorInterface": true,
"convertConstructorInterfaceData": false,
"importRequiredTypes": true,
"useGetBaseUrlMethod": false,
"baseUrlTokenName": "API_BASE_URL",
"queryNullValue": "",
"output": "../src/shared/service-proxies/service-proxies.ts"
},
"swaggerToCSharpClient": {
"generateClientClasses": true,
"generateClientInterfaces": false,
"generateDtoTypes": true,
"injectHttpClient": false,
"disposeHttpClient": true,
"generateExceptionClasses": true,
"exceptionClass": "SwaggerException",
"wrapDtoExceptions": true,
"useHttpClientCreationMethod": false,
"httpClientType": "System.Net.Http.HttpClient",
"useHttpRequestMessageCreationMethod": false,
"useBaseUrl": true,
"generateBaseUrlProperty": true,
"generateSyncMethods": false,
"exposeJsonSerializerSettings": false,
"clientClassAccessModifier": "public",
"typeAccessModifier": "public",
"generateContractsOutput": false,
"parameterDateTimeFormat": "s",
"generateUpdateJsonSerializerSettingsMethod": true,
"serializeTypeInformation": false,
"queryNullValue": "",
"className": "{controller}Client",
"operationGenerationMode": "MultipleClientsFromOperationId",
"generateOptionalParameters": false,
"generateJsonMethods": true,
"parameterArrayType": "System.Collections.Generic.IEnumerable",
"parameterDictionaryType": "System.Collections.Generic.IDictionary",
"responseArrayType": "System.Collections.ObjectModel.ObservableCollection",
"responseDictionaryType": "System.Collections.Generic.Dictionary",
"wrapResponses": false,
"generateResponseClasses": true,
"responseClass": "SwaggerResponse",
"namespace": "MyNamespace",
"requiredPropertiesMustBeDefined": true,
"dateType": "System.DateTime",
"dateTimeType": "System.DateTime",
"timeType": "System.TimeSpan",
"timeSpanType": "System.TimeSpan",
"arrayType": "System.Collections.ObjectModel.ObservableCollection",
"dictionaryType": "System.Collections.Generic.Dictionary",
"arrayBaseType": "System.Collections.ObjectModel.ObservableCollection",
"dictionaryBaseType": "System.Collections.Generic.Dictionary",
"classStyle": "Inpc",
"generateDefaultValues": true,
"generateDataAnnotations": true,
"excludedTypeNames": [],
"handleReferences": false,
"generateImmutableArrayProperties": false,
"generateImmutableDictionaryProperties": false,
"output": null
},
"swaggerToCSharpController": {
"controllerStyle": "Partial",
"useCancellationToken": false,
"aspNetNamespace": "System.Web.Http",
"className": "{controller}",
"operationGenerationMode": "MultipleClientsFromOperationId",
"additionalNamespaceUsages": [
"System.Web.Http"
],
"generateOptionalParameters": false,
"generateJsonMethods": true,
"parameterArrayType": "System.Collections.Generic.IEnumerable",
"parameterDictionaryType": "System.Collections.Generic.IDictionary",
"responseArrayType": "System.Collections.ObjectModel.ObservableCollection",
"responseDictionaryType": "System.Collections.Generic.Dictionary",
"wrapResponses": false,
"generateResponseClasses": true,
"responseClass": "SwaggerResponse",
"namespace": "MyNamespace",
"requiredPropertiesMustBeDefined": true,
"dateType": "System.DateTime",
"dateTimeType": "System.DateTime",
"timeType": "System.TimeSpan",
"timeSpanType": "System.TimeSpan",
"arrayType": "System.Collections.Generic.IEnumerable",
"dictionaryType": "System.Collections.Generic.Dictionary",
"arrayBaseType": "System.Collections.ObjectModel.ObservableCollection",
"dictionaryBaseType": "System.Collections.Generic.Dictionary",
"classStyle": "Inpc",
"generateDefaultValues": true,
"generateDataAnnotations": true,
"excludedTypeNames": [],
"handleReferences": false,
"generateImmutableArrayProperties": false,
"generateImmutableDictionaryProperties": false,
"output": null
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,91 @@
{
"name": "SystemKonkursow",
"version": "0.0.0",
"license": "MIT",
"angular-cli": {},
"scripts": {
"ng": "ng",
"start": "ng serve --host 0.0.0.0 --port 4200",
"hmr": "ng serve --host 0.0.0.0 --port 4200 --hmr",
"test": "ng test",
"pree2e": "webdriver-manager update --standalone false --gecko false",
"e2e": "protractor"
},
"private": true,
"dependencies": {
"@angular/animations": "^6.0.5",
"@angular/common": "^6.0.5",
"@angular/compiler": "^6.0.5",
"@angular/core": "^6.0.5",
"@angular/forms": "^6.0.5",
"@angular/http": "^6.0.5",
"@angular/platform-browser": "^6.0.5",
"@angular/platform-browser-dynamic": "^6.0.5",
"@angular/router": "^6.0.5",
"@aspnet/signalr": "^1.0.0",
"@types/bootstrap": "^3.3.33",
"@types/jquery": "^3.2.12",
"@types/jquery.blockui": "0.0.28",
"@types/jquery.validation": "^1.16.3",
"@types/lodash": "^4.14.62",
"@types/moment": "^2.13.0",
"@types/moment-timezone": "^0.2.34",
"@types/toastr": "^2.1.33",
"abp-ng2-module": "^3.2.2",
"abp-web-resources": "^3.8.2",
"animate.css": "^3.5.2",
"block-ui": "^2.70.1",
"bootstrap": "^3.3.7",
"bootstrap-select": "^1.12.2",
"chart.js": "^2.6.0",
"core-js": "^2.4.1",
"famfamfam-flags": "^1.0.0",
"flot": "^0.8.0-alpha",
"font-awesome": "^4.7.0",
"jquery": "^3.1.1",
"jquery-countto": "^1.2.0",
"jquery-migrate": "^3.0.0",
"jquery-slimscroll": "^1.3.8",
"jquery-sparkline": "^2.4.0",
"js-cookie": "^2.1.4",
"lodash": "^4.17.4",
"moment": "^2.18.1",
"moment-timezone": "^0.5.13",
"morris.js": "^0.5.0",
"ngx-bootstrap": "^3.0.0",
"ngx-pagination": "^3.0.3",
"node-waves": "^0.7.5",
"push.js": "1.0.4",
"raphael": "^2.2.7",
"rxjs": "^6.2.0",
"simple-line-icons": "^2.4.1",
"spin.js": "^2.3.2",
"sweetalert": "^2.0.8",
"toastr": "^2.1.2",
"ts-helpers": "^1.1.2",
"web-animations-js": "^2.3.1",
"zone.js": "0.8.26"
},
"devDependencies": {
"@angular/cli": "^6.0.8",
"@angular/compiler-cli": "^6.0.5",
"@angularclass/hmr": "^2.1.3",
"@types/jasmine": "^2.5.38",
"@types/node": "^8.0.27",
"codelyzer": "^4.0.1",
"jasmine-core": "^2.5.2",
"jasmine-spec-reporter": "^4.2.1",
"karma": "^1.4.1",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-coverage-istanbul-reporter": "^1.3.0",
"karma-jasmine": "^1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"nswag": "^11.17.10",
"protractor": "^5.1.1",
"ts-node": "^3.3.0",
"tslint": "^5.7.0",
"typescript": "2.7.2",
"@angular-devkit/build-angular": "~0.6.8"
}
}

View File

@ -0,0 +1,32 @@
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
/*global jasmine */
var SpecReporter = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
useAllAngular2AppRoots: true,
beforeLaunch: function() {
require('ts-node').register({
project: 'e2e'
});
},
onPrepare: function() {
jasmine.getEnv().addReporter(new SpecReporter());
}
};

View File

@ -0,0 +1,70 @@
import * as moment from 'moment';
import { AppConsts } from '@shared/AppConsts';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { Type, CompilerOptions, NgModuleRef } from '@angular/core';
import { environment } from './environments/environment';
export class AppPreBootstrap {
static run(appRootUrl: string, callback: () => void): void {
AppPreBootstrap.getApplicationConfig(appRootUrl, () => {
AppPreBootstrap.getUserConfiguration(callback);
});
}
static bootstrap<TM>(moduleType: Type<TM>, compilerOptions?: CompilerOptions | CompilerOptions[]): Promise<NgModuleRef<TM>> {
return platformBrowserDynamic().bootstrapModule(moduleType, compilerOptions);
}
private static getApplicationConfig(appRootUrl: string, callback: () => void) {
return abp.ajax({
url: appRootUrl + 'assets/' + environment.appConfig,
method: 'GET',
headers: {
'Abp.TenantId': abp.multiTenancy.getTenantIdCookie()
}
}).done(result => {
AppConsts.appBaseUrl = result.appBaseUrl;
AppConsts.remoteServiceBaseUrl = result.remoteServiceBaseUrl;
AppConsts.localeMappings = result.localeMappings;
callback();
});
}
private static getCurrentClockProvider(currentProviderName: string): abp.timing.IClockProvider {
if (currentProviderName === "unspecifiedClockProvider") {
return abp.timing.unspecifiedClockProvider;
}
if (currentProviderName === "utcClockProvider") {
return abp.timing.utcClockProvider;
}
return abp.timing.localClockProvider;
}
private static getUserConfiguration(callback: () => void): JQueryPromise<any> {
return abp.ajax({
url: AppConsts.remoteServiceBaseUrl + '/AbpUserConfiguration/GetAll',
method: 'GET',
headers: {
Authorization: 'Bearer ' + abp.auth.getToken(),
'.AspNetCore.Culture': abp.utils.getCookieValue("Abp.Localization.CultureName"),
'Abp.TenantId': abp.multiTenancy.getTenantIdCookie()
}
}).done(result => {
$.extend(true, abp, result);
abp.clock.provider = this.getCurrentClockProvider(result.clock.provider);
moment.locale(abp.localization.currentLanguage.name);
if (abp.clock.provider.supportsMultipleTimezone) {
moment.tz.setDefault(abp.timing.timeZoneInfo.iana.timeZoneId);
}
callback();
});
}
}

View File

@ -0,0 +1,24 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { AccountComponent } from './account.component';
@NgModule({
imports: [
RouterModule.forChild([
{
path: '',
component: AccountComponent,
children: [
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent }
]
}
])
],
exports: [
RouterModule
]
})
export class AccountRoutingModule { }

View File

@ -0,0 +1,20 @@
<div class="login-box">
<div class="logo">
<a href="javascript:void(0);">System Konkursów</a>
</div>
<div *ngIf="showTenantChange()" class="tenant-change-box">
<tenant-change></tenant-change>
</div>
<router-outlet></router-outlet>
<!-- <account-languages></account-languages> -->
<div class="row">
<div class="col-xs-12 text-center" style="color: #e9e9e9">
<small>&copy; {{currentYear}} SystemKonkursow. <b>Wersja </b> {{versionText}}</small>
</div>
</div>
</div>

View File

@ -0,0 +1,13 @@
.content.account-forms {
margin-top: 10px;
}
.content.tenant-change-box {
padding: 16px 16px 0px 16px;
margin: 120px auto 0px auto;
max-width: 400px;
a {
cursor: pointer;
}
}

View File

@ -0,0 +1,36 @@
import { Component, ViewContainerRef, OnInit, ViewEncapsulation, Injector } from '@angular/core';
import { LoginService } from './login/login.service';
import { AppComponentBase } from '@shared/app-component-base';
@Component({
templateUrl: './account.component.html',
styleUrls: [
'./account.component.less'
],
encapsulation: ViewEncapsulation.None
})
export class AccountComponent extends AppComponentBase implements OnInit {
private viewContainerRef: ViewContainerRef;
versionText: string;
currentYear: number;
public constructor(
injector: Injector,
private _loginService: LoginService
) {
super(injector);
this.currentYear = new Date().getFullYear();
this.versionText = this.appSession.application.version + ' [' + this.appSession.application.releaseDate.format('YYYYDDMM') + ']';
}
showTenantChange(): boolean {
return abp.multiTenancy.isEnabled;
}
ngOnInit(): void {
$('body').attr('class', 'login-page');
}
}

View File

@ -0,0 +1,52 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { JsonpModule } from '@angular/http';
import { HttpClientModule } from '@angular/common/http';
import { ModalModule } from 'ngx-bootstrap';
import { AbpModule } from '@abp/abp.module';
import { AccountRoutingModule } from './account-routing.module';
import { ServiceProxyModule } from '@shared/service-proxies/service-proxy.module';
import { SharedModule } from '@shared/shared.module';
import { AccountComponent } from './account.component';
import { TenantChangeComponent } from './tenant/tenant-change.component';
import { TenantChangeModalComponent } from './tenant/tenant-change-modal.component';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { AccountLanguagesComponent } from './layout/account-languages.component';
import { LoginService } from './login/login.service';
@NgModule({
imports: [
CommonModule,
FormsModule,
HttpClientModule,
JsonpModule,
AbpModule,
SharedModule,
ServiceProxyModule,
AccountRoutingModule,
ModalModule.forRoot()
],
declarations: [
AccountComponent,
TenantChangeComponent,
TenantChangeModalComponent,
LoginComponent,
RegisterComponent,
AccountLanguagesComponent
],
providers: [
LoginService
]
})
export class AccountModule {
}

View File

@ -0,0 +1,5 @@
<ul class="account-language-switch-list text-center">
<li *ngFor="let language of languages">
<a *ngIf="language.name != currentLanguage.name" href="javascript:void();" title="{{language.displayName}}" (click)="changeLanguage(language.name)"><i class="{{language.icon}}"></i></a>
</li>
</ul>

View File

@ -0,0 +1,11 @@
.account-language-switch-list {
list-style: none;
margin: 0px;
padding: 10px;
> li {
display: inline;
margin: 0px;
padding: 0px;
}
}

View File

@ -0,0 +1,39 @@
import { Component, OnInit, Injector } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
import * as _ from 'lodash';
@Component({
selector: 'account-languages',
templateUrl: './account-languages.component.html',
styleUrls: [
'./account-languages.component.less'
]
})
export class AccountLanguagesComponent extends AppComponentBase implements OnInit {
languages: abp.localization.ILanguageInfo[];
currentLanguage: abp.localization.ILanguageInfo;
constructor(
injector: Injector
) {
super(injector);
}
ngOnInit() {
this.languages = _.filter(this.localization.languages, l => !l.isDisabled);
this.currentLanguage = this.localization.currentLanguage;
}
changeLanguage(languageName: string): void {
abp.utils.setCookieValue(
"Abp.Localization.CultureName",
languageName,
new Date(new Date().getTime() + 5 * 365 * 86400000), //5 year
abp.appPath
);
location.reload();
}
}

View File

@ -0,0 +1,40 @@
<div class="card" id="LoginArea" [@routerTransition]>
<div #cardBody class="body">
<form #loginForm="ngForm" id="LoginForm" method="post" novalidate (ngSubmit)="login()">
<h4 class="text-center">{{l("Logowanie")}}</h4>
<div class="input-group">
<span class="input-group-addon">
<i class="material-icons">person</i>
</span>
<div class="form-line">
<input materialInput [(ngModel)]="loginService.authenticateModel.userNameOrEmailAddress" autoFocus class="form-control" type="text" autocomplete="off" placeholder="{{l('Login')}}" name="userNameOrEmailAddress" required maxlength="255" />
</div>
</div>
<div class="input-group">
<span class="input-group-addon">
<i class="material-icons">lock</i>
</span>
<div class="form-line">
<input materialInput type="password" [(ngModel)]="loginService.authenticateModel.password" class="form-control" name="password" placeholder="{{l('Hasło')}}" required maxlength="32">
</div>
</div>
<div class="row">
<div class="col-xs-8 p-t-5">
<input type="checkbox" [(ngModel)]="loginService.rememberMe" name="rememberMe" id="rememberme" class="filled-in chk-col-pink" value="true">
<label for="rememberme">{{l("Zapamiętaj mnie")}}</label>
</div>
<div class="col-xs-4">
<button id="LoginButton" class="btn btn-block bg-pink waves-effect" type="submit">{{l("Zaloguj")}}</button>
</div>
</div>
<div class="row m-t-15 m-b--20" *ngIf="isSelfRegistrationAllowed">
<div class="col-xs-12">
<a [routerLink]="['../register']">{{l("Zarejestruj się")}}</a>
</div>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,12 @@
.social-icons {
padding-left: 0px;
li {
display: inline-block;
margin-right: 5px;
a {
width: 40px;
}
}
}

View File

@ -0,0 +1,52 @@
import { Component, Injector, ElementRef, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { AppComponentBase } from '@shared/app-component-base';
import { LoginService } from './login.service';
import { accountModuleAnimation } from '@shared/animations/routerTransition';
import { AbpSessionService } from '@abp/session/abp-session.service';
@Component({
templateUrl: './login.component.html',
styleUrls: [
'./login.component.less'
],
animations: [accountModuleAnimation()]
})
export class LoginComponent extends AppComponentBase {
@ViewChild('cardBody') cardBody: ElementRef;
submitting: boolean = false;
constructor(
injector: Injector,
public loginService: LoginService,
private _router: Router,
private _sessionService: AbpSessionService
) {
super(injector);
}
ngAfterViewInit(): void {
$(this.cardBody.nativeElement).find('input:first').focus();
}
get multiTenancySideIsTeanant(): boolean {
return this._sessionService.tenantId > 0;
}
get isSelfRegistrationAllowed(): boolean {
if (!this._sessionService.tenantId) {
return false;
}
return true;
}
login(): void {
this.submitting = true;
this.loginService.authenticate(
() => this.submitting = false
);
}
}

View File

@ -0,0 +1,90 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { TokenAuthServiceProxy, AuthenticateModel, AuthenticateResultModel, ExternalLoginProviderInfoModel, ExternalAuthenticateModel, ExternalAuthenticateResultModel } from '@shared/service-proxies/service-proxies';
import { UrlHelper } from '@shared/helpers/UrlHelper';
import { AppConsts } from '@shared/AppConsts';
import { MessageService } from '@abp/message/message.service';
import { LogService } from '@abp/log/log.service';
import { TokenService } from '@abp/auth/token.service';
import { UtilsService } from '@abp/utils/utils.service';
import { finalize } from 'rxjs/operators';
@Injectable()
export class LoginService {
static readonly twoFactorRememberClientTokenName = 'TwoFactorRememberClientToken';
authenticateModel: AuthenticateModel;
authenticateResult: AuthenticateResultModel;
rememberMe: boolean;
constructor(
private _tokenAuthService: TokenAuthServiceProxy,
private _router: Router,
private _utilsService: UtilsService,
private _messageService: MessageService,
private _tokenService: TokenService,
private _logService: LogService
) {
this.clear();
}
authenticate(finallyCallback?: () => void): void {
finallyCallback = finallyCallback || (() => { });
this._tokenAuthService
.authenticate(this.authenticateModel)
.pipe(finalize(() => { finallyCallback() }))
.subscribe((result: AuthenticateResultModel) => {
this.processAuthenticateResult(result);
});
}
private processAuthenticateResult(authenticateResult: AuthenticateResultModel) {
this.authenticateResult = authenticateResult;
if (authenticateResult.accessToken) {
//Successfully logged in
this.login(authenticateResult.accessToken, authenticateResult.encryptedAccessToken, authenticateResult.expireInSeconds, this.rememberMe);
} else {
//Unexpected result!
this._logService.warn('Unexpected authenticateResult!');
this._router.navigate(['account/login']);
}
}
private login(accessToken: string, encryptedAccessToken: string, expireInSeconds: number, rememberMe?: boolean): void {
var tokenExpireDate = rememberMe ? (new Date(new Date().getTime() + 1000 * expireInSeconds)) : undefined;
this._tokenService.setToken(
accessToken,
tokenExpireDate
);
this._utilsService.setCookieValue(
AppConsts.authorization.encrptedAuthTokenName,
encryptedAccessToken,
tokenExpireDate,
abp.appPath
);
var initialUrl = UrlHelper.initialUrl;
if (initialUrl.indexOf('/login') > 0) {
initialUrl = AppConsts.appBaseUrl;
}
location.href = initialUrl;
}
private clear(): void {
this.authenticateModel = new AuthenticateModel();
this.authenticateModel.rememberClient = false;
this.authenticateResult = null;
this.rememberMe = false;
}
}

View File

@ -0,0 +1,48 @@
<div class="card" [@routerTransition]>
<div #cardBody class="body">
<form #registerForm="ngForm" method="post" novalidate (ngSubmit)="save()">
<h4 class="text-center">{{l("Rejestracja")}}</h4>
<div class="form-group form-float">
<div class="form-line">
<input materialInput class="form-control" autoFocus type="text" [(ngModel)]="model.name" name="Name" required maxlength="32" />
<label class="form-label">{{l('Imię')}}</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input materialInput class="form-control" type="text" [(ngModel)]="model.surname" name="Surname" required maxlength="32" />
<label class="form-label">{{l('Nazwisko')}}</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input materialInput class="form-control" type="email" [(ngModel)]="model.emailAddress" name="EmailAddress" required maxlength="255" pattern="^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$" />
<label class="form-label">{{l('Adres e-mail')}}</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input materialInput class="form-control" type="text" autocomplete="off" [(ngModel)]="model.userName" name="UserName" required maxlength="32" />
<label class="form-label">{{l('Login')}}</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input materialInput class="form-control" type="password" [(ngModel)]="model.password" name="Password" required maxlength="32" />
<label class="form-label">{{l('Hasło')}}</label>
</div>
</div>
<div class="form-actions">
<button [disabled]="saving" [routerLink]="['../login']" type="button" class="btn btn-default">{{l("Powrót")}}</button>
<button type="submit" class="btn btn-success" [disabled]="!registerForm.form.valid">{{l("Zarejestruj")}}</button>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,56 @@
import { Component, Injector, ElementRef, AfterViewInit, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { AccountServiceProxy, RegisterInput, RegisterOutput } from '@shared/service-proxies/service-proxies'
import { AppComponentBase } from '@shared/app-component-base';
import { LoginService } from '../login/login.service';
import { accountModuleAnimation } from '@shared/animations/routerTransition';
import { finalize } from 'rxjs/operators';
@Component({
templateUrl: './register.component.html',
animations: [accountModuleAnimation()]
})
export class RegisterComponent extends AppComponentBase implements AfterViewInit {
@ViewChild('cardBody') cardBody: ElementRef;
model: RegisterInput = new RegisterInput();
saving: boolean = false;
constructor(
injector: Injector,
private _accountService: AccountServiceProxy,
private _router: Router,
private readonly _loginService: LoginService
) {
super(injector);
}
ngAfterViewInit(): void {
$(this.cardBody.nativeElement).find('input:first').focus();
}
back(): void {
this._router.navigate(['/login']);
}
save(): void {
this.saving = true;
this._accountService.register(this.model)
.pipe(finalize(() => { this.saving = false; }))
.subscribe((result:RegisterOutput) => {
if (!result.canLogin) {
this.notify.success(this.l('SuccessfullyRegistered'));
this._router.navigate(['/login']);
return;
}
//Autheticate
this.saving = true;
this._loginService.authenticateModel.userNameOrEmailAddress = this.model.userName;
this._loginService.authenticateModel.password = this.model.password;
this._loginService.authenticate(() => { this.saving = false; });
});
}
}

View File

@ -0,0 +1,36 @@
<div bsModal #tenantChangeModal="bs-modal" (onShown)="onShown()" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="tenantChangeModal" aria-hidden="true" [config]="{backdrop: 'static'}">
<div class="modal-dialog">
<div #modalContent class="modal-content">
<form *ngIf="active" #changeTenantForm="ngForm" novalidate (ngSubmit)="save()">
<div class="modal-header">
<button type="button" class="close" (click)="close()" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">
<span>{{l("ChangeTenant")}}</span>
</h4>
</div>
<div class="modal-body">
<div class="form-group form-float">
<div class="form-line">
<input #tenancyNameInput materialInput type="text" name="TenancyName" class="form-control" [ngClass]="{'edited':tenancyName}" [(ngModel)]="tenancyName" maxlength="64">
<label class="form-label">{{l("TenancyName")}}</label>
</div>
</div>
<span class="help-block">{{l("LeaveEmptyToSwitchToHost")}}</span>
</div>
<div class="modal-footer">
<button [disabled]="saving" type="button" class="btn btn-default waves-effect" (click)="close()">{{l("Cancel")}}</button>
<button type="submit" class="btn btn-primary waves-effect" [disabled]="!changeTenantForm.form.valid">{{l("Save")}}</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,76 @@
import { Component, OnInit, ViewChild, Injector, ElementRef } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
import { AccountServiceProxy } from '@shared/service-proxies/service-proxies';
import { IsTenantAvailableInput, IsTenantAvailableOutput } from '@shared/service-proxies/service-proxies';
import { AppTenantAvailabilityState } from '@shared/AppEnums';
import { ModalDirective } from 'ngx-bootstrap';
import { finalize } from 'rxjs/operators';
@Component({
selector: 'tenantChangeModal',
templateUrl: './tenant-change-modal.component.html'
})
export class TenantChangeModalComponent extends AppComponentBase {
@ViewChild('tenantChangeModal') modal: ModalDirective;
@ViewChild('tenancyNameInput') tenancyNameInput: ElementRef;
@ViewChild('modalContent') modalContent: ElementRef;
tenancyName: string = '';
active: boolean = false;
saving: boolean = false;
constructor(
private _accountService: AccountServiceProxy,
injector: Injector
) {
super(injector);
}
show(tenancyName: string): void {
this.tenancyName = tenancyName;
this.active = true;
this.modal.show();
}
onShown(): void {
$(this.tenancyNameInput.nativeElement).focus().select();
}
save(): void {
if (!this.tenancyName) {
abp.multiTenancy.setTenantIdCookie(undefined);;
this.close();
location.reload();
return;
}
var input = new IsTenantAvailableInput();
input.tenancyName = this.tenancyName;
this.saving = true;
this._accountService.isTenantAvailable(input)
.pipe(finalize(() => { this.saving = false; }))
.subscribe((result: IsTenantAvailableOutput) => {
switch (result.state) {
case AppTenantAvailabilityState.Available:
abp.multiTenancy.setTenantIdCookie(result.tenantId);
this.close();
location.reload();
return;
case AppTenantAvailabilityState.InActive:
this.message.warn(this.l('TenantIsNotActive', this.tenancyName));
break;
case AppTenantAvailabilityState.NotFound: //NotFound
this.message.warn(this.l('ThereIsNoTenantDefinedWithName{0}', this.tenancyName));
break;
}
});
}
close(): void {
this.active = false;
this.modal.hide();
}
}

View File

@ -0,0 +1,8 @@
<div *ngIf="isMultiTenancyEnabled" class="card tenant-change-component" style="margin-bottom: 3px;">
<div class="body text-center">
<span>
{{l("CurrentTenant")}}: <span *ngIf="tenancyName" title="{{name}}"><strong>{{tenancyName}}</strong></span> <span *ngIf="!tenancyName">{{l("NotSelected")}}</span> (<a href="javascript:void();" (click)="showChangeModal()">{{l("Change")}}</a>)
<tenantChangeModal #tenantChangeModal></tenantChangeModal>
</span>
</div>
</div>

View File

@ -0,0 +1,39 @@
import { Component, OnInit, Injector, ViewChild } from '@angular/core';
import { AccountServiceProxy } from '@shared/service-proxies/service-proxies'
import { TenantChangeModalComponent } from './tenant-change-modal.component'
import { AppComponentBase } from '@shared/app-component-base';
@Component({
selector: 'tenant-change',
templateUrl: './tenant-change.component.html'
})
export class TenantChangeComponent extends AppComponentBase implements OnInit {
@ViewChild('tenantChangeModal') tenantChangeModal: TenantChangeModalComponent;
tenancyName: string;
name: string;
constructor(
injector: Injector,
private _accountService: AccountServiceProxy
) {
super(injector);
}
ngOnInit() {
if (this.appSession.tenant) {
this.tenancyName = this.appSession.tenant.tenancyName;
this.name = this.appSession.tenant.name;
}
}
get isMultiTenancyEnabled(): boolean {
return abp.multiTenancy.isEnabled;
}
showChangeModal(): void{
this.tenantChangeModal.show(this.tenancyName);
}
}

View File

@ -0,0 +1,84 @@
<div class="row clearfix" [@routerTransition]>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="card">
<div class="header">
<h2>
About This Template
</h2>
</div>
<div class="body">
<p>
This is a simple startup template based on ASP.NET Boilerplate framework and Module Zero.
If you need an enterprise startup project, check <a href="http://aspnetzero.com?ref=abptmpl" target="_blank">ASP.NET ZERO</a>.
</p>
<h3>What is ASP.NET Boilerplate?</h3>
<p>
ASP.NET Boilerplate is an application framework built on latest <strong>ASP.NET Core</strong> framework.
It makes easy to use authorization, dependency injection, validation, exception handling, localization, logging, caching, background jobs and so on.
It's built on already familiar tools like Entity Framework, AutoMapper, Castle Windsor...
</p>
<p>
ASP.NET Boilerplate implements <strong>NLayer architecture</strong> (Domain, Application, Infrastructure and Presentation Layers)
and <strong>Domain Driven Design</strong> (Entities, Repositories, Domain/Application Services, DTO's...).
Also implements and provides a good infrastructure to implement common software development <strong>best practices</strong>.
</p>
<h3>What is Module Zero?</h3>
<p>
ASP.NET Boilerplate framework is designed to be independent of any database
schema and to be as generic as possible. Therefore, It leaves some concepts
<strong>abstract</strong> and <strong>optional</strong> (like audit logging, permission and setting stores)
which requires some <strong>data store</strong>.
</p>
<p>
<strong>Module Zero </strong>implements all fundamental concepts of ASP.NET
Boilerplate framework such as <a href="http://www.aspnetboilerplate.com/Pages/Documents/Zero/Tenant-Management">tenant management</a> (<strong>multi-tenancy</strong>),
<a href="http://www.aspnetboilerplate.com/Pages/Documents/Zero/Role-Management">
role management
</a>, <a href="http://www.aspnetboilerplate.com/Pages/Documents/Zero/User-Management">user management</a>,
<a href="http://www.aspnetboilerplate.com/Pages/Documents/Authorization">authorization</a> (<a href="http://www.aspnetboilerplate.com/Pages/Documents/Zero/Permission-Management">
permission management
</a>),
<a href="http://www.aspnetboilerplate.com/Pages/Documents/Setting-Management">setting management</a>, <a href="http://www.aspnetboilerplate.com/Pages/Documents/Zero/Language-Management">
language management
</a>, <a href="http://www.aspnetboilerplate.com/Pages/Documents/Audit-Logging">audit logging</a>
and so on.
</p>
<p>
Module-Zero defines entities and implements <strong>domain logic</strong>
(domain layer) and leaves application and presentation layers to you.
</p>
<h4>Based on Microsoft ASP.NET Core Identity</h4>
<p>
Module Zero is based on Microsoft's
<a href="https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity" target="_blank">ASP.NET Core Identity</a> library.
It extends user and role managers and implements user and role stores using generic repositories.
</p>
<h3>Documentation</h3>
<ul>
<li>
<a href="https://www.aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template-Angular">Documentation for this template</a>
</li>
<li>
<a href="http://www.aspnetboilerplate.com/Pages/Documents">ASP.NET Boilerplate documentation</a>
</li>
</ul>
<h3>Source code</h3>
<p>
This template is developed open source on Github. You can contribute to the template.
<a href="https://github.com/aspnetboilerplate/module-zero-core-template" target="_blank">https://github.com/aspnetboilerplate/module-zero-core-template</a>
</p>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,16 @@
import { Component, Injector, AfterViewInit } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
import { appModuleAnimation } from '@shared/animations/routerTransition';
@Component({
templateUrl: './about.component.html',
animations: [appModuleAnimation()]
})
export class AboutComponent extends AppComponentBase {
constructor(
injector: Injector
) {
super(injector);
}
}

View File

@ -0,0 +1,29 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { AppRouteGuard } from '@shared/auth/auth-route-guard';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { UsersComponent } from './users/users.component';
import { TenantsComponent } from './tenants/tenants.component';
import { RolesComponent } from 'app/roles/roles.component';
@NgModule({
imports: [
RouterModule.forChild([
{
path: '',
component: AppComponent,
children: [
{ path: 'home', component: HomeComponent, canActivate: [AppRouteGuard] },
{ path: 'users', component: UsersComponent, data: { permission: 'Pages.Users' }, canActivate: [AppRouteGuard] },
{ path: 'roles', component: RolesComponent, data: { permission: 'Pages.Roles' }, canActivate: [AppRouteGuard] },
{ path: 'tenants', component: TenantsComponent, data: { permission: 'Pages.Tenants' }, canActivate: [AppRouteGuard] },
{ path: 'about', component: AboutComponent }
]
}
])
],
exports: [RouterModule]
})
export class AppRoutingModule { }

View File

@ -0,0 +1,19 @@
<div class="overlay"></div>
<top-bar></top-bar>
<section (window:resize)="onResize($event)">
<aside id="leftsidebar" class="sidebar">
<sidebar-user-area></sidebar-user-area>
<sidebar-nav></sidebar-nav>
<sidebar-footer></sidebar-footer>
</aside>
<right-sidebar></right-sidebar>
</section>
<section class="content">
<div class="container-fluid">
<router-outlet></router-outlet>
</div>
</section>

View File

@ -0,0 +1,34 @@
/* tslint:disable:no-unused-variable */
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
});
TestBed.compileComponents();
});
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'app works!'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('app works!');
}));
it('should render title in a h1 tag', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('app works!');
}));
});

View File

@ -0,0 +1,53 @@
import { Component, ViewContainerRef, Injector, OnInit, AfterViewInit, ChangeDetectorRef } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
import { SignalRAspNetCoreHelper } from '@shared/helpers/SignalRAspNetCoreHelper';
@Component({
templateUrl: './app.component.html'
})
export class AppComponent extends AppComponentBase implements OnInit, AfterViewInit {
private viewContainerRef: ViewContainerRef;
constructor(
injector: Injector
) {
super(injector);
}
ngOnInit(): void {
SignalRAspNetCoreHelper.initSignalR();
abp.event.on('abp.notifications.received', userNotification => {
abp.notifications.showUiNotifyForUserNotification(userNotification);
//Desktop notification
Push.create("AbpZeroTemplate", {
body: userNotification.notification.data.message,
icon: abp.appPath + 'assets/app-logo-small.png',
timeout: 6000,
onClick: function () {
window.focus();
this.close();
}
});
});
}
ngAfterViewInit(): void {
$.AdminBSB.activateAll();
$.AdminBSB.activateDemo();
}
onResize(event) {
// exported from $.AdminBSB.activateAll
$.AdminBSB.leftSideBar.setMenuHeight();
$.AdminBSB.leftSideBar.checkStatuForResize(false);
// exported from $.AdminBSB.activateDemo
$.AdminBSB.demo.setSkinListHeightAndScroll();
$.AdminBSB.demo.setSettingListHeightAndScroll();
}
}

View File

@ -0,0 +1,74 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { JsonpModule } from '@angular/http';
import { HttpClientModule, HttpResponse } from '@angular/common/http';
import { ModalModule } from 'ngx-bootstrap';
import { NgxPaginationModule } from 'ngx-pagination';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AbpModule } from '@abp/abp.module';
import { ServiceProxyModule } from '@shared/service-proxies/service-proxy.module';
import { SharedModule } from '@shared/shared.module';
import { HomeComponent } from '@app/home/home.component';
import { AboutComponent } from '@app/about/about.component';
import { UsersComponent } from '@app/users/users.component';
import { CreateUserComponent } from '@app/users/create-user/create-user.component';
import { EditUserComponent } from './users/edit-user/edit-user.component';
import { RolesComponent } from '@app/roles/roles.component';
import { CreateRoleComponent } from '@app/roles/create-role/create-role.component';
import { EditRoleComponent } from './roles/edit-role/edit-role.component';
import { TenantsComponent } from '@app/tenants/tenants.component';
import { CreateTenantComponent } from './tenants/create-tenant/create-tenant.component';
import { EditTenantComponent } from './tenants/edit-tenant/edit-tenant.component';
import { TopBarComponent } from '@app/layout/topbar.component';
import { TopBarLanguageSwitchComponent } from '@app/layout/topbar-languageswitch.component';
import { SideBarUserAreaComponent } from '@app/layout/sidebar-user-area.component';
import { SideBarNavComponent } from '@app/layout/sidebar-nav.component';
import { SideBarFooterComponent } from '@app/layout/sidebar-footer.component';
import { RightSideBarComponent } from '@app/layout/right-sidebar.component';
@NgModule({
declarations: [
AppComponent,
HomeComponent,
AboutComponent,
TenantsComponent,
CreateTenantComponent,
EditTenantComponent,
UsersComponent,
CreateUserComponent,
EditUserComponent,
RolesComponent,
CreateRoleComponent,
EditRoleComponent,
TopBarComponent,
TopBarLanguageSwitchComponent,
SideBarUserAreaComponent,
SideBarNavComponent,
SideBarFooterComponent,
RightSideBarComponent
],
imports: [
CommonModule,
FormsModule,
HttpClientModule,
JsonpModule,
ModalModule.forRoot(),
AbpModule,
AppRoutingModule,
ServiceProxyModule,
SharedModule,
NgxPaginationModule
],
providers: [
]
})
export class AppModule { }

View File

@ -0,0 +1,310 @@
<div [@routerTransition]>
<div class="block-header">
<h2>SAMPLE DASHBOARD</h2>
</div>
<!-- Widgets -->
<div class="row clearfix">
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-12">
<div class="info-box bg-pink hover-expand-effect">
<div class="icon">
<i class="material-icons">playlist_add_check</i>
</div>
<div class="content">
<div class="text">NEW TASKS</div>
<div class="number count-to" data-from="0" data-to="125" data-speed="1000" data-fresh-interval="20"></div>
</div>
</div>
</div>
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-12">
<div class="info-box bg-cyan hover-expand-effect">
<div class="icon">
<i class="material-icons">help</i>
</div>
<div class="content">
<div class="text">NEW TICKETS</div>
<div class="number count-to" data-from="0" data-to="257" data-speed="1000" data-fresh-interval="20"></div>
</div>
</div>
</div>
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-12">
<div class="info-box bg-light-green hover-expand-effect">
<div class="icon">
<i class="material-icons">forum</i>
</div>
<div class="content">
<div class="text">NEW COMMENTS</div>
<div class="number count-to" data-from="0" data-to="243" data-speed="1000" data-fresh-interval="20"></div>
</div>
</div>
</div>
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-12">
<div class="info-box bg-orange hover-expand-effect">
<div class="icon">
<i class="material-icons">person_add</i>
</div>
<div class="content">
<div class="text">NEW VISITORS</div>
<div class="number count-to" data-from="0" data-to="1225" data-speed="1000" data-fresh-interval="20"></div>
</div>
</div>
</div>
</div>
<!-- #END# Widgets -->
<!-- CPU Usage -->
<div class="row clearfix">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<div class="card">
<div class="header">
<div class="row clearfix">
<div class="col-xs-12 col-sm-6">
<h2>CPU USAGE (%)</h2>
</div>
<div class="col-xs-12 col-sm-6 align-right">
<div class="switch panel-switch-btn">
<span class="m-r-10 font-12">REAL TIME</span>
<label>OFF<input type="checkbox" id="realtime" checked><span class="lever switch-col-cyan"></span>ON</label>
</div>
</div>
</div>
<ul class="header-dropdown m-r--5">
<li class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">more_vert</i>
</a>
<ul class="dropdown-menu pull-right">
<li><a href="javascript:void(0);">Action</a></li>
<li><a href="javascript:void(0);">Another action</a></li>
<li><a href="javascript:void(0);">Something else here</a></li>
</ul>
</li>
</ul>
</div>
<div class="body">
<div id="real_time_chart" class="dashboard-flot-chart"></div>
</div>
</div>
</div>
</div>
<!-- #END# CPU Usage -->
<div class="row clearfix">
<!-- Visitors -->
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4">
<div class="card">
<div class="body bg-pink">
<div class="sparkline" data-type="line" data-spot-Radius="4" data-highlight-Spot-Color="rgb(233, 30, 99)" data-highlight-Line-Color="#fff"
data-min-Spot-Color="rgb(255,255,255)" data-max-Spot-Color="rgb(255,255,255)" data-spot-Color="rgb(255,255,255)"
data-offset="90" data-width="100%" data-height="92px" data-line-Width="2" data-line-Color="rgba(255,255,255,0.7)"
data-fill-Color="rgba(0, 188, 212, 0)">
12,10,9,6,5,6,10,5,7,5,12,13,7,12,11
</div>
<ul class="dashboard-stat-list">
<li>
TODAY
<span class="pull-right"><b>1 200</b> <small>USERS</small></span>
</li>
<li>
YESTERDAY
<span class="pull-right"><b>3 872</b> <small>USERS</small></span>
</li>
<li>
LAST WEEK
<span class="pull-right"><b>26 582</b> <small>USERS</small></span>
</li>
</ul>
</div>
</div>
</div>
<!-- #END# Visitors -->
<!-- Latest Social Trends -->
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4">
<div class="card">
<div class="body bg-cyan">
<div class="m-b--35 font-bold">LATEST SOCIAL TRENDS</div>
<ul class="dashboard-stat-list">
<li>
#socialtrends
<span class="pull-right">
<i class="material-icons">trending_up</i>
</span>
</li>
<li>
#materialdesign
<span class="pull-right">
<i class="material-icons">trending_up</i>
</span>
</li>
<li>#adminbsb</li>
<li>#freeadmintemplate</li>
<li>#bootstraptemplate</li>
<li>
#freehtmltemplate
<span class="pull-right">
<i class="material-icons">trending_up</i>
</span>
</li>
</ul>
</div>
</div>
</div>
<!-- #END# Latest Social Trends -->
<!-- Answered Tickets -->
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4">
<div class="card">
<div class="body bg-teal">
<div class="font-bold m-b--35">ANSWERED TICKETS</div>
<ul class="dashboard-stat-list">
<li>
TODAY
<span class="pull-right"><b>12</b> <small>TICKETS</small></span>
</li>
<li>
YESTERDAY
<span class="pull-right"><b>15</b> <small>TICKETS</small></span>
</li>
<li>
LAST WEEK
<span class="pull-right"><b>90</b> <small>TICKETS</small></span>
</li>
<li>
LAST MONTH
<span class="pull-right"><b>342</b> <small>TICKETS</small></span>
</li>
<li>
LAST YEAR
<span class="pull-right"><b>4 225</b> <small>TICKETS</small></span>
</li>
<li>
ALL
<span class="pull-right"><b>8 752</b> <small>TICKETS</small></span>
</li>
</ul>
</div>
</div>
</div>
<!-- #END# Answered Tickets -->
</div>
<div class="row clearfix">
<!-- Task Info -->
<div class="col-xs-12 col-sm-12 col-md-8 col-lg-8">
<div class="card">
<div class="header">
<h2>TASK INFOS</h2>
<ul class="header-dropdown m-r--5">
<li class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">more_vert</i>
</a>
<ul class="dropdown-menu pull-right">
<li><a href="javascript:void(0);">Action</a></li>
<li><a href="javascript:void(0);">Another action</a></li>
<li><a href="javascript:void(0);">Something else here</a></li>
</ul>
</li>
</ul>
</div>
<div class="body">
<div class="table-responsive">
<table class="table table-hover dashboard-task-infos">
<thead>
<tr>
<th>#</th>
<th>Task</th>
<th>Status</th>
<th>Manager</th>
<th>Progress</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Task A</td>
<td><span class="label bg-green">Doing</span></td>
<td>John Doe</td>
<td>
<div class="progress">
<div class="progress-bar bg-green" role="progressbar" aria-valuenow="62" aria-valuemin="0" aria-valuemax="100" style="width: 62%"></div>
</div>
</td>
</tr>
<tr>
<td>2</td>
<td>Task B</td>
<td><span class="label bg-blue">To Do</span></td>
<td>John Doe</td>
<td>
<div class="progress">
<div class="progress-bar bg-blue" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 40%"></div>
</div>
</td>
</tr>
<tr>
<td>3</td>
<td>Task C</td>
<td><span class="label bg-light-blue">On Hold</span></td>
<td>John Doe</td>
<td>
<div class="progress">
<div class="progress-bar bg-light-blue" role="progressbar" aria-valuenow="72" aria-valuemin="0" aria-valuemax="100" style="width: 72%"></div>
</div>
</td>
</tr>
<tr>
<td>4</td>
<td>Task D</td>
<td><span class="label bg-orange">Wait Approvel</span></td>
<td>John Doe</td>
<td>
<div class="progress">
<div class="progress-bar bg-orange" role="progressbar" aria-valuenow="95" aria-valuemin="0" aria-valuemax="100" style="width: 95%"></div>
</div>
</td>
</tr>
<tr>
<td>5</td>
<td>Task E</td>
<td>
<span class="label bg-red">Suspended</span>
</td>
<td>John Doe</td>
<td>
<div class="progress">
<div class="progress-bar bg-red" role="progressbar" aria-valuenow="87" aria-valuemin="0" aria-valuemax="100" style="width: 87%"></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- #END# Task Info -->
<!-- Browser Usage -->
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4">
<div class="card">
<div class="header">
<h2>BROWSER USAGE</h2>
<ul class="header-dropdown m-r--5">
<li class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">more_vert</i>
</a>
<ul class="dropdown-menu pull-right">
<li><a href="javascript:void(0);">Action</a></li>
<li><a href="javascript:void(0);">Another action</a></li>
<li><a href="javascript:void(0);">Something else here</a></li>
</ul>
</li>
</ul>
</div>
<div class="body">
<div id="donut_chart" class="dashboard-donut-chart"></div>
</div>
</div>
</div>
<!-- #END# Browser Usage -->
</div>
</div>

View File

@ -0,0 +1,135 @@
import { Component, Injector, AfterViewInit } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
import { appModuleAnimation } from '@shared/animations/routerTransition';
@Component({
templateUrl: './home.component.html',
animations: [appModuleAnimation()]
})
export class HomeComponent extends AppComponentBase implements AfterViewInit {
constructor(
injector: Injector
) {
super(injector);
}
ngAfterViewInit(): void {
$(function () {
//Widgets count
$('.count-to').countTo();
//Sales count to
$('.sales-count-to').countTo({
formatter: function (value, options) {
return '$' + value.toFixed(2).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, ' ').replace('.', ',');
}
});
initRealTimeChart();
initDonutChart();
initSparkline();
});
var realtime = 'on';
function initRealTimeChart() {
//Real time ==========================================================================================
var plot = ($ as any).plot('#real_time_chart', [getRandomData()], {
series: {
shadowSize: 0,
color: 'rgb(0, 188, 212)'
},
grid: {
borderColor: '#f3f3f3',
borderWidth: 1,
tickColor: '#f3f3f3'
},
lines: {
fill: true
},
yaxis: {
min: 0,
max: 100
},
xaxis: {
min: 0,
max: 100
}
});
function updateRealTime() {
plot.setData([getRandomData()]);
plot.draw();
var timeout;
if (realtime === 'on') {
timeout = setTimeout(updateRealTime, 320);
} else {
clearTimeout(timeout);
}
}
updateRealTime();
$('#realtime').on('change', function () {
realtime = (this as any).checked ? 'on' : 'off';
updateRealTime();
});
//====================================================================================================
}
function initSparkline() {
$(".sparkline").each(function () {
var $this = $(this);
$this.sparkline('html', $this.data());
});
}
function initDonutChart() {
((window as any).Morris).Donut({
element: 'donut_chart',
data: [{
label: 'Chrome',
value: 37
}, {
label: 'Firefox',
value: 30
}, {
label: 'Safari',
value: 18
}, {
label: 'Opera',
value: 12
},
{
label: 'Other',
value: 3
}],
colors: ['rgb(233, 30, 99)', 'rgb(0, 188, 212)', 'rgb(255, 152, 0)', 'rgb(0, 150, 136)', 'rgb(96, 125, 139)'],
formatter: function (y) {
return y + '%'
}
});
}
var data = [], totalPoints = 110;
function getRandomData() {
if (data.length > 0) data = data.slice(1);
while (data.length < totalPoints) {
var prev = data.length > 0 ? data[data.length - 1] : 50, y = prev + Math.random() * 10 - 5;
if (y < 0) { y = 0; } else if (y > 100) { y = 100; }
data.push(y);
}
var res = [];
for (var i = 0; i < data.length; ++i) {
res.push([i, data[i]]);
}
return res;
}
}
}

View File

@ -0,0 +1,65 @@
<aside id="rightsidebar" class="right-sidebar">
<ul class="nav nav-tabs tab-nav-right" role="tablist">
<li role="presentation" class="active"><a href="#skins" data-toggle="tab">SKINS</a></li>
<li role="presentation"><a href="#settings" data-toggle="tab">SETTINGS</a></li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active in active" id="skins">
<ul class="demo-choose-skin">
<li *ngFor="let theme of themes" [ngClass]="{'active': selectedThemeCssClass == theme.cssClass}" (click)="setTheme(theme)">
<div class="{{theme.cssClass}}"></div>
<span>{{theme.name}}</span>
</li>
</ul>
</div>
<div role="tabpanel" class="tab-pane fade" id="settings">
<div class="demo-settings">
<p>GENERAL SETTINGS</p>
<ul class="setting-list">
<li>
<span>Report Panel Usage</span>
<div class="switch">
<label><input type="checkbox" checked><span class="lever"></span></label>
</div>
</li>
<li>
<span>Email Redirect</span>
<div class="switch">
<label><input type="checkbox"><span class="lever"></span></label>
</div>
</li>
</ul>
<p>SYSTEM SETTINGS</p>
<ul class="setting-list">
<li>
<span>Notifications</span>
<div class="switch">
<label><input type="checkbox" checked><span class="lever"></span></label>
</div>
</li>
<li>
<span>Auto Updates</span>
<div class="switch">
<label><input type="checkbox" checked><span class="lever"></span></label>
</div>
</li>
</ul>
<p>ACCOUNT SETTINGS</p>
<ul class="setting-list">
<li>
<span>Offline</span>
<div class="switch">
<label><input type="checkbox"><span class="lever"></span></label>
</div>
</li>
<li>
<span>Location Permission</span>
<div class="switch">
<label><input type="checkbox" checked><span class="lever"></span></label>
</div>
</li>
</ul>
</div>
</div>
</div>
</aside>

View File

@ -0,0 +1,70 @@
import { Component, Injector, ViewEncapsulation, OnInit } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
import { ConfigurationServiceProxy, ChangeUiThemeInput } from '@shared/service-proxies/service-proxies';
@Component({
templateUrl: './right-sidebar.component.html',
selector: 'right-sidebar',
encapsulation: ViewEncapsulation.None
})
export class RightSideBarComponent extends AppComponentBase implements OnInit {
themes: UiThemeInfo[] = [
new UiThemeInfo("Red", "red"),
new UiThemeInfo("Pink", "pink"),
new UiThemeInfo("Purple", "purple"),
new UiThemeInfo("Deep Purple", "deep-purple"),
new UiThemeInfo("Indigo", "indigo"),
new UiThemeInfo("Blue", "blue"),
new UiThemeInfo("Light Blue", "light-blue"),
new UiThemeInfo("Cyan", "cyan"),
new UiThemeInfo("Teal", "teal"),
new UiThemeInfo("Green", "green"),
new UiThemeInfo("Light Green", "light-green"),
new UiThemeInfo("Lime", "lime"),
new UiThemeInfo("Yellow", "yellow"),
new UiThemeInfo("Amber", "amber"),
new UiThemeInfo("Orange", "orange"),
new UiThemeInfo("Deep Orange", "deep-orange"),
new UiThemeInfo("Brown", "brown"),
new UiThemeInfo("Grey", "grey"),
new UiThemeInfo("Blue Grey", "blue-grey"),
new UiThemeInfo("Black", "black")
];
selectedThemeCssClass: string = "red";
constructor(
injector: Injector,
private _configurationService: ConfigurationServiceProxy
) {
super(injector);
}
ngOnInit(): void {
this.selectedThemeCssClass = this.setting.get('App.UiTheme');
$('body').addClass('theme-' + this.selectedThemeCssClass);
}
setTheme(theme: UiThemeInfo): void {
const input = new ChangeUiThemeInput();
input.theme = theme.cssClass;
this._configurationService.changeUiTheme(input).subscribe(() => {
const $body = $('body');
$('.right-sidebar .demo-choose-skin li').removeClass('active');
$body.removeClass('theme-' + this.selectedThemeCssClass);
$('.right-sidebar .demo-choose-skin li div.' + theme.cssClass).closest('li').addClass('active');
$body.addClass('theme-' + theme.cssClass);
this.selectedThemeCssClass = theme.cssClass;
});
}
}
class UiThemeInfo {
constructor(
public name: string,
public cssClass: string
) { }
}

View File

@ -0,0 +1,8 @@
<div class="legal">
<div class="copyright">
&copy; {{currentYear}} <a href="javascript:void(0);">SystemKonkursow</a>.
</div>
<div class="version">
<b>Version </b> {{versionText}}
</div>
</div>

View File

@ -0,0 +1,22 @@
import { Component, Injector, ViewEncapsulation } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
@Component({
templateUrl: './sidebar-footer.component.html',
selector: 'sidebar-footer',
encapsulation: ViewEncapsulation.None
})
export class SideBarFooterComponent extends AppComponentBase {
versionText: string;
currentYear: number;
constructor(
injector: Injector
) {
super(injector);
this.currentYear = new Date().getFullYear();
this.versionText = this.appSession.application.version + ' [' + this.appSession.application.releaseDate.format('YYYYDDMM') + ']';
}
}

View File

@ -0,0 +1,60 @@
<div class="menu">
<ul class="list">
<ng-template ngFor let-menuItem [ngForOf]="menuItems" let-mainMenuItemIndex="index">
<li *ngIf="showMenuItem(menuItem)" routerLinkActive="active">
<!-- route name -->
<a [routerLink]="[menuItem.route]" *ngIf="!menuItem.items.length && menuItem.route.indexOf('http') != 0">
<i *ngIf="menuItem.icon" class="material-icons">{{menuItem.icon}}</i>
<span>{{menuItem.name}}</span>
</a>
<!-- Static link (starts with 'http') -->
<a href="{{menuItem.route}}" target="_blank" *ngIf="!menuItem.items.length && menuItem.route.indexOf('http') == 0">
<i *ngIf="menuItem.icon" class="material-icons">{{menuItem.icon}}</i>
<span>{{menuItem.name}}</span>
</a>
<!-- Has child menu items (so, this is a parent menu) -->
<a href="javascript:void(0);" [ngClass]="{'menu-toggle': menuItem.items.length}" *ngIf="menuItem.items.length">
<i *ngIf="menuItem.icon" class="material-icons">{{menuItem.icon}}</i>
<span>{{menuItem.name}}</span>
</a>
<ul class="ml-menu" *ngIf="menuItem.items.length">
<ng-template ngFor let-subMenuItem [ngForOf]="menuItem.items" let-mainMenuItemIndex="index">
<li *ngIf="showMenuItem(subMenuItem)" routerLinkActive="active">
<!-- route name -->
<a [routerLink]="[subMenuItem.route]" class="toggled" *ngIf="!subMenuItem.items.length && subMenuItem.route.indexOf('http') != 0">
<i *ngIf="subMenuItem.icon" class="material-icons">{{subMenuItem.icon}}</i>
<span>{{subMenuItem.name}}</span>
</a>
<!-- Static link (starts with 'http') -->
<a href="{{subMenuItem.route}}" class="toggled" target="_blank" *ngIf="!subMenuItem.items.length && subMenuItem.route.indexOf('http') == 0">
<i *ngIf="subMenuItem.icon" class="material-icons">{{subMenuItem.icon}}</i>
<span>{{subMenuItem.name}}</span>
</a>
<!-- Has child menu items (so, this is a parent menu) -->
<a href="javascript:void(0);" [ngClass]="{'menu-toggle': subMenuItem.items.length}" *ngIf="subMenuItem.items.length">
<i *ngIf="subMenuItem.icon" class="material-icons">{{subMenuItem.icon}}</i>
<span>{{subMenuItem.name}}</span>
</a>
<ul class="ml-menu" *ngIf="subMenuItem.items.length">
<ng-template ngFor let-subSubMenuItem [ngForOf]="subMenuItem.items" let-mainMenuItemIndex="index">
<li *ngIf="showMenuItem(subSubMenuItem)" routerLinkActive="active">
<!-- route name -->
<a [routerLink]="[subSubMenuItem.route]" *ngIf="subSubMenuItem.route.indexOf('http') != 0">
<i *ngIf="subSubMenuItem.icon" class="material-icons">{{subSubMenuItem.icon}}</i>
<span>{{subSubMenuItem.name}}</span>
</a>
<!-- Static link (starts with 'http') -->
<a href="{{subSubMenuItem.route}}" target="_blank" *ngIf="subSubMenuItem.route.indexOf('http') == 0">
<i *ngIf="subSubMenuItem.icon" class="material-icons">{{subSubMenuItem.icon}}</i>
<span>{{subSubMenuItem.name}}</span>
</a>
</li>
</ng-template>
</ul>
</li>
</ng-template>
</ul>
</li>
</ng-template>
</ul>
</div>

View File

@ -0,0 +1,51 @@
import { Component, Injector, ViewEncapsulation } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
import { MenuItem } from '@shared/layout/menu-item';
@Component({
templateUrl: './sidebar-nav.component.html',
selector: 'sidebar-nav',
encapsulation: ViewEncapsulation.None
})
export class SideBarNavComponent extends AppComponentBase {
menuItems: MenuItem[] = [
new MenuItem(this.l("HomePage"), "", "home", "/app/home"),
new MenuItem(this.l("Tenants"), "Pages.Tenants", "business", "/app/tenants"),
new MenuItem(this.l("Users"), "Pages.Users", "people", "/app/users"),
new MenuItem(this.l("Roles"), "Pages.Roles", "local_offer", "/app/roles"),
new MenuItem(this.l("About"), "", "info", "/app/about"),
new MenuItem(this.l("MultiLevelMenu"), "", "menu", "", [
new MenuItem("ASP.NET Boilerplate", "", "", "", [
new MenuItem("Home", "", "", "https://aspnetboilerplate.com/?ref=abptmpl"),
new MenuItem("Templates", "", "", "https://aspnetboilerplate.com/Templates?ref=abptmpl"),
new MenuItem("Samples", "", "", "https://aspnetboilerplate.com/Samples?ref=abptmpl"),
new MenuItem("Documents", "", "", "https://aspnetboilerplate.com/Pages/Documents?ref=abptmpl")
]),
new MenuItem("ASP.NET Zero", "", "", "", [
new MenuItem("Home", "", "", "https://aspnetzero.com?ref=abptmpl"),
new MenuItem("Description", "", "", "https://aspnetzero.com/?ref=abptmpl#description"),
new MenuItem("Features", "", "", "https://aspnetzero.com/?ref=abptmpl#features"),
new MenuItem("Pricing", "", "", "https://aspnetzero.com/?ref=abptmpl#pricing"),
new MenuItem("Faq", "", "", "https://aspnetzero.com/Faq?ref=abptmpl"),
new MenuItem("Documents", "", "", "https://aspnetzero.com/Documents?ref=abptmpl")
])
])
];
constructor(
injector: Injector
) {
super(injector);
}
showMenuItem(menuItem): boolean {
if (menuItem.permissionName) {
return this.permission.isGranted(menuItem.permissionName);
}
return true;
}
}

View File

@ -0,0 +1,15 @@
<div class="user-info">
<div class="image">
<img src="assets/images/user.png" width="48" height="48" alt="User" />
</div>
<div class="info-container">
<div class="name" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{shownLoginName}}</div>
<div class="email">{{appSession.user.emailAddress}}</div>
<div class="btn-group user-helper-dropdown">
<i class="material-icons" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">keyboard_arrow_down</i>
<ul class="dropdown-menu pull-right">
<li><a (click)="logout()"><i class="material-icons">input</i>{{l('Wyloguj')}}</a></li>
</ul>
</div>
</div>
</div>

View File

@ -0,0 +1,28 @@
import { Component, OnInit, Injector, ViewEncapsulation } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
import { AppAuthService } from '@shared/auth/app-auth.service';
@Component({
templateUrl: './sidebar-user-area.component.html',
selector: 'sidebar-user-area',
encapsulation: ViewEncapsulation.None
})
export class SideBarUserAreaComponent extends AppComponentBase implements OnInit {
shownLoginName: string = "";
constructor(
injector: Injector,
private _authService: AppAuthService
) {
super(injector);
}
ngOnInit() {
this.shownLoginName = this.appSession.getShownLoginName();
}
logout(): void {
this._authService.logout();
}
}

View File

@ -0,0 +1,12 @@
<li class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button">
<i class="{{currentLanguage.icon}}" title="{{currentLanguage.displayName}}"></i>
{{currentLanguage.displayName}}
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li *ngFor="let language of languages">
<a *ngIf="language.name != currentLanguage.name" (click)="changeLanguage(language.name)"><i class="{{language.icon}}"></i> {{language.displayName}}</a>
</li>
</ul>
</li>

View File

@ -0,0 +1,44 @@
import { Component, OnInit, Injector, ViewEncapsulation } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
import { UserServiceProxy, ChangeUserLanguageDto } from '@shared/service-proxies/service-proxies';
import * as _ from 'lodash';
@Component({
templateUrl: './topbar-languageswitch.component.html',
selector: 'topbar-languageswitch',
encapsulation: ViewEncapsulation.None
})
export class TopBarLanguageSwitchComponent extends AppComponentBase implements OnInit {
languages: abp.localization.ILanguageInfo[];
currentLanguage: abp.localization.ILanguageInfo;
constructor(
injector: Injector,
private _userService: UserServiceProxy
) {
super(injector);
}
ngOnInit() {
this.languages = _.filter(this.localization.languages, l => !l.isDisabled);
this.currentLanguage = this.localization.currentLanguage;
}
changeLanguage(languageName: string): void {
const input = new ChangeUserLanguageDto();
input.languageName = languageName;
this._userService.changeLanguage(input).subscribe(() => {
abp.utils.setCookieValue(
'Abp.Localization.CultureName',
languageName,
new Date(new Date().getTime() + 5 * 365 * 86400000), //5 year
abp.appPath
);
window.location.reload();
});
}
}

View File

@ -0,0 +1,27 @@
<!-- Search Bar -->
<div class="search-bar">
<div class="search-icon">
<i class="material-icons">search</i>
</div>
<input materialInput type="text" placeholder="START TYPING...">
<div class="close-search">
<i class="material-icons">close</i>
</div>
</div> <!-- #END# Search Bar -->
<nav class="navbar">
<div class="container-fluid">
<div class="navbar-header">
<a href="javascript:void(0);" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false"></a>
<a href="javascript:void(0);" class="bars"></a>
<a routerLink="/app/home" class="navbar-brand"><i class="fa fa-cubes"></i> System Konkursów</a>
</div>
<div class="collapse navbar-collapse" id="navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="javascript:void(0);" class="js-search" data-close="true"><i class="material-icons">search</i></a></li>
<!-- <topbar-languageswitch></topbar-languageswitch> -->
<li class="pull-right"><a href="javascript:void(0);" class="js-right-sidebar" data-close="true"><i class="material-icons">more_vert</i></a></li>
</ul>
</div>
</div>
</nav>

View File

@ -0,0 +1,16 @@
import { Component, Injector, ViewEncapsulation } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
@Component({
templateUrl: './topbar.component.html',
selector: 'top-bar',
encapsulation: ViewEncapsulation.None
})
export class TopBarComponent extends AppComponentBase {
constructor(
injector: Injector
) {
super(injector);
}
}

View File

@ -0,0 +1,75 @@
<div bsModal #createRoleModal="bs-modal" class="modal fade" (onShown)="onShown()" tabindex="-1" role="dialog" aria-labelledby="createRoleModal" aria-hidden="true" [config]="{backdrop: 'static'}">
<div class="modal-dialog">
<div #modalContent class="modal-content">
<form *ngIf="active" #createRoleForm="ngForm" id="frm_create_role" novalidate (ngSubmit)="save()">
<div class="modal-header">
<button type="button" class="close" (click)="close()" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">
<span>{{l("CreateNewRole")}}</span>
</h4>
</div>
<div class="modal-body">
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input id="rolename" type="text" name="RoleName" [(ngModel)]="role.name" required maxlength="32" minlength="2" class="validate form-control">
<label for="rolename" class="form-label">{{l("RoleName")}}</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input id="displayname" type="text" name="DisplayName" [(ngModel)]="role.displayName" required maxlength="32" minlength="2" class="validate form-control">
<label for="displayname" class="form-label">{{l("DisplayName")}}</label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<textarea id="role-description" name="Description" [(ngModel)]="role.description" class="validate form-control"></textarea>
<label for="role-description" class="form-label">Role Description</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-12">
<h4>Permissions</h4>
<ng-template ngFor let-permission [ngForOf]="permissions.items" let-permissionIndex="index">
<div class="col-sm-6">
<input type="checkbox" name="permission" value="{{permission.name}}" class="filled-in" id="permission-{{permissionIndex}}" checked="checked" />
<label for="permission-{{permissionIndex}}">{{permission.displayName}}</label>
</div>
</ng-template>
</div>
</div>
</div>
<div class="modal-footer">
<button [disabled]="saving" type="button" class="btn btn-default waves-effect" (click)="close()">
{{l("Cancel")}}
</button>
<button [disabled]="!createRoleForm.form.valid || saving" type="submit" class="btn btn-primary waves-effect">
{{l("Save")}}
</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,74 @@
import { Component, ViewChild, Injector, Output, EventEmitter, ElementRef, OnInit } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap';
import { RoleServiceProxy, CreateRoleDto, ListResultDtoOfPermissionDto } from '@shared/service-proxies/service-proxies';
import { AppComponentBase } from '@shared/app-component-base';
import { finalize } from 'rxjs/operators';
@Component({
selector: 'create-role-modal',
templateUrl: './create-role.component.html'
})
export class CreateRoleComponent extends AppComponentBase implements OnInit {
@ViewChild('createRoleModal') modal: ModalDirective;
@ViewChild('modalContent') modalContent: ElementRef;
active: boolean = false;
saving: boolean = false;
permissions: ListResultDtoOfPermissionDto = null;
role: CreateRoleDto = null;
@Output() modalSave: EventEmitter<any> = new EventEmitter<any>();
constructor(
injector: Injector,
private _roleService: RoleServiceProxy
) {
super(injector);
}
ngOnInit(): void {
this._roleService.getAllPermissions()
.subscribe((permissions: ListResultDtoOfPermissionDto) => {
this.permissions = permissions;
});
}
show(): void {
this.active = true;
this.role = new CreateRoleDto();
this.role.init({ isStatic: false });
this.modal.show();
}
onShown(): void {
$.AdminBSB.input.activate($(this.modalContent.nativeElement));
}
save(): void {
var permissions = [];
$(this.modalContent.nativeElement).find("[name=permission]").each(
(index: number, elem: Element) => {
if ($(elem).is(":checked")) {
permissions.push(elem.getAttribute("value").valueOf());
}
}
);
this.role.permissions = permissions;
this.saving = true;
this._roleService.create(this.role)
.pipe(finalize(() => { this.saving = false; }))
.subscribe(() => {
this.notify.info(this.l('SavedSuccessfully'));
this.close();
this.modalSave.emit(null);
});
}
close(): void {
this.active = false;
this.modal.hide();
}
}

View File

@ -0,0 +1,77 @@
<div bsModal #editRoleModal="bs-modal" class="modal fade" (onShown)="onShown()" tabindex="-1" role="dialog" aria-labelledby="edidtRoleModal" aria-hidden="true" [config]="{backdrop: 'static'}">
<div class="modal-dialog">
<div #modalContent class="modal-content">
<form *ngIf="active" #editRoleForm="ngForm" id="frm_edit_role" novalidate (ngSubmit)="save()">
<div class="modal-header">
<button type="button" class="close" (click)="close()" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">
<span>{{l("EditRole")}} <span *ngIf="model.role.isStatic"> (<span style="color:red">static</span>)</span></span>
</h4>
</div>
<div class="modal-body">
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input id="rolename" [disabled]="model.role.isStatic" type="text" name="RoleName" [(ngModel)]="model.role.name" required maxlength="32" minlength="2" class="validate form-control">
<label for="rolename" class="form-label">{{l("RoleName")}}</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input id="displayname" type="text" name="DisplayName" [(ngModel)]="model.role.displayName" required maxlength="32" minlength="2" class="validate form-control">
<label for="displayname" class="form-label">{{l("DisplayName")}}</label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<textarea id="role-description" name="Description" [(ngModel)]="model.role.description" class="validate form-control"></textarea>
<label for="role-description" class="form-label">Role Description</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-12">
<h4>Permissions</h4>
<ng-template ngFor let-permission [ngForOf]="model.permissions" let-permissionIndex="index">
<div class="col-sm-6">
<input [disabled]="model.role.isStatic" type="checkbox" name="permission" value="{{permission.name}}" class="filled-in" id="permission-{{permissionIndex}}" checked="{{checkPermission(permission.name)}}" />
<label for="permission-{{permissionIndex}}">{{permission.displayName}}</label>
</div>
</ng-template>
</div>
</div>
</div>
<div class="modal-footer">
<button [disabled]="saving" type="button" class="btn btn-default waves-effect" (click)="close()">
{{l("Cancel")}}
</button>
<button [disabled]="!editRoleForm.form.valid || saving" type="submit" class="btn btn-primary waves-effect">
{{l("Save")}}
</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,88 @@
import { Component, ViewChild, Injector, Output, EventEmitter, ElementRef } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap';
import { RoleServiceProxy, GetRoleForEditOutput, RoleDto } from '@shared/service-proxies/service-proxies';
import { AppComponentBase } from '@shared/app-component-base';
import { finalize } from 'rxjs/operators';
@Component({
selector: 'edit-role-modal',
templateUrl: './edit-role.component.html'
})
export class EditRoleComponent extends AppComponentBase {
@ViewChild('editRoleModal') modal: ModalDirective;
@ViewChild('modalContent') modalContent: ElementRef;
active: boolean = false;
saving: boolean = false;
model: GetRoleForEditOutput = null;
@Output() modalSave: EventEmitter<any> = new EventEmitter<any>();
constructor(
injector: Injector,
private _roleService: RoleServiceProxy
) {
super(injector);
}
show(id: number): void {
this._roleService.getRoleForEdit(id)
.pipe(finalize(() => {
this.active = true;
this.modal.show();
}))
.subscribe((result: GetRoleForEditOutput) => {
this.model = result;
});
}
onShown(): void {
$.AdminBSB.input.activate($(this.modalContent.nativeElement));
}
checkPermission(permissionName: string): string {
if (this.model.grantedPermissionNames.indexOf(permissionName) != -1) {
return "checked";
}
else {
return "";
}
}
save(): void {
const role = this.model.role;
var permissions = [];
$(this.modalContent.nativeElement).find("[name=permission]").each(
function (index: number, elem: Element) {
if ($(elem).is(":checked") == true) {
permissions.push(elem.getAttribute("value").valueOf());
}
}
)
this.saving = true;
var input = new RoleDto();
input.name = role.name;
input.displayName = role.displayName;
input.description = role.description;
input.id = role.id;
input.isStatic = role.isStatic;
input.permissions = permissions;
this._roleService.update(input)
.pipe(finalize(() => { this.saving = false; }))
.subscribe(() => {
this.notify.info(this.l('SavedSuccessfully'));
this.close();
this.modalSave.emit(null);
});
}
close(): void {
this.active = false;
this.modal.hide();
}
}

View File

@ -0,0 +1,59 @@
<div class="row clearfix" [@routerTransition]>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="card main-content">
<div class="header">
<h2>
{{l('Roles')}}
</h2>
<ul class="header-dropdown m-r--5">
<i class="fa fa-spin fa-spinner" *ngIf="isTableLoading"></i>
<li class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">more_vert</i>
</a>
<ul class="dropdown-menu pull-right">
<li><a href="javascript:void(0);" class=" waves-effect <waves-block></waves-block>" (click)="refresh();"><i class="material-icons">refresh</i> Refresh</a></li>
</ul>
</li>
</ul>
</div>
<div class="body table-responsive">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>{{l('RoleName')}}</th>
<th>{{l('DisplayName')}}</th>
<th>{{l('Actions')}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let role of roles | paginate: { id: 'server', itemsPerPage: pageSize, currentPage: pageNumber, totalItems: totalItems }">
<td>{{role.name}}</td>
<td>{{role.displayName}}</td>
<td class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">menu</i>
</a>
<ul class="dropdown-menu pull-right">
<li><a href="javascript:void(0);" class="waves-effect waves-block" (click)="editRole(role)"><i class="material-icons">create</i>Edit</a></li>
<li><a href="javascript:void(0);" class="waves-effect waves-block" (click)="delete(role)"><i class="material-icons">delete_sweep</i>Delete</a></li>
</ul>
</td>
</tr>
</tbody>
</table>
<div class="text-align: center;" *ngIf="totalItems > pageSize">
<pagination-controls (pageChange)="getDataPage($event)" id="server"></pagination-controls>
</div>
<button type="button" data-toggle="modal" class="btn btn-primary btn-circle waves-effect waves-circle waves-float pull-right" (click)="createRole()">
<i class="material-icons">add</i>
</button>
</div>
</div>
</div>
</div>
<create-role-modal #createRoleModal (modalSave)="refresh()"></create-role-modal>
<edit-role-modal #editRoleModal (modalSave)="refresh()"></edit-role-modal>

View File

@ -0,0 +1,62 @@
import { Component, Injector, ViewChild } from '@angular/core';
import { PagedListingComponentBase, PagedRequestDto } from 'shared/paged-listing-component-base';
import { RoleServiceProxy, RoleDto, PagedResultDtoOfRoleDto } from 'shared/service-proxies/service-proxies';
import { appModuleAnimation } from '@shared/animations/routerTransition';
import { CreateRoleComponent } from 'app/roles/create-role/create-role.component';
import { EditRoleComponent } from 'app/roles/edit-role/edit-role.component';
import { finalize } from 'rxjs/operators';
@Component({
templateUrl: './roles.component.html',
animations: [appModuleAnimation()]
})
export class RolesComponent extends PagedListingComponentBase<RoleDto> {
@ViewChild('createRoleModal') createRoleModal: CreateRoleComponent;
@ViewChild('editRoleModal') editRoleModal: EditRoleComponent;
roles: RoleDto[] = [];
constructor(
private injector:Injector,
private rolesService: RoleServiceProxy
) {
super(injector);
}
list(request: PagedRequestDto, pageNumber: number, finishedCallback: Function): void {
this.rolesService.getAll(request.skipCount, request.maxResultCount)
.pipe(finalize(() => { finishedCallback() }))
.subscribe((result: PagedResultDtoOfRoleDto)=>{
this.roles = result.items;
this.showPaging(result, pageNumber);
});
}
delete(role: RoleDto): void {
abp.message.confirm(
"Remove Users from Role and delete Role '"+ role.displayName +"'?",
"Permanently delete this Role",
(result:boolean) =>{
if(result)
{
this.rolesService.delete(role.id)
.pipe(finalize(() => {
abp.notify.info("Deleted Role: " + role.displayName);
this.refresh();
}))
.subscribe(() => { });
}
}
);
}
// Show Modals
createRole(): void {
this.createRoleModal.show();
}
editRole(role:RoleDto): void {
this.editRoleModal.show(role.id);
}
}

View File

@ -0,0 +1,60 @@
<div bsModal #createTenantModal="bs-modal" class="modal fade" (onShown)="onShown()" tabindex="-1" role="dialog" aria-labelledby="createUserModal" aria-hidden="true" [config]="{backdrop: 'static'}">
<div class="modal-dialog">
<div #modalContent class="modal-content">
<form *ngIf="active" #createTenantForm="ngForm" id="frm_create_tenant" novalidate (ngSubmit)="save()">
<div class="modal-header">
<button type="button" class="close" (click)="close()" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">
<span>{{l("CreateNewTenant")}}</span>
</h4>
</div>
<div class="modal-body">
<div class="form-group form-float">
<div class="form-line">
<input class="form-control" type="text" name="TenancyName" [(ngModel)]="tenant.tenancyName" required maxlength="64" minlength="2">
<label class="form-label">{{l("TenancyName")}}</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="text" name="Name" class="form-control" [(ngModel)]="tenant.name" required maxlength="128">
<label class="form-label">{{l("Name")}}</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="text" name="ConnectionString" class="form-control" [(ngModel)]="tenant.connectionString" maxlength="1024">
<label class="form-label">{{l("DatabaseConnectionString")}} ({{l("Optional")}})</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="email" name="AdminEmailAddress" class="form-control" [(ngModel)]="tenant.adminEmailAddress" required maxlength="256" pattern="^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$">
<label class="form-label">{{l("AdminEmailAddress")}}</label>
</div>
</div>
<div class="form-group form-float">
<div class="">
<input id="isactive" type="checkbox" name="IsActive" [(ngModel)]="tenant.isActive" checked class="form-control" />
<label for="isactive" class="form-label">{{l("IsActive")}}</label>
</div>
</div>
<p>{{l("DefaultPasswordIs","123qwe")}}</p>
</div>
<div class="modal-footer">
<button [disabled]="saving" type="button" class="btn btn-default" (click)="close()">{{l("Cancel")}}</button>
<button [disabled]="!createTenantForm.form.valid || saving" type="submit" class="btn btn-primary blue">{{l("Save")}}</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,55 @@
import { Component, ViewChild, Injector, Output, EventEmitter, ElementRef } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap';
import { TenantServiceProxy, CreateTenantDto } from '@shared/service-proxies/service-proxies';
import { AppComponentBase } from '@shared/app-component-base';
import { finalize } from 'rxjs/operators';
@Component({
selector: 'create-tenant-modal',
templateUrl: './create-tenant.component.html'
})
export class CreateTenantComponent extends AppComponentBase {
@ViewChild('createTenantModal') modal: ModalDirective;
@ViewChild('modalContent') modalContent: ElementRef;
@Output() modalSave: EventEmitter<any> = new EventEmitter<any>();
active: boolean = false;
saving: boolean = false;
tenant: CreateTenantDto = null;
constructor(
injector: Injector,
private _tenantService: TenantServiceProxy
) {
super(injector);
}
show(): void {
this.active = true;
this.modal.show();
this.tenant = new CreateTenantDto();
this.tenant.init({isActive:true});
}
onShown(): void {
$.AdminBSB.input.activate($(this.modalContent.nativeElement));
}
save(): void {
this.saving = true;
this._tenantService.create(this.tenant)
.pipe(finalize(() => { this.saving = false; }))
.subscribe(() => {
this.notify.info(this.l('SavedSuccessfully'));
this.close();
this.modalSave.emit(null);
});
}
close(): void {
this.active = false;
this.modal.hide();
}
}

View File

@ -0,0 +1,47 @@
<div bsModal #editTenantModal="bs-modal" class="modal fade" (onShown)="onShown()" tabindex="-1" role="dialog" aria-labelledby="editUserModal" aria-hidden="true" [config]="{backdrop: 'static'}">
<div class="modal-dialog">
<div #modalContent class="modal-content">
<form *ngIf="active" #editTenantForm="ngForm" id="frm_edit_tenant" novalidate (ngSubmit)="save()">
<div class="modal-header">
<button type="button" class="close" (click)="close()" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">
<span>{{l("EditTenant")}}</span>
</h4>
</div>
<div class="modal-body">
<div class="form-group form-float">
<div class="form-line">
<input class="form-control" type="text" name="TenancyName" [(ngModel)]="tenant.tenancyName" required maxlength="64" minlength="2">
<label class="form-label">{{l("TenancyName")}}</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="text" name="Name" class="form-control" [(ngModel)]="tenant.name" required maxlength="128">
<label class="form-label">{{l("Name")}}</label>
</div>
</div>
<div class="form-group form-float">
<div class="">
<input id="isactive" type="checkbox" name="IsActive" [(ngModel)]="tenant.isActive" checked class="form-control" />
<label for="isactive" class="form-label">{{l("IsActive")}}</label>
</div>
</div>
</div>
<div class="modal-footer">
<button [disabled]="saving" type="button" class="btn btn-default" (click)="close()">{{l("Cancel")}}</button>
<button [disabled]="!editTenantForm.form.valid || saving" type="submit" class="btn btn-primary blue">{{l("Save")}}</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,59 @@
import { Component, ViewChild, Injector, Output, EventEmitter, ElementRef} from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap';
import { TenantServiceProxy, TenantDto } from '@shared/service-proxies/service-proxies';
import { AppComponentBase } from '@shared/app-component-base';
import { finalize } from 'rxjs/operators';
@Component({
selector: 'edit-tenant-modal',
templateUrl: './edit-tenant.component.html'
})
export class EditTenantComponent extends AppComponentBase{
@ViewChild('editTenantModal') modal: ModalDirective;
@ViewChild('modalContent') modalContent: ElementRef;
@Output() modalSave: EventEmitter<any> = new EventEmitter<any>();
active: boolean = false;
saving: boolean = false;
tenant: TenantDto = null;
constructor(
injector: Injector,
private _tenantService: TenantServiceProxy
) {
super(injector);
}
show(id:number): void {
this._tenantService.get(id)
.pipe(finalize(() => {
this.active = true;
this.modal.show();
}))
.subscribe((result: TenantDto)=>{
this.tenant = result;
});
}
onShown(): void {
$.AdminBSB.input.activate($(this.modalContent.nativeElement));
}
save(): void {
this.saving = true;
this._tenantService.update(this.tenant)
.pipe(finalize(() => { this.saving = false; }))
.subscribe(() => {
this.notify.info(this.l('SavedSuccessfully'));
this.close();
this.modalSave.emit(null);
});
}
close(): void {
this.active = false;
this.modal.hide();
}
}

View File

@ -0,0 +1,66 @@
<div class="row clearfix" [@routerTransition]>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="card main-content">
<div class="header">
<h2>
{{l("Tenants")}}
</h2>
<ul class="header-dropdown m-r--5">
<i class="fa fa-spin fa-spinner" *ngIf="isTableLoading"></i>
<li class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">more_vert</i>
</a>
<ul class="dropdown-menu pull-right">
<li><a href="javascript:void(0);" class=" waves-effect waves-block()" (click)="refresh();"><i class="material-icons">refresh</i>Refresh</a></li>
</ul>
</li>
</ul>
</div>
<div class="body table-responsive">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>{{l("TenancyName")}}</th>
<th>{{l("Name")}}</th>
<th>
<div style="text-align:center">{{l('IsActive')}}</div>
</th>
<th>{{l('Actions')}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let tenant of tenants | paginate: { id: 'server', itemsPerPage: pageSize, currentPage: pageNumber, totalItems: totalItems }">
<td>{{tenant.tenancyName}}</td>
<td>{{tenant.name}}</td>
<td align="center">
<i class="material-icons" *ngIf="tenant.isActive" style="color:green;">check_box</i>
<i class="material-icons" *ngIf="!tenant.isActive" style="color:red;">indeterminate_check_box</i>
</td>
<td class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">menu</i>
</a>
<ul class="dropdown-menu pull-right">
<li><a href="javascript:void(0);" class="waves-effect waves-block" (click)="editTenant(tenant)"><i class="material-icons">create</i>Edit</a></li>
<li><a href="javascript:void(0);" class="waves-effect waves-block" (click)="delete(tenant)"><i class="material-icons">delete_sweep</i>Delete</a></li>
</ul>
</td>
</tr>
</tbody>
</table>
<div class="text-align: center;" *ngIf="totalItems > pageSize">
<pagination-controls (pageChange)="getDataPage($event)" id="server"></pagination-controls>
</div>
<button type="button" data-toggle="modal" class="btn btn-primary btn-circle waves-effect waves-circle waves-float pull-right" (click)="createTenant()">
<i class="material-icons">add</i>
</button>
</div>
</div>
</div>
</div>
<create-tenant-modal #createTenantModal (modalSave)="refresh()"></create-tenant-modal>
<edit-tenant-modal #editTenantModal (modalSave)="refresh()"></edit-tenant-modal>

View File

@ -0,0 +1,61 @@
import { Component, Injector, ViewChild } from '@angular/core';
import { appModuleAnimation } from '@shared/animations/routerTransition';
import { TenantServiceProxy, TenantDto, PagedResultDtoOfTenantDto } from '@shared/service-proxies/service-proxies';
import { PagedListingComponentBase, PagedRequestDto } from 'shared/paged-listing-component-base';
import { EditTenantComponent } from 'app/tenants/edit-tenant/edit-tenant.component';
import { CreateTenantComponent } from 'app/tenants/create-tenant/create-tenant.component';
import { finalize } from 'rxjs/operators';
@Component({
templateUrl: './tenants.component.html',
animations: [appModuleAnimation()]
})
export class TenantsComponent extends PagedListingComponentBase<TenantDto> {
@ViewChild('createTenantModal') createTenantModal: CreateTenantComponent;
@ViewChild('editTenantModal') editTenantModal: EditTenantComponent;
tenants: TenantDto[] = [];
constructor(
injector: Injector,
private _tenantService: TenantServiceProxy
) {
super(injector);
}
list(request:PagedRequestDto, pageNumber:number, finishedCallback: Function): void {
this._tenantService.getAll(request.skipCount, request.maxResultCount)
.pipe(finalize(() => { finishedCallback() }))
.subscribe((result:PagedResultDtoOfTenantDto)=>{
this.tenants = result.items;
this.showPaging(result, pageNumber);
});
}
delete(tenant: TenantDto): void {
abp.message.confirm(
"Delete tenant '"+ tenant.name +"'?",
(result:boolean) => {
if(result) {
this._tenantService.delete(tenant.id)
.pipe(finalize(() => {
abp.notify.info("Deleted tenant: " + tenant.name);
this.refresh();
}))
.subscribe(() => { });
}
}
);
}
// Show modals
createTenant(): void {
this.createTenantModal.show();
}
editTenant(tenant:TenantDto): void{
this.editTenantModal.show(tenant.id);
}
}

View File

@ -0,0 +1,126 @@
<div bsModal #createUserModal="bs-modal" class="modal fade" (onShown)="onShown()" tabindex="-1" role="dialog" aria-labelledby="createUserModal" aria-hidden="true" [config]="{backdrop: 'static'}">
<div class="modal-dialog">
<div #modalContent class="modal-content">
<form *ngIf="active" #createUserForm="ngForm" id="frm_create_user" novalidate (ngSubmit)="save()">
<div class="modal-header">
<button type="button" class="close" (click)="close()" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">
<span>{{l("CreateNewUser")}}</span>
</h4>
</div>
<div class="modal-body">
<ul class="nav nav-tabs tab-nav-right" role="tablist">
<li role="presentation" class="active"><a href="#user-details" data-toggle="tab">User Details</a></li>
<li role="presentation"><a href="#user-roles" data-toggle="tab">User Roles</a></li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane animated fadeIn active" id="user-details">
<div class="row clearfix" style="margin-top:10px;">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input id="username" type="text" name="UserName" [(ngModel)]="user.userName" required maxlength="32" minlength="2" class="validate form-control">
<label for="username" class="form-label">{{l("UserName")}}</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-6">
<div class="form-group form-float">
<div class="form-line">
<input id="name" type="text" name="Name" [(ngModel)]="user.name" required maxlength="32" class="validate form-control">
<label for="name" class="form-label">{{l("Name")}}</label>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group form-float">
<div class="form-line">
<input id="surname" type="text" name="Surname" [(ngModel)]="user.surname" required maxlength="32" class="validate form-control">
<label for="surname" class="form-label">{{l("Surname")}}</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input id="email" type="email" name="EmailAddress" [(ngModel)]="user.emailAddress" maxlength="256" pattern="^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$" class="validate form-control">
<label for="email" class="form-label">{{l("EmailAddress")}}</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input id="password" type="password" name="Password" [(ngModel)]="user.password" required maxlength="32" class="validate form-control">
<label for="password" class="form-label">{{l("Password")}}</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input id="confirmpassword" type="password" name="ConfirmPassword" class="validate form-control" [(ngModel)]="user.confirmPassword" equalTo="#password" data-msg-equalto="Please enter the same password again." required maxlength="32">
<label for="confirmpassword" class="form-label">{{l("ConfirmPassword")}}</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="">
<input id="isactive" type="checkbox" name="IsActive" [(ngModel)]="user.isActive" checked class="form-control" />
<label for="isactive" class="form-label">{{l("IsActive")}}</label>
</div>
</div>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane animated fadeIn" id="user-roles">
<div class="row">
<div class="col-sm-12 ">
<ng-template ngFor let-role [ngForOf]="roles" let-roleIndex="index">
<div class="col-sm-6">
<input type="checkbox" name="role" value="{{role.normalizedName}}" title="{{role.description}}" class="filled-in" id="role-{{roleIndex}}" checked="checked" />
<label for="role-{{roleIndex}}" title="{{role.displayName}}">{{role.name}}</label>
</div>
</ng-template>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button [disabled]="saving" type="button" class="btn btn-default waves-effect" (click)="close()">
{{l("Cancel")}}
</button>
<button [disabled]="!createUserForm.form.valid || saving" type="submit" class="btn btn-primary waves-effect">
{{l("Save")}}
</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,72 @@
import { Component, ViewChild, Injector, Output, EventEmitter, ElementRef, OnInit } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap';
import { UserServiceProxy, CreateUserDto, RoleDto } from '@shared/service-proxies/service-proxies';
import { AppComponentBase } from '@shared/app-component-base';
import { finalize } from 'rxjs/operators';
@Component({
selector: 'create-user-modal',
templateUrl: './create-user.component.html'
})
export class CreateUserComponent extends AppComponentBase implements OnInit {
@ViewChild('createUserModal') modal: ModalDirective;
@ViewChild('modalContent') modalContent: ElementRef;
@Output() modalSave: EventEmitter<any> = new EventEmitter<any>();
active: boolean = false;
saving: boolean = false;
user: CreateUserDto = null;
roles: RoleDto[] = null;
constructor(
injector: Injector,
private _userService: UserServiceProxy,
) {
super(injector);
}
ngOnInit(): void {
this._userService.getRoles()
.subscribe((result) => {
this.roles = result.items;
});
}
show(): void {
this.active = true;
this.modal.show();
this.user = new CreateUserDto();
this.user.init({ isActive: true });
}
onShown(): void {
$.AdminBSB.input.activate($(this.modalContent.nativeElement));
}
save(): void {
//TODO: Refactor this, don't use jQuery style code
var roles = [];
$(this.modalContent.nativeElement).find("[name=role]").each((ind:number, elem:Element) => {
if($(elem).is(":checked") == true){
roles.push(elem.getAttribute("value").valueOf());
}
});
this.user.roleNames = roles;
this.saving = true;
this._userService.create(this.user)
.pipe(finalize(() => { this.saving = false; }))
.subscribe(() => {
this.notify.info(this.l('SavedSuccessfully'));
this.close();
this.modalSave.emit(null);
});
}
close(): void {
this.active = false;
this.modal.hide();
}
}

View File

@ -0,0 +1,102 @@
<div bsModal #editUserModal="bs-modal" class="modal fade" (onShown)="onShown()" tabindex="-1" role="dialog" aria-labelledby="editUserModal" aria-hidden="true" [config]="{backdrop: 'static'}">
<div class="modal-dialog">
<div #modalContent class="modal-content">
<form *ngIf="active" #editUserForm="ngForm" id="frm_edit_user" novalidate (ngSubmit)="save()">
<div class="modal-header">
<button type="button" class="close" (click)="close()" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">
<span>{{l("EditUser")}}</span>
</h4>
</div>
<div class="modal-body">
<ul class="nav nav-tabs tab-nav-right" role="tablist">
<li role="presentation" class="active"><a href="#edit-user-details" data-toggle="tab">User Details</a></li>
<li role="presentation"><a href="#edit-user-roles" data-toggle="tab">User Roles</a></li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane animated fadeIn active" id="edit-user-details">
<div class="row clearfix" style="margin-top:10px;">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input id="username" type="text" name="UserName" [(ngModel)]="user.userName" required maxlength="32" minlength="2" class="validate form-control">
<label for="username" class="form-label">{{l("UserName")}}</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-6">
<div class="form-group form-float">
<div class="form-line">
<input id="name" type="text" name="Name" [(ngModel)]="user.name" required maxlength="32" class="validate form-control">
<label for="name" class="form-label">{{l("Name")}}</label>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group form-float">
<div class="form-line">
<input id="surname" type="text" name="Surname" [(ngModel)]="user.surname" required maxlength="32" class="validate form-control">
<label for="surname" class="form-label">{{l("Surname")}}</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input id="email" type="email" name="EmailAddress" [(ngModel)]="user.emailAddress" maxlength="256" pattern="^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$" class="validate form-control">
<label for="email" class="form-label">{{l("EmailAddress")}}</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="">
<input id="isactive" type="checkbox" name="IsActive" [(ngModel)]="user.isActive" checked class="form-control" />
<label for="isactive" class="form-label">{{l("IsActive")}}</label>
</div>
</div>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane animated fadeIn" id="edit-user-roles">
<div class="row">
<div class="col-sm-12 ">
<ng-template ngFor let-role [ngForOf]="roles" let-roleIndex="index">
<div class="col-sm-6">
<input type="checkbox" name="role" value="{{role.normalizedName}}" title="{{role.description}}" class="filled-in" id="role-{{roleIndex}}" checked="{{userInRole(role,user)}}" />
<label for="role-{{roleIndex}}" title="{{role.displayName}}">{{role.name}}</label>
</div>
</ng-template>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button [disabled]="saving" type="button" class="btn btn-default waves-effect" (click)="close()">
{{l("Cancel")}}
</button>
<button [disabled]="!editUserForm.form.valid" type="submit" class="btn btn-primary waves-effect">
{{l("Save")}}
</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,84 @@
import { Component, ViewChild, Injector, Output, EventEmitter, ElementRef } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap';
import { UserServiceProxy, UserDto, RoleDto } from '@shared/service-proxies/service-proxies';
import { AppComponentBase } from '@shared/app-component-base';
import { finalize } from 'rxjs/operators';
@Component({
selector: 'edit-user-modal',
templateUrl: './edit-user.component.html'
})
export class EditUserComponent extends AppComponentBase {
@ViewChild('editUserModal') modal: ModalDirective;
@ViewChild('modalContent') modalContent: ElementRef;
@Output() modalSave: EventEmitter<any> = new EventEmitter<any>();
active: boolean = false;
saving: boolean = false;
user: UserDto = null;
roles: RoleDto[] = null;
constructor(
injector: Injector,
private _userService: UserServiceProxy
) {
super(injector);
}
userInRole(role: RoleDto, user: UserDto): string {
if (user.roleNames.indexOf(role.normalizedName) !== -1) {
return "checked";
}
else {
return "";
}
}
show(id: number): void {
this._userService.getRoles()
.subscribe((result) => {
this.roles = result.items;
});
this._userService.get(id)
.subscribe(
(result) => {
this.user = result;
this.active = true;
this.modal.show();
}
);
}
onShown(): void {
$.AdminBSB.input.activate($(this.modalContent.nativeElement));
}
save(): void {
var roles = [];
$(this.modalContent.nativeElement).find("[name=role]").each(function (ind: number, elem: Element) {
if ($(elem).is(":checked")) {
roles.push(elem.getAttribute("value").valueOf());
}
});
this.user.roleNames = roles;
this.saving = true;
this._userService.update(this.user)
.pipe(finalize(() => { this.saving = false; }))
.subscribe(() => {
this.notify.info(this.l('SavedSuccessfully'));
this.close();
this.modalSave.emit(null);
});
}
close(): void {
this.active = false;
this.modal.hide();
}
}

View File

@ -0,0 +1,70 @@
<div class="row clearfix" [@routerTransition]>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="card main-content">
<div class="header">
<h2>
{{l('Users')}}
</h2>
<ul class="header-dropdown m-r--5">
<i class="fa fa-spin fa-spinner" *ngIf="isTableLoading"></i>
<li class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">more_vert</i>
</a>
<ul class="dropdown-menu pull-right">
<li><a href="javascript:void(0);" class=" waves-effect waves-block()" (click)="refresh();"><i class="material-icons">refresh</i> {{l('Refresh')}}</a></li>
</ul>
</li>
</ul>
</div>
<div class="body table-responsive">
<!-- ******************************************************** -->
<table class="table table-hover table-striped">
<thead>
<tr>
<th>{{l('UserName')}}</th>
<th>{{l('FullName')}}</th>
<th>{{l('EmailAddress')}}</th>
<th>
<div style="text-align:center">{{l('IsActive')}}</div>
</th>
<th>{{l('Actions')}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users | paginate: { id: 'server', itemsPerPage: pageSize, currentPage: pageNumber, totalItems: totalItems }">
<td>{{user.userName}}</td>
<td>{{user.fullName}}</td>
<td>{{user.emailAddress}}</td>
<td align="center">
<i class="material-icons" *ngIf="user.isActive" style="color:green;">check_box</i>
<i class="material-icons" *ngIf="!user.isActive" style="color:red;">indeterminate_check_box</i>
</td>
<td class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">menu</i>
</a>
<ul class="dropdown-menu pull-right">
<li><a href="javascript:void(0);" class="waves-effect waves-block" (click)="editUser(user)"><i class="material-icons">create</i>{{l('Edit')}}</a></li>
<li><a href="javascript:void(0);" class="waves-effect waves-block" (click)="delete(user)"><i class="material-icons">delete_sweep</i>{{l('Delete')}}</a></li>
</ul>
</td>
</tr>
</tbody>
</table>
<!-- ******************************************************** -->
<div class="text-align: center;" *ngIf="totalItems > pageSize">
<pagination-controls (pageChange)="getDataPage($event)" id="server"></pagination-controls>
</div>
<button type="button" data-toggle="modal" class="btn btn-primary btn-circle waves-effect waves-circle waves-float pull-right" (click)="createUser()">
<i class="material-icons">add</i>
</button>
</div>
</div>
</div>
</div>
<create-user-modal #createUserModal (modalSave)="refresh()"></create-user-modal>
<edit-user-modal #editUserModal (modalSave)="refresh()"></edit-user-modal>

View File

@ -0,0 +1,62 @@
import { Component, Injector, ViewChild } from '@angular/core';
import { appModuleAnimation } from '@shared/animations/routerTransition';
import { UserServiceProxy, UserDto, PagedResultDtoOfUserDto } from '@shared/service-proxies/service-proxies';
import { PagedListingComponentBase, PagedRequestDto } from 'shared/paged-listing-component-base';
import { CreateUserComponent } from 'app/users/create-user/create-user.component';
import { EditUserComponent } from 'app/users/edit-user/edit-user.component';
import { finalize } from 'rxjs/operators';
@Component({
templateUrl: './users.component.html',
animations: [appModuleAnimation()]
})
export class UsersComponent extends PagedListingComponentBase<UserDto> {
@ViewChild('createUserModal') createUserModal: CreateUserComponent;
@ViewChild('editUserModal') editUserModal: EditUserComponent;
active: boolean = false;
users: UserDto[] = [];
constructor(
injector: Injector,
private _userService: UserServiceProxy
) {
super(injector);
}
protected list(request: PagedRequestDto, pageNumber: number, finishedCallback: Function): void {
this._userService.getAll(request.skipCount, request.maxResultCount)
.pipe(finalize(() => {
finishedCallback()
}))
.subscribe((result: PagedResultDtoOfUserDto) => {
this.users = result.items;
this.showPaging(result, pageNumber);
});
}
protected delete(user: UserDto): void {
abp.message.confirm(
"Delete user '" + user.fullName + "'?",
(result: boolean) => {
if (result) {
this._userService.delete(user.id)
.subscribe(() => {
abp.notify.info("Deleted User: " + user.fullName);
this.refresh();
});
}
}
);
}
// Show Modals
createUser(): void {
this.createUserModal.show();
}
editUser(user: UserDto): void {
this.editUserModal.show(user.id);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 B

View File

@ -0,0 +1,18 @@
{
"remoteServiceBaseUrl": "http://localhost:21021",
"appBaseUrl": "http://localhost:4200",
"localeMappings": [
{
"from": "pt-BR",
"to": "pt"
},
{
"from": "zh-CN",
"to": "zh"
},
{
"from": "he-IL",
"to": "he"
}
]
}

View File

@ -0,0 +1,112 @@
/* cyrillic-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
}
/* cyrillic */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(CWB0XYA8bzo0kSThX0UTuA.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
}
/* cyrillic-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
src: local('Roboto Bold'), local('Roboto-Bold'), url(77FXFjRbGzN4aCrSFhlh3hJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
}
/* cyrillic */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
src: local('Roboto Bold'), local('Roboto-Bold'), url(isZ-wbCXNKAbnjo6_TwHThJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
src: local('Roboto Bold'), local('Roboto-Bold'), url(UX6i4JxQDm3fVTc1CPuwqhJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
src: local('Roboto Bold'), local('Roboto-Bold'), url(jSN2CGVDbcVyCnfJfjSdfBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
src: local('Roboto Bold'), local('Roboto-Bold'), url(PwZc-YbIL414wB9rB1IAPRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
src: local('Roboto Bold'), local('Roboto-Bold'), url(97uahxiqZRoncBaCEI3aWxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
src: local('Roboto Bold'), local('Roboto-Bold'), url(d-6IYplOFocCacKzxwXSOFtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
}

Some files were not shown because too many files have changed in this diff Show More