SKE-4
This commit is contained in:
parent
5e6f7ea90a
commit
23a46d9f28
9
SystemKonkursow/4.2.1/.gitignore
vendored
Normal file
9
SystemKonkursow/4.2.1/.gitignore
vendored
Normal 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
|
21
SystemKonkursow/4.2.1/LICENSE
Normal file
21
SystemKonkursow/4.2.1/LICENSE
Normal 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.
|
33
SystemKonkursow/4.2.1/README.md
Normal file
33
SystemKonkursow/4.2.1/README.md
Normal 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).
|
BIN
SystemKonkursow/4.2.1/_screenshots/Thumbs.db
Normal file
BIN
SystemKonkursow/4.2.1/_screenshots/Thumbs.db
Normal file
Binary file not shown.
BIN
SystemKonkursow/4.2.1/_screenshots/ui-home.png
Normal file
BIN
SystemKonkursow/4.2.1/_screenshots/ui-home.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 157 KiB |
BIN
SystemKonkursow/4.2.1/_screenshots/ui-login.png
Normal file
BIN
SystemKonkursow/4.2.1/_screenshots/ui-login.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
SystemKonkursow/4.2.1/_screenshots/ui-user-create-modal.png
Normal file
BIN
SystemKonkursow/4.2.1/_screenshots/ui-user-create-modal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 86 KiB |
12
SystemKonkursow/4.2.1/angular/.editorconfig
Normal file
12
SystemKonkursow/4.2.1/angular/.editorconfig
Normal 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
|
43
SystemKonkursow/4.2.1/angular/.gitignore
vendored
Normal file
43
SystemKonkursow/4.2.1/angular/.gitignore
vendored
Normal 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
|
3
SystemKonkursow/4.2.1/angular/Dockerfile
Normal file
3
SystemKonkursow/4.2.1/angular/Dockerfile
Normal file
@ -0,0 +1,3 @@
|
||||
FROM nginx
|
||||
|
||||
COPY . /usr/share/nginx/html
|
27
SystemKonkursow/4.2.1/angular/Properties/launchSettings.json
Normal file
27
SystemKonkursow/4.2.1/angular/Properties/launchSettings.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
SystemKonkursow/4.2.1/angular/README.md
Normal file
27
SystemKonkursow/4.2.1/angular/README.md
Normal 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).
|
@ -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>
|
33
SystemKonkursow/4.2.1/angular/SystemKonkursow.AngularUI.sln
Normal file
33
SystemKonkursow/4.2.1/angular/SystemKonkursow.AngularUI.sln
Normal 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
|
249
SystemKonkursow/4.2.1/angular/angular.json
Normal file
249
SystemKonkursow/4.2.1/angular/angular.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
5
SystemKonkursow/4.2.1/angular/app.config
Normal file
5
SystemKonkursow/4.2.1/angular/app.config
Normal file
@ -0,0 +1,5 @@
|
||||
<configuration>
|
||||
<runtime>
|
||||
<gcServer enabled="true"/>
|
||||
</runtime>
|
||||
</configuration>
|
14
SystemKonkursow/4.2.1/angular/e2e/app.e2e-spec.ts
Normal file
14
SystemKonkursow/4.2.1/angular/e2e/app.e2e-spec.ts
Normal 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!');
|
||||
});
|
||||
});
|
11
SystemKonkursow/4.2.1/angular/e2e/app.po.ts
Normal file
11
SystemKonkursow/4.2.1/angular/e2e/app.po.ts
Normal 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();
|
||||
}
|
||||
}
|
19
SystemKonkursow/4.2.1/angular/e2e/tsconfig.json
Normal file
19
SystemKonkursow/4.2.1/angular/e2e/tsconfig.json
Normal 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"
|
||||
]
|
||||
}
|
||||
}
|
41
SystemKonkursow/4.2.1/angular/karma.conf.js
Normal file
41
SystemKonkursow/4.2.1/angular/karma.conf.js
Normal 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
|
||||
});
|
||||
};
|
1
SystemKonkursow/4.2.1/angular/nswag/refresh.bat
Normal file
1
SystemKonkursow/4.2.1/angular/nswag/refresh.bat
Normal file
@ -0,0 +1 @@
|
||||
"..\node_modules\.bin\nswag" run
|
139
SystemKonkursow/4.2.1/angular/nswag/service.config.nswag
Normal file
139
SystemKonkursow/4.2.1/angular/nswag/service.config.nswag
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
10842
SystemKonkursow/4.2.1/angular/package-lock.json
generated
Normal file
10842
SystemKonkursow/4.2.1/angular/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
91
SystemKonkursow/4.2.1/angular/package.json
Normal file
91
SystemKonkursow/4.2.1/angular/package.json
Normal 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"
|
||||
}
|
||||
}
|
32
SystemKonkursow/4.2.1/angular/protractor.conf.js
Normal file
32
SystemKonkursow/4.2.1/angular/protractor.conf.js
Normal 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());
|
||||
}
|
||||
};
|
70
SystemKonkursow/4.2.1/angular/src/AppPreBootstrap.ts
Normal file
70
SystemKonkursow/4.2.1/angular/src/AppPreBootstrap.ts
Normal 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();
|
||||
});
|
||||
}
|
||||
}
|
@ -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 { }
|
@ -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>© {{currentYear}} SystemKonkursow. <b>Wersja </b> {{versionText}}</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
@ -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;
|
||||
}
|
||||
}
|
@ -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');
|
||||
}
|
||||
}
|
52
SystemKonkursow/4.2.1/angular/src/account/account.module.ts
Normal file
52
SystemKonkursow/4.2.1/angular/src/account/account.module.ts
Normal 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 {
|
||||
|
||||
}
|
@ -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>
|
@ -0,0 +1,11 @@
|
||||
.account-language-switch-list {
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
|
||||
> li {
|
||||
display: inline;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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>
|
@ -0,0 +1,12 @@
|
||||
.social-icons {
|
||||
padding-left: 0px;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
|
||||
a {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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>
|
@ -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; });
|
||||
});
|
||||
}
|
||||
}
|
@ -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">×</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>
|
@ -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();
|
||||
}
|
||||
}
|
@ -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>
|
@ -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);
|
||||
}
|
||||
}
|
@ -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>
|
@ -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);
|
||||
}
|
||||
}
|
29
SystemKonkursow/4.2.1/angular/src/app/app-routing.module.ts
Normal file
29
SystemKonkursow/4.2.1/angular/src/app/app-routing.module.ts
Normal 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 { }
|
19
SystemKonkursow/4.2.1/angular/src/app/app.component.html
Normal file
19
SystemKonkursow/4.2.1/angular/src/app/app.component.html
Normal 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>
|
34
SystemKonkursow/4.2.1/angular/src/app/app.component.spec.ts
Normal file
34
SystemKonkursow/4.2.1/angular/src/app/app.component.spec.ts
Normal 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!');
|
||||
}));
|
||||
});
|
53
SystemKonkursow/4.2.1/angular/src/app/app.component.ts
Normal file
53
SystemKonkursow/4.2.1/angular/src/app/app.component.ts
Normal 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();
|
||||
}
|
||||
}
|
74
SystemKonkursow/4.2.1/angular/src/app/app.module.ts
Normal file
74
SystemKonkursow/4.2.1/angular/src/app/app.module.ts
Normal 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 { }
|
310
SystemKonkursow/4.2.1/angular/src/app/home/home.component.html
Normal file
310
SystemKonkursow/4.2.1/angular/src/app/home/home.component.html
Normal 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>
|
135
SystemKonkursow/4.2.1/angular/src/app/home/home.component.ts
Normal file
135
SystemKonkursow/4.2.1/angular/src/app/home/home.component.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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>
|
@ -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
|
||||
) { }
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<div class="legal">
|
||||
<div class="copyright">
|
||||
© {{currentYear}} <a href="javascript:void(0);">SystemKonkursow</a>.
|
||||
</div>
|
||||
<div class="version">
|
||||
<b>Version </b> {{versionText}}
|
||||
</div>
|
||||
</div>
|
@ -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') + ']';
|
||||
}
|
||||
}
|
@ -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>
|
@ -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;
|
||||
}
|
||||
}
|
@ -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>
|
@ -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();
|
||||
}
|
||||
}
|
@ -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>
|
@ -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();
|
||||
});
|
||||
}
|
||||
}
|
@ -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>
|
@ -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);
|
||||
}
|
||||
}
|
@ -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">×</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>
|
@ -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();
|
||||
}
|
||||
}
|
@ -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">×</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>
|
@ -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();
|
||||
}
|
||||
}
|
@ -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>
|
@ -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);
|
||||
}
|
||||
}
|
@ -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">×</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>
|
@ -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();
|
||||
}
|
||||
}
|
@ -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">×</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>
|
@ -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();
|
||||
}
|
||||
}
|
@ -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>
|
@ -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);
|
||||
}
|
||||
}
|
@ -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">×</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>
|
@ -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();
|
||||
}
|
||||
}
|
@ -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">×</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>
|
@ -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();
|
||||
}
|
||||
}
|
@ -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>
|
@ -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);
|
||||
}
|
||||
}
|
0
SystemKonkursow/4.2.1/angular/src/assets/.gitkeep
Normal file
0
SystemKonkursow/4.2.1/angular/src/assets/.gitkeep
Normal file
BIN
SystemKonkursow/4.2.1/angular/src/assets/app-logo-small.png
Normal file
BIN
SystemKonkursow/4.2.1/angular/src/assets/app-logo-small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 731 B |
18
SystemKonkursow/4.2.1/angular/src/assets/appconfig.json
Normal file
18
SystemKonkursow/4.2.1/angular/src/assets/appconfig.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
112
SystemKonkursow/4.2.1/angular/src/assets/fonts/roboto/roboto.css
Normal file
112
SystemKonkursow/4.2.1/angular/src/assets/fonts/roboto/roboto.css
Normal 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
Loading…
Reference in New Issue
Block a user