Compare commits
41 Commits
Testing_co
...
master
Author | SHA1 | Date | |
---|---|---|---|
13bfb0a45f | |||
29caf98af5 | |||
912cbdbecf | |||
5565bb7070 | |||
7cf0245b43 | |||
77b0c99296 | |||
51235211f6 | |||
bbc45daee3 | |||
761596db7d | |||
537f08e99c | |||
180830c921 | |||
9ecd87db5d | |||
4ef8928ec9 | |||
5274208b60 | |||
4337a5eff5 | |||
3b82ed8111 | |||
cca78cdcc8 | |||
49f0441067 | |||
79e797edeb | |||
2fc97f469c | |||
b8d56680a5 | |||
6f0a565558 | |||
d9ab9802cd | |||
b75d8893c6 | |||
8a8226dad1 | |||
47e4f2be51 | |||
dfcb5e97d7 | |||
d519712c2d | |||
c6f0c3059b | |||
b382d3fe3b | |||
a09c5b8d0e | |||
e1d9fa6ebc | |||
79dde935f3 | |||
f93499ea67 | |||
513c26f155 | |||
c119ef9964 | |||
4bb63859d2 | |||
e13a951ded | |||
0248cf639d | |||
422fe1a99d | |||
23a46d9f28 |
10
SystemKonkursow/4.2.1/.gitignore
vendored
Normal file
10
SystemKonkursow/4.2.1/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# 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
|
||||||
|
aspnet-core/src/SystemKonkursow.EntityFrameworkCore/Migrations/
|
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/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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10872
SystemKonkursow/4.2.1/angular/package-lock.json
generated
Normal file
10872
SystemKonkursow/4.2.1/angular/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
94
SystemKonkursow/4.2.1/angular/package.json
Normal file
94
SystemKonkursow/4.2.1/angular/package.json
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
{
|
||||||
|
"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/cdk": "^6.4.7",
|
||||||
|
"@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/material": "^6.4.7",
|
||||||
|
"@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",
|
||||||
|
"rxjs-compat": "^6.3.3",
|
||||||
|
"simple-line-icons": "^2.4.1",
|
||||||
|
"spin.js": "^2.3.2",
|
||||||
|
"sweetalert": "^2.1.2",
|
||||||
|
"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);">EduKwiz</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}} EduKwiz. <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,74 @@
|
|||||||
|
<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-group form-float">
|
||||||
|
<div class="form-line">
|
||||||
|
<select class="form-control"
|
||||||
|
[(ngModel)]="model.role"
|
||||||
|
name="Role"
|
||||||
|
required>
|
||||||
|
<option *ngFor="let possibleRole of possibleRoles" [value]="possibleRole.value">
|
||||||
|
{{possibleRole.viewValue}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="model.role === 'Participant'" class="form-group form-float">
|
||||||
|
<div class="form-line">
|
||||||
|
<select class="form-control"
|
||||||
|
[(ngModel)]="model.participantClass"
|
||||||
|
name="ParticipantClass"
|
||||||
|
required>
|
||||||
|
<option *ngFor="let possibleClass of possibleClasses" [value]="possibleClass.value">
|
||||||
|
{{possibleClass.viewValue}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</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,82 @@
|
|||||||
|
import { Component, Injector, ElementRef, OnInit, 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 OnInit, AfterViewInit {
|
||||||
|
|
||||||
|
@ViewChild('cardBody') cardBody: ElementRef;
|
||||||
|
|
||||||
|
model: RegisterInput = new RegisterInput();
|
||||||
|
|
||||||
|
saving: boolean = false;
|
||||||
|
|
||||||
|
public possibleClasses = [
|
||||||
|
{value: 1, viewValue: 'Klasa 1'},
|
||||||
|
{value: 2, viewValue: 'Klasa 2'},
|
||||||
|
{value: 3, viewValue: 'Klasa 3'},
|
||||||
|
{value: 4, viewValue: 'Klasa 4'},
|
||||||
|
{value: 5, viewValue: 'Klasa 5'},
|
||||||
|
{value: 6, viewValue: 'Klasa 6'},
|
||||||
|
{value: 7, viewValue: 'Klasa 7'},
|
||||||
|
{value: 8, viewValue: 'Klasa 8'}
|
||||||
|
];
|
||||||
|
|
||||||
|
public possibleRoles = [
|
||||||
|
{value: 'Participant', viewValue: 'Uczestnik'},
|
||||||
|
{value: 'Organizer', viewValue: 'Organizator'}
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
injector: Injector,
|
||||||
|
private _accountService: AccountServiceProxy,
|
||||||
|
private _router: Router,
|
||||||
|
private readonly _loginService: LoginService
|
||||||
|
) {
|
||||||
|
super(injector);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
$(this.cardBody.nativeElement).find('input:first').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.model.role = 'Participant';
|
||||||
|
this.model.participantClass = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
back(): void {
|
||||||
|
this._router.navigate(['/login']);
|
||||||
|
}
|
||||||
|
|
||||||
|
save(): void {
|
||||||
|
if (this.model.role === 'Organizer') {
|
||||||
|
this.model.participantClass = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.model.participantClass = +this.model.participantClass;
|
||||||
|
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,30 @@
|
|||||||
|
<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>
|
||||||
|
O projekcie
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
|
<h3>NASZ ZESPÓŁ</h3>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Izabela Kosmala
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Weronika Bola
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Przemysław Stawujak
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Marek Wendlandt
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</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);
|
||||||
|
}
|
||||||
|
}
|
39
SystemKonkursow/4.2.1/angular/src/app/app-routing.module.ts
Normal file
39
SystemKonkursow/4.2.1/angular/src/app/app-routing.module.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
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 { ProfileComponent } from './profile/profile.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';
|
||||||
|
import { CategoriesListComponent } from '@app/categories-list/categories-list.component';
|
||||||
|
import { CompetitionsListComponent } from '@app/competitions-list/competitions-list.component';
|
||||||
|
import { CompetitionDetailComponent } from '@app/competition-detail/competition-detail.component';
|
||||||
|
import { CompetitionCreateComponent } from '@app/competition-create/competition-create.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild([
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: AppComponent,
|
||||||
|
children: [
|
||||||
|
{ path: 'home', component: HomeComponent, canActivate: [AppRouteGuard] },
|
||||||
|
{ path: 'profile', component: ProfileComponent, 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 },
|
||||||
|
{ path: 'categories-list', component: CategoriesListComponent, canActivate: [AppRouteGuard] },
|
||||||
|
{ path: 'categories-list/:categoryId', component: CompetitionsListComponent, canActivate: [AppRouteGuard] },
|
||||||
|
{ path: 'categories-list/:categoryId/competitions/:competitionId', component: CompetitionDetailComponent, canActivate: [AppRouteGuard] },
|
||||||
|
{ path: 'competition-create', component: CompetitionCreateComponent, data: { permission: 'Pages.Create.Competition' }, canActivate: [AppRouteGuard] },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
],
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
106
SystemKonkursow/4.2.1/angular/src/app/app.module.ts
Normal file
106
SystemKonkursow/4.2.1/angular/src/app/app.module.ts
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
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 { ProfileComponent } from '@app/profile/profile.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';
|
||||||
|
import { CategoriesListComponent } from '@app/categories-list/categories-list.component';
|
||||||
|
import { CompetitionsListComponent } from '@app/competitions-list/competitions-list.component';
|
||||||
|
import { CompetitionDetailComponent } from '@app/competition-detail/competition-detail.component';
|
||||||
|
import { CompetitionCreateComponent } from '@app/competition-create/competition-create.component';
|
||||||
|
import { CreateQuestionComponent } from '@app/create-question/create-question.component';
|
||||||
|
|
||||||
|
import { FilterClassesPipe } from '@app/pipe/filter-classes.pipe';
|
||||||
|
|
||||||
|
import {
|
||||||
|
MatSelectModule,
|
||||||
|
MatOptionModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatDatepickerModule,
|
||||||
|
MatNativeDateModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatIconModule
|
||||||
|
} from '@angular/material';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent,
|
||||||
|
HomeComponent,
|
||||||
|
ProfileComponent,
|
||||||
|
AboutComponent,
|
||||||
|
TenantsComponent,
|
||||||
|
CreateTenantComponent,
|
||||||
|
EditTenantComponent,
|
||||||
|
UsersComponent,
|
||||||
|
CreateUserComponent,
|
||||||
|
EditUserComponent,
|
||||||
|
RolesComponent,
|
||||||
|
CreateRoleComponent,
|
||||||
|
EditRoleComponent,
|
||||||
|
TopBarComponent,
|
||||||
|
TopBarLanguageSwitchComponent,
|
||||||
|
SideBarUserAreaComponent,
|
||||||
|
SideBarNavComponent,
|
||||||
|
SideBarFooterComponent,
|
||||||
|
RightSideBarComponent,
|
||||||
|
CategoriesListComponent,
|
||||||
|
CompetitionsListComponent,
|
||||||
|
CompetitionDetailComponent,
|
||||||
|
CompetitionCreateComponent,
|
||||||
|
CreateQuestionComponent,
|
||||||
|
FilterClassesPipe
|
||||||
|
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
FormsModule,
|
||||||
|
HttpClientModule,
|
||||||
|
JsonpModule,
|
||||||
|
ModalModule.forRoot(),
|
||||||
|
AbpModule,
|
||||||
|
AppRoutingModule,
|
||||||
|
ServiceProxyModule,
|
||||||
|
SharedModule,
|
||||||
|
NgxPaginationModule,
|
||||||
|
MatSelectModule,
|
||||||
|
MatOptionModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatDatepickerModule,
|
||||||
|
MatNativeDateModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatIconModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
@ -0,0 +1,26 @@
|
|||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-item {
|
||||||
|
background-color: deepskyblue;
|
||||||
|
width: 200px;
|
||||||
|
margin: 10px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 90px;
|
||||||
|
font-size: 25px;
|
||||||
|
border-radius: 25px;
|
||||||
|
border: 1px solid white;
|
||||||
|
color: darkolivegreen;
|
||||||
|
text-shadow: 2px 2px 6px ghostwhite;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-item:hover {
|
||||||
|
box-shadow: 0px 0px 10px #2196F3;
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<div id="categories-list-area">
|
||||||
|
<div class="flex-container">
|
||||||
|
<div class="flex-item" *ngFor="let category of categoriesList" (click)="goToCompetitions(category)">
|
||||||
|
{{ category.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,54 @@
|
|||||||
|
import { Component, OnInit, Injector, OnDestroy } from '@angular/core';
|
||||||
|
import { appModuleAnimation } from '@shared/animations/routerTransition';
|
||||||
|
import { CategoryServiceProxy, CategoryDto } from '@shared/service-proxies/service-proxies';
|
||||||
|
import { List } from 'lodash';
|
||||||
|
import { AppComponentBase } from '@shared/app-component-base';
|
||||||
|
import { Subscription } from 'rxjs/Rx';
|
||||||
|
import { finalize } from 'rxjs/operators';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: './categories-list.component.html',
|
||||||
|
styleUrls: ['./categories-list.component.css'],
|
||||||
|
animations: [appModuleAnimation()]
|
||||||
|
})
|
||||||
|
export class CategoriesListComponent extends AppComponentBase implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
public categoriesList: List<CategoryDto> = [];
|
||||||
|
public categoriesListAreaId: string = 'categories-list-area';
|
||||||
|
|
||||||
|
private categoryListSubscription: Subscription;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
injector: Injector,
|
||||||
|
private _categoryService: CategoryServiceProxy,
|
||||||
|
private router: Router
|
||||||
|
) {
|
||||||
|
super(injector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnInit() {
|
||||||
|
this.getCompetitionCategories();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnDestroy() {
|
||||||
|
if (this.categoryListSubscription) {
|
||||||
|
this.categoryListSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCompetitionCategories(): void {
|
||||||
|
this.setBusy(this.categoriesListAreaId);
|
||||||
|
|
||||||
|
this.categoryListSubscription = this._categoryService.getAllCategories()
|
||||||
|
.pipe(finalize(() => { this.clearBusy(this.categoriesListAreaId); }))
|
||||||
|
.subscribe((result: List<CategoryDto>) => {
|
||||||
|
this.categoriesList = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public goToCompetitions(category: CategoryDto): void {
|
||||||
|
const route: string = `app/categories-list/${category.id}`;
|
||||||
|
this.router.navigate([route]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
#create-competition-area {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: cornflowerblue;
|
||||||
|
text-shadow: 1px 1px 1px #ab93ab;
|
||||||
|
}
|
||||||
|
|
||||||
|
.element-size {
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.field {
|
||||||
|
background-color: #DED4F4;
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-left: 10px #739CB9 solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-name {
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 400px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
@ -0,0 +1,195 @@
|
|||||||
|
<div id="create-competition-area">
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<h2 class="title">Tworzenie konkursu</h2>
|
||||||
|
|
||||||
|
<form (ngSubmit)="saveCompetition()"
|
||||||
|
#createCompetitionForm="ngForm">
|
||||||
|
<div class="field">
|
||||||
|
<div class="form-group">
|
||||||
|
<mat-form-field class="element-size">
|
||||||
|
<input matInput
|
||||||
|
name="name"
|
||||||
|
#name="ngModel"
|
||||||
|
[(ngModel)]="createCompetition.name"
|
||||||
|
type="text"
|
||||||
|
placeholder="Nazwa konkursu"
|
||||||
|
required
|
||||||
|
maxlength="100">
|
||||||
|
<mat-error *ngIf="name.invalid && name.errors.required">
|
||||||
|
Nazwa jest wymagana.
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="name.invalid && name.errors.maxlength">
|
||||||
|
Przekroczono maksymalną długość nazwy, 100 znaków.
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="form-group">
|
||||||
|
<mat-form-field class="element-size">
|
||||||
|
<mat-select placeholder="Kategorie"
|
||||||
|
[(ngModel)]="createCompetition.categoriesId"
|
||||||
|
name="categoriesId"
|
||||||
|
#categoriesId="ngModel"
|
||||||
|
multiple
|
||||||
|
required>
|
||||||
|
<mat-option *ngFor="let category of categoriesList" [value]="category.id">
|
||||||
|
{{category.name}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="categoriesId.invalid && categoriesId.errors.required">
|
||||||
|
Kategoria jest wymagana.
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="form-group">
|
||||||
|
<mat-form-field class="element-size">
|
||||||
|
<textarea matInput
|
||||||
|
matTextareaAutosize
|
||||||
|
matAutosizeMinRows="3"
|
||||||
|
matAutosizeMaxRows="6"
|
||||||
|
name="description"
|
||||||
|
#description="ngModel"
|
||||||
|
[(ngModel)]="createCompetition.description"
|
||||||
|
type="text"
|
||||||
|
placeholder="Opis"
|
||||||
|
required
|
||||||
|
maxlength="1000">
|
||||||
|
</textarea>
|
||||||
|
<mat-error *ngIf="description.invalid && description.errors.required">
|
||||||
|
Opis jest wymagany.
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="description.invalid && description.errors.maxlength">
|
||||||
|
Przekroczono maksymalną długość opisu, 1000 znaków.
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="form-group">
|
||||||
|
<mat-form-field class="element-size">
|
||||||
|
<textarea matInput
|
||||||
|
matTextareaAutosize
|
||||||
|
matAutosizeMinRows="3"
|
||||||
|
matAutosizeMaxRows="6"
|
||||||
|
name="prize"
|
||||||
|
#prize="ngModel"
|
||||||
|
[(ngModel)]="createCompetition.prize"
|
||||||
|
type="text"
|
||||||
|
placeholder="Nagrody"
|
||||||
|
required
|
||||||
|
maxlength="1000">
|
||||||
|
</textarea>
|
||||||
|
<mat-error *ngIf="prize.invalid && prize.errors.required">
|
||||||
|
Opis nagród jest wymagany.
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="prize.invalid && prize.errors.maxlength">
|
||||||
|
Przekroczono maksymalną długość opisu nagród, 1000 znaków.
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="form-group">
|
||||||
|
<mat-form-field class="element-size">
|
||||||
|
<mat-select placeholder="Minimalna klasa"
|
||||||
|
[(ngModel)]="createCompetition.minClass"
|
||||||
|
name="minClass"
|
||||||
|
#minClass="ngModel"
|
||||||
|
required>
|
||||||
|
<mat-option *ngFor="let possibleClass of possibleClasses" [value]="possibleClass.value">
|
||||||
|
{{possibleClass.viewValue}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="minClass.invalid && minClass.errors.required">
|
||||||
|
Minimalna klasa jest wymagana.
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="form-group">
|
||||||
|
<mat-form-field class="element-size">
|
||||||
|
<mat-select placeholder="Maksymalna klasa"
|
||||||
|
[(ngModel)]="createCompetition.maxClass"
|
||||||
|
name="maxClass"
|
||||||
|
#maxClass="ngModel"
|
||||||
|
required>
|
||||||
|
<mat-option *ngFor="let possibleClass of possibleClasses" [value]="possibleClass.value">
|
||||||
|
{{possibleClass.viewValue}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="maxClass.invalid && maxClass.errors.required">
|
||||||
|
Maksymalna klasa jest wymagana.
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="form-group">
|
||||||
|
<mat-form-field class="element-size">
|
||||||
|
<input matInput
|
||||||
|
[matDatepicker]="picker"
|
||||||
|
placeholder="Wybierz datę rozpoczęcia"
|
||||||
|
[(ngModel)]="createCompetition.startDate"
|
||||||
|
name="startDate"
|
||||||
|
#startDate="ngModel"
|
||||||
|
disabled
|
||||||
|
min="{{ today | date: 'yyyy-MM-dd'}}"
|
||||||
|
max="{{ createCompetition.endDate | date: 'yyyy-MM-dd'}}">
|
||||||
|
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #picker disabled="false"></mat-datepicker>
|
||||||
|
<mat-error *ngIf="startDate.invalid && startDate.errors">
|
||||||
|
Data rozpoczęcia konkursu jest nieprawidłowa.
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="form-group">
|
||||||
|
<mat-form-field class="element-size">
|
||||||
|
<input matInput
|
||||||
|
[matDatepicker]="picker2"
|
||||||
|
placeholder="Wybierz datę zakończenia"
|
||||||
|
[(ngModel)]="createCompetition.endDate"
|
||||||
|
name="endDate"
|
||||||
|
#endDate="ngModel"
|
||||||
|
disabled
|
||||||
|
min="{{ (createCompetition.startDate ? createCompetition.startDate : today) | date: 'yyyy-MM-dd'}}">
|
||||||
|
<mat-datepicker-toggle matSuffix [for]="picker2"></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #picker2 disabled="false"></mat-datepicker>
|
||||||
|
<mat-error *ngIf="endDate.invalid && endDate.errors">
|
||||||
|
Data zakończenia konkursu jest nieprawidłowa.
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-8 col-md-8">
|
||||||
|
<button type="button" data-toggle="modal" style="margin-bottom: 20px" class="btn btn-success" (click)="createQuestion()">Dodaj pytanie</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-8 col-md-8">
|
||||||
|
<div *ngFor="let question of questionsList">
|
||||||
|
<label class="question-name">{{question.name}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-8 col-md-8">
|
||||||
|
<button type="submit" style="margin-bottom: 20px" class="btn btn-success" [disabled]="!createCompetitionForm.form.valid">Utwórz</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<create-question-modal #createQuestionModal (modalSave)="addQuestion($event)"></create-question-modal>
|
@ -0,0 +1,126 @@
|
|||||||
|
import { Component, OnInit, Injector, OnDestroy, ViewChild } from '@angular/core';
|
||||||
|
import { appModuleAnimation } from '@shared/animations/routerTransition';
|
||||||
|
import { CategoryServiceProxy,
|
||||||
|
CategoryDto,
|
||||||
|
CompetitionServiceProxy,
|
||||||
|
CreateCompetitionDto,
|
||||||
|
CreateQuestionDto } from '@shared/service-proxies/service-proxies';
|
||||||
|
import { CreateQuestionComponent } from 'app/create-question/create-question.component';
|
||||||
|
import { List } from 'lodash';
|
||||||
|
import { AppComponentBase } from '@shared/app-component-base';
|
||||||
|
import { Subscription } from 'rxjs/Rx';
|
||||||
|
import { finalize } from 'rxjs/operators';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import * as moment from 'moment';
|
||||||
|
import swal from 'sweetalert';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: './competition-create.component.html',
|
||||||
|
styleUrls: ['./competition-create.component.css'],
|
||||||
|
animations: [appModuleAnimation()]
|
||||||
|
})
|
||||||
|
export class CompetitionCreateComponent extends AppComponentBase implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
@ViewChild('createQuestionModal') createQuestionModal: CreateQuestionComponent;
|
||||||
|
|
||||||
|
public categoriesList: List<CategoryDto> = [];
|
||||||
|
public createCompetitionAreaId: string = 'create-competition-area';
|
||||||
|
|
||||||
|
public createCompetition: CreateCompetitionDto = null;
|
||||||
|
|
||||||
|
public questionsList: CreateQuestionDto[] = null;
|
||||||
|
|
||||||
|
private categoryListSubscription: Subscription;
|
||||||
|
private createCompetitionSubscription: Subscription;
|
||||||
|
|
||||||
|
public today: Date = new Date();
|
||||||
|
|
||||||
|
public possibleClasses = [
|
||||||
|
{value: 1, viewValue: 'Klasa 1'},
|
||||||
|
{value: 2, viewValue: 'Klasa 2'},
|
||||||
|
{value: 3, viewValue: 'Klasa 3'},
|
||||||
|
{value: 4, viewValue: 'Klasa 4'},
|
||||||
|
{value: 5, viewValue: 'Klasa 5'},
|
||||||
|
{value: 6, viewValue: 'Klasa 6'},
|
||||||
|
{value: 7, viewValue: 'Klasa 7'},
|
||||||
|
{value: 8, viewValue: 'Klasa 8'}
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
injector: Injector,
|
||||||
|
private _categoryService: CategoryServiceProxy,
|
||||||
|
private _competitionService: CompetitionServiceProxy,
|
||||||
|
private router: Router
|
||||||
|
) {
|
||||||
|
super(injector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnInit() {
|
||||||
|
this.createCompetition = new CreateCompetitionDto();
|
||||||
|
this.questionsList = [];
|
||||||
|
this.getCompetitionCategories();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnDestroy() {
|
||||||
|
if (this.categoryListSubscription) {
|
||||||
|
this.categoryListSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.createCompetitionSubscription) {
|
||||||
|
this.createCompetitionSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCompetitionCategories(): void {
|
||||||
|
this.setBusy(this.createCompetitionAreaId);
|
||||||
|
|
||||||
|
this.categoryListSubscription = this._categoryService.getAllCategories()
|
||||||
|
.pipe(finalize(() => { this.clearBusy(this.createCompetitionAreaId); }))
|
||||||
|
.subscribe((result: List<CategoryDto>) => {
|
||||||
|
this.categoriesList = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public saveCompetition(): void {
|
||||||
|
|
||||||
|
if ((this.createCompetition.maxClass < this.createCompetition.minClass)
|
||||||
|
|| (!this.createCompetition.startDate)
|
||||||
|
|| (!this.createCompetition.endDate)
|
||||||
|
|| (this.questionsList.length === 0)) {
|
||||||
|
|
||||||
|
swal({
|
||||||
|
title: "Błąd - Dodanie konkursu!",
|
||||||
|
text: "Sprawdź, czy wybrałeś daty konkursu. Maksymalna klasa musi być większa niż minimalna klasa. Konkurs musi mieć chociaż jedno pytanie.",
|
||||||
|
icon: "error"
|
||||||
|
})
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
this.createCompetition.startDate = moment(this.createCompetition.startDate, 'YYYY-MM-DD');
|
||||||
|
this.createCompetition.endDate = moment(this.createCompetition.endDate, 'YYYY-MM-DD');
|
||||||
|
|
||||||
|
this.createCompetition.createQuestions = this.questionsList;
|
||||||
|
|
||||||
|
this.createCompetitionSubscription = this._competitionService.createCompetition(this.createCompetition)
|
||||||
|
.subscribe((result: number) => {
|
||||||
|
this.goToCategoriesList();
|
||||||
|
this.notify.success(this.l('Zapisano pomyślnie'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show Question Modal
|
||||||
|
public createQuestion(): void {
|
||||||
|
this.createQuestionModal.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public addQuestion(question): void {
|
||||||
|
this.questionsList.push(question);
|
||||||
|
}
|
||||||
|
|
||||||
|
public goToCategoriesList(): void {
|
||||||
|
const route: string = `app/categories-list`;
|
||||||
|
this.router.navigate([route]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
h2 {
|
||||||
|
color: #771111;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border-top-color: #03a9f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
width: 100%;
|
||||||
|
color: #2783b0;
|
||||||
|
white-space: normal;
|
||||||
|
word-wrap: break-word;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-color {
|
||||||
|
color: #771111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #359088;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option {
|
||||||
|
background-color: #cadaee;
|
||||||
|
font-size: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-size {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
border-radius: 0;
|
||||||
|
margin: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-question {
|
||||||
|
background-color: #eee;
|
||||||
|
margin: 4px;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
<div id="competition-detail-area">
|
||||||
|
<div>
|
||||||
|
<h2 class="text-center font-weight-normal">{{competition.name}}</h2>
|
||||||
|
<div class="description">
|
||||||
|
<div class="section-color">Opis:</div> {{competition.description}}
|
||||||
|
</div>
|
||||||
|
<div class="description">
|
||||||
|
<div class="section-color">Nagrody:</div> {{competition.prize}}
|
||||||
|
</div>
|
||||||
|
<div *ngIf="mode!=='quiz'" class="card">
|
||||||
|
<div class="header">
|
||||||
|
<h2>Ranking konkursu</h2>
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover dashboard-task-infos">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Użytkownik</th>
|
||||||
|
<th>Punkty</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr *ngFor="let position of ranking">
|
||||||
|
<td>{{position.participantName}}</td>
|
||||||
|
<td>{{position.points}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button *ngIf="mode!=='quiz' && canSolveCompetition" type="button" style="margin-top: 20px" [disabled]="mode==='quiz' || !canSolveCompetition" class="btn btn-success" (click)="solveCompetition()">
|
||||||
|
{{l("Start")}}
|
||||||
|
</button>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div *ngIf="mode==='quiz'">
|
||||||
|
<div *ngFor="let question of filteredQuestions">
|
||||||
|
<div class="badge">Pytanie {{pager.index + 1}}/{{pager.count}}</div>
|
||||||
|
<h3 class="font-weight-normal">{{pager.index + 1}}.
|
||||||
|
<span [innerHTML]="question.name"></span>
|
||||||
|
</h3>
|
||||||
|
<div class="row">
|
||||||
|
<div *ngFor="let option of question.questionOptions">
|
||||||
|
<div class="option">
|
||||||
|
<input type="checkbox" [(ngModel)]="option.selected" id="{{option.id}}" (change)="onSelect(question, option)" class="filled-in chk-col-blue">
|
||||||
|
<label class="option-size" for="{{option.id}}">{{option.name}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<button *ngIf="pager.index!==0" class="btn btn-default" (click)="goTo(0);">Pierwsza</button>
|
||||||
|
<button *ngIf="pager.index!==0" class="btn btn-default" (click)="goTo(pager.index - 1);">Poprzednia</button>
|
||||||
|
<button *ngIf="pager.index!==pager.count-1" class="btn btn-primary" (click)="goTo(pager.index + 1);">Następna</button>
|
||||||
|
<button *ngIf="pager.index!==pager.count-1" class="btn btn-default" (click)="goTo(pager.count - 1);">Ostatnia</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button class="btn btn-primary" (click)="onSubmit()">Zatwierdź rozwiązanie</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="mode==='result'">
|
||||||
|
<h2>Twoje odpowiedzi</h2>
|
||||||
|
<div *ngFor="let question of competition.questions; let index = index">
|
||||||
|
<div class="result-question">
|
||||||
|
<h5>{{index + 1}}. {{question.name}}</h5>
|
||||||
|
<div>
|
||||||
|
<div [ngClass]="{'alert alert-success': option.isAnswer}" *ngFor="let option of question.questionOptions">
|
||||||
|
<input type="checkbox" [(ngModel)]="option.selected" id="{{option.id}}" disabled="true">
|
||||||
|
<label class="option-size" for="{{option.id}}">{{option.name}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-1 m-2 alert {{ isCorrect(question) === 'poprawna' ? 'alert-success' : 'alert-danger'}}">Twoja odpowiedź jest {{isCorrect(question)}}.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,164 @@
|
|||||||
|
import { Component, OnInit, Injector, OnDestroy } from '@angular/core';
|
||||||
|
import { appModuleAnimation } from '@shared/animations/routerTransition';
|
||||||
|
import { AppComponentBase } from '@shared/app-component-base';
|
||||||
|
import { Subscription } from 'rxjs/Rx';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { mergeMap } from 'rxjs/operators';
|
||||||
|
import { finalize } from 'rxjs/operators';
|
||||||
|
import { forkJoin } from 'rxjs';
|
||||||
|
import { List } from 'lodash';
|
||||||
|
import { CompetitionServiceProxy,
|
||||||
|
CompetitionDto,
|
||||||
|
QuestionDto,
|
||||||
|
QuestionOptionDto,
|
||||||
|
CreateRankingPositionDto,
|
||||||
|
RankingPositionDto } from '@shared/service-proxies/service-proxies';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: './competition-detail.component.html',
|
||||||
|
styleUrls: ['./competition-detail.component.css'],
|
||||||
|
animations: [appModuleAnimation()]
|
||||||
|
})
|
||||||
|
export class CompetitionDetailComponent extends AppComponentBase implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
private paramSubscription: Subscription;
|
||||||
|
private routeSubscription: Subscription;
|
||||||
|
private solveSubscription: Subscription;
|
||||||
|
|
||||||
|
public competitionId: number;
|
||||||
|
public competition: CompetitionDto = null;
|
||||||
|
public ranking: List<RankingPositionDto> = [];
|
||||||
|
public competitionDetailAreaId: string = 'competition-detail-area';
|
||||||
|
|
||||||
|
public canSolveCompetition: boolean = false;
|
||||||
|
|
||||||
|
public mode = 'detail';
|
||||||
|
|
||||||
|
public pager = {
|
||||||
|
index: 0,
|
||||||
|
size: 1,
|
||||||
|
count: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
injector: Injector,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private _competitionService: CompetitionServiceProxy,
|
||||||
|
) {
|
||||||
|
super(injector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnInit() {
|
||||||
|
this.competition = new CompetitionDto();
|
||||||
|
|
||||||
|
this.routeSubscription = this.route.params
|
||||||
|
.subscribe(params => {
|
||||||
|
this.competitionId = +params['competitionId'];
|
||||||
|
this.getCompetition();
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCompetition(): void {
|
||||||
|
this.setBusy(this.competitionDetailAreaId);
|
||||||
|
|
||||||
|
this.paramSubscription = forkJoin([this._competitionService.getCompetition(this.competitionId),
|
||||||
|
this._competitionService.canSolveCompetition(this.competitionId),
|
||||||
|
this._competitionService.getRanking(this.competitionId)])
|
||||||
|
.pipe(finalize(() => { this.clearBusy(this.competitionDetailAreaId); }))
|
||||||
|
.subscribe((data: [CompetitionDto, boolean, List<RankingPositionDto>]) => {
|
||||||
|
this.competition = data[0];
|
||||||
|
this.shuffleOptions(this.competition.questions);
|
||||||
|
this.competition.questions.forEach((x) => this.shuffleOptions(x.questionOptions));
|
||||||
|
this.pager.count = this.competition.questions.length;
|
||||||
|
|
||||||
|
this.canSolveCompetition = data[1];
|
||||||
|
|
||||||
|
this.ranking = data[2];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private shuffleOptions(array) {
|
||||||
|
let currentIndex = array.length, temp, randomIndex;
|
||||||
|
|
||||||
|
while (0 !== currentIndex) {
|
||||||
|
randomIndex = Math.floor(Math.random() * currentIndex);
|
||||||
|
currentIndex -= 1;
|
||||||
|
|
||||||
|
temp = array[currentIndex];
|
||||||
|
array[currentIndex] = array[randomIndex];
|
||||||
|
array[randomIndex] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public solveCompetition(): void {
|
||||||
|
this.mode = 'quiz';
|
||||||
|
}
|
||||||
|
|
||||||
|
get filteredQuestions() {
|
||||||
|
return (this.competition.questions) ?
|
||||||
|
this.competition.questions.slice(this.pager.index, this.pager.index + this.pager.size) : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public onSelect(question: QuestionDto, option: QuestionOptionDto) {
|
||||||
|
question.questionOptions.forEach((x) => { if (x.id !== option.id) x.selected = false; });
|
||||||
|
}
|
||||||
|
|
||||||
|
public goTo(index: number) {
|
||||||
|
if (index >= 0 && index < this.pager.count) {
|
||||||
|
this.pager.index = index;
|
||||||
|
this.mode = 'quiz';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public isCorrect(question: QuestionDto) {
|
||||||
|
return question.questionOptions.every(x => x.selected === x.isAnswer) ? 'poprawna' : 'niepoprawna';
|
||||||
|
}
|
||||||
|
|
||||||
|
public onSubmit() {
|
||||||
|
let points: number = 0;
|
||||||
|
this.competition.questions.forEach(
|
||||||
|
(x) => {
|
||||||
|
if (x.questionOptions.every(
|
||||||
|
(y) => y.selected === y.isAnswer)
|
||||||
|
) points += 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
let rankingPosition = new CreateRankingPositionDto();
|
||||||
|
|
||||||
|
rankingPosition.competitionId = this.competitionId;
|
||||||
|
rankingPosition.points = points;
|
||||||
|
|
||||||
|
this.setBusy(this.competitionDetailAreaId);
|
||||||
|
|
||||||
|
this.solveSubscription = this._competitionService.solveCompetition(rankingPosition)
|
||||||
|
.pipe(mergeMap((result: number) => {
|
||||||
|
const solveCompetitionStream = this._competitionService.canSolveCompetition(this.competitionId);
|
||||||
|
const rankingStream = this._competitionService.getRanking(this.competitionId);
|
||||||
|
return forkJoin([solveCompetitionStream, rankingStream]).pipe(finalize(() => { this.clearBusy(this.competitionDetailAreaId); }));
|
||||||
|
}))
|
||||||
|
.subscribe((data: [boolean, List<RankingPositionDto>]) => {
|
||||||
|
this.canSolveCompetition = data[0];
|
||||||
|
this.ranking = data[1];
|
||||||
|
});
|
||||||
|
|
||||||
|
this.mode = 'result';
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnDestroy() {
|
||||||
|
if (this.paramSubscription) {
|
||||||
|
this.paramSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.routeSubscription) {
|
||||||
|
this.routeSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.solveSubscription) {
|
||||||
|
this.solveSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-item {
|
||||||
|
background-color: #DED4F4;
|
||||||
|
width: 450px;
|
||||||
|
margin: 10px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-left: 10px #739CB9 solid;
|
||||||
|
color: darkblue;
|
||||||
|
text-shadow: 0px 0px 1px #ab93ab;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-item:hover {
|
||||||
|
box-shadow: 0px 0px 10px #2196F3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.organizer {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #f44336;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-flex {
|
||||||
|
color: white;
|
||||||
|
background-color: #2196F3;
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<div id="competitions-list-area">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 col-md-offset-3 col-sm-3 col-sm-offset-3">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-select placeholder="Filtr - minimalna klasa" [(ngModel)]="minClassValue">
|
||||||
|
<mat-option *ngFor="let possibleClass of possibleClasses" [value]="possibleClass.value">
|
||||||
|
{{possibleClass.viewValue}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3 col-sm-3">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-select placeholder="Filtr - maksymalna klasa" [(ngModel)]="maxClassValue">
|
||||||
|
<mat-option *ngFor="let possibleClass of possibleClasses" [value]="possibleClass.value">
|
||||||
|
{{possibleClass.viewValue}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-container">
|
||||||
|
<div class="flex-item" (click)="goToDetail(competition)" *ngFor="let competition of (competitionsList | filterClasses : [minClassValue, maxClassValue])">
|
||||||
|
<p><u>{{ competition.name }}</u></p>
|
||||||
|
<div class="organizer">Organizowany przez: {{ competition.creatorName }}</div>
|
||||||
|
|
||||||
|
<div class="bottom-flex">
|
||||||
|
<p>Czas trwania: {{ competition.startDate | date:"dd/MM/yyyy" }} - {{ competition.endDate | date:"dd/MM/yyyy" }}</p>
|
||||||
|
<p>Przedział klasowy: {{ competition.minClass }}-{{ competition.maxClass }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="(competitionsList | filterClasses : [minClassValue, maxClassValue])?.length === 0">
|
||||||
|
Brak konkursów
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,78 @@
|
|||||||
|
import { Component, OnInit, Injector, OnDestroy } from '@angular/core';
|
||||||
|
import { appModuleAnimation } from '@shared/animations/routerTransition';
|
||||||
|
import { CompetitionCategoryServiceProxy, CompetitionDto } from '@shared/service-proxies/service-proxies';
|
||||||
|
import { List } from 'lodash';
|
||||||
|
import { AppComponentBase } from '@shared/app-component-base';
|
||||||
|
import { Subscription } from 'rxjs/Rx';
|
||||||
|
import { finalize } from 'rxjs/operators';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { mergeMap } from 'rxjs/operators';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: './competitions-list.component.html',
|
||||||
|
styleUrls: ['./competitions-list.component.css'],
|
||||||
|
animations: [appModuleAnimation()]
|
||||||
|
})
|
||||||
|
export class CompetitionsListComponent extends AppComponentBase implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
public competitionsList: List<CompetitionDto> = [];
|
||||||
|
public competitionsListAreaId: string = 'competitions-list-area';
|
||||||
|
|
||||||
|
private paramSubscription: Subscription;
|
||||||
|
|
||||||
|
public categoryId: number;
|
||||||
|
|
||||||
|
public minClassValue: number = 1;
|
||||||
|
public maxClassValue: number = 8;
|
||||||
|
|
||||||
|
public possibleClasses = [
|
||||||
|
{value: 1, viewValue: 'Klasa 1'},
|
||||||
|
{value: 2, viewValue: 'Klasa 2'},
|
||||||
|
{value: 3, viewValue: 'Klasa 3'},
|
||||||
|
{value: 4, viewValue: 'Klasa 4'},
|
||||||
|
{value: 5, viewValue: 'Klasa 5'},
|
||||||
|
{value: 6, viewValue: 'Klasa 6'},
|
||||||
|
{value: 7, viewValue: 'Klasa 7'},
|
||||||
|
{value: 8, viewValue: 'Klasa 8'}
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
injector: Injector,
|
||||||
|
private _competitionCategoryService: CompetitionCategoryServiceProxy,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private router: Router
|
||||||
|
) {
|
||||||
|
super(injector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnInit() {
|
||||||
|
this.getCompetitions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnDestroy() {
|
||||||
|
if (this.paramSubscription) {
|
||||||
|
this.paramSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCompetitions(): void {
|
||||||
|
this.paramSubscription = this.route.params
|
||||||
|
.pipe(mergeMap(params => {
|
||||||
|
this.categoryId = +params['categoryId'];
|
||||||
|
this.setBusy(this.competitionsListAreaId);
|
||||||
|
const competitionListStream = this._competitionCategoryService
|
||||||
|
.getAllCompetitionsForCategory(this.categoryId)
|
||||||
|
.pipe(finalize(() => { this.clearBusy(this.competitionsListAreaId); }))
|
||||||
|
return competitionListStream
|
||||||
|
})).subscribe((result: List<CompetitionDto>) => {
|
||||||
|
this.competitionsList = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public goToDetail(competition: CompetitionDto): void {
|
||||||
|
const route: string = this.router.url + `/competitions/${competition.id}`;
|
||||||
|
this.router.navigate([route]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
<div bsModal #createQuestionModal="bs-modal" class="modal fade" (onShown)="onShown()" tabindex="-1" role="dialog" aria-labelledby="createQuestionModal" aria-hidden="true" [config]="{backdrop: 'static'}">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
|
||||||
|
<div #modalContent class="modal-content">
|
||||||
|
|
||||||
|
<form *ngIf="active" #createQuestionForm="ngForm" id="frm_create_question" 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("Nowe pytanie")}}</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="questionname" type="text" name="QuestionName" [(ngModel)]="question.name" required class="validate form-control">
|
||||||
|
<label for="questionname" class="form-label">{{l("Nazwa pytania")}}</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="correctOption" type="text" name="CorrectOption" [(ngModel)]="question.correctOption" required class="validate form-control">
|
||||||
|
<label for="correctOption" class="form-label">{{l("Poprawna odpowiedź")}}</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="firstIncorrectOption" type="text" name="FirstIncorrectOption" [(ngModel)]="question.firstIncorrectOption" required class="validate form-control">
|
||||||
|
<label for="firstIncorrectOption" class="form-label">{{l("Błędna odpowiedź")}}</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="secondIncorrectOption" type="text" name="SecondIncorrectOption" [(ngModel)]="question.secondIncorrectOption" required class="validate form-control">
|
||||||
|
<label for="secondIncorrectOption" class="form-label">{{l("Błędna odpowiedź")}}</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="thirdIncorrectOption" type="text" name="ThirdIncorrectOption" [(ngModel)]="question.thirdIncorrectOption" required class="validate form-control">
|
||||||
|
<label for="thirdIncorrectOption" class="form-label">{{l("Błędna odpowiedź")}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button [disabled]="saving" type="button" class="btn btn-default waves-effect" (click)="close()">
|
||||||
|
{{l("Anuluj")}}
|
||||||
|
</button>
|
||||||
|
<button [disabled]="!createQuestionForm.form.valid || saving" type="submit" class="btn btn-primary waves-effect">
|
||||||
|
{{l("Zapisz")}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,50 @@
|
|||||||
|
import { Component, ViewChild, Injector, Output, EventEmitter, ElementRef, OnInit } from '@angular/core';
|
||||||
|
import { ModalDirective } from 'ngx-bootstrap';
|
||||||
|
import { CreateQuestionDto } from '@shared/service-proxies/service-proxies';
|
||||||
|
import { AppComponentBase } from '@shared/app-component-base';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'create-question-modal',
|
||||||
|
templateUrl: './create-question.component.html'
|
||||||
|
})
|
||||||
|
export class CreateQuestionComponent extends AppComponentBase implements OnInit {
|
||||||
|
|
||||||
|
@ViewChild('createQuestionModal') modal: ModalDirective;
|
||||||
|
@ViewChild('modalContent') modalContent: ElementRef;
|
||||||
|
|
||||||
|
@Output() modalSave: EventEmitter<CreateQuestionDto> = new EventEmitter<CreateQuestionDto>();
|
||||||
|
|
||||||
|
active: boolean = false;
|
||||||
|
saving: boolean = false;
|
||||||
|
question: CreateQuestionDto = null;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
injector: Injector,
|
||||||
|
) {
|
||||||
|
super(injector);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
show(): void {
|
||||||
|
this.active = true;
|
||||||
|
this.modal.show();
|
||||||
|
this.question = new CreateQuestionDto();
|
||||||
|
}
|
||||||
|
|
||||||
|
onShown(): void {
|
||||||
|
$.AdminBSB.input.activate($(this.modalContent.nativeElement));
|
||||||
|
}
|
||||||
|
|
||||||
|
public save(): void {
|
||||||
|
this.notify.info(this.l('Pytanie dodano pomyślnie'));
|
||||||
|
this.close();
|
||||||
|
this.modalSave.emit(this.question);
|
||||||
|
}
|
||||||
|
|
||||||
|
public close(): void {
|
||||||
|
this.active = false;
|
||||||
|
this.modal.hide();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
h2 {
|
||||||
|
color: #771111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-item {
|
||||||
|
background-color: #DED4F4;
|
||||||
|
width: 450px;
|
||||||
|
margin: 10px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-left: 10px #739CB9 solid;
|
||||||
|
color: darkblue;
|
||||||
|
text-shadow: 0px 0px 1px #ab93ab;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-item:hover {
|
||||||
|
box-shadow: 0px 0px 10px #2196F3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.organizer {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #f44336;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-flex {
|
||||||
|
color: white;
|
||||||
|
background-color: #2196F3;
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
<div [@routerTransition] id="home-area">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2 class="text-center font-weight-normal">MOJE KONKURSY</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-container">
|
||||||
|
<div class="flex-item" (click)="goToDetail(competition)" *ngFor="let competition of myCompetitionsList">
|
||||||
|
<p><u>{{ competition.name }}</u></p>
|
||||||
|
<div class="organizer">Organizowany przez: {{ competition.creatorName }}</div>
|
||||||
|
|
||||||
|
<div class="bottom-flex">
|
||||||
|
<p>Czas trwania: {{ competition.startDate | date:"dd/MM/yyyy" }} - {{ competition.endDate | date:"dd/MM/yyyy" }}</p>
|
||||||
|
<p>Przedział klasowy: {{ competition.minClass }}-{{ competition.maxClass }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="myCompetitionsList?.length === 0">
|
||||||
|
Brak konkursów
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
55
SystemKonkursow/4.2.1/angular/src/app/home/home.component.ts
Normal file
55
SystemKonkursow/4.2.1/angular/src/app/home/home.component.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { Component, Injector, OnInit, OnDestroy } from '@angular/core';
|
||||||
|
import { AppComponentBase } from '@shared/app-component-base';
|
||||||
|
import { appModuleAnimation } from '@shared/animations/routerTransition';
|
||||||
|
import { CompetitionServiceProxy, CompetitionDto } from '@shared/service-proxies/service-proxies';
|
||||||
|
import { List } from 'lodash';
|
||||||
|
import { Subscription } from 'rxjs/Rx';
|
||||||
|
import { finalize } from 'rxjs/operators';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: './home.component.html',
|
||||||
|
styleUrls: ['./home.component.css'],
|
||||||
|
animations: [appModuleAnimation()]
|
||||||
|
})
|
||||||
|
export class HomeComponent extends AppComponentBase implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
public myCompetitionsList: List<CompetitionDto> = [];
|
||||||
|
public homeAreaId: string = 'home-area';
|
||||||
|
|
||||||
|
private myCompetitionsListSubscription: Subscription;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
injector: Injector,
|
||||||
|
private _competitionService: CompetitionServiceProxy,
|
||||||
|
private router: Router
|
||||||
|
) {
|
||||||
|
super(injector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnInit(): void {
|
||||||
|
this.getCompetitionsForUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnDestroy(): void {
|
||||||
|
if (this.myCompetitionsListSubscription) {
|
||||||
|
this.myCompetitionsListSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCompetitionsForUser(): void {
|
||||||
|
this.setBusy(this.homeAreaId);
|
||||||
|
|
||||||
|
this.myCompetitionsListSubscription = this._competitionService.getAllCompetitionsForUser()
|
||||||
|
.pipe(finalize(() => { this.clearBusy(this.homeAreaId); }))
|
||||||
|
.subscribe((result: List<CompetitionDto>) => {
|
||||||
|
this.myCompetitionsList = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public goToDetail(competition: CompetitionDto): void {
|
||||||
|
const route: string = `app/categories-list/${competition.categoryId}/competitions/${competition.id}`;
|
||||||
|
this.router.navigate([route]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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">KOLOR</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("Czerwony", "red"),
|
||||||
|
new UiThemeInfo("Różowy", "pink"),
|
||||||
|
new UiThemeInfo("Fioletowy", "purple"),
|
||||||
|
new UiThemeInfo("Ciemnofioletowy", "deep-purple"),
|
||||||
|
new UiThemeInfo("Indygo", "indigo"),
|
||||||
|
new UiThemeInfo("Niebieski", "blue"),
|
||||||
|
new UiThemeInfo("Jasnoniebieski", "light-blue"),
|
||||||
|
new UiThemeInfo("Cyjan", "cyan"),
|
||||||
|
new UiThemeInfo("Turkusowy", "teal"),
|
||||||
|
new UiThemeInfo("Zielony", "green"),
|
||||||
|
new UiThemeInfo("Jasnozielony", "light-green"),
|
||||||
|
new UiThemeInfo("Limonkowy", "lime"),
|
||||||
|
new UiThemeInfo("Żółty", "yellow"),
|
||||||
|
new UiThemeInfo("Bursztynowy", "amber"),
|
||||||
|
new UiThemeInfo("Pomarańczowy", "orange"),
|
||||||
|
new UiThemeInfo("Ciemnopomarańczowy", "deep-orange"),
|
||||||
|
new UiThemeInfo("Brązowy", "brown"),
|
||||||
|
new UiThemeInfo("Szary", "grey"),
|
||||||
|
new UiThemeInfo("Ciemnoszary", "blue-grey"),
|
||||||
|
new UiThemeInfo("Czarny", "black")
|
||||||
|
];
|
||||||
|
|
||||||
|
selectedThemeCssClass: string = "blue";
|
||||||
|
|
||||||
|
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);">EduKwiz</a>.
|
||||||
|
</div>
|
||||||
|
<div class="version">
|
||||||
|
<b>Wersja </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,39 @@
|
|||||||
|
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("Strona domowa"), "", "home", "/app/home"),
|
||||||
|
new MenuItem(this.l("Edycja profilu"), "", "person", "/app/profile"),
|
||||||
|
|
||||||
|
new MenuItem(this.l("Konkursy"), "", "list", "/app/categories-list"),
|
||||||
|
new MenuItem(this.l("Dodaj konkurs"), "Pages.Create.Competition", "add", "/app/competition-create"),
|
||||||
|
|
||||||
|
new MenuItem(this.l("Tenants"), "Pages.Tenants", "business", "/app/tenants"),
|
||||||
|
new MenuItem(this.l("Użytkownicy"), "Pages.Users", "people", "/app/users"),
|
||||||
|
new MenuItem(this.l("Role"), "Pages.Roles", "local_offer", "/app/roles"),
|
||||||
|
new MenuItem(this.l("O projekcie"), "", "info", "/app/about"),
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
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,28 @@
|
|||||||
|
<!-- Search Bar -->
|
||||||
|
<div class="search-bar">
|
||||||
|
<div class="search-icon">
|
||||||
|
<i class="material-icons">search</i>
|
||||||
|
</div>
|
||||||
|
<input materialInput type="text" placeholder="ZACZNIJ PISAĆ...">
|
||||||
|
<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"><p style="margin-top: -10px;"><img src="{{logoUrl}}" style="height:50px; width: 50px;"> EduKwiz</p></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><a href="javascript:void(0);" class="js-right-sidebar" data-close="true"><i class="material-icons">more_vert</i></a></li>
|
||||||
|
<li><a (click)="logout()"><i class="material-icons">input</i></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
@ -0,0 +1,24 @@
|
|||||||
|
import { Component, Injector, ViewEncapsulation } from '@angular/core';
|
||||||
|
import { AppComponentBase } from '@shared/app-component-base';
|
||||||
|
import { AppAuthService } from '@shared/auth/app-auth.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: './topbar.component.html',
|
||||||
|
selector: 'top-bar',
|
||||||
|
encapsulation: ViewEncapsulation.None
|
||||||
|
})
|
||||||
|
export class TopBarComponent extends AppComponentBase {
|
||||||
|
|
||||||
|
public logoUrl: string = '/assets/images/logo.png';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
injector: Injector,
|
||||||
|
private _authService: AppAuthService
|
||||||
|
) {
|
||||||
|
super(injector);
|
||||||
|
}
|
||||||
|
|
||||||
|
logout(): void {
|
||||||
|
this._authService.logout();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
|
||||||
|
import { CompetitionDto } from '@shared/service-proxies/service-proxies';
|
||||||
|
|
||||||
|
@Pipe({ name: 'filterClasses' })
|
||||||
|
export class FilterClassesPipe implements PipeTransform {
|
||||||
|
|
||||||
|
transform(allCompetitions: CompetitionDto[], args?: any) {
|
||||||
|
let minClass = args[0];
|
||||||
|
let maxClass = args[1];
|
||||||
|
return allCompetitions
|
||||||
|
.filter(competition => competition.minClass >= minClass && competition.maxClass <= maxClass);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
h2 {
|
||||||
|
color: #771111;
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
<div id="profile-area">
|
||||||
|
<div class="card">
|
||||||
|
<div #cardBody class="body">
|
||||||
|
<div>
|
||||||
|
<h2 class="text-center font-weight-normal">MÓJ PROFIL</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form #profileForm="ngForm" method="post" novalidate (ngSubmit)="saveProfile()">
|
||||||
|
|
||||||
|
<div class="form-group form-float">
|
||||||
|
<div class="form-line focused">
|
||||||
|
<input materialInput class="form-control" type="text" [(ngModel)]="profile.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 focused">
|
||||||
|
<input materialInput class="form-control" type="text" [(ngModel)]="profile.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 focused">
|
||||||
|
<input materialInput class="form-control" type="email" [(ngModel)]="profile.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 focused">
|
||||||
|
<input materialInput class="form-control" type="text" autocomplete="off" [(ngModel)]="profile.userName" name="UserName" required maxlength="32" />
|
||||||
|
<label class="form-label">{{l('Login')}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="profile.participantClass !== 0" class="form-group form-float">
|
||||||
|
<div class="form-line">
|
||||||
|
<select class="form-control"
|
||||||
|
[(ngModel)]="profile.participantClass"
|
||||||
|
name="ParticipantClass"
|
||||||
|
required>
|
||||||
|
<option *ngFor="let possibleClass of possibleClasses" [value]="possibleClass.value">
|
||||||
|
{{possibleClass.viewValue}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-actions">
|
||||||
|
<button type="submit" class="btn btn-success" [disabled]="!profileForm.form.valid">{{l("Zapisz profil")}}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,71 @@
|
|||||||
|
import { Component, Injector, ElementRef, OnInit, OnDestroy, AfterViewInit, ViewChild } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { UserProfileServiceProxy, UserProfileDto } from '@shared/service-proxies/service-proxies'
|
||||||
|
import { AppComponentBase } from '@shared/app-component-base';
|
||||||
|
import { accountModuleAnimation } from '@shared/animations/routerTransition';
|
||||||
|
import { finalize } from 'rxjs/operators';
|
||||||
|
import { Subscription } from 'rxjs/Rx';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: './profile.component.html',
|
||||||
|
styleUrls: ['./profile.component.css'],
|
||||||
|
animations: [accountModuleAnimation()]
|
||||||
|
})
|
||||||
|
export class ProfileComponent extends AppComponentBase implements OnInit, OnDestroy, AfterViewInit {
|
||||||
|
|
||||||
|
@ViewChild('cardBody') cardBody: ElementRef;
|
||||||
|
|
||||||
|
public profileAreaId: string = 'profile-area';
|
||||||
|
|
||||||
|
public profile: UserProfileDto = new UserProfileDto();
|
||||||
|
|
||||||
|
private profileSubscription: Subscription;
|
||||||
|
|
||||||
|
public possibleClasses = [
|
||||||
|
{value: 1, viewValue: 'Klasa 1'},
|
||||||
|
{value: 2, viewValue: 'Klasa 2'},
|
||||||
|
{value: 3, viewValue: 'Klasa 3'},
|
||||||
|
{value: 4, viewValue: 'Klasa 4'},
|
||||||
|
{value: 5, viewValue: 'Klasa 5'},
|
||||||
|
{value: 6, viewValue: 'Klasa 6'},
|
||||||
|
{value: 7, viewValue: 'Klasa 7'},
|
||||||
|
{value: 8, viewValue: 'Klasa 8'}
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
injector: Injector,
|
||||||
|
private userProfileService: UserProfileServiceProxy,
|
||||||
|
private router: Router,
|
||||||
|
) {
|
||||||
|
super(injector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngAfterViewInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnInit(): void {
|
||||||
|
this.setBusy(this.profileAreaId);
|
||||||
|
|
||||||
|
this.profileSubscription = this.userProfileService.getProfile()
|
||||||
|
.pipe(finalize(() => { this.clearBusy(this.profileAreaId); }))
|
||||||
|
.subscribe((result: UserProfileDto) => {
|
||||||
|
this.profile = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnDestroy(): void {
|
||||||
|
if (this.profileSubscription) {
|
||||||
|
this.profileSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public saveProfile(): void {
|
||||||
|
this.profile.participantClass = +this.profile.participantClass;
|
||||||
|
this.userProfileService.updateProfile(this.profile)
|
||||||
|
.pipe(finalize(() => { }))
|
||||||
|
.subscribe(() => {
|
||||||
|
this.notify.success(this.l('Zapisano profil'));
|
||||||
|
this.router.navigate(['app/home']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -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("Tworzenie roli")}}</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("Nazwa roli")}}</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("Wyświetlana nazwa roli")}}</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">Opis roli</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row clearfix">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<h4>Uprawnienia</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("Anuluj")}}
|
||||||
|
</button>
|
||||||
|
<button [disabled]="!createRoleForm.form.valid || saving" type="submit" class="btn btn-primary waves-effect">
|
||||||
|
{{l("Zapisz")}}
|
||||||
|
</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('Zapisano pomyślnie'));
|
||||||
|
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("Edycja roli")}} <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("Nazwa roli")}}</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("Wyświetlana nazwa roli")}}</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">Opis roli</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row clearfix">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<h4>Uprawnienia</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("Anuluj")}}
|
||||||
|
</button>
|
||||||
|
<button [disabled]="!editRoleForm.form.valid || saving" type="submit" class="btn btn-primary waves-effect">
|
||||||
|
{{l("Zapisz")}}
|
||||||
|
</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('Zapisano pomyślnie'));
|
||||||
|
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('Role')}}
|
||||||
|
</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>Odśwież</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="body table-responsive">
|
||||||
|
|
||||||
|
<table class="table table-hover table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{l('Nazwa roli')}}</th>
|
||||||
|
<th>{{l('Wyświetlana nazwa roli')}}</th>
|
||||||
|
<th>{{l('Akcje')}}</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>Edytuj</a></li>
|
||||||
|
<li><a href="javascript:void(0);" class="waves-effect waves-block" (click)="delete(role)"><i class="material-icons">delete_sweep</i>Usuń</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,64 @@
|
|||||||
|
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';
|
||||||
|
import swal from 'sweetalert';
|
||||||
|
|
||||||
|
@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 {
|
||||||
|
swal({
|
||||||
|
title: "Usuwanie roli",
|
||||||
|
text: "Czy usunąć role '"+ role.displayName +"'?",
|
||||||
|
icon: "warning",
|
||||||
|
buttons: ['Anuluj', 'Tak']
|
||||||
|
}).then(result => {
|
||||||
|
if (result) {
|
||||||
|
this.rolesService.delete(role.id)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.refresh();
|
||||||
|
swal("Usunięto role: " + role.displayName, {
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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("Tworzenie użytkownika")}}</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">Dane użytkownika</a></li>
|
||||||
|
<li role="presentation"><a href="#user-roles" data-toggle="tab">Role użytkownika</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("Nazwa użytkownika")}}</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("Imię")}}</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("Nazwisko")}}</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("Adres e-mail")}}</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("Hasło")}}</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)]="confirmationPassword" required maxlength="32">
|
||||||
|
<label for="confirmpassword" class="form-label">{{l("Potwierdzenie hasła")}}</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("Aktywny")}}</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("Anuluj")}}
|
||||||
|
</button>
|
||||||
|
<button [disabled]="!createUserForm.form.valid || saving" type="submit" class="btn btn-primary waves-effect">
|
||||||
|
{{l("Zapisz")}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,83 @@
|
|||||||
|
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';
|
||||||
|
import swal from 'sweetalert';
|
||||||
|
|
||||||
|
@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;
|
||||||
|
confirmationPassword: string = '';
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if (this.user.password === this.confirmationPassword) {
|
||||||
|
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('Zapisano pomyślnie'));
|
||||||
|
this.close();
|
||||||
|
this.modalSave.emit(null);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
swal({
|
||||||
|
title: "Błąd - Hasło!",
|
||||||
|
text: "Proszę podaj takie same hasła",
|
||||||
|
icon: "error"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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("Edycja użytkownika")}}</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">Dane użytkownika</a></li>
|
||||||
|
<li role="presentation"><a href="#edit-user-roles" data-toggle="tab">Role użytkownika</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("Nazwa użytkownika")}}</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("Imię")}}</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("Nazwisko")}}</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("Adres e-mail")}}</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("Aktywny")}}</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("Anuluj")}}
|
||||||
|
</button>
|
||||||
|
<button [disabled]="!editUserForm.form.valid" type="submit" class="btn btn-primary waves-effect">
|
||||||
|
{{l("Zapisz")}}
|
||||||
|
</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('Zapisano pomyślnie'));
|
||||||
|
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('Użytkownicy')}}
|
||||||
|
</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('Odśwież')}}</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="body table-responsive">
|
||||||
|
|
||||||
|
<!-- ******************************************************** -->
|
||||||
|
<table class="table table-hover table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{l('Nazwa użytkownika')}}</th>
|
||||||
|
<th>{{l('Imię i nazwisko')}}</th>
|
||||||
|
<th>{{l('Adres e-mail')}}</th>
|
||||||
|
<th>
|
||||||
|
<div style="text-align:center">{{l('Aktywny')}}</div>
|
||||||
|
</th>
|
||||||
|
<th>{{l('Akcje')}}</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('Edytuj')}}</a></li>
|
||||||
|
<li><a href="javascript:void(0);" class="waves-effect waves-block" (click)="delete(user)"><i class="material-icons">delete_sweep</i>{{l('Usuń')}}</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>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user