first commit

This commit is contained in:
Булат Хайруллин 2024-11-20 16:17:13 +03:00
commit bfa87a5f9b
967 changed files with 188027 additions and 0 deletions

1
frontend/.npmrc Normal file
View file

@ -0,0 +1 @@
registry=https://repo.micord.ru/repository/npm-all/

71
frontend/angular.json Normal file
View file

@ -0,0 +1,71 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"webbpm-frontend": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/ts/main.ts",
"tsConfig": "src/tsconfig.json",
"polyfills": "src/ts/polyfills.ts",
"assets": [
"src/resources"
],
"styles": [
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/moment/min/moment-with-locales.js",
"node_modules/moment-timezone/builds/moment-timezone-with-data.min.js",
"node_modules/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js",
"node_modules/selectize/dist/js/standalone/selectize.min.js",
"node_modules/downloadjs/download.min.js"
]
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "webbpm-frontend:build"
},
"configurations": {}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "webbpm-frontend:build"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [],
"exclude": []
}
}
}
}
},
"defaultProject": "webbpm-frontend"
}

10
frontend/bs-config.json Normal file
View file

@ -0,0 +1,10 @@
{
"port": 8000,
"open": false,
"files": [
"./**/*.{html,htm,css,js}"
],
"server": {
"baseDir": "./"
}
}

23
frontend/index.html Normal file
View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<title>ervu_usr_autority</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="icon" type="image/png" href="src/resources/img/logo.png"/>
<link rel="stylesheet" href="src/resources/css/style.css"/>
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('webbpm').catch(function (err) {
console.error(err);
});
</script>
</head>
<body webbpm class="webbpm ervu_usr_autority">
<div class="loader"></div>
</body>
</html>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>ervu_usr_autority</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="icon" type="image/png" href="src/resources/img/logo.png"/>
</head>
<body webbpm class="webbpm ervu_usr_autority">
<div class="loader"></div>
</body>
</html>

8929
frontend/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

103
frontend/package.json Normal file
View file

@ -0,0 +1,103 @@
{
"name": "ervu_usr_autority",
"version": "1.0.0",
"scripts": {
"lite": "node ./node_modules/lite-server/bin/lite-server",
"cleanup": "npm run cleanup-ngc && node ./node_modules/rimraf/bin ./build ./dist",
"cleanup-ngc": "node ./node_modules/rimraf/bin ./src/ts/**/*.js ./src/ts/**/*.json ./src/ts/page.routing.ts",
"cleanup-and-ngc": "npm run cleanup && npm run ngc",
"ngc": "node --max-old-space-size=14336 ./node_modules/@angular/compiler-cli/src/main -p tsconfig.aot.json",
"build-webpack": "node --max-old-space-size=14336 ./node_modules/webpack/bin/webpack --config webpack.aot.config.js --progress --profile",
"save-ts-metadata": "node save.ts.metadata.js",
"tsc": "node ./node_modules/typescript/bin/tsc",
"tsc-watch": "node ./node_modules/typescript/bin/tsc --watch",
"ts-watch": "node node_modules/cross-env/dist/bin/cross-env.js TSC_NONPOLLING_WATCHER=true npm run tsc-watch",
"ts": "npm install && npm run tsc",
"compile": "npm run ts-watch",
"install-compile": "npm install && npm run ts-watch"
},
"dependencies": {
"@angular/animations": "7.2.15",
"@angular/common": "7.2.15",
"@angular/compiler": "7.2.15",
"@angular/core": "7.2.15",
"@angular/forms": "7.2.15",
"@angular/http": "7.2.15",
"@angular/platform-browser": "7.2.15",
"@angular/platform-browser-dynamic": "7.2.15",
"@angular/router": "7.2.15",
"@ng-bootstrap/ng-bootstrap": "4.2.2-micord.1",
"@webbpm/base-package": "3.182.0",
"ag-grid-angular": "29.0.0-micord.4",
"ag-grid-community": "29.0.0-micord.4",
"angular-calendar": "0.28.28",
"autonumeric": "4.5.10-cg",
"bootstrap": "4.3.1",
"bootstrap-icons": "1.10.3",
"cadesplugin_api": "2.0.4-micord.1",
"chart.js": "3.8.0-cg.1",
"chartjs-adapter-moment": "1.0.0",
"core-js": "2.4.1",
"date-fns": "2.29.3",
"downloadjs": "1.4.8",
"eonasdan-bootstrap-datetimepicker": "4.17.47-micord.4",
"esmarttokenjs": "2.2.1-cg",
"font-awesome": "4.7.0",
"google-libphonenumber": "3.0.9",
"inputmask": "5.0.5-cg.2",
"jquery": "3.3.1",
"js-year-calendar": "1.0.0-cg.2",
"jsgantt-improved": "2.0.10-cg",
"moment": "2.17.1",
"moment-timezone": "0.5.11",
"ngx-cookie": "3.0.1",
"ngx-international-phone-number": "1.0.6",
"ngx-toastr": "10.2.0-cg",
"popper.js": "1.14.7",
"reflect-metadata": "0.1.13",
"rxjs": "6.4.0",
"rxjs-compat": "6.4.0",
"selectize": "0.12.4-cg.11",
"systemjs": "0.21.4",
"systemjs-plugin-babel": "0.0.25",
"tslib": "1.9.3",
"zone.js": "0.11.8"
},
"devDependencies": {
"@angular-devkit/build-optimizer": "0.13.9",
"@angular-devkit/core": "7.3.9",
"@angular/cli": "7.3.9",
"@angular/compiler-cli": "7.2.15",
"@angular/platform-server": "7.2.15",
"@babel/core": "7.18.10",
"@babel/preset-env": "7.18.10",
"@types/bootstrap": "3.3.39",
"@types/eslint": "7.2.5",
"@types/jquery": "2.0.49",
"@types/node": "7.0.5",
"@types/selectize": "0.12.33",
"ajv": "8.8.2",
"angular-router-loader": "0.8.5",
"angular2-template-loader": "0.6.2",
"babel-loader": "9.1.2",
"codelyzer": "5.2.1",
"copy-webpack-plugin": "5.0.3",
"cross-env": "5.2.1",
"css-loader": "6.11.0",
"del": "2.2.2",
"file-loader": "6.2.0",
"html-webpack-plugin": "5.6.0",
"lite-server": "2.3.0",
"mini-css-extract-plugin": "2.9.1",
"mkdirp": "3.0.1",
"raw-loader": "4.0.2",
"style-loader": "3.3.4",
"terser-webpack-plugin": "5.3.10",
"tslint": "5.13.1",
"typescript": "3.2.4",
"typescript-parser": "2.6.1-cg.2",
"webpack": "5.90.1",
"webpack-bundle-analyzer": "4.10.1",
"webpack-cli": "5.0.2"
}
}

113
frontend/pom.xml Normal file
View file

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ervu_usr_autority</groupId>
<artifactId>ervu_usr_autority</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>ervu_usr_autority.ervu_usr_autority</groupId>
<artifactId>frontend</artifactId>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<id>replace-version-in-url</id>
<phase>process-resources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>${basedir}/src/resources/app-config.json</include>
<include>${basedir}/dist/src/resources/app-config.json</include>
<include>${basedir}/src/resources/app.version</include>
<include>${basedir}/dist/src/resources/app.version</include>
</includes>
<replacements>
<replacement>
<token>%project.version%</token>
<value>${project.version}</value>
</replacement>
<replacement>
<token>%enable.version.in.url%</token>
<value>${enable.version.in.url}</value>
</replacement>
</replacements>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<copyWebResources>false</copyWebResources>
<webResources>
<resource>
<directory>${basedir}</directory>
<includes>
<include>src/resources/**/*</include>
<include>build_dev/**/*</include>
<include>node_modules/**/*</include>
<include>index.html</include>
<include>systemjs.config.js</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>compile-ts</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<copyWebResources>false</copyWebResources>
<webResources>
<resource>
<directory>${basedir}/dist</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>enable-version-in-url</id>
<properties>
<enable.version.in.url>true</enable.version.in.url>
</properties>
</profile>
</profiles>
</project>

23
frontend/preview.html Normal file
View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<title>Web BPM</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="icon" type="image/png" href="src/resources/img/logo.png"/>
<link rel="stylesheet" href="src/resources/css/style.css"/>
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.preview.config.js"></script>
<script>
System.import('preview').catch(function (err) {
console.error(err);
});
</script>
</head>
<body preview-container id="webbpm-angular-application-container" class="webbpm ervu_usr_autority">
<div class="loader"></div>
</body>
</html>

View file

@ -0,0 +1,72 @@
#!/usr/bin/env node
var tsp = require("typescript-parser");
var fs = require('fs');
var path = require('path');
var ts = require("typescript");
var parser = new tsp.TypescriptParser();
var excludedDirs = [
'generated-sources'
];
var walkFileTree = function (dir, action) {
if (typeof action !== "function") {
return;
}
fs.readdirSync(dir).forEach(function (file) {
var path = dir + "/" + file;
var stat = fs.statSync(path);
var extension = ".ts";
if (stat && stat.isDirectory() && excludedDirs.indexOf(file) === -1) {
walkFileTree(path, action);
}
else if (path.indexOf(extension, path.length - extension.length) !== -1) {
action(null, path);
}
});
};
var dateInLong = Date.now();
var arr = [];
var basePath = path.resolve(__dirname, "src/ts/");
walkFileTree(basePath, function (err, file) {
var content = fs.readFileSync(file).toString();
var jsonStructure = parser.parseTypescript(ts.createSourceFile(
file,
content,
ts.ScriptTarget.Latest,
true,
ts.ScriptKind.TS
),
'/');
jsonStructure['packageName'] = path.relative(path.resolve(__dirname, "src/ts/"),jsonStructure['filePath']);
jsonStructure['imports'].forEach( function (val) {
if (val.libraryName.startsWith(".")) {
val['libraryName'] = path.resolve(path.dirname(jsonStructure['filePath']), val['libraryName']);
val['libraryName'] = path.relative(path.resolve(__dirname, "src/ts/"), val['libraryName']);
val['libraryName'] = path.dirname(val['libraryName']).split(path.sep).join(".");
}
});
delete jsonStructure['filePath'];
jsonStructure['packageName'] = path.dirname(jsonStructure['packageName']).split(path.sep).join( ".");
arr.push(jsonStructure);
});
var cache = [];
fs.writeFileSync("./../.studio/typescript.metadata.json",
JSON.stringify(arr, function (key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
return;
}
// Store value in our collection
cache.push(value);
}
return value;
}));
cache = null;
console.log("typescript parse time = " + (Date.now() - dateInLong));

View file

@ -0,0 +1,20 @@
{
"electronic_sign.esmart_extension_url": "",
"electronic_sign.tsp_address": "",
"filter_cleanup_interval_hours": 720,
"filter_cleanup_check_period_minutes": 30,
"auth_method": "form",
"enable.version.in.url": "%enable.version.in.url%",
"backend.context": "ervu_usr_autority",
"guard.confirm_exit": false,
"message_service_error_timeout": "",
"message_service_warning_timeout": "",
"message_service_success_timeout": "",
"message_service_info_timeout": "",
"jivo_chat_widget_api_url": "https://code.jivo.ru/widget/{ID}",
"jivo_chat_widget_enabled": false,
"password_pattern": "^((?=(.*\\d){1,})(?=.*[a-zа-яё])(?=.*[A-ZА-ЯЁ]).{8,})$",
"password_pattern_error": "Пароль должен содержать заглавные или прописные буквы и как минимум 1 цифру",
"show.client.errors": false,
"available_task.single_fetch": true
}

View file

@ -0,0 +1 @@
%project.version%

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,182 @@
.webbpm.ervu_usr_autority .container-inside > div > div > [page-object] {
display: flex;
}
.webbpm.ervu_usr_autority [page-home] {
display: flex;
align-items: center;
background-color: var(--bg-light);
}
.webbpm.ervu_usr_autority #home {
flex: 1;
}
.webbpm.ervu_usr_autority .title {
font-size: var(--size-text-title);
font-family: 'InterSB';
padding-top: 0;
padding-bottom: var(--indent-small);
}
.webbpm.ervu_usr_autority .title .form-group {
display: block;
margin-bottom: 0;
}
.webbpm.ervu_usr_autority .font-bold {
font-family: 'InterSB';
}
.webbpm.ervu_usr_autority .btn {
font-size: var(--size-text-secondary);
font-family: 'Inter';
color: var(--color-link);
padding: 13px 39px;
border: 1px solid var(--color-link);
border-radius: 4px;
background-color: transparent;
box-shadow: none;
}
.webbpm.ervu_usr_autority .btn:is(:not(:disabled):not(.disabled):hover, :not(:disabled):not(.disabled):active, :not(:disabled):not(.disabled):focus) {
color: var(--color-link-hover);
border-color: var(--color-link-hover);
background-color: transparent;
}
.webbpm.ervu_usr_autority .btn-main:not(.info):not(.link) .btn,
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm, .confirmation) .btn-primary {
color: var(--white);
border: 1px solid var(--color-link);
background: var(--color-link);
}
.webbpm.ervu_usr_autority .btn-main .btn:is(:not(:disabled):not(.disabled):hover, :not(:disabled):not(.disabled):active, :not(:disabled):not(.disabled):focus),
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm, .confirmation) .btn-primary:is(:not(:disabled):not(.disabled):hover, :not(:disabled):not(.disabled):active, :not(:disabled):not(.disabled):focus) {
color: var(--white);
border-color: var(--color-link-hover);
background-color: var(--color-link-hover);
}
.webbpm.ervu_usr_autority .btn:is(:disabled, .disabled) {
color: var(--color-text-secondary);
border-color: var(--border-light);
}
.webbpm.ervu_usr_autority .btn-big-group > div {
justify-content: center;
align-items: center;
}
.webbpm.ervu_usr_autority .btn-big-group .btn {
font-family: 'Inter';
color: var(--color-text-primary);
min-width: 300px;
padding: 40px;
border: 0;
border-radius: 12px;
background-color: var(--white) !important;
box-shadow: var(--bg-shadow);
}
.webbpm.ervu_usr_autority .btn-big-group .btn::before {
display: flex;
justify-content: center;
margin-bottom: 8px;
}
.webbpm.ervu_usr_autority .btn-big-group vbox:first-child .btn::before {
content: url(../img/svg/users-bl.svg);
}
.webbpm.ervu_usr_autority .btn-big-group vbox:first-child .btn:is(:hover, :active, :focus)::before {
content: url(../img/svg/users.svg);
}
.webbpm.ervu_usr_autority .btn-big-group vbox:last-child .btn::before {
content: url(../img/svg/notes-bl.svg);
}
.webbpm.ervu_usr_autority .btn-big-group vbox:last-child .btn:is(:hover, :active, :focus)::before {
content: url(../img/svg/notes.svg);
}
.webbpm.ervu_usr_autority .btn-big-group vbox {
padding-right: 0;
}
.webbpm.ervu_usr_autority .btn-big-group vbox + vbox {
margin-left: 40px;
}
.webbpm.ervu_usr_autority collapsible-panel .card {
margin-bottom: var(--indent-small);
border: 1px solid var(--border-light) !important;
}
.webbpm.ervu_usr_autority collapsible-panel .card i {
width: 16px;
}
.webbpm.ervu_usr_autority collapsible-panel .card-header,
.webbpm.ervu_usr_autority collapsible-panel .card-block .font-bold {
font-family: 'InterSB' !important;
font-size: var(--size-text-primary) !important;
}
.webbpm.ervu_usr_autority collapsible-panel .card-block {
font-size: var(--size-text-secondary);
padding-top: var(--indent-mini) !important;
border-top: 1px solid var(--border-light);
}
.webbpm.ervu_usr_autority collapsible-panel .card-block .filter-group .horizontal-container > * {
padding-left: var(--indent-big);
padding-right: 0;
}
.webbpm.ervu_usr_autority collapsible-panel .card-block .filter-group .horizontal-container > *:first-child {
padding-left: 0;
}
.webbpm.ervu_usr_autority collapsible-panel .card-block .filter-group .width-full label {
width: 160px;
}
.webbpm.ervu_usr_autority collapsible-panel .card-block .filter-group .width-full.fixed-label-mini label {
width: 100px;
}
.webbpm.ervu_usr_autority collapsible-panel .card-block .filter-group .width-full.fixed-label-extra-mini label {
width: 60px;
}
.webbpm.ervu_usr_autority grid-v2 {
flex: 1;
}
.webbpm.ervu_usr_autority * + grid-v2,
.webbpm.ervu_usr_autority grid-v2 ~ *:not([hidden]) {
margin-top: var(--indent-small);
}
.webbpm.ervu_usr_autority ag-grid-angular {
font-family: 'Inter';
}
.webbpm.ervu_usr_autority ag-grid-angular .grid-setting-icon,
.webbpm.ervu_usr_autority ag-grid-angular .ag-header-cell.ag-header-active .ag-header-cell-menu-button,
.webbpm.ervu_usr_autority ag-grid-angular .ag-header-cell .ag-header-icon .ag-icon,
.webbpm.ervu_usr_autority ag-grid-angular .ag-header-row-column-filter :is(.ag-header-cell, .ag-header-group-cell)::after,
.webbpm.ervu_usr_autority ag-grid-angular .ag-filter .ag-filter-condition,
.webbpm.ervu_usr_autority ag-grid-angular .ag-filter .ag-filter-condition ~ * {
display: none !important;
}
.webbpm.ervu_usr_autority ag-grid-angular .ag-header-row {
font-family: 'InterSB';
}
.webbpm.ervu_usr_autority ag-grid-angular .ag-header-row:not(:first-child) .ag-header-cell,
.webbpm.ervu_usr_autority ag-grid-angular .ag-header-row:not(:first-child) .ag-header-group-cell.ag-header-group-cell-with-group {
border-top: 0;
}
.webbpm.ervu_usr_autority ag-grid-angular .ag-row.ag-row-hover,
.webbpm.ervu_usr_autority ag-grid-angular .ag-row.ag-row-hover .ag-cell {
color: var(--color-link);
border-radius: 0;
background-color: transparent !important;
}
.webbpm.ervu_usr_autority ag-grid-angular .ag-row.ag-row-hover,
.webbpm.ervu_usr_autority ag-grid-angular .ag-row.ag-row-hover + .ag-row {
border-color: var(--border-light);
}
.webbpm.ervu_usr_autority ag-grid-angular .ag-row-last:not(.ag-row-first) {
border-width: 1px 0 0;
}
.webbpm.ervu_usr_autority ag-grid-angular .ag-cell-focus:not(.ag-cell-range-selected):focus-within {
border-color: var(--color-link);
}

View file

@ -0,0 +1,342 @@
@font-face {
font-family: 'Segoe';
src: url('../fonts/Segoe.ttf');
}
@font-face {
font-family: 'SegoeSL';
src: url('../fonts/SegoeSL.ttf');
}
@font-face {
font-family: 'SegoeSB';
src: url('../fonts/SegoeSB.ttf');
}
@font-face {
font-family: 'SegoeB';
src: url('../fonts/SegoeB.ttf');
}
@font-face {
font-family: 'SegoeBL';
src: url('../fonts/SegoeBL.ttf');
}
.webbpm a {
color: var(--color-link);
&:hover,
&:focus,
&:active {
color: var(--color-link-hover);
text-decoration: none;
}
}
body.webbpm {
display: flex;
flex-direction: column;
color: var(--color-text-primary);
font-family: 'Segoe';
background-color: var(--white);
}
.webbpm .container {
padding: 70px 0 0;
}
body.webbpm [id="page"],
.webbpm .container .container-inside {
font-family: 'Segoe';
font-size: var(--size-text-primary);
}
.webbpm .logo {
height: auto;
width: auto;
}
.webbpm .header-logo {
display: flex;
flex-direction: row;
align-items: center;
margin-left: 40px;
.logo a {
background: url('../../../src/resources/img/logo-full.png') no-repeat 0 50%;
}
}
.webbpm .header-menu {
display: flex;
flex-direction: row;
margin-left: auto;
margin-right: 40px;
& > * {
margin-right: 20px;
&:last-child {
margin-right: 0;
}
}
.nav-link {
display: flex;
align-items: center;
justify-content: center;
color: var(--white);
font-size: var(--size-text-primary);
width: 30px;
height: 30px;
padding: 0;
border: 0;
border-radius: 15px;
background-color: var(--color-text-primary);
outline: transparent;
&::after {
display: none;
}
&:hover,
&:focus,
&:active {
background-color: var(--color-link);
}
}
.logout .user-info {
display: flex;
flex-direction: column;
color: var(--black);
padding: 4px 20px;
background: transparent;
cursor: default;
& > * {
display: flex;
padding-bottom: 10px;
margin: 0 0 10px 0;
border-bottom: 1px solid #f1f5f9;
&:last-child {
margin-bottom: 0;
}
}
.user-fio {
padding-bottom: 0;
margin-bottom: 0;
border-bottom: 0;
}
.user-department {
color: #a0b1bc;
line-height: 1.2;
}
}
}
.webbpm .header {
display: flex;
font-family: 'Segoe';
width: 100%;
height: auto;
min-height: 70px;
border-bottom: 1px solid var(--bg-light);
background: var(--white);
box-shadow: 0px 15px 20px 0px rgb(0 0 0 / 4%);
& > div > * {
position: relative;
display: flex;
align-items: center;
}
.dropdown-menu.show {
top: 69px !important;
right: 0px !important;
left: auto !important;
transform: none !important;
margin: 0;
border: 0;
border-radius: 0 0 10px 10px;
background-color: var(--white);
box-shadow: 0 8px 12px rgb(77 72 91 / 5%), 0 6px 10px rgb(77 72 91 / 0%);
.dropdown-menu-inner {
max-height: calc(100vh - 140px);
overflow-y: auto;
}
}
:is(process, admin-menu) .dropdown-menu.show {
top: 49px !important;
}
.logout .dropdown-menu.show {
width: 300px;
}
}
.webbpm .dropdown-menu-inner:hover {
background-color: transparent;
}
.webbpm .dropdown-item {
padding: 4px 20px;
&:hover,
&:focus,
&:active {
color: var(--color-link);
background-color: transparent;
outline: transparent;
}
}
.webbpm footer {
color: var(--color-text-primary);
font-size: var(--size-text-secondary);
left: 0;
right: 0;
padding: 15px 40px;
border-top: 1px solid var(--border-light);
a {
color: var(--color-text-primary);
&:hover {
color: var(--color-link);
}
}
}
/*-------------- Menu tasks -------------- */
.webbpm .task-list-tree-panel {
padding: 0 40px;
.task-list-filter {
font-family: 'Segoe';
box-shadow: none;
li:first-of-type {
font-family: 'SegoeSB';
font-weight: normal;
padding-left: 0;
}
li.ontime label div {
background-color: #31c980;
}
li.overdue label div {
background-color: var(--color-link);
}
}
}
.webbpm .task-list-workplace {
padding: 20px 40px 0 40px;
}
.webbpm .task-tbl :is(.tr.task-ontime, .tr.task-overdue) > .td.task::before {
top: 24px;
background-color: #31c980;
}
.webbpm .task-tbl .tr.task-overdue > .td.task::before {
background-color: var(--color-link);
}
.webbpm .task-tbl .thead {
display: table-header-group;
border: 0;
background: transparent;
}
.webbpm .task-tbl .th {
color: var(--color-text-primary);
font-family: 'SegoeSB';
font-size: var(--size-text-secondary);
font-weight: normal;
padding: 9px 12px;
border: 0;
background: var(--bg-light);
}
.webbpm .task-tbl .th:first-child {
border-top-left-radius: 12px;
border-bottom-left-radius: 12px;
}
.webbpm .task-tbl .th:last-child {
border-top-right-radius: 12px;
border-bottom-right-radius: 12px;
}
.webbpm .task-tbl .td {
color: var(--color-text-primary);
font-size: var(--size-text-primary);
padding: 16px 12px;
border: 0;
}
.webbpm .task-tbl .thead ~ .tr {
border-color: var(--border-light);
border-width: 1px 0 0 0;
border-style: solid;
}
.webbpm .task-tbl .thead + .tr {
border-top-color: transparent;
}
.webbpm .task-tbl .thead ~ .tr:hover {
border-top-color: transparent;
border-bottom-color: transparent;
}
.webbpm .task-tbl .thead ~ .tr:hover +.tr {
border-top-color: transparent;
}
.webbpm .task-tbl .thead ~ .tr:hover .td {
background-color: #f9f9f9;
}
.webbpm .task-tbl .thead ~ .tr:hover .td:first-child {
border-top-left-radius: 12px;
border-bottom-left-radius: 12px;
}
.webbpm .task-tbl .thead ~ .tr:hover .td:last-child {
border-top-right-radius: 12px;
border-bottom-right-radius: 12px;
}
/*------------- end Menu tasks ----------- */
/*----------------- Login ---------------- */
.webbpm :is(.form-signin, .form-signup, .confirm) {
color: var(--color-text-primary);
width: 560px;
padding: 60px 80px;
margin: 30px auto;
border: 0;
border-radius: 15px;
box-shadow: 0px 0px 30px 2px rgb(77 72 91 / 12%);
background-color: var(--white);
}
.webbpm :is(.form-signin, .form-signup) .row.title {
position: relative;
padding: 0;
}
.webbpm .form-signin h1,
.webbpm .form-signin h2,
.webbpm .form-signup h2,
.webbpm .confirm h2 {
font-family: 'SegoeB';
font-size: 32px;
text-align: left;
margin-bottom: 20px;
}
.webbpm :is(.form-signin, .form-signup, .confirm) .logo {
position: absolute;
top: -10px;
right: 0;
width: 145px;
height: 40px;
background: none;
}
.webbpm .form-signin .row.registration > * + *,
.webbpm .form-signin .login-btn-box .password,
.webbpm .form-signin .login-btn-box .btn + .btn {
margin-left: 20px;
}
/*--------------- end Login -------------- */

View file

@ -0,0 +1,253 @@
@font-face {
font-family: 'InterL';
src: url('../fonts/Inter-Light.otf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Inter';
src: url('../fonts/Inter-Regular.otf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'InterM';
src: url('../fonts/Inter-Medium.otf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'InterSB';
src: url('../fonts/Inter-SemiBold.otf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'InterB';
src: url('../fonts/Inter-Bold.otf');
font-weight: 400;
font-style: normal;
}
body.webbpm.ervu_usr_autority {
-ms-text-size-adjust: 100%;
-moz-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
.webbpm.ervu_usr_autority {
--color-text-primary: #1d1e21;
--color-text-secondary: #acacac;
--color-link: #c64e1b;
--color-link-hover: #fa773f;
--color-form: #3f434b;
--color-bg-main: #223d36;
--color-light: #868b87;
--bg-light: #fafafa;
--bg-warn: #ffdcc6;
--bg-form: #eee;
--border-light: #d2d2d2;
--bg-shadow: 0 19px 19px 8px rgba(230, 230, 230, 0.19), 0 0px 4px 0px #f3f3f3;
--h-header: 64px;
--h-footer: 48px;
--w-screen: 75px;
--size-text-title: 36px;
--size-text-subtitle: 20px;
--size-text-primary: 18px;
--size-text-secondary: 16px;
--indent-huge: 48px;
--indent-big: 40px;
--indent-medium: 32px;
--indent-small: 24px;
--indent-mini: 16px;
--indent-extra-mini: 10px;
}
.webbpm.ervu_usr_autority a {
color: var(--color-link);
text-decoration: none;
}
.webbpm.ervu_usr_autority a:is(:hover, :focus, :active) {
color: var(--color-link-hover);
}
.webbpm.ervu_usr_autority .header {
font-family: 'Inter';
min-height: var(--h-header);
border: 0;
background-color: var(--color-text-primary);
}
.webbpm.ervu_usr_autority .header .header-logo {
margin-left: var(--w-screen);
}
.webbpm.ervu_usr_autority .header .header-logo a {
color: var(--white);
font-family: 'Inter';
}
.webbpm.ervu_usr_autority .header .header-logo .logo {
position: relative;
display: flex;
align-items: center;
}
.webbpm.ervu_usr_autority .header .header-logo .logo a {
position: absolute;
width: 62px;
height: 40px;
background: url(../img/svg/mil-logo.svg) no-repeat 0 50%;
}
.webbpm.ervu_usr_autority .header .header-logo .main-page {
font-family: 'InterSB';
margin-left: calc(62px + 16px);
}
.webbpm.ervu_usr_autority footer {
height: var(--h-footer);
border: 0;
background-color: var(--color-text-primary);
}
.webbpm.ervu_usr_autority .container {
padding-top: var(--h-header);
bottom: var(--h-footer);
}
.webbpm.ervu_usr_autority .container-inside {
display: flex;
flex-direction: column;
font-family: 'Inter';
height: 100%;
padding: 0;
overflow: auto;
}
.webbpm.ervu_usr_autority .container-inside > div {
flex: 1;
padding: var(--indent-huge) var(--w-screen);
}
/*----------------- Login ---------------- */
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) {
color: var(--color-text-primary);
font-size: var(--size-text-secondary);
width: 500px;
padding: 32px;
margin: 30px auto;
border: 0;
border-radius: 8px;
background-color: var(--white);
box-shadow: var(--bg-shadow);
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) :is(h1, h2) {
color: var(--color-form);
font-family: 'InterB';
font-size: var(--size-text-subtitle);
text-align: left;
margin-bottom: 0;
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) .logo {
position: relative;
display: flex;
justify-content: center;
width: 100%;
height: 76px;
padding: 0 0 0 128px;
margin-bottom: 32px;
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) .logo::after {
position: absolute;
content: "";
left: 0;
width: 112px;
height: 72px;
background-image: url(../img/svg/form-logo.svg);
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) .row {
position: relative;
margin-bottom: 0;
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) .row + .row {
margin-top: 20px;
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) input {
height: 56px;
padding-top: 20px;
padding-left: 16px;
border: 0;
border-radius: 8px;
background-color: var(--bg-light);
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) input[type="password"] {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) input[type="password"] ~ .input-group-append > .input-group-text {
border: 0;
background-color: var(--bg-light);
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) input + label {
position: absolute;
top: 16px;
left: 16px;
pointer-events: none;
transition: all 200ms;
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) input:focus + label,
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) input:not(:placeholder-shown) + label {
top: 4px;
font-size: var(--indent-extra-mini);
z-index: 20;
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) .msg-text {
margin-top: 12px;
}
.webbpm.ervu_usr_autority :is(.form-signin, .form-signup, .confirm) .btn-box {
margin-top: 32px;
}
.webbpm.ervu_usr_autority .form-signin .row.registration > * + *,
.webbpm.ervu_usr_autority .form-signin .login-btn-box .password,
.webbpm.ervu_usr_autority .form-signin .login-btn-box .btn + .btn {
margin-left: 32px;
}
/*--------------- end Login -------------- */
.webbpm.ervu_usr_autority .loader {
font-size: 15px;
left: calc(50% - 50px);
top: calc(50% - 50px);
width: 0.8em;
height: 0.8em;
border-radius: 50%;
position: relative;
text-indent: -9999em;
animation: loader-pin 1.1s infinite ease;
transform: translateZ(0);
}
@keyframes loader-pin {
0%,
100% {
box-shadow: 0em -2.6em 0em 0em #ffffff, 1.8em -1.8em 0 0em rgba(198, 78, 27, 0.3), 2.5em 0em 0 0em rgba(198, 78, 27, 0.3), 1.75em 1.75em 0 0em rgba(198, 78, 27, 0.3), 0em 2.5em 0 0em rgba(198, 78, 27, 0.3), -1.8em 1.8em 0 0em rgba(198, 78, 27, 0.3), -2.6em 0em 0 0em rgba(198, 78, 27, 0.7), -1.8em -1.8em 0 0em rgba(198, 78, 27, 1);
}
12.5% {
box-shadow: 0em -2.6em 0em 0em rgba(198, 78, 27, 1), 1.8em -1.8em 0 0em #ffffff, 2.5em 0em 0 0em rgba(198, 78, 27, 0.3), 1.75em 1.75em 0 0em rgba(198, 78, 27, 0.3), 0em 2.5em 0 0em rgba(198, 78, 27, 0.3), -1.8em 1.8em 0 0em rgba(198, 78, 27, 0.3), -2.6em 0em 0 0em rgba(198, 78, 27, 0.3), -1.8em -1.8em 0 0em rgba(198, 78, 27, 0.7);
}
25% {
box-shadow: 0em -2.6em 0em 0em rgba(198, 78, 27, 0.7), 1.8em -1.8em 0 0em rgba(198, 78, 27, 1), 2.5em 0em 0 0em #ffffff, 1.75em 1.75em 0 0em rgba(198, 78, 27, 0.3), 0em 2.5em 0 0em rgba(198, 78, 27, 0.3), -1.8em 1.8em 0 0em rgba(198, 78, 27, 0.3), -2.6em 0em 0 0em rgba(198, 78, 27, 0.3), -1.8em -1.8em 0 0em rgba(198, 78, 27, 0.3);
}
37.5% {
box-shadow: 0em -2.6em 0em 0em rgba(198, 78, 27, 0.3), 1.8em -1.8em 0 0em rgba(198, 78, 27, 0.7), 2.5em 0em 0 0em rgba(198, 78, 27, 1), 1.75em 1.75em 0 0em #ffffff, 0em 2.5em 0 0em rgba(198, 78, 27, 0.3), -1.8em 1.8em 0 0em rgba(198, 78, 27, 0.3), -2.6em 0em 0 0em rgba(198, 78, 27, 0.3), -1.8em -1.8em 0 0em rgba(198, 78, 27, 0.3);
}
50% {
box-shadow: 0em -2.6em 0em 0em rgba(198, 78, 27, 0.3), 1.8em -1.8em 0 0em rgba(198, 78, 27, 0.3), 2.5em 0em 0 0em rgba(198, 78, 27, 0.7), 1.75em 1.75em 0 0em rgba(198, 78, 27, 1), 0em 2.5em 0 0em #ffffff, -1.8em 1.8em 0 0em rgba(198, 78, 27, 0.3), -2.6em 0em 0 0em rgba(198, 78, 27, 0.3), -1.8em -1.8em 0 0em rgba(198, 78, 27, 0.3);
}
62.5% {
box-shadow: 0em -2.6em 0em 0em rgba(198, 78, 27, 0.3), 1.8em -1.8em 0 0em rgba(198, 78, 27, 0.3), 2.5em 0em 0 0em rgba(198, 78, 27, 0.3), 1.75em 1.75em 0 0em rgba(198, 78, 27, 0.7), 0em 2.5em 0 0em rgba(198, 78, 27, 1), -1.8em 1.8em 0 0em #ffffff, -2.6em 0em 0 0em rgba(198, 78, 27, 0.3), -1.8em -1.8em 0 0em rgba(198, 78, 27, 0.3);
}
75% {
box-shadow: 0em -2.6em 0em 0em rgba(198, 78, 27, 0.3), 1.8em -1.8em 0 0em rgba(198, 78, 27, 0.3), 2.5em 0em 0 0em rgba(198, 78, 27, 0.3), 1.75em 1.75em 0 0em rgba(198, 78, 27, 0.3), 0em 2.5em 0 0em rgba(198, 78, 27, 0.7), -1.8em 1.8em 0 0em rgba(198, 78, 27, 1), -2.6em 0em 0 0em #ffffff, -1.8em -1.8em 0 0em rgba(198, 78, 27, 0.3);
}
87.5% {
box-shadow: 0em -2.6em 0em 0em rgba(198, 78, 27, 0.3), 1.8em -1.8em 0 0em rgba(198, 78, 27, 0.3), 2.5em 0em 0 0em rgba(198, 78, 27, 0.3), 1.75em 1.75em 0 0em rgba(198, 78, 27, 0.3), 0em 2.5em 0 0em rgba(198, 78, 27, 0.3), -1.8em 1.8em 0 0em rgba(198, 78, 27, 0.7), -2.6em 0em 0 0em rgba(198, 78, 27, 1), -1.8em -1.8em 0 0em #ffffff;
}
}

View file

@ -0,0 +1,846 @@
:root {
--white: #ffffff;
--black: #000000;
--color-text-primary: #404954;
--color-link: #1c92ea;
--color-link-hover: #1b84d2;
--bg-light: #f5f7fa;
--bg-secondary: #4c5969;
--border-light: #e3e6ed;
--size-text-primary: 16px;
--size-text-secondary: 14px;
}
* {
margin: 0;
padding: 0;
}
*, *:before, *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.webbpm .form-signin label {
width: 160px;
margin-right: 0;
}
.webbpm .progress {
position: absolute;
width: 64px;
height: 64px;
margin-bottom: 0 !important;
background: url("../img/progress.gif") no-repeat 0 0;
}
.webbpm > .progress {
top: 50%;
left: 50%;
margin-top: -30px;
margin-left: -30px;
}
.webbpm .search-task-progress-bar {
text-align: center;
}
.webbpm .modal-body .progress,
.webbpm .search-task-progress-bar .progress {
position: relative;
top: 0;
margin-top: 0;
}
/*-- common class --*/
.webbpm .fl-left {
float: left;
}
.webbpm .fl-right {
float: right;
}
.webbpm .anchor {
float: none;
clear: both;
}
.webbpm :is(ul, ol) li {
list-style: none;
}
.webbpm :is(h1, h2, h3) {
margin: 0;
font-weight: normal;
}
.webbpm h1 {
font-size: 2.33em;
}
.webbpm h2 {
font-size: 2em;
}
.webbpm h3 {
font-size: 1.5em;
}
.webbpm .table {
display: table;
}
.webbpm .tr {
display: table-row;
}
.webbpm .td, .webbpm .th {
display: table-cell;
}
/*-- layout --*/
html, .webbpm {
width: 100%;
height: 100%;
display: block;
}
.webbpm {
background-color: #f9f9fa;
font-family: Arial;
font-size: var(--size-text-secondary);
min-height: 0;
padding: 0;
}
.webbpm .wrapper {
height: 100%;
min-height: 100%;
position: relative;
}
.webbpm .container {
width: 100%;
max-width: 100%;
height: auto;
margin: 0;
padding: 67px 0 0;
position: absolute;
top: 0px;
left: 0;
right: 0;
bottom: 50px;
border: 0;
overflow: hidden;
[ng-include="taskPageFile"] {
position: relative;
min-height: 100%;
height: 100%;
overflow: auto;
}
.container-inside {
font-family: Arial;
font-size: var(--size-text-secondary);
position: relative;
height: 100%;
overflow: auto;
}
}
.webbpm footer {
position: absolute;
color: var(--black);
font-size: 12px;
bottom: 0;
left: 15px;
right: 15px;
height: 50px;
padding: 15px 0;
border-top: 1px solid #c1c1c1;
background: transparent;
span + span {
padding-left: 20px;
}
}
/*--------- TOP MENU ----------*/
.webbpm .logo {
display: inline-block;
margin: 0;
float: left;
a {
width: 200px;
height: 67px;
position: absolute;
background: url("../img/logo.png") no-repeat 0 0;
}
}
.webbpm .header {
position: absolute;
color: var(--white);
font-family: Corbel;
font-size: var(--size-text-secondary);
top: 0;
left: 0;
right: 0;
height: 67px;
min-height: 67px;
line-height: normal;
border: 0;
padding: 0;
background: #b9c0ca;
z-index: 997;
.nav .nav-link {
color: var(--white);
float: none;
display: block;
line-height: 60px;
padding: 0 15px 0 60px;
text-shadow: none;
cursor: pointer;
}
.nav .nav-link:hover {
text-decoration: none;
}
}
.webbpm .dropdown-menu {
background-color: #eee;
}
.webbpm .nav .nav-item .dropdown-menu:after {
border-bottom: 6px solid #eee;
}
.webbpm .inner {
overflow-y: auto;
}
@media (min-width: 768px) {
.webbpm .navbar .nav > * {
float: left;
}
}
@media (max-width: 767px) {
.webbpm .dropdown-menu > div > button {
color: #d1dbe5;
}
}
/*--------- end - TOP MENU ----------*/
.webbpm .user-department,
.webbpm .user-info {
color: #5a6473;
}
.webbpm .user-info > * {
display: inline-block;
margin-left: 5px;
}
.webbpm [log-out] {
max-width: 40%;
margin-right: 15px;
}
.webbpm .content {
padding: 0 20px;
}
.webbpm .inner {
min-height: 100%;
height: 100%;
overflow-y : scroll;
}
/*--------------task-list------------------*/
.task-list {
font-size: 0;
height: 100%;
min-height: 100%;
}
.task-list > div {
display: block;
float: left;
height: 100%;
min-height: 100%;
font-size: var(--size-text-secondary);
}
.task-list-tree-panel {
width: 20%;
background: #e9edf2;
border-right: 1px solid #b9c1ca;
}
.task-list-tree-panel .task-list-filter {
position: relative;
margin-top: 15px;
z-index: 10;
}
.task-list-tree-panel .task-list-filter li {
position: relative;
padding: 8px 10px;
margin: 2px 10px;
}
.task-list-tree-panel .task-list-filter li::before {
content: "";
position: absolute;
left: 0px;
bottom: 0px;
right: 0;
top: 0;
border: 1px solid rgb(206, 212, 219);
border-radius: 4px;
background-color: var(--white);
opacity: 0.6;
}
.task-list-tree-panel .task-list-filter li label:hover {
cursor: pointer;
}
.task-list-tree-panel .task-list-filter li label {
position: relative;
width: 100%;
margin: 0;
z-index: 11;
}
.task-list-tree-panel .task-list-filter li label input[type="radio"] {
float: left;
margin-top: 2px;
margin-right: 4px;
}
.task-list-tree-panel .task-list-filter li label span {
float: right;
background-color: #bbb;
padding: 0px 4px;
border-radius: 3px;
min-width: 25px;
text-align: center;
color: var(--white);
}
.task-list-tree-panel .task-list-filter li.ontime label span {
background-color: #a0c367;
}
.task-list-tree-panel .task-list-filter li.overdue label span {
background-color: #fc2d2d;
}
.task-list-header {
border-bottom: 1px solid #b9c1ca;
background-color: #ccd6e0;
height: 30px;
line-height: 30px;
color: #565968;
font-size: var(--size-text-secondary);
padding: 0 12px;
}
.structure-box {
padding: 15px;
}
.task-list-workplace {
width: 80%;
padding: 15px 15px 0;
overflow-y: auto;
}
/*--------------task-list end--------------*/
/*---------------table-list----------------*/
.task-tbl {
background: var(--white);
width: 100%;
border-collapse: collapse;
}
.task-tbl .td, .task-tbl .th {
border: 1px solid #b9c1ca;
padding: 10px 15px;
}
.task-tbl .th {
color: #565968;
}
.task-tbl .td {
color: #333;
}
.task-tbl .thead {
background: #ccd6e0;
}
.task-tbl > .tr:hover {
cursor: pointer;
background: #e9edf2;
}
.task-tbl .tr.task-ontime > .td.task,
.task-tbl .tr.task-overdue > .td.task {
position: relative;
padding-left: 20px;
}
.task-tbl .tr.task-ontime > .td.task::before,
.task-tbl .tr.task-overdue > .td.task::before {
content: "";
position: absolute;
top: 12px;
left: 5px;
width: 10px;
height: 10px;
background-color: #a0c367;
border-radius: 10px;
z-index: 1;
}
.task-tbl .tr.task-overdue > .td.task::before {
background-color: #ff0000;
}
/*----------------table-list end----------------*/
/*--------------Окно сообщения об ошибке--------------*/
.webbpm #toast-container {
font-size: 12px;
bottom: auto;
overflow-y: auto;
overflow-x: hidden;
max-height: 95%;
}
.webbpm #toast-container .toast:hover {
box-shadow: 0 0 12px #999999;
}
.webbpm #toast-container .ngx-toastr {
min-width: 540px;
opacity: 0.9;
}
.webbpm #toast-container .toast-error {
background-color: #d9534f;
}
.webbpm #toast-container .toast-close-button {
text-shadow: none;
}
.webbpm .toast-message > div {
display: none;
}
.webbpm .toast-message > .active {
display: block;
}
.webbpm .toast-message > .active::after {
display: block;
content: "";
float: none;
clear: both;
}
.webbpm .toast-message > .active a {
float: right;
margin: 5px 0;
}
.webbpm .toast-message > .toast-msg-close.active ~ .toast-msg-text {
display: block;
font-size: 0.8em;
}
.webbpm .toast-message a:not([href]):not([tabindex]) {
text-decoration: underline;
}
/*------------Окно сообщения об ошибке end------------*/
/*----------------- Ошибка 404 -------------------*/
.webbpm .container .task-not-found-page {
position: relative;
display: table;
width: 100%;
height: 100%;
}
.webbpm .container .task-not-found-container {
display: table-cell;
color: var(--black);
font-size: 1.8em;
background-color: #c9d4e0;
text-align: center;
vertical-align: middle;
}
.webbpm .container .task-not-found-container > div {
display: inline-block;
}
.webbpm .container .task-not-found-container > div:first-child {
color: var(--white);
font-size: 7.8em;
font-weight: bold;
}
.webbpm .container .task-not-found-container > div:last-child {
text-align: left;
margin-left: 40px;
}
.webbpm .container .task-not-found-container h2 {
font-size: 2em;
margin-bottom: 10px;
}
.webbpm .container .task-not-found-container a {
cursor: pointer;
}
/*--------------- end Ошибка 404 -----------------*/
/*-------------- MOBILE --------------*/
.webbpm.mobile .task-list-tree-panel,
.webbpm.mobile footer {
display: none;
}
.webbpm.mobile .task-list-workplace {
margin-left: 0;
}
.webbpm.mobile .container {
bottom: 0;
}
.webbpm.mobile form {
overflow: hidden;
}
.webbpm.mobile .form-signin {
width: auto;
padding: 20px;
margin: 40px 20px;
border-radius: 4px;
}
.webbpm.mobile .form-signin h1,
.webbpm.mobile .form-signin h2 {
margin-left: 0;
}
.webbpm.mobile .form-signin label {
text-align: left;
}
.webbpm.mobile .form-signin input[type="text"],
.webbpm.mobile .form-signin input[type="password"] {
width: 100%;
}
.webbpm.mobile .form-signin .login-btn-box {
width: auto;
margin-right: 0;
}
/*-------------- end MOBILE --------------*/
/*-------------- НОВЫЙ ДИЗАЙН --------------*/
/*------------------ Фильтры ------------------*/
.webbpm .task-list {
height: auto;
min-height: auto;
}
.webbpm .task-list > .task-list-tree-panel {
background: var(--white);
border-right: 0;
}
.webbpm .task-list > .task-list-tree-panel,
.webbpm .task-list > .task-list-workplace {
font-size: var(--size-text-secondary);
float: none;
width: 100%;
height: auto;
min-height: auto;
}
.webbpm .task-list-tree-panel .task-list-filter {
font-family: Corbel;
margin: 0;
box-shadow: 0px 4px 10px -5px rgba(40, 40, 40, 0.3);
ul {
margin: 0;
}
li {
display: inline-block;
padding: 12px 0px;
margin: 0;
&:first-of-type {
font-size: 1.4em;
font-weight: bold;
width: 197px;
padding: 0 15px;
}
&::before {
display: none;
}
label {
font-size: 1.3em;
font-weight: normal;
}
label div {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 10px;
margin-right: 8px;
}
&.ontime label div {
background-color: #2da6a1;
}
&.overdue label div {
background-color: #9c5d7a;
}
label input[type="radio"] {
float: none;
display: none;
}
label span {
float: none;
color: var(--black);
font-weight: normal;
text-align: left;
min-width: auto;
padding: 5px 15px;
border-radius: 0;
background-color: transparent;
}
label input[type="radio"].ng-valid-parse ~ span {
background-color: #eaedf2;
}
}
}
/*-------------- end НОВЫЙ ДИЗАЙН --------------*/
.webbpm .dialog-stack-trace {
overflow-x: auto;
overflow-y: auto;
max-height: 300px;
}
.webbpm .dialog-show-button {
text-decoration: underline;
cursor: pointer;
}
.webbpm .dialog-error-number {
font-size: 1.25rem;
}
.webbpm .dialog-error-title {
font-size: 1rem;
}
/*-- login --*/
.webbpm :is(.form-signin, .form-signup, .confirm) {
color: #333;
width: 580px;
padding: 80px 100px;
margin: 20px auto;
border: 1px solid var(--bg-light);
background: var(--white);
}
.webbpm .form-signin.esia {
width: 450px;
text-align: center;
padding: 45px 55px 35px 55px;
}
.webbpm .form-signin h1,
.webbpm .form-signin h2,
.webbpm .form-signup h2,
.webbpm .confirm h2 {
text-align: center;
margin-bottom: 20px;
}
.webbpm .form-signin.esia :is(h1, h2) {
margin-left: 0;
}
.webbpm .form-signin label,
.webbpm .form-signup label {
margin-bottom: 0;
}
.webbpm .form-signin input {
width: 240px;
font-size: var(--size-text-secondary);
display: inline-block;
}
.webbpm .form-signin.esia input {
width: 160px;
margin-top: 40px;
}
.webbpm :is(.form-signin, .form-signup) .row {
display: flex;
margin: 0 0 20px;
}
.webbpm .registration-link,
.webbpm .login-link {
margin-right: 20px;
font-size: var(--size-text-secondary);
}
.webbpm .form-signin .row.registration {
flex-direction: row;
}
.webbpm .form-signin .login-btn-box {
display: flex;
flex-direction: row;
align-items: center;
}
.webbpm .form-signin .row.registration > * + *,
.webbpm .form-signin .login-btn-box .password,
.webbpm .form-signin .login-btn-box .btn + .btn {
margin-left: 10px;
}
.webbpm .input-group > .input-group-append > .input-group-text {
border-radius: 0;
}
.webbpm .form-signin .register-btn-box,
.webbpm .form-signup .register-btn-box,
.webbpm .form-signup .reset-password-btn-box {
width: 220px;
}
.webbpm .form-signup .row international-phone-number .flagInput .btn {
border-left: 1px solid #c6cdd3;
}
.webbpm .form-signup .row international-phone-number .flagInput ~ input {
border-left: none;
}
.webbpm .form-signin .has-error .help-block {
padding-left: 125px;
font-size: var(--size-text-secondary);
}
.webbpm .form-signup .has-account a {
margin-left: 10px;
}
/*------------------ Формы регистрации и подтверждения ------------------*/
.form-signup .has-account {
flex-direction: row;
}
.form-signup .has-account a span,
.confirm a span {
margin-right: 4px;
}
.form-signup .dropbtn.btn {
margin-bottom: 0;
}
.form-signup .input-group-text {
border-left-width: 0;
}
.form-signup input.ng-invalid.ng-touched,
.form-signup input.ng-invalid.ng-dirty {
border-color: red !important;
}
.form-signup .msg-alert {
color: red;
font-size: 11px;
padding: 3px 0 0;
}
.form-signup .consent {
color: #929292;
font-size: 13px;
margin-top: 20px;
}
/*------------------ End - Формы регистрации и подтверждения ------------------*/
/*------------------ Сообщения об ошибке ------------------*/
.webbpm .error_message {
width: 650px;
margin: 0 auto;
margin-top: 10%;
}
.webbpm .error_title {
position: relative;
color: #9c5d7a;
font-size: 5.5em;
font-weight: bold;
margin-left: 100px;
line-height: 1;
}
.webbpm .error_title::before {
position: absolute;
content: "";
left: -100px;
width: 75px;
height: 75px;
border-radius: 40px;
background-color: #9c5d7a;
background-image: url("../img/access_denied.png");
background-repeat: no-repeat;
background-position: 50% 50%;
}
.webbpm .error_title_long {
margin-bottom: 20px;
font-size: 2.5em;
}
.webbpm .error_body {
font-size: 2em;
line-height: 1.2;
margin: 5px 0 0 100px;
}
/*---------------- end Сообщения об ошибке ---------------*/
/*-------------- Поле телефона ------------ */
.flag {
background-image: url('./../img/country-flags.jpg') !important;
}
/*-------------- end Поле телефона ------------ */

View file

@ -0,0 +1,12 @@
@import "../../../node_modules/angular-calendar/css/angular-calendar.css";
@import "../../../node_modules/bootstrap/dist/css/bootstrap-grid.css";
@import "../../../node_modules/bootstrap/dist/css/bootstrap-reboot.css";
@import "../../../node_modules/bootstrap/dist/css/bootstrap.css";
@import "../../../node_modules/bootstrap-icons/font/bootstrap-icons.css";
@import "../../../node_modules/font-awesome/css/font-awesome.css";
@import "../../../node_modules/@webbpm/base-package/css/style.css";
@import "structure.css";
@import "inbox-app.css";
@import "components-app.css";
@import "inbox-autority.css";
@import "components-autority.css";

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

View file

@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_340_5833)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.5 3.75C6.5 4.16421 6.16421 4.5 5.75 4.5C5.33579 4.5 5 4.16421 5 3.75C5 3.33579 5.33579 3 5.75 3C6.16421 3 6.5 3.33579 6.5 3.75ZM11 3.75C11 4.16421 10.6642 4.5 10.25 4.5C9.83579 4.5 9.5 4.16421 9.5 3.75C9.5 3.33579 9.83579 3 10.25 3C10.6642 3 11 3.33579 11 3.75ZM5.75 8.75C6.16421 8.75 6.5 8.41421 6.5 8C6.5 7.58579 6.16421 7.25 5.75 7.25C5.33579 7.25 5 7.58579 5 8C5 8.41421 5.33579 8.75 5.75 8.75ZM11 8C11 8.41421 10.6642 8.75 10.25 8.75C9.83579 8.75 9.5 8.41421 9.5 8C9.5 7.58579 9.83579 7.25 10.25 7.25C10.6642 7.25 11 7.58579 11 8ZM5.75 13C6.16421 13 6.5 12.6642 6.5 12.25C6.5 11.8358 6.16421 11.5 5.75 11.5C5.33579 11.5 5 11.8358 5 12.25C5 12.6642 5.33579 13 5.75 13ZM11 12.25C11 12.6642 10.6642 13 10.25 13C9.83579 13 9.5 12.6642 9.5 12.25C9.5 11.8358 9.83579 11.5 10.25 11.5C10.6642 11.5 11 11.8358 11 12.25Z" fill="#353535"/>
</g>
<defs>
<clipPath id="clip0_340_5833">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.4289 4.03093L14.5357 3.84641C14.7628 3.46915 15.2354 3.35853 15.5798 3.56346L15.593 3.57113L17.3235 4.56141C17.7982 4.83272 17.9624 5.4493 17.6908 5.91957C17.1401 6.8701 16.9763 7.94135 17.4902 8.83311C18.0042 9.72502 19.0132 10.12 20.11 10.12C20.656 10.12 21.11 10.5701 21.11 11.12V12.88C21.11 13.426 20.6598 13.88 20.11 13.88C19.0132 13.88 18.0042 14.275 17.4902 15.1669C16.9767 16.058 17.1399 17.1284 17.6896 18.0784C17.9642 18.5612 17.7961 19.1685 17.323 19.4389L15.593 20.4289L15.5798 20.4365C15.2354 20.6415 14.7628 20.5308 14.5357 20.1536L14.4308 19.9724L14.4297 19.9706C13.8837 19.0191 13.0383 18.3425 12.0087 18.3425C10.9799 18.3425 10.1319 19.0187 9.58109 19.9691L9.47424 20.1536C9.24711 20.5308 8.77457 20.6414 8.43014 20.4365L8.41699 20.4289L6.6865 19.4386C6.21174 19.1673 6.04759 18.5507 6.31911 18.0805C6.8698 17.1299 7.03367 16.0587 6.51976 15.1669C6.00578 14.275 4.99672 13.88 3.89998 13.88C3.35011 13.88 2.89998 13.426 2.89998 12.88V11.12C2.89998 10.574 3.35011 10.12 3.89998 10.12C4.99672 10.12 6.00578 9.72502 6.51976 8.83311C7.03367 7.94133 6.8698 6.87005 6.31911 5.9195C6.04759 5.44924 6.21222 4.83243 6.68699 4.56113L8.41699 3.57113L8.43014 3.56346C8.77458 3.35854 9.24714 3.46915 9.47426 3.8464L9.58016 4.02932C10.1262 4.98086 10.9716 5.65749 12.0012 5.65749C13.03 5.65749 13.878 4.9813 14.4289 4.03093ZM6.31911 5.9195C6.31895 5.91922 6.31879 5.91894 6.31863 5.91867L5.53998 6.36999L6.31925 5.91974C6.31921 5.91966 6.31916 5.91958 6.31911 5.9195ZM17.6896 18.0784C17.6902 18.0794 17.6908 18.0804 17.6913 18.0813L18.47 17.63L17.6886 18.0765C17.6889 18.0772 17.6893 18.0778 17.6896 18.0784ZM12.9865 2.92983C13.6989 1.73245 15.2596 1.28388 16.4929 2.01224L18.217 2.99885C19.5618 3.76765 20.0174 5.49069 19.2493 6.82024L19.2486 6.82132C18.8897 7.44056 18.9688 7.79392 19.0498 7.93437C19.1308 8.07497 19.3967 8.31999 20.11 8.31999C21.6439 8.31999 22.91 9.56986 22.91 11.12V12.88C22.91 14.414 21.6601 15.68 20.11 15.68C19.3967 15.68 19.1308 15.925 19.0498 16.0656C18.9688 16.2061 18.8897 16.5594 19.2486 17.1787L19.2514 17.1835C20.0153 18.5204 19.5627 20.2321 18.2165 21.0014L16.4929 21.9878C15.2596 22.7161 13.6989 22.2675 12.9865 21.0702L12.9811 21.0609L12.8711 20.8709L12.8692 20.8676C12.5152 20.25 12.171 20.1425 12.0087 20.1425C11.8451 20.1425 11.4977 20.252 11.1386 20.8713L11.0234 21.0702C10.3111 22.2675 8.75036 22.7161 7.51707 21.9878L5.79345 21.0014C4.4483 20.2328 3.99242 18.5095 4.7607 17.1797L4.76132 17.1787C5.12024 16.5594 5.04113 16.2061 4.96019 16.0656C4.87917 15.925 4.61323 15.68 3.89998 15.68C2.34984 15.68 1.09998 14.414 1.09998 12.88V11.12C1.09998 9.58602 2.34984 8.31999 3.89998 8.31999C4.61323 8.31999 4.87917 8.07497 4.96019 7.93437C5.04113 7.79392 5.12024 7.44056 4.76132 6.82132L4.7607 6.82024C3.99251 5.49069 4.44867 3.76737 5.79345 2.99857L7.51705 2.01224C8.75034 1.28388 10.3111 1.73245 11.0234 2.92983L11.0289 2.93906L11.1408 3.1324C11.4948 3.74995 11.8389 3.85749 12.0012 3.85749C12.1649 3.85749 12.5122 3.74829 12.8713 3.12867L12.9865 2.92983ZM9.89998 12C9.89998 10.8402 10.8402 9.89998 12 9.89998C13.1598 9.89998 14.1 10.8402 14.1 12C14.1 13.1598 13.1598 14.1 12 14.1C10.8402 14.1 9.89998 13.1598 9.89998 12ZM12 8.09998C9.84607 8.09998 8.09998 9.84607 8.09998 12C8.09998 14.1539 9.84607 15.9 12 15.9C14.1539 15.9 15.9 14.1539 15.9 12C15.9 9.84607 14.1539 8.09998 12 8.09998Z" fill="#353535"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

View file

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.29537 10.7195C5.90154 10.3261 5.90154 9.68836 6.29537 9.29501C6.68919 8.90166 7.3277 8.90166 7.72152 9.29501L12.7131 14.2805C13.1069 14.6739 13.1069 15.3116 12.7131 15.705C12.3193 16.0983 11.6807 16.0983 11.2869 15.705L6.29537 10.7195Z" fill="white"/>
<path d="M16.2785 9.29516C16.6723 8.90181 17.3108 8.90181 17.7046 9.29516C18.0985 9.68851 18.0985 10.3263 17.7046 10.7196L12.7131 15.705C12.3193 16.0983 11.6807 16.0983 11.2869 15.705C10.8931 15.3116 10.8931 14.674 11.2869 14.2807L16.2785 9.29516Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 631 B

View file

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 19H6C5.20435 19 4.44129 18.6839 3.87868 18.1213C3.31607 17.5587 3 16.7956 3 16V8C3 7.73478 2.89464 7.48043 2.70711 7.29289C2.51957 7.10536 2.26522 7 2 7C1.73478 7 1.48043 7.10536 1.29289 7.29289C1.10536 7.48043 1 7.73478 1 8V16C1 17.3261 1.52678 18.5979 2.46447 19.5355C2.92876 19.9998 3.47995 20.3681 4.08658 20.6194C4.69321 20.8707 5.34339 21 6 21H18C18.2652 21 18.5196 20.8946 18.7071 20.7071C18.8946 20.5196 19 20.2652 19 20C19 19.7348 18.8946 19.4804 18.7071 19.2929C18.5196 19.1054 18.2652 19 18 19ZM14 11H10C9.73478 11 9.48043 11.1054 9.29289 11.2929C9.10536 11.4804 9 11.7348 9 12C9 12.2652 9.10536 12.5196 9.29289 12.7071C9.48043 12.8946 9.73478 13 10 13H14C14.2652 13 14.5196 12.8946 14.7071 12.7071C14.8946 12.5196 15 12.2652 15 12C15 11.7348 14.8946 11.4804 14.7071 11.2929C14.5196 11.1054 14.2652 11 14 11ZM23 9.94C22.9896 9.84813 22.9695 9.75763 22.94 9.67V9.58C22.8919 9.47718 22.8278 9.38267 22.75 9.3L16.75 3.3C16.6673 3.22222 16.5728 3.15808 16.47 3.11H16.38C16.2784 3.05174 16.1662 3.01434 16.05 3H8C7.20435 3 6.44129 3.31607 5.87868 3.87868C5.31607 4.44129 5 5.20435 5 6V14C5 14.7956 5.31607 15.5587 5.87868 16.1213C6.44129 16.6839 7.20435 17 8 17H20C20.7956 17 21.5587 16.6839 22.1213 16.1213C22.6839 15.5587 23 14.7956 23 14V10C23 10 23 10 23 9.94ZM17 6.41L19.59 9H18C17.7348 9 17.4804 8.89464 17.2929 8.70711C17.1054 8.51957 17 8.26522 17 8V6.41ZM21 14C21 14.2652 20.8946 14.5196 20.7071 14.7071C20.5196 14.8946 20.2652 15 20 15H8C7.73478 15 7.48043 14.8946 7.29289 14.7071C7.10536 14.5196 7 14.2652 7 14V6C7 5.73478 7.10536 5.48043 7.29289 5.29289C7.48043 5.10536 7.73478 5 8 5H15V8C15 8.79565 15.3161 9.55871 15.8787 10.1213C16.4413 10.6839 17.2044 11 18 11H21V14ZM10 9H12C12.2652 9 12.5196 8.89464 12.7071 8.70711C12.8946 8.51957 13 8.26522 13 8C13 7.73478 12.8946 7.48043 12.7071 7.29289C12.5196 7.10536 12.2652 7 12 7H10C9.73478 7 9.48043 7.10536 9.29289 7.29289C9.10536 7.48043 9 7.73478 9 8C9 8.26522 9.10536 8.51957 9.29289 8.70711C9.48043 8.89464 9.73478 9 10 9Z" fill="#C64E1B"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 12C4 12.2652 4.10536 12.5196 4.29289 12.7071C4.48043 12.8946 4.73478 13 5 13H12.59L10.29 15.29C10.1963 15.383 10.1219 15.4936 10.0711 15.6154C10.0203 15.7373 9.9942 15.868 9.9942 16C9.9942 16.132 10.0203 16.2627 10.0711 16.3846C10.1219 16.5064 10.1963 16.617 10.29 16.71C10.383 16.8037 10.4936 16.8781 10.6154 16.9289C10.7373 16.9797 10.868 17.0058 11 17.0058C11.132 17.0058 11.2627 16.9797 11.3846 16.9289C11.5064 16.8781 11.617 16.8037 11.71 16.71L15.71 12.71C15.801 12.6149 15.8724 12.5028 15.92 12.38C16.02 12.1365 16.02 11.8635 15.92 11.62C15.8724 11.4972 15.801 11.3851 15.71 11.29L11.71 7.29C11.6168 7.19676 11.5061 7.1228 11.3842 7.07234C11.2624 7.02188 11.1319 6.99591 11 6.99591C10.8681 6.99591 10.7376 7.02188 10.6158 7.07234C10.4939 7.1228 10.3832 7.19676 10.29 7.29C10.1968 7.38324 10.1228 7.49393 10.0723 7.61575C10.0219 7.73757 9.99591 7.86814 9.99591 8C9.99591 8.13186 10.0219 8.26243 10.0723 8.38425C10.1228 8.50607 10.1968 8.61676 10.29 8.71L12.59 11H5C4.73478 11 4.48043 11.1054 4.29289 11.2929C4.10536 11.4804 4 11.7348 4 12ZM17 2H7C6.20435 2 5.44129 2.31607 4.87868 2.87868C4.31607 3.44129 4 4.20435 4 5V8C4 8.26522 4.10536 8.51957 4.29289 8.70711C4.48043 8.89464 4.73478 9 5 9C5.26522 9 5.51957 8.89464 5.70711 8.70711C5.89464 8.51957 6 8.26522 6 8V5C6 4.73478 6.10536 4.48043 6.29289 4.29289C6.48043 4.10536 6.73478 4 7 4H17C17.2652 4 17.5196 4.10536 17.7071 4.29289C17.8946 4.48043 18 4.73478 18 5V19C18 19.2652 17.8946 19.5196 17.7071 19.7071C17.5196 19.8946 17.2652 20 17 20H7C6.73478 20 6.48043 19.8946 6.29289 19.7071C6.10536 19.5196 6 19.2652 6 19V16C6 15.7348 5.89464 15.4804 5.70711 15.2929C5.51957 15.1054 5.26522 15 5 15C4.73478 15 4.48043 15.1054 4.29289 15.2929C4.10536 15.4804 4 15.7348 4 16V19C4 19.7956 4.31607 20.5587 4.87868 21.1213C5.44129 21.6839 6.20435 22 7 22H17C17.7956 22 18.5587 21.6839 19.1213 21.1213C19.6839 20.5587 20 19.7956 20 19V5C20 4.20435 19.6839 3.44129 19.1213 2.87868C18.5587 2.31607 17.7956 2 17 2Z" fill="#C64E1B"/>
</svg>

After

Width:  |  Height:  |  Size: 2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 464 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 464 KiB

View file

@ -0,0 +1,3 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M36 38H12C10.4087 38 8.88258 37.3679 7.75736 36.2426C6.63214 35.1174 6 33.5913 6 32V16C6 15.4696 5.78929 14.9609 5.41421 14.5858C5.03914 14.2107 4.53043 14 4 14C3.46957 14 2.96086 14.2107 2.58579 14.5858C2.21071 14.9609 2 15.4696 2 16V32C2 34.6522 3.05357 37.1957 4.92893 39.0711C5.85752 39.9997 6.95991 40.7362 8.17317 41.2388C9.38642 41.7413 10.6868 42 12 42H36C36.5304 42 37.0391 41.7893 37.4142 41.4142C37.7893 41.0391 38 40.5304 38 40C38 39.4696 37.7893 38.9609 37.4142 38.5858C37.0391 38.2107 36.5304 38 36 38ZM28 22H20C19.4696 22 18.9609 22.2107 18.5858 22.5858C18.2107 22.9609 18 23.4696 18 24C18 24.5304 18.2107 25.0391 18.5858 25.4142C18.9609 25.7893 19.4696 26 20 26H28C28.5304 26 29.0391 25.7893 29.4142 25.4142C29.7893 25.0391 30 24.5304 30 24C30 23.4696 29.7893 22.9609 29.4142 22.5858C29.0391 22.2107 28.5304 22 28 22ZM46 19.88C45.9792 19.6963 45.9389 19.5153 45.88 19.34V19.16C45.7838 18.9544 45.6556 18.7653 45.5 18.6L33.5 6.6C33.3347 6.44443 33.1456 6.31616 32.94 6.22H32.76C32.5568 6.10348 32.3324 6.02869 32.1 6H16C14.4087 6 12.8826 6.63214 11.7574 7.75736C10.6321 8.88258 10 10.4087 10 12V28C10 29.5913 10.6321 31.1174 11.7574 32.2426C12.8826 33.3679 14.4087 34 16 34H40C41.5913 34 43.1174 33.3679 44.2426 32.2426C45.3679 31.1174 46 29.5913 46 28V20C46 20 46 20 46 19.88ZM34 12.82L39.18 18H36C35.4696 18 34.9609 17.7893 34.5858 17.4142C34.2107 17.0391 34 16.5304 34 16V12.82ZM42 28C42 28.5304 41.7893 29.0391 41.4142 29.4142C41.0391 29.7893 40.5304 30 40 30H16C15.4696 30 14.9609 29.7893 14.5858 29.4142C14.2107 29.0391 14 28.5304 14 28V12C14 11.4696 14.2107 10.9609 14.5858 10.5858C14.9609 10.2107 15.4696 10 16 10H30V16C30 17.5913 30.6321 19.1174 31.7574 20.2426C32.8826 21.3679 34.4087 22 36 22H42V28ZM20 18H24C24.5304 18 25.0391 17.7893 25.4142 17.4142C25.7893 17.0391 26 16.5304 26 16C26 15.4696 25.7893 14.9609 25.4142 14.5858C25.0391 14.2107 24.5304 14 24 14H20C19.4696 14 18.9609 14.2107 18.5858 14.5858C18.2107 14.9609 18 15.4696 18 16C18 16.5304 18.2107 17.0391 18.5858 17.4142C18.9609 17.7893 19.4696 18 20 18Z" fill="#1D1E21"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -0,0 +1,3 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M36 38H12C10.4087 38 8.88258 37.3679 7.75736 36.2426C6.63214 35.1174 6 33.5913 6 32V16C6 15.4696 5.78929 14.9609 5.41421 14.5858C5.03914 14.2107 4.53043 14 4 14C3.46957 14 2.96086 14.2107 2.58579 14.5858C2.21071 14.9609 2 15.4696 2 16V32C2 34.6522 3.05357 37.1957 4.92893 39.0711C5.85752 39.9997 6.95991 40.7362 8.17317 41.2388C9.38642 41.7413 10.6868 42 12 42H36C36.5304 42 37.0391 41.7893 37.4142 41.4142C37.7893 41.0391 38 40.5304 38 40C38 39.4696 37.7893 38.9609 37.4142 38.5858C37.0391 38.2107 36.5304 38 36 38ZM28 22H20C19.4696 22 18.9609 22.2107 18.5858 22.5858C18.2107 22.9609 18 23.4696 18 24C18 24.5304 18.2107 25.0391 18.5858 25.4142C18.9609 25.7893 19.4696 26 20 26H28C28.5304 26 29.0391 25.7893 29.4142 25.4142C29.7893 25.0391 30 24.5304 30 24C30 23.4696 29.7893 22.9609 29.4142 22.5858C29.0391 22.2107 28.5304 22 28 22ZM46 19.88C45.9792 19.6963 45.9389 19.5153 45.88 19.34V19.16C45.7838 18.9544 45.6556 18.7653 45.5 18.6L33.5 6.6C33.3347 6.44443 33.1456 6.31616 32.94 6.22H32.76C32.5568 6.10348 32.3324 6.02869 32.1 6H16C14.4087 6 12.8826 6.63214 11.7574 7.75736C10.6321 8.88258 10 10.4087 10 12V28C10 29.5913 10.6321 31.1174 11.7574 32.2426C12.8826 33.3679 14.4087 34 16 34H40C41.5913 34 43.1174 33.3679 44.2426 32.2426C45.3679 31.1174 46 29.5913 46 28V20C46 20 46 20 46 19.88ZM34 12.82L39.18 18H36C35.4696 18 34.9609 17.7893 34.5858 17.4142C34.2107 17.0391 34 16.5304 34 16V12.82ZM42 28C42 28.5304 41.7893 29.0391 41.4142 29.4142C41.0391 29.7893 40.5304 30 40 30H16C15.4696 30 14.9609 29.7893 14.5858 29.4142C14.2107 29.0391 14 28.5304 14 28V12C14 11.4696 14.2107 10.9609 14.5858 10.5858C14.9609 10.2107 15.4696 10 16 10H30V16C30 17.5913 30.6321 19.1174 31.7574 20.2426C32.8826 21.3679 34.4087 22 36 22H42V28ZM20 18H24C24.5304 18 25.0391 17.7893 25.4142 17.4142C25.7893 17.0391 26 16.5304 26 16C26 15.4696 25.7893 14.9609 25.4142 14.5858C25.0391 14.2107 24.5304 14 24 14H20C19.4696 14 18.9609 14.2107 18.5858 14.5858C18.2107 14.9609 18 15.4696 18 16C18 16.5304 18.2107 17.0391 18.5858 17.4142C18.9609 17.7893 19.4696 18 20 18Z" fill="#FA773F"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="11.7673" cy="8.4382" r="4.4382" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.6503 13.9199C14.8934 15.2849 13.4378 16.2089 11.7663 16.2089C10.0951 16.2089 8.63959 15.2851 7.88257 13.9204C7.3 14.2568 6.75879 14.6703 6.27486 15.1542C4.81829 16.6108 4 18.5863 4 20.6462L11.7668 20.6462H19.5337C19.5337 18.5863 18.7154 16.6108 17.2588 15.1542C16.7747 14.6701 16.2332 14.2564 15.6503 13.9199Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 541 B

View file

@ -0,0 +1,3 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24.6 24.44C25.6672 23.5163 26.5231 22.3738 27.1097 21.09C27.6964 19.8063 28 18.4114 28 17C28 14.3478 26.9464 11.8043 25.0711 9.92893C23.1957 8.05357 20.6522 7 18 7C15.3478 7 12.8043 8.05357 10.9289 9.92893C9.05357 11.8043 8 14.3478 8 17C7.99998 18.4114 8.3036 19.8063 8.89025 21.09C9.4769 22.3738 10.3328 23.5163 11.4 24.44C8.60028 25.7078 6.22493 27.7551 4.55796 30.3371C2.89099 32.9191 2.00294 35.9266 2 39C2 39.5304 2.21071 40.0391 2.58579 40.4142C2.96086 40.7893 3.46957 41 4 41C4.53043 41 5.03914 40.7893 5.41421 40.4142C5.78929 40.0391 6 39.5304 6 39C6 35.8174 7.26428 32.7652 9.51472 30.5147C11.7652 28.2643 14.8174 27 18 27C21.1826 27 24.2348 28.2643 26.4853 30.5147C28.7357 32.7652 30 35.8174 30 39C30 39.5304 30.2107 40.0391 30.5858 40.4142C30.9609 40.7893 31.4696 41 32 41C32.5304 41 33.0391 40.7893 33.4142 40.4142C33.7893 40.0391 34 39.5304 34 39C33.9971 35.9266 33.109 32.9191 31.442 30.3371C29.7751 27.7551 27.3997 25.7078 24.6 24.44ZM18 23C16.8133 23 15.6533 22.6481 14.6666 21.9888C13.6799 21.3295 12.9108 20.3925 12.4567 19.2961C12.0026 18.1997 11.8838 16.9933 12.1153 15.8295C12.3468 14.6656 12.9182 13.5965 13.7574 12.7574C14.5965 11.9182 15.6656 11.3468 16.8295 11.1153C17.9933 10.8838 19.1997 11.0026 20.2961 11.4567C21.3925 11.9108 22.3295 12.6799 22.9888 13.6666C23.6481 14.6533 24 15.8133 24 17C24 18.5913 23.3679 20.1174 22.2426 21.2426C21.1174 22.3679 19.5913 23 18 23ZM37.48 23.64C38.7599 22.1987 39.596 20.4181 39.8876 18.5127C40.1792 16.6072 39.9139 14.6581 39.1235 12.9C38.3332 11.1419 37.0516 9.64959 35.4329 8.60285C33.8143 7.5561 31.9276 6.99948 30 7C29.4696 7 28.9609 7.21071 28.5858 7.58579C28.2107 7.96086 28 8.46957 28 9C28 9.53043 28.2107 10.0391 28.5858 10.4142C28.9609 10.7893 29.4696 11 30 11C31.5913 11 33.1174 11.6321 34.2426 12.7574C35.3679 13.8826 36 15.4087 36 17C35.9972 18.0505 35.7186 19.0818 35.1921 19.9908C34.6657 20.8999 33.9097 21.6548 33 22.18C32.7035 22.351 32.4558 22.5953 32.2807 22.8895C32.1056 23.1836 32.009 23.5178 32 23.86C31.9916 24.1995 32.0699 24.5356 32.2273 24.8365C32.3848 25.1374 32.6163 25.3933 32.9 25.58L33.68 26.1L33.94 26.24C36.3508 27.3834 38.3846 29.192 39.802 31.4526C41.2193 33.7133 41.9611 36.3319 41.94 39C41.94 39.5304 42.1507 40.0391 42.5258 40.4142C42.9009 40.7893 43.4096 41 43.94 41C44.4704 41 44.9791 40.7893 45.3542 40.4142C45.7293 40.0391 45.94 39.5304 45.94 39C45.9563 35.9309 45.1876 32.9085 43.7069 30.2201C42.2262 27.5317 40.0827 25.2666 37.48 23.64Z" fill="#1D1E21"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -0,0 +1,3 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24.6 24.44C25.6672 23.5163 26.5231 22.3738 27.1097 21.09C27.6964 19.8063 28 18.4114 28 17C28 14.3478 26.9464 11.8043 25.0711 9.92893C23.1957 8.05357 20.6522 7 18 7C15.3478 7 12.8043 8.05357 10.9289 9.92893C9.05357 11.8043 8 14.3478 8 17C7.99998 18.4114 8.3036 19.8063 8.89025 21.09C9.4769 22.3738 10.3328 23.5163 11.4 24.44C8.60028 25.7078 6.22493 27.7551 4.55796 30.3371C2.89099 32.9191 2.00294 35.9266 2 39C2 39.5304 2.21071 40.0391 2.58579 40.4142C2.96086 40.7893 3.46957 41 4 41C4.53043 41 5.03914 40.7893 5.41421 40.4142C5.78929 40.0391 6 39.5304 6 39C6 35.8174 7.26428 32.7652 9.51472 30.5147C11.7652 28.2643 14.8174 27 18 27C21.1826 27 24.2348 28.2643 26.4853 30.5147C28.7357 32.7652 30 35.8174 30 39C30 39.5304 30.2107 40.0391 30.5858 40.4142C30.9609 40.7893 31.4696 41 32 41C32.5304 41 33.0391 40.7893 33.4142 40.4142C33.7893 40.0391 34 39.5304 34 39C33.9971 35.9266 33.109 32.9191 31.442 30.3371C29.7751 27.7551 27.3997 25.7078 24.6 24.44ZM18 23C16.8133 23 15.6533 22.6481 14.6666 21.9888C13.6799 21.3295 12.9108 20.3925 12.4567 19.2961C12.0026 18.1997 11.8838 16.9933 12.1153 15.8295C12.3468 14.6656 12.9182 13.5965 13.7574 12.7574C14.5965 11.9182 15.6656 11.3468 16.8295 11.1153C17.9933 10.8838 19.1997 11.0026 20.2961 11.4567C21.3925 11.9108 22.3295 12.6799 22.9888 13.6666C23.6481 14.6533 24 15.8133 24 17C24 18.5913 23.3679 20.1174 22.2426 21.2426C21.1174 22.3679 19.5913 23 18 23ZM37.48 23.64C38.7599 22.1987 39.596 20.4181 39.8876 18.5127C40.1792 16.6072 39.9139 14.6581 39.1235 12.9C38.3332 11.1419 37.0516 9.64959 35.4329 8.60285C33.8143 7.5561 31.9276 6.99948 30 7C29.4696 7 28.9609 7.21071 28.5858 7.58579C28.2107 7.96086 28 8.46957 28 9C28 9.53043 28.2107 10.0391 28.5858 10.4142C28.9609 10.7893 29.4696 11 30 11C31.5913 11 33.1174 11.6321 34.2426 12.7574C35.3679 13.8826 36 15.4087 36 17C35.9972 18.0505 35.7186 19.0818 35.1921 19.9908C34.6657 20.8999 33.9097 21.6548 33 22.18C32.7035 22.351 32.4558 22.5953 32.2807 22.8895C32.1056 23.1836 32.009 23.5178 32 23.86C31.9916 24.1995 32.0699 24.5356 32.2273 24.8365C32.3848 25.1374 32.6163 25.3933 32.9 25.58L33.68 26.1L33.94 26.24C36.3508 27.3834 38.3846 29.192 39.802 31.4526C41.2193 33.7133 41.9611 36.3319 41.94 39C41.94 39.5304 42.1507 40.0391 42.5258 40.4142C42.9009 40.7893 43.4096 41 43.94 41C44.4704 41 44.9791 40.7893 45.3542 40.4142C45.7293 40.0391 45.94 39.5304 45.94 39C45.9563 35.9309 45.1876 32.9085 43.7069 30.2201C42.2262 27.5317 40.0827 25.2666 37.48 23.64Z" fill="#FA773F"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -0,0 +1,4 @@
<div class="error_message">
<div class="error_title">403</div>
<div class="error_body">Доступ запрещен</div>
</div>

View file

@ -0,0 +1,29 @@
<div *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.USER.LIST') ||
(currentSession | async)?.authorities.includes('USER_MANAGEMENT.GROUP.LIST') ||
(currentSession | async)?.authorities.includes('USER_MANAGEMENT.ROLE.LIST') ||
(currentSession | async)?.authorities.includes('USER_MANAGEMENT.ORG_UNIT.LIST') ||
(currentSession | async)?.authorities.includes('USER_MANAGEMENT.AUTHORITY.LIST')" ngbDropdown class="nav-item" [placement]="placement">
<button class="nav-link bi bi-gear-fill" id="adminDropdownMenu" ngbDropdownToggle title="Администрирование"></button>
<div ngbDropdownMenu aria-labelledby="adminDropdownMenu">
<button *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.USER.LIST')"
routerLink="/user-management/users" ngbDropdownItem>
Пользователи
</button>
<button *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.GROUP.LIST')"
routerLink="/user-management/groups" ngbDropdownItem>
Группы
</button>
<button *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.ROLE.LIST')"
routerLink="/user-management/roles" ngbDropdownItem>
Роли
</button>
<button *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.ORG_UNIT.LIST')"
routerLink="/user-management/org-units" ngbDropdownItem>
Организации
</button>
<button *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.AUTHORITY.LIST')"
routerLink="/user-management/authorities" ngbDropdownItem>
Безопасность действий
</button>
</div>
</div>

View file

@ -0,0 +1,4 @@
<footer>
<div id="webbpm-footer">
</div>
</footer>

View file

@ -0,0 +1,11 @@
<nav class="header" *ngIf="currentSession | async as session" id="webbpm-header">
<div class="header-logo">
<div class="logo"><a routerLink="/"></a></div>
<div class="main-page">ЦЕНТРАЛИЗОВАННОЕ УПРАВЛЕНИЕ УЧЕТНЫМИ ЗАПИСЯМИ</div>
</div>
<div class="header-menu">
<admin-menu [placement]="'bottom'"></admin-menu>
<div ngbDropdown class="logout" log-out></div>
</div>
</nav>

View file

@ -0,0 +1 @@
<span id="version-footer">Версия: {{applicationVersion}}</span>

View file

@ -0,0 +1,27 @@
<div class="confirm">
<div class="form-logo">
<div></div>
</div>
<div class="info">
<div>
<h2>Подтверждение почты</h2>
<div *ngIf="verificationStatus.toString() === 'VERIFYING'">
Подтверждение...
</div>
<div *ngIf="verificationStatus.toString() === 'VERIFIED'">
<div class="alert alert-success">
Адрес электронной почты успешно подтвержден
</div>
</div>
<div *ngIf="verificationStatus.toString() === 'FAILED'">
<div class="alert alert-danger">{{ errorMessage }}</div>
</div>
<div *ngIf="(currentSession | async) == null">
<a href="#/login"><span class="fa fa-lock"></span>Войти</a><br/>
<a href="#/registration">Зарегистрироваться</a>
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,9 @@
<button class="nav-link bi bi-person-fill" ngbDropdownToggle title="Пользователь"></button>
<div ngbDropdownMenu *ngIf="currentSession | async as session">
<div class="user-info">
<div class="user-fio">{{session.fullUserName}}</div>
<div class="user-login">{{session.username}}</div>
<div class="user-department">{{getOrgUnitName()}}</div>
</div>
<button ngbDropdownItem *ngIf="isLogoutButtonVisible()" (click)="logout()">Выход</button>
</div>

View file

@ -0,0 +1,49 @@
<div class="form-signin">
<form #formComponent="ngForm">
<div class="alert alert-success" [hidden]="!confirmationSent">На ваш почтовый адрес было отправлено письмо. Подтвердите почту, чтобы войти в систему
</div>
<div class="alert alert-danger" [hidden]="!errorMessage">{{errorMessage}}</div>
<div class="logo">
<h2>ЦЕНТРАЛИЗОВАННОЕ УПРАВЛЕНИЕ<br />УЧЕТНЫМИ ЗАПИСЯМИ</h2>
</div>
<div class="row">
<div class="input-group">
<input type="text" name="username" class="form-control" placeholder=" " required autofocus [(ngModel)]="username" maxlength="100">
<label>Логин</label>
</div>
</div>
<div class="row">
<div class="input-group">
<input
[type]="passwordType ? 'text' : 'password'"
name="password"
class="form-control field-password-view"
placeholder=" " required
[(ngModel)]="password"
maxlength="100"
>
<label>Пароль</label>
<div class="input-group-append">
<span class="input-group-text">
<i
(click)="togglePasswordType()"
class="fa"
[ngClass]="{
'fa-eye': passwordType,
'fa-eye-slash': !passwordType
}"
></i>
</span>
</div>
</div>
<div class="msg-text"><a href="#/reset-password">Восстановить пароль</a></div>
</div>
<div class="btn-box">
<!--<esia-login-button></esia-login-button>-->
<button type="submit" class="btn btn-primary" (click)="formComponent.form.valid && login()">Войти</button>
</div>
</form>
</div>

View file

@ -0,0 +1,103 @@
<div class="form-signup">
<div class="form-logo">
<div></div>
</div>
<div class="form-new-password">
<form #formComponent="ngForm">
<div [hidden]="!errorMessage" class="alert alert-danger">{{ errorMessage }}</div>
<p class="has-account">Вспомнили пароль?
<a href="#/login"><span class="fa fa-lock"></span>Войти</a></p>
<p class="has-account">Задайте новый пароль</p>
<div class="row">
<label>Пароль</label>
<div class="input-group">
<input
#passwordInput="ngModel"
[(ngModel)]="password"
[type]="passwordType ? 'text' : 'password'"
class="form-control"
maxlength="32"
minlength="6"
name="password"
pattern="^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]+$"
required
(change)="validPasswords()"
>
<div class="input-group-append">
<span class="input-group-text">
<i
(click)="togglePasswordType()"
class="fa"
[ngClass]="{
'fa-eye': passwordType,
'fa-eye-slash': !passwordType
}"
></i>
</span>
</div>
</div>
<div *ngIf="passwordInput.invalid && (passwordInput.dirty || passwordInput.touched)">
<div *ngIf="passwordInput.errors.required" class="msg-alert">Поле обязательно
</div>
<div *ngIf="passwordInput.errors.minlength" class="msg-alert">Пароль должен
содержать как минимум 6 символов
</div>
<div *ngIf="passwordInput.errors.pattern" class="msg-alert">Пароль должен
содержать заглавные и прописные буквы и как минимум 1 цифру
</div>
</div>
</div>
<div class="row">
<label>Подтверждение пароля</label>
<div class="input-group">
<input
#confirmPasswordInput="ngModel"
[(ngModel)]="confirmPassword"
[type]="confirmPasswordType ? 'text' : 'password'"
class="form-control"
maxlength="32"
minlength="6"
name="confirmPassword"
pattern="^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]+$"
required
(change)="validPasswords()"
>
<div class="input-group-append">
<span class="input-group-text">
<i
(click)="toggleConfirmPasswordType()"
class="fa"
[ngClass]="{
'fa-eye': confirmPasswordType,
'fa-eye-slash': !confirmPasswordType
}"
></i>
</span>
</div>
</div>
<div *ngIf="confirmPasswordInput.invalid && (confirmPasswordInput.dirty || confirmPasswordInput.touched)">
<div *ngIf="confirmPasswordInput.errors.required" class="msg-alert">Поле обязательно
</div>
<div *ngIf="confirmPasswordInput.errors.minlength" class="msg-alert">Пароль должен
содержать как минимум 6 символов
</div>
<div *ngIf="confirmPasswordInput.errors.pattern" class="msg-alert">Пароль должен
содержать заглавные и прописные буквы и как минимум 1 цифру
</div>
</div>
</div>
<div class="reset-password-btn-box">
<button
(click)="formComponent.form.valid && validPasswords() && changePassword()"
[disabled]="!formComponent.form.valid && !validPasswords()"
class="btn btn-primary"
type="submit"
>
Изменить пароль
</button>
</div>
</form>
</div>
</div>

View file

@ -0,0 +1,3 @@
<div class="modal-body">
<div class="progress"></div>
</div>

View file

@ -0,0 +1,121 @@
<div class="form-signup">
<div class="form-logo">
<div></div>
</div>
<div class="form-register">
<form #formComponent="ngForm">
<div [hidden]="!errorMessage" class="alert alert-danger">{{ errorMessage }}</div>
<h2>Регистрация</h2>
<p class="has-account">Уже зарегистрированы?
<a href="#/login"><span class="fa fa-lock"></span>Войти</a></p>
<div class="row">
<label>Имя</label>
<input
#name="ngModel"
[(ngModel)]="username"
class="form-control"
maxlength="100"
name="username"
required
type="text"
>
<div *ngIf="name.invalid && (name.dirty || name.touched)">
<div *ngIf="name.errors.required" class="msg-alert">Поле обязательно</div>
</div>
</div>
<div class="row">
<label>Адрес эл. почты</label>
<input
#emailInput="ngModel"
[(ngModel)]="email"
class="form-control"
email
maxlength="100"
name="email"
required
type="email"
>
<div *ngIf="emailInput.invalid && (emailInput.dirty || emailInput.touched)">
<div *ngIf="emailInput.errors.required" class="msg-alert">Поле обязательно</div>
<div *ngIf="emailInput.errors.email" class="msg-alert">Неверный формат адреса
эл. почты
</div>
</div>
</div>
<div class="row">
<label>Номер телефона</label>
<international-phone-number
#phoneInput="ngModel"
[(ngModel)]="phoneNumber"
[defaultCountry]="'ru'"
[pattern]="'^\\+(?!7 ?\\d{11})[0-9 ]+$'"
maxlength="20"
minlength="8"
name="phoneNumber"
placeholder="+79991112233"
(focusout)="phoneInputFocusOut()"
required
></international-phone-number>
<div *ngIf="phoneInput.invalid && (phoneInput.dirty || phoneIsTouched)">
<div *ngIf="phone.selectedCountry">
<div *ngIf="phoneHasOnlyDialCode()" class="msg-alert">Поле обязательно</div>
<div *ngIf="!phoneHasOnlyDialCode()" class="msg-alert">Введите корректный номер</div>
</div>
<div *ngIf="!phone.selectedCountry">
<div *ngIf="phoneInput.errors.required" class="msg-alert">Поле обязательно</div>
<div *ngIf="!phoneInput.errors.required" class="msg-alert">Введите код страны</div>
</div>
</div>
</div>
<div class="row">
<label>Пароль</label>
<div class="input-group">
<input
#passwordInput="ngModel"
[(ngModel)]="password"
[type]="fieldType ? 'text' : 'password'"
class="form-control"
maxlength="32"
minlength="8"
name="password"
[pattern]="passwordPattern"
required
>
<div class="input-group-append">
<span class="input-group-text">
<i
(click)="toggleFieldType()"
class="fa"
[ngClass]="{
'fa-eye': fieldType,
'fa-eye-slash': !fieldType
}"
></i>
</span>
</div>
</div>
<div *ngIf="passwordInput.invalid && (passwordInput.dirty || passwordInput.touched)">
<div *ngIf="passwordInput.errors.required" class="msg-alert">Поле обязательно
</div>
<div *ngIf="passwordInput.errors.minlength" class="msg-alert">Пароль должен
содержать как минимум 8 символов
</div>
<div *ngIf="passwordInput.errors.pattern" class="msg-alert" [innerText]="passwordPatternErrorMessage">
</div>
</div>
</div>
<div class="register-btn-box">
<button
(click)="formComponent.form.valid && register()"
[disabled]="!formComponent.form.valid"
class="btn btn-primary"
type="submit"
>
Зарегистрироваться
</button>
</div>
<div *ngIf="consent" [innerHTML]="consent" class="consent"></div>
</form>
</div>
</div>

View file

@ -0,0 +1,45 @@
<div class="form-signup">
<div class="form-logo">
<div></div>
</div>
<div class="form-reset-password">
<form #formComponent="ngForm">
<div [hidden]="!errorMessage" class="alert alert-danger">{{ errorMessage }}</div>
<p class="has-account">Вспомнили пароль?
<a href="#/login"><span class="fa fa-lock"></span>Войти</a></p>
<p class="has-account">Укажите адрес эл. почты, который был указан при регистрации,
на него пришлем временный пароль. Пароль сможете поменять в личном кабинете.
</p>
<div class="row">
<input
#emailInput="ngModel"
[(ngModel)]="email"
class="form-control"
email
maxlength="100"
name="email"
required
type="email"
>
<label>Адрес эл. почты</label>
<div *ngIf="emailInput.invalid && (emailInput.dirty || emailInput.touched)" class="msg-text">
<div *ngIf="emailInput.errors.required" class="msg-alert">Поле обязательно</div>
<div *ngIf="emailInput.errors.email" class="msg-alert">Неверный формат адреса эл. почты
</div>
</div>
</div>
<div class="btn-box">
<button
(click)="formComponent.form.valid && resetPassword()"
[disabled]="!formComponent.form.valid"
class="btn btn-primary"
type="submit"
>
Восстановить
</button>
</div>
</form>
</div>
</div>

View file

@ -0,0 +1,5 @@
<div [id]="getObjectId()"
class="vertical-container"
[ngbTooltip]="tooltip | emptyIfNull">
<ng-content></ng-content>
</div>

View file

@ -0,0 +1,3 @@
<div id="page">
<router-outlet></router-outlet>
</div>

View file

@ -0,0 +1 @@
<router-outlet></router-outlet>

View file

@ -0,0 +1,4 @@
<div id="home">
<div class="inner">
</div>
</div>

View file

@ -0,0 +1 @@
<div #pageContent></div>

View file

@ -0,0 +1,9 @@
<div class="wrapper">
<app-header *ngIf="headerVisible"></app-header>
<div class="container">
<div class="container-inside" id="webbpm-angular-application-container">
<router-outlet></router-outlet>
</div>
</div>
<app-footer *ngIf="footerVisible"></app-footer>
</div>

View file

@ -0,0 +1,26 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef} from "@angular/core";
import {VBox} from "@webbpm/base-package";
@Component({
moduleId: module.id,
selector: 'vbox-load-values',
templateUrl: '../../../../../src/resources/template/ervu-usr-autority/component/container/VBoxLoadValues.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class VBoxLoadValues extends VBox {
constructor(el: ElementRef, cd: ChangeDetectorRef) {
super(el, cd);
}
public loadValues(selected: any, guids: any): Promise<any> {
if (selected) {
return this.containerLoader.containerLoaderRpcService.loadData(selected, guids, false)
.then(fieldDataList => this.setData(fieldDataList))
.then(() => this.fireOnLoadEvent());
}
else {
return Promise.resolve();
}
}
}

View file

@ -0,0 +1,24 @@
import {AnalyticalScope, Behavior, SessionStore, TextField} from "@webbpm/base-package";
@AnalyticalScope("TextField")
export class SetCurrentUserIdAsDefValue extends Behavior {
private textField: TextField;
private sessionStore: SessionStore;
initialize() {
super.initialize();
this.textField = this.getScript('component.ControlWithValue');
this.sessionStore = this.injector.get(SessionStore);
}
start(): void {
super.start();
if (this.textField && this.textField.isPristine() && this.sessionStore &&
this.sessionStore.getSession()) {
this.textField.setValue(this.sessionStore.getSession().userAccountId);
this.getContext().getChangeDetector().detectChanges();
}
}
}

View file

@ -0,0 +1,8 @@
import "../../src/resources/css/style.css";
import {platformBrowser} from '@angular/platform-browser';
import {enableProdMode} from "@angular/core";
import {WebbpmModuleNgFactory} from "./modules/webbpm/webbpm.module.ngfactory";
window['dev_mode'] = false;
enableProdMode();
platformBrowser().bootstrapModuleFactory(WebbpmModuleNgFactory);

7
frontend/src/ts/main.ts Normal file
View file

@ -0,0 +1,7 @@
import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
import {enableProdMode} from "@angular/core";
import {WebbpmModule} from "./modules/webbpm/webbpm.module";
window['dev_mode'] = true;
enableProdMode();
platformBrowserDynamic().bootstrapModule(WebbpmModule);

View file

@ -0,0 +1,77 @@
import {NgModule} from "@angular/core";
import {RouterModule, Routes} from "@angular/router";
import {AccessDeniedComponent} from "./component/access-denied.component";
import {LoginComponent} from "./component/login.component";
import {AuthenticationGuard, ConfirmExitGuard, SignedInGuard} from "@webbpm/base-package";
import {RegisterComponent} from "./component/register.component";
import {ConfirmUserEmailComponent} from "./component/confirm-user-email.component";
import {ResetPasswordComponent} from "./component/reset-password.component";
import {NewPasswordComponent} from "./component/new-password.component";
const appRoutes: Routes = [
{
path: 'login',
component: LoginComponent,
canActivate: [SignedInGuard]
},
{
path: 'home',
loadChildren: 'generated-sources/page-home.module#PagehomeModule',
canActivate: [AuthenticationGuard, ConfirmExitGuard]
},
{
path: 'app_list',
loadChildren: 'generated-sources/page-app_list.module#Pageapp_listModule',
canActivate: [AuthenticationGuard, ConfirmExitGuard]
},
{
path: 'add_user_application',
loadChildren: 'generated-sources/page-add_user_application.module#Pageadd_user_applicationModule',
canActivate: [AuthenticationGuard, ConfirmExitGuard]
},
{
path: 'edit_user_application',
loadChildren: 'generated-sources/page-edit_user_application.module#Pageedit_user_applicationModule',
canActivate: [AuthenticationGuard, ConfirmExitGuard]
},
{
path: 'block_user_application',
loadChildren: 'generated-sources/page-block_user_application.module#Pageblock_user_applicationModule',
canActivate: [AuthenticationGuard, ConfirmExitGuard]
},
{
path: 'process_application/:id',
loadChildren: 'generated-sources/page-process_application.module#Pageprocess_applicationModule',
canActivate: [AuthenticationGuard, ConfirmExitGuard]
},
{
path: 'access-denied',
component: AccessDeniedComponent,
canActivate: [AuthenticationGuard, ConfirmExitGuard]
},
{
path: 'registration',
component: RegisterComponent,
canActivate: [SignedInGuard]
},
{
path: 'confirm',
component: ConfirmUserEmailComponent
},
{
path: 'reset-password',
component: ResetPasswordComponent
},
{
path: 'new-password',
component: NewPasswordComponent
}
];
@NgModule({
imports: [RouterModule.forChild(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule {
}

View file

@ -0,0 +1,74 @@
import {forwardRef, NgModule} from "@angular/core";
import {NgbModule} from "@ng-bootstrap/ng-bootstrap";
import {CommonModule, registerLocaleData} from "@angular/common";
import localeRu from '@angular/common/locales/ru';
import {FormsModule} from "@angular/forms";
import {AgGridModule} from "ag-grid-angular";
import {
BpmnModule,
ComponentsModule,
CoreModule,
ProgressIndicationService,
SecurityModule
} from "@webbpm/base-package";
import {AdminMenuComponent} from "./component/admin-menu.component";
import {AppHeaderComponent} from "./component/app-header.component";
import {AppFooterComponent} from "./component/app-footer.component";
import {LogOutComponent} from "./component/logout.component";
import {LoginComponent} from "./component/login.component";
import {AccessDeniedComponent} from "./component/access-denied.component";
import {ApplicationVersionComponent} from "./component/application-version.component";
import {RouterModule} from "@angular/router";
import {RegisterComponent} from "./component/register.component";
import {ConfirmUserEmailComponent} from "./component/confirm-user-email.component";
import {InternationalPhoneNumberModule} from "ngx-international-phone-number";
import {ResetPasswordComponent} from "./component/reset-password.component";
import {NewPasswordComponent} from "./component/new-password.component";
import {AppProgressIndicationComponent} from "./component/app-progress-indication.component";
import {AppProgressIndicationService} from "./service/app-progress-indication.service";
import {VBoxLoadValues} from "../../ervu-usr-autority/component/container/VBoxLoadValues";
registerLocaleData(localeRu);
export const DIRECTIVES = [
forwardRef(() => AppHeaderComponent),
forwardRef(() => AppFooterComponent),
forwardRef(() => AdminMenuComponent),
forwardRef(() => ApplicationVersionComponent),
forwardRef(() => LogOutComponent),
forwardRef(() => LoginComponent),
forwardRef(() => AccessDeniedComponent),
forwardRef(() => RegisterComponent),
forwardRef(() => ConfirmUserEmailComponent),
forwardRef(() => ResetPasswordComponent),
forwardRef(() => NewPasswordComponent),
forwardRef(() => AppProgressIndicationComponent),
forwardRef(() => VBoxLoadValues)
];
@NgModule({
imports: [
CommonModule,
FormsModule,
CoreModule,
NgbModule,
BpmnModule,
SecurityModule,
ComponentsModule,
AgGridModule,
RouterModule,
InternationalPhoneNumberModule
],
declarations: [
DIRECTIVES
],
exports: [
DIRECTIVES
],
providers: [
{ provide: ProgressIndicationService, useClass: AppProgressIndicationService }
],
bootstrap: [],
entryComponents: [AppProgressIndicationComponent]
})
export class AppModule {
}

View file

@ -0,0 +1,11 @@
import {ChangeDetectionStrategy, Component} from "@angular/core";
@Component({
moduleId: module.id,
selector: "access-denied",
templateUrl: "../../../../../src/resources/template/app/component/access_denied.html",
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AccessDeniedComponent {
}

View file

@ -0,0 +1,23 @@
import {ChangeDetectionStrategy, Component, Input} from "@angular/core";
import {UserService, Session} from "@webbpm/base-package";
import {NgbDropdownConfig, Placement} from "@ng-bootstrap/ng-bootstrap";
import {Observable} from "rxjs";
@Component({
moduleId: module.id,
selector: 'admin-menu',
templateUrl: '../../../../../src/resources/template/app/component/admin_menu.html',
providers: [NgbDropdownConfig],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AdminMenuComponent {
@Input()
public placement: Placement = 'bottom';
public currentSession: Observable<Session>;
constructor(protected userService: UserService, public config: NgbDropdownConfig) {
this.config.placement = this.placement;
this.currentSession = this.userService.getCurrentSession();
}
}

View file

@ -0,0 +1,9 @@
import {Component} from "@angular/core";
@Component({
moduleId: module.id,
selector: "app-footer",
templateUrl: "../../../../../src/resources/template/app/component/app_footer.html"
})
export class AppFooterComponent {
}

View file

@ -0,0 +1,20 @@
import {ChangeDetectionStrategy, Component} from "@angular/core";
import {Router} from "@angular/router";
import {UserService, Session} from "@webbpm/base-package";
import {Observable} from "rxjs";
@Component({
moduleId: module.id,
selector: "app-header",
templateUrl: "../../../../../src/resources/template/app/component/app_header.html",
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppHeaderComponent {
public currentSession: Observable<Session>;
constructor(protected userService: UserService,
protected router: Router) {
this.currentSession = this.userService.getCurrentSession();
}
}

View file

@ -0,0 +1,11 @@
import {ChangeDetectionStrategy, Component} from "@angular/core";
@Component({
moduleId: module.id,
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'progress-indication-dialog-content',
templateUrl: '../../../../../src/resources/template/app/component/progress-indication.html'
})
export class AppProgressIndicationComponent {
}

View file

@ -0,0 +1,24 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input} from "@angular/core";
import {HttpClient} from "@angular/common/http";
@Component({
moduleId: module.id,
selector: "application-version",
templateUrl: "../../../../../src/resources/template/app/component/application_version.html",
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ApplicationVersionComponent {
@Input()
public applicationVersion: string;
constructor(private httpClient: HttpClient, private cd: ChangeDetectorRef) {
this.loadAppVersion(); //TODO: check version url
}
private loadAppVersion() {
this.httpClient.get("version").toPromise().then((version: any) => {
this.applicationVersion = version.number;
this.cd.markForCheck();
})
}
}

View file

@ -0,0 +1,51 @@
import {ActivatedRoute, Router} from "@angular/router";
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input} from "@angular/core";
import {Session, UserService} from "@webbpm/base-package";
import {Observable} from "rxjs";
enum VerificationStatus {
VERIFYING = "VERIFYING",
VERIFIED = "VERIFIED",
FAILED = "FAILED"
}
@Component({
moduleId: module.id,
selector: "confirm",
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: "../../../../../src/resources/template/app/component/confirm-user-email.html"
})
export class ConfirmUserEmailComponent {
public verificationStatus = VerificationStatus.VERIFYING;
public currentSession: Observable<Session>;
@Input()
public errorMessage: string;
constructor(private router: Router, private userService: UserService,
private route: ActivatedRoute, private cd: ChangeDetectorRef) {
this.currentSession = this.userService.getCurrentSession();
}
ngOnInit() {
const link: string = this.route.snapshot.queryParamMap.get("link");
// remove link from url to prevent http referer leakage
this.router.navigate([], { relativeTo: this.route, replaceUrl: true });
this.userService.confirm(
link,
(reason) => {
this.verificationStatus = VerificationStatus.FAILED;
if (reason.status === 404) {
this.errorMessage = 'Ссылка недействительна. Требуется повторная регистрация.';
}
else {
this.errorMessage = 'Произошла ошибка, обратитесь в службу технической поддержки!';
}
this.cd.markForCheck();
})
.then(() => {
this.verificationStatus = VerificationStatus.VERIFIED;
this.cd.markForCheck();
});
}
}

View file

@ -0,0 +1,68 @@
import {Component, Input} from "@angular/core";
import {ActivatedRoute, Router} from "@angular/router";
import {UserService, Credentials} from "@webbpm/base-package";
@Component({
moduleId: module.id,
selector: "login",
templateUrl: "../../../../../src/resources/template/app/component/login.html"
})
export class LoginComponent {
@Input()
public username: string;
@Input()
public password: string;
public passwordType: boolean;
@Input()
public errorMessage: string;
@Input()
public confirmationSent: boolean;
constructor(private router: Router, private userService: UserService,
private route: ActivatedRoute) {
}
ngOnInit() {
this.confirmationSent = this.route.snapshot.queryParamMap.get('confirmationSent') === 'true';
this.router.navigate([], { relativeTo: this.route, replaceUrl: true });
}
public login(): void {
let credentials: Credentials = new Credentials();
credentials.username = this.username;
credentials.password = this.password;
this.userService.login(credentials, "Password")
.then(() => this.router.navigateByUrl("/"),
(reason: any) => {
switch (reason.status) {
case 401: {
this.errorMessage = "Неправильный логин или пароль";
break;
}
case 404: {
this.errorMessage = "Приложение стартует. Пожалуйста, подождите...";
break;
}
default: {
this.errorMessage =
"Произошла неизвестная ошибка, обратитесь в службу технической поддержки!";
break;
}
}
}
);
}
public goToRegister(): void {
this.router.navigateByUrl("/register");
}
togglePasswordType(): void {
this.passwordType = !this.passwordType;
}
}

View file

@ -0,0 +1,37 @@
import {Component} from "@angular/core";
import {UserService, Session, AuthenticationMethodService} from "@webbpm/base-package";
import {Observable} from "rxjs";
@Component({
moduleId: module.id,
selector: "[log-out]",
templateUrl: "../../../../../src/resources/template/app/component/log_out.html"
})
export class LogOutComponent {
public currentSession: Observable<Session>;
constructor(private userService: UserService, private authenticationMethodService: AuthenticationMethodService) {
this.currentSession = userService.getCurrentSession();
}
public logout(): void {
this.userService.logout();
}
public getCurrentUserName(): string {
return this.userService.getCurrentUserName();
}
public getFullUserName(): string {
return this.userService.getFullUserName();
}
public isLogoutButtonVisible(): boolean {
return this.authenticationMethodService.isFormAuth();
}
public getOrgUnitName(): string {
return this.userService.getOrgUnitName();
}
}

View file

@ -0,0 +1,79 @@
import {ActivatedRoute, Router} from "@angular/router";
import {Component, Input} from "@angular/core";
import {Session, UserPasswordResetRequestDto, UserService} from "@webbpm/base-package";
import {Observable} from "rxjs";
@Component({
moduleId: module.id,
selector: "newPassword",
templateUrl: "../../../../../src/resources/template/app/component/new_password.html"
})
export class NewPasswordComponent {
public currentSession: Observable<Session>;
private token: string;
@Input()
public password: string;
public passwordType: boolean;
@Input()
public confirmPassword: string;
public confirmPasswordType: boolean;
@Input()
public errorMessage: string;
constructor(private router: Router, private userService: UserService,
private route: ActivatedRoute) {
this.currentSession = this.userService.getCurrentSession();
}
ngOnInit() {
this.token = this.route.snapshot.queryParamMap.get("token");
this.router.navigate([], {relativeTo: this.route, replaceUrl: true});
if (this.token == undefined || this.token === '') {
this.errorMessage = 'Ссылка недействительна. Требуется повторить восстановление пароля.';
return;
}
}
public changePassword(): void {
let dto: UserPasswordResetRequestDto = new UserPasswordResetRequestDto();
dto.password = this.password;
dto.passwordConfirm = this.confirmPassword;
this.userService.changePassword(dto, this.token)
.then(() => this.router.navigateByUrl("/"),
() => {
this.errorMessage =
'Произошла неизвестная ошибка, обратитесь в службу технической поддержки!';
});
}
togglePasswordType(): void {
this.passwordType = !this.passwordType;
}
toggleConfirmPasswordType(): void {
this.confirmPasswordType = !this.confirmPasswordType;
}
validPasswords(): boolean {
if (this.password === undefined || this.confirmPassword === undefined) {
return false;
}
let eq = this.password === this.confirmPassword;
if (!eq) {
this.errorMessage = 'Введенные пароли не совпадают. Убедитесь, что данные, ' +
'введенные в поле "Подтверждение пароля", совпадают с теми, ' +
'которые указаны в поле "Пароль".';
}
else {
this.errorMessage = '';
}
return eq;
}
}

View file

@ -0,0 +1,71 @@
import {Component, Input, ViewChild} from "@angular/core";
import {AppConfigService, UserDto, UserService} from "@webbpm/base-package";
import {Router} from "@angular/router";
import {PhoneNumberComponent} from "ngx-international-phone-number";
@Component({
moduleId: module.id,
selector: "register",
templateUrl: "../../../../../src/resources/template/app/component/register.html"
})
export class RegisterComponent {
public passwordPattern: string;
public passwordPatternErrorMessage: string;
public errorMessage: string;
@Input()
public username: string;
@Input()
public email: string;
@ViewChild(PhoneNumberComponent)
public phone: PhoneNumberComponent;
public phoneNumber: string;
public phoneIsTouched: boolean = false;
@Input()
public password: string;
public fieldType: boolean;
@Input()
public consent: string;
constructor(private router: Router, private userService: UserService,private appConfigService: AppConfigService) {
this.passwordPattern = appConfigService.getParamValue("password_pattern");
this.passwordPatternErrorMessage = appConfigService.getParamValue("password_pattern_error");
}
public register(): void {
let user: UserDto = new UserDto();
user.username = this.username;
user.email = this.email;
user.name = this.username;
user.phone = this.phone.value;
user.password = this.password;
this.userService.register(user)
.then(() => this.router.navigateByUrl("/login?confirmationSent=true"),
(reason: any) => {
if (reason.status === 409) {
this.errorMessage = 'Пользователь с данным почтовым адресом уже существует';
}
else {
this.errorMessage = 'Произошла неизвестная ошибка, обратитесь в службу технической поддержки!';
}
});
}
toggleFieldType(): void {
this.fieldType = !this.fieldType;
}
phoneHasOnlyDialCode(): boolean {
return this.phone.phoneNumber.trim() === this.phone.getSelectedCountryDialCode().trim()
}
phoneInputFocusOut(): void {
this.phoneIsTouched = true;
}
}

View file

@ -0,0 +1,30 @@
import {Component, Input} from "@angular/core";
import {UserService} from "@webbpm/base-package";
import {Router} from "@angular/router";
@Component({
moduleId: module.id,
selector: "resetPassword",
templateUrl: "../../../../../src/resources/template/app/component/reset_password.html"
})
export class ResetPasswordComponent {
@Input()
public email: string;
@Input()
public errorMessage: string;
constructor(private router: Router, private userService: UserService) {
}
resetPassword(): void {
this.userService.resetPassword(this.email)
.then(() => this.router.navigateByUrl("/"),
(reason: any) => {
this.errorMessage =
'Произошла неизвестная ошибка, обратитесь в службу технической поддержки!';
});
}
}

View file

@ -0,0 +1,95 @@
import {Injectable} from "@angular/core";
import {AppProgressIndicationComponent} from "../component/app-progress-indication.component";
import {NgbModal, NgbModalOptions, NgbModalRef} from "@ng-bootstrap/ng-bootstrap";
@Injectable()
export class AppProgressIndicationService {
private static readonly EVENT_INTERCEPTOR = (event) => {
event.preventDefault();
event.stopPropagation();
};
private counter: number = 0;
private focused: any;
private ngbModalRef: NgbModalRef;
private options: NgbModalOptions = {
backdrop: 'static',
keyboard: false,
windowClass: 'modal-center loader'
};
constructor(private ngbModal: NgbModal) {
}
public showProgressBar(): boolean {
if (this.counter == 0) {
this.disableEvents();
this.saveFocus();
this.showProgressIndicator();
}
++this.counter;
return this.counter == 1;
}
public hideProgressBar(): boolean {
if (this.counter == 0) {
return false;
}
if (this.counter == 1) {
this.hideProgressIndicator();
this.restoreFocus();
this.enableEvents();
}
--this.counter;
return this.counter == 0;
}
public unconditionallyHideProgressBar(): void {
this.enableEvents();
this.hideProgressIndicator();
}
public restoreProgressBar(): void {
if (this.counter > 0 && this.ngbModalRef == null) {
this.disableEvents();
this.showProgressIndicator();
}
}
private showProgressIndicator() {
this.ngbModalRef = this.ngbModal.open(AppProgressIndicationComponent, this.options);
}
private hideProgressIndicator() {
this.ngbModalRef.dismiss('cancel');
this.ngbModalRef = null;
}
private saveFocus() {
this.focused = $(':focus');
}
private restoreFocus() {
if (this.focused) {
this.focused.focus();
this.focused = null;
}
}
private disableEvents() {
let body = $('body');
body.keydown(AppProgressIndicationService.EVENT_INTERCEPTOR);
body.keyup(AppProgressIndicationService.EVENT_INTERCEPTOR);
body.contextmenu(AppProgressIndicationService.EVENT_INTERCEPTOR)
}
private enableEvents() {
let body = $('body');
body.off('keydown', AppProgressIndicationService.EVENT_INTERCEPTOR);
body.off('keyup', AppProgressIndicationService.EVENT_INTERCEPTOR);
body.off('contextmenu', AppProgressIndicationService.EVENT_INTERCEPTOR);
}
}

View file

@ -0,0 +1,9 @@
import {Component} from "@angular/core";
@Component({
moduleId: module.id,
selector: "[preview-container]",
templateUrl: "../../../../../src/resources/template/preview/preview_container.html"
})
export class PreviewContainerComponent {
}

View file

@ -0,0 +1,9 @@
import {Component} from "@angular/core";
@Component({
moduleId: module.id,
selector: "[preview]",
templateUrl: "../../../../../src/resources/template/preview/preview.html"
})
export class PreviewComponent {
}

View file

@ -0,0 +1,20 @@
import {NgModule} from "@angular/core";
import {RouterModule, Routes} from "@angular/router";
import {PreviewComponent} from "./component/preview.component";
import {DYNAMIC_ROUTING} from "../../page.routing";
const previewRoutes: Routes = [
{
path: 'preview',
component: PreviewComponent,
children: DYNAMIC_ROUTING,
}
];
@NgModule({
imports: [RouterModule.forRoot(previewRoutes, {useHash: true})],
exports: [RouterModule]
})
export class PreviewRoutingModule {
}

View file

@ -0,0 +1,7 @@
import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
import {enableProdMode} from "@angular/core";
import {PreviewModule} from "./preview.module";
window['dev_mode'] = true;
enableProdMode();
platformBrowserDynamic().bootstrapModule(PreviewModule);

View file

@ -0,0 +1,51 @@
import {NgModule, NgZone} from "@angular/core";
import {FormsModule} from "@angular/forms";
import {BrowserModule} from "@angular/platform-browser";
import {AgGridModule} from "ag-grid-angular";
import {PreviewComponent} from "./component/preview.component";
import {PreviewRoutingModule} from "./preview-routing.module";
import {PreviewContainerComponent} from "./component/preview-container.component";
import {NgbModule} from "@ng-bootstrap/ng-bootstrap";
import {ToastNoAnimationModule} from "ngx-toastr";
import {AppModule} from "../app/app.module";
import {ComponentsModule, CoreModule, SecurityModule} from "@webbpm/base-package";
import {HTTP_INTERCEPTORS} from "@angular/common/http";
import {HttpPreviewInterceptor} from "./service/http-preview-interceptor.service";
export const HTTP_INTERCEPTOR_PROVIDERS = [
{ provide: HTTP_INTERCEPTORS, useClass: HttpPreviewInterceptor, multi: true }
];
let IMPORTS = [
BrowserModule,
FormsModule,
NgbModule,
ToastNoAnimationModule.forRoot(),
AgGridModule,
CoreModule,
ComponentsModule,
AppModule,
SecurityModule,
PreviewRoutingModule
];
@NgModule({
imports: IMPORTS,
declarations: [
PreviewContainerComponent,
PreviewComponent
],
exports: [],
providers: [
HTTP_INTERCEPTOR_PROVIDERS
],
bootstrap: [
PreviewContainerComponent
]
})
export class PreviewModule {
constructor(zone: NgZone) {
window['zoneImpl'] = zone;
}
}

View file

@ -0,0 +1,16 @@
import {Injectable} from "@angular/core";
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from "@angular/common/http";
import {EMPTY, Observable} from "rxjs";
import {catchError} from "rxjs/operators";
@Injectable()
export class HttpPreviewInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(catchError(() => {
return EMPTY;
}
));
}
}

View file

@ -0,0 +1,9 @@
import {Component} from "@angular/core";
@Component({
moduleId: module.id,
selector: "home",
templateUrl: './../../../../../src/resources/template/webbpm/home.html'
})
export class HomeComponent {
}

View file

@ -0,0 +1,34 @@
import {Component} from "@angular/core";
import {
Event,
NavigationCancel,
NavigationEnd,
NavigationError,
NavigationStart,
Router
} from "@angular/router";
import {ProgressIndicationService} from "@webbpm/base-package";
@Component({
moduleId: module.id,
selector: '[webbpm]',
templateUrl: './../../../../../src/resources/template/webbpm/webbpm.html'
})
export class WebbpmComponent {
public headerVisible: boolean = true;
public footerVisible: boolean = true;
constructor(private router: Router,
private progressIndicationService: ProgressIndicationService) {
router.events.subscribe((event: Event) => {
if (event instanceof NavigationStart) {
progressIndicationService.showProgressBar();
}
else if (event instanceof NavigationEnd
|| event instanceof NavigationError
|| event instanceof NavigationCancel) {
progressIndicationService.hideProgressBar();
}
})
}
}

View file

@ -0,0 +1,10 @@
import {ErrorHandler, Injectable, Injector} from '@angular/core';
import {BaseErrorHandler} from "@webbpm/base-package";
@Injectable({providedIn: 'root'})
export class GlobalErrorHandler extends BaseErrorHandler implements ErrorHandler {
constructor(injector: Injector) {
super(injector);
}
}

View file

@ -0,0 +1,35 @@
import {ErrorHandler, Injectable, Injector} from '@angular/core';
import {BaseErrorHandler} from "@webbpm/base-package";
//todo: will be used after angular update in dev mode
@Injectable({providedIn: 'root'})
export class GlobalErrorHandler extends BaseErrorHandler implements ErrorHandler {
constructor(injector: Injector) {
super(injector);
}
handleError(error) {
const chunkFailedMessage = /Loading chunk [\d]+ failed/;
if (chunkFailedMessage.test(error.message)) {
window.location.reload();
}
else if (!this.isPreviewPage()) {
super.handleError(error);
}
}
internalHandleError(error) {
if (this.isPreviewPage()) {
return;
}
else {
super.internalHandleError(error);
}
}
private isPreviewPage() {
return window.location.hash.includes("webbpm-preview");
}
}

View file

@ -0,0 +1,12 @@
import {HTTP_INTERCEPTORS} from "@angular/common/http";
import {
FormDirtyInterceptor,
HttpSecurityErrorInterceptor,
HttpSecurityInterceptor
} from "@webbpm/base-package";
export const DEFAULT_HTTP_INTERCEPTOR_PROVIDERS = [
{provide: HTTP_INTERCEPTORS, useClass: HttpSecurityInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: HttpSecurityErrorInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: FormDirtyInterceptor, multi: true}
];

View file

@ -0,0 +1,9 @@
import {HTTP_INTERCEPTORS} from "@angular/common/http";
import {FormDirtyInterceptor, HttpSecurityInterceptor} from "@webbpm/base-package";
import {DevHttpSecurityErrorInterceptor} from "./http-security-error-interceptor.dev";
export const DEFAULT_HTTP_INTERCEPTOR_PROVIDERS = [
{provide: HTTP_INTERCEPTORS, useClass: HttpSecurityInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: DevHttpSecurityErrorInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: FormDirtyInterceptor, multi: true}
];

View file

@ -0,0 +1,31 @@
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from "@angular/common/http";
import {HttpSecurityErrorInterceptor, MessagesService, UserService} from "@webbpm/base-package";
import {Injectable} from "@angular/core";
import {Router} from "@angular/router";
import {EMPTY, Observable} from "rxjs";
import {catchError} from "rxjs/operators";
@Injectable()
export class DevHttpSecurityErrorInterceptor extends HttpSecurityErrorInterceptor
implements HttpInterceptor {
private router: Router;
constructor(router: Router, messagesService: MessagesService, userService: UserService) {
super(router, messagesService, userService);
this.router = router;
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (window.location.hash.includes("webbpm-preview")) {
return next.handle(req).pipe(catchError(() => {
return EMPTY;
}
));
}
else {
return super.intercept(req, next);
}
}
}

View file

@ -0,0 +1,88 @@
import {RouterModule, Routes} from "@angular/router";
import {NgModule} from "@angular/core";
import {
AuthenticationGuard,
ConfirmExitGuard
} from "@webbpm/base-package";
const routes: Routes = [
{
path: 'user-management',
canActivate: [AuthenticationGuard],
children: [
{
path: 'users',
loadChildren: 'generated-sources/page-user-management-users.module#PageusermanagementusersModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'users/new',
loadChildren: 'generated-sources/page-user-management-user-create.module#PageusermanagementusercreateModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'users/:id',
loadChildren: 'generated-sources/page-user-management-user-edit.module#PageusermanagementusereditModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'org-units',
loadChildren: 'generated-sources/page-user-management-org-units.module#PageusermanagementorgunitsModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'org-units/new',
loadChildren: 'generated-sources/page-user-management-org-unit.module#PageusermanagementorgunitModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'org-units/:id',
loadChildren: 'generated-sources/page-user-management-org-unit.module#PageusermanagementorgunitModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'roles',
loadChildren: 'generated-sources/page-user-management-roles.module#PageusermanagementrolesModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'roles/new',
loadChildren: 'generated-sources/page-user-management-role.module#PageusermanagementroleModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'roles/:id',
loadChildren: 'generated-sources/page-user-management-role.module#PageusermanagementroleModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'groups',
loadChildren: 'generated-sources/page-user-management-groups.module#PageusermanagementgroupsModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'groups/new',
loadChildren: 'generated-sources/page-user-management-group-create.module#PageusermanagementgroupcreateModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'groups/:id',
loadChildren: 'generated-sources/page-user-management-group-edit.module#PageusermanagementgroupeditModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'authorities',
loadChildren: 'generated-sources/page-user-management-authorities.module#PageusermanagementauthoritiesModule',
canActivate: [ConfirmExitGuard]
}
]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class UserManagementRoutingModule {
}

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