TSK-981: Provide frontend formatter for common IDEs (#1187)
* TSK-981: tested adding prettier * TSK-981: Refined prettier and eslint configs * TSK-981: Update eslint rules * TSK-981: Updated VS Code settings and ignore folders * TSK-981: Added editor config * TSK-981: added html to prettierignore * TSK-981: tested adding prettier * TSK-981: Refined prettier and eslint configs * TSK-981: Update eslint rules * TSK-981: Updated VS Code settings and ignore folders * TSK-981: Added editor config * TSK-981: added html to prettierignore * TSK-981: reformatted code using prettier/new eslint configs
This commit is contained in:
parent
59b45f626a
commit
29e468e6aa
|
@ -0,0 +1,14 @@
|
||||||
|
# Editor configuration, see http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
max_line_length = off
|
||||||
|
trim_trailing_whitespace = false
|
|
@ -1,42 +1,17 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"extends": [
|
extends: ['prettier/@typescript-eslint', 'plugin:prettier/recommended'],
|
||||||
"airbnb-typescript/base"
|
env: {
|
||||||
],
|
browser: true,
|
||||||
"env": {
|
node: true
|
||||||
"browser": true,
|
|
||||||
"node": true
|
|
||||||
},
|
},
|
||||||
"parser": "@typescript-eslint/parser",
|
parser: '@typescript-eslint/parser',
|
||||||
"parserOptions": {
|
parserOptions: {
|
||||||
"project": "tsconfig.json",
|
ecmaVersion: 2018,
|
||||||
|
sourceType: 'module',
|
||||||
|
project: './tsconfig.json',
|
||||||
|
errorOnUnknownASTType: true,
|
||||||
|
errorOnTypeScriptSyntacticAndSemanticIssues: true
|
||||||
},
|
},
|
||||||
"plugins": [
|
plugins: ['@typescript-eslint', '@typescript-eslint/tslint'],
|
||||||
"@typescript-eslint",
|
rules: {}
|
||||||
"@typescript-eslint/tslint"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"arrow-parens": ["error", "as-needed"],
|
|
||||||
"@typescript-eslint/indent": ['error', 2],
|
|
||||||
"max-len": ["error", { "code": 140, "ignorePattern": "import *" }], // smaller than 140?
|
|
||||||
"object-curly-newline": ["error", { "ImportDeclaration": "never" }],
|
|
||||||
"quote-props": ["error", "as-needed"],
|
|
||||||
"lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }],
|
|
||||||
"comma-dangle": ["error", "only-multiline"],
|
|
||||||
"no-underscore-dangle": ["error", { "allow": ["_links", "__karma__"] }],
|
|
||||||
"no-param-reassign": ["error", { "props": false }],
|
|
||||||
"no-plusplus" : ["error", { "allowForLoopAfterthoughts": true }],
|
|
||||||
"@typescript-eslint/no-use-before-define": ["error", { "functions": false, "classes": false }],
|
|
||||||
"@typescript-eslint/no-unused-expressions": ["error", { "allowTernary": true }],
|
|
||||||
|
|
||||||
// all following rules SHOULD be removed
|
|
||||||
"class-methods-use-this": "off",
|
|
||||||
"import/extensions": "off",
|
|
||||||
"import/no-unresolved": "off",
|
|
||||||
"import/prefer-default-export": "off",
|
|
||||||
"max-classes-per-file": "off",
|
|
||||||
"@typescript-eslint/no-unused-vars": "off",
|
|
||||||
|
|
||||||
// all following rules MUST be removed (mostly autofix)
|
|
||||||
"linebreak-style": ["off", "unix"], // own PR
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
*.lint.ts
|
||||||
|
**/node_modules/**
|
||||||
|
.github/**
|
||||||
|
.idea/**
|
||||||
|
.cache/**
|
||||||
|
.vscode/**
|
||||||
|
dist*/**
|
||||||
|
build/**
|
||||||
|
coverage/**
|
||||||
|
**/dist/**
|
||||||
|
out-tsc/**
|
||||||
|
**/*.html
|
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
tabWidth: 2,
|
||||||
|
semi: true,
|
||||||
|
singleQuote: true,
|
||||||
|
bracketSpacing: true,
|
||||||
|
printWidth: 120,
|
||||||
|
trailingComma: 'none'
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"eslint.validate": [ "javascript", "typescript", "html"],
|
||||||
|
|
||||||
|
"eslint.options": {
|
||||||
|
"extensions": [".js", ".ts", "html"]
|
||||||
|
},
|
||||||
|
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": true,
|
||||||
|
},
|
||||||
|
"[html]": {
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.defaultFormatter": "vscode.html-language-features"
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,14 +16,8 @@
|
||||||
"main": "src/main.ts",
|
"main": "src/main.ts",
|
||||||
"tsConfig": "src/tsconfig.app.json",
|
"tsConfig": "src/tsconfig.app.json",
|
||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"assets": [
|
"assets": ["src/assets", "src/environments/data-sources"],
|
||||||
"src/assets",
|
"styles": ["./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", "src/theme/_main.scss"],
|
||||||
"src/environments/data-sources"
|
|
||||||
],
|
|
||||||
"styles": [
|
|
||||||
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
|
||||||
"src/theme/_main.scss"
|
|
||||||
],
|
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"node_modules/jquery/dist/jquery.min.js",
|
"node_modules/jquery/dist/jquery.min.js",
|
||||||
"node_modules/popper.js/dist/umd/popper.min.js",
|
"node_modules/popper.js/dist/umd/popper.min.js",
|
||||||
|
@ -80,23 +74,14 @@
|
||||||
"node_modules/popper.js/dist/umd/popper.min.js",
|
"node_modules/popper.js/dist/umd/popper.min.js",
|
||||||
"node_modules/bootstrap/dist/js/bootstrap.min.js"
|
"node_modules/bootstrap/dist/js/bootstrap.min.js"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": ["./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", "src/theme/_main.scss"],
|
||||||
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
"assets": ["src/assets", "src/environments/data-sources"]
|
||||||
"src/theme/_main.scss"
|
|
||||||
],
|
|
||||||
"assets": [
|
|
||||||
"src/assets",
|
|
||||||
"src/environments/data-sources"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lint": {
|
"lint": {
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
"options": {
|
"options": {
|
||||||
"tsConfig": [
|
"tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"],
|
||||||
"src/tsconfig.app.json",
|
|
||||||
"src/tsconfig.spec.json"
|
|
||||||
],
|
|
||||||
"exclude": []
|
"exclude": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
var SeedReporter = function(baseReporterDecorator) {
|
var SeedReporter = function (baseReporterDecorator) {
|
||||||
baseReporterDecorator(this);
|
baseReporterDecorator(this);
|
||||||
|
|
||||||
this.onBrowserComplete = function(browser, result) {
|
this.onBrowserComplete = function (browser, result) {
|
||||||
if (result.order && result.order.random && result.order.seed) {
|
if (result.order && result.order.random && result.order.seed) {
|
||||||
this.write("%s: Randomized with seed %s\n", browser, result.order.seed);
|
this.write('%s: Randomized with seed %s\n', browser, result.order.seed);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"reporter:jasmine-seed": ["type", SeedReporter]
|
'reporter:jasmine-seed': ['type', SeedReporter]
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,23 +21,21 @@ module.exports = function (config) {
|
||||||
},
|
},
|
||||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
},
|
},
|
||||||
files: [
|
files: [],
|
||||||
|
preprocessors: {},
|
||||||
],
|
|
||||||
preprocessors: {
|
|
||||||
|
|
||||||
},
|
|
||||||
mime: {
|
mime: {
|
||||||
'text/x-typescript': ['ts', 'tsx']
|
'text/x-typescript': ['ts', 'tsx']
|
||||||
},
|
},
|
||||||
coverageIstanbulReporter: {
|
coverageIstanbulReporter: {
|
||||||
dir: require('path').join(__dirname, 'coverage'), reports: ['html', 'lcovonly'],
|
dir: require('path').join(__dirname, 'coverage'),
|
||||||
|
reports: ['html', 'lcovonly'],
|
||||||
fixWebpackSourcePaths: true
|
fixWebpackSourcePaths: true
|
||||||
},
|
},
|
||||||
|
|
||||||
reporters: config.angularCli && config.angularCli.codeCoverage
|
reporters:
|
||||||
? ['progress', 'coverage-istanbul', 'jasmine-seed']
|
config.angularCli && config.angularCli.codeCoverage
|
||||||
: ['progress', 'kjhtml', 'jasmine-seed'],
|
? ['progress', 'coverage-istanbul', 'jasmine-seed']
|
||||||
|
: ['progress', 'kjhtml', 'jasmine-seed'],
|
||||||
port: 9876,
|
port: 9876,
|
||||||
colors: true,
|
colors: true,
|
||||||
logLevel: config.LOG_INFO,
|
logLevel: config.LOG_INFO,
|
||||||
|
|
|
@ -665,6 +665,7 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"bindings": "^1.5.0",
|
||||||
"nan": "^2.12.1"
|
"nan": "^2.12.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -3166,6 +3167,16 @@
|
||||||
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
|
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"bindings": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"file-uri-to-path": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"blob": {
|
"blob": {
|
||||||
"version": "0.0.5",
|
"version": "0.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
|
||||||
|
@ -5397,6 +5408,23 @@
|
||||||
"eslint-config-airbnb-base": "^14.0.0"
|
"eslint-config-airbnb-base": "^14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"eslint-config-prettier": {
|
||||||
|
"version": "6.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz",
|
||||||
|
"integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"get-stdin": "^6.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"get-stdin": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"eslint-import-resolver-node": {
|
"eslint-import-resolver-node": {
|
||||||
"version": "0.3.4",
|
"version": "0.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz",
|
||||||
|
@ -5654,6 +5682,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"eslint-plugin-prettier": {
|
||||||
|
"version": "3.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz",
|
||||||
|
"integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"prettier-linter-helpers": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"eslint-scope": {
|
"eslint-scope": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
|
||||||
|
@ -6044,6 +6081,12 @@
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||||
},
|
},
|
||||||
|
"fast-diff": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"fast-glob": {
|
"fast-glob": {
|
||||||
"version": "3.2.4",
|
"version": "3.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
|
||||||
|
@ -6132,6 +6175,13 @@
|
||||||
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz",
|
||||||
"integrity": "sha1-zdTETTqiZOrC9o7BZbx5HDSvEjI="
|
"integrity": "sha1-zdTETTqiZOrC9o7BZbx5HDSvEjI="
|
||||||
},
|
},
|
||||||
|
"file-uri-to-path": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"fileset": {
|
"fileset": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz",
|
||||||
|
@ -10116,6 +10166,21 @@
|
||||||
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
|
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"prettier": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"prettier-linter-helpers": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fast-diff": "^1.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"process": {
|
"process": {
|
||||||
"version": "0.11.10",
|
"version": "0.11.10",
|
||||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||||
|
@ -13278,6 +13343,7 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"bindings": "^1.5.0",
|
||||||
"nan": "^2.12.1"
|
"nan": "^2.12.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -13855,6 +13921,7 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"bindings": "^1.5.0",
|
||||||
"nan": "^2.12.1"
|
"nan": "^2.12.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
"test": "ng test --karma-config karma.conf.js --watch=false --browsers Firefox",
|
"test": "ng test --karma-config karma.conf.js --watch=false --browsers Firefox",
|
||||||
"test:watch": "ng test --karma-config karma.conf.js --browsers Chrome",
|
"test:watch": "ng test --karma-config karma.conf.js --browsers Chrome",
|
||||||
"lint": "eslint --ext .ts src",
|
"lint": "eslint --ext .ts src",
|
||||||
"lint:fix": "eslint --ext .ts src --fix"
|
"lint:fix": "eslint --ext .ts src --fix",
|
||||||
|
"format": "prettier --write \"**/*.{js,ts,css,scss,md,json,yml}\"",
|
||||||
|
"format:html": "prettier --write \"**/*.{html,}\""
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -62,6 +64,8 @@
|
||||||
"eslint-config-airbnb-typescript": "6.3.1",
|
"eslint-config-airbnb-typescript": "6.3.1",
|
||||||
"eslint-plugin-import": "2.22.0",
|
"eslint-plugin-import": "2.22.0",
|
||||||
"@hapi/hoek": "9.0.4",
|
"@hapi/hoek": "9.0.4",
|
||||||
|
"eslint-config-prettier": "^6.11.0",
|
||||||
|
"eslint-plugin-prettier": "^3.1.4",
|
||||||
"jasmine-core": "3.5.0",
|
"jasmine-core": "3.5.0",
|
||||||
"jasmine-spec-reporter": "4.2.1",
|
"jasmine-spec-reporter": "4.2.1",
|
||||||
"karma": "5.1.0",
|
"karma": "5.1.0",
|
||||||
|
@ -73,6 +77,7 @@
|
||||||
"karma-jasmine-html-reporter": "1.4.0",
|
"karma-jasmine-html-reporter": "1.4.0",
|
||||||
"moment": "2.22.1",
|
"moment": "2.22.1",
|
||||||
"ng2-mock-component": "0.1.1",
|
"ng2-mock-component": "0.1.1",
|
||||||
|
"prettier": "^2.0.5",
|
||||||
"protractor": "7.0.0",
|
"protractor": "7.0.0",
|
||||||
"ts-mockito": "2.3.0",
|
"ts-mockito": "2.3.0",
|
||||||
"ts-node": "4.1.0",
|
"ts-node": "4.1.0",
|
||||||
|
|
|
@ -75,5 +75,4 @@ const routes: Routes = [
|
||||||
imports: [RouterModule.forChild(routes)],
|
imports: [RouterModule.forChild(routes)],
|
||||||
exports: [RouterModule]
|
exports: [RouterModule]
|
||||||
})
|
})
|
||||||
export class AdministrationRoutingModule {
|
export class AdministrationRoutingModule {}
|
||||||
}
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ const MODULES = [
|
||||||
SharedModule,
|
SharedModule,
|
||||||
AdministrationRoutingModule,
|
AdministrationRoutingModule,
|
||||||
TypeaheadModule,
|
TypeaheadModule,
|
||||||
InfiniteScrollModule,
|
InfiniteScrollModule
|
||||||
];
|
];
|
||||||
|
|
||||||
const DECLARATIONS = [
|
const DECLARATIONS = [
|
||||||
|
@ -66,17 +66,13 @@ const DECLARATIONS = [
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: DECLARATIONS,
|
declarations: DECLARATIONS,
|
||||||
imports: [
|
imports: [MODULES, MatRadioModule],
|
||||||
MODULES,
|
|
||||||
MatRadioModule
|
|
||||||
],
|
|
||||||
providers: [
|
providers: [
|
||||||
ClassificationDefinitionService,
|
ClassificationDefinitionService,
|
||||||
WorkbasketDefinitionService,
|
WorkbasketDefinitionService,
|
||||||
SavingWorkbasketService,
|
SavingWorkbasketService,
|
||||||
ClassificationCategoriesService,
|
ClassificationCategoriesService,
|
||||||
ImportExportService,
|
ImportExportService
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AdministrationModule {
|
export class AdministrationModule {}
|
||||||
}
|
|
||||||
|
|
|
@ -1,36 +1,37 @@
|
||||||
@import '../../../../theme/colors';
|
@import '../../../../theme/colors';
|
||||||
|
|
||||||
.margin {
|
.margin {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.required-header:after {
|
.required-header:after {
|
||||||
|
content: ' *';
|
||||||
content:" *";
|
color: $invalid;
|
||||||
color: $invalid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
&.has-changes {
|
&.has-changes {
|
||||||
border-bottom: 1px solid $brown;
|
border-bottom: 1px solid $brown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.table > thead > tr > th {
|
.table > thead > tr > th {
|
||||||
max-width: 150px;
|
max-width: 150px;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table > thead > tr:last-child > th {
|
.table > thead > tr:last-child > th {
|
||||||
max-width: 150px;
|
max-width: 150px;
|
||||||
border-bottom: 2px solid $grey;
|
border-bottom: 2px solid $grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wrap{
|
.wrap {
|
||||||
max-width: 150px;
|
max-width: 150px;
|
||||||
word-wrap:break-word;
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
.min-width {
|
||||||
|
min-width: 135px;
|
||||||
}
|
}
|
||||||
.min-width{ min-width: 135px;}
|
|
||||||
|
|
||||||
.modal-title {
|
.modal-title {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
|
@ -22,8 +22,8 @@ describe('AccessItemsManagementComponent', () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
fixture = testBed.createComponent(AccessItemsManagementComponent);
|
fixture = testBed.createComponent(AccessItemsManagementComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
accessIdsService = testBed.get(AccessIdsService);
|
accessIdsService = testBed.get(AccessIdsService);
|
||||||
|
|
|
@ -16,9 +16,7 @@ import { AccessIdsService } from '../../../shared/services/access-ids/access-ids
|
||||||
import { AccessIdDefinition } from '../../../shared/models/access-id';
|
import { AccessIdDefinition } from '../../../shared/models/access-id';
|
||||||
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
||||||
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
||||||
import { AccessItemsCustomisation,
|
import { AccessItemsCustomisation, CustomField, getCustomFields } from '../../../shared/models/customisation';
|
||||||
CustomField,
|
|
||||||
getCustomFields } from '../../../shared/models/customisation';
|
|
||||||
import { customFieldCount } from '../../../shared/models/workbasket-access-items';
|
import { customFieldCount } from '../../../shared/models/workbasket-access-items';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -34,22 +32,28 @@ export class AccessItemsManagementComponent implements OnInit {
|
||||||
toggleValidationAccessIdMap = new Map<number, boolean>();
|
toggleValidationAccessIdMap = new Map<number, boolean>();
|
||||||
accessId: AccessIdDefinition;
|
accessId: AccessIdDefinition;
|
||||||
groups: AccessIdDefinition[];
|
groups: AccessIdDefinition[];
|
||||||
sortingFields = new Map([['access-id', 'Access id'], ['workbasket-key', 'Workbasket Key']]);
|
sortingFields = new Map([
|
||||||
|
['access-id', 'Access id'],
|
||||||
|
['workbasket-key', 'Workbasket Key']
|
||||||
|
]);
|
||||||
sortModel: Sorting = new Sorting('access-id', Direction.DESC);
|
sortModel: Sorting = new Sorting('access-id', Direction.DESC);
|
||||||
isGroup: boolean = false;
|
isGroup: boolean = false;
|
||||||
|
|
||||||
@Select(EngineConfigurationSelectors.accessItemsCustomisation) accessItemsCustomization$: Observable<AccessItemsCustomisation>;
|
@Select(EngineConfigurationSelectors.accessItemsCustomisation) accessItemsCustomization$: Observable<
|
||||||
|
AccessItemsCustomisation
|
||||||
|
>;
|
||||||
customFields$: Observable<CustomField[]>;
|
customFields$: Observable<CustomField[]>;
|
||||||
|
|
||||||
constructor(private formBuilder: FormBuilder,
|
constructor(
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
private accessIdsService: AccessIdsService,
|
private accessIdsService: AccessIdsService,
|
||||||
private formsValidatorService: FormsValidatorService,
|
private formsValidatorService: FormsValidatorService,
|
||||||
private requestInProgressService: RequestInProgressService,
|
private requestInProgressService: RequestInProgressService,
|
||||||
private notificationService: NotificationService) {
|
private notificationService: NotificationService
|
||||||
}
|
) {}
|
||||||
|
|
||||||
get accessItemsGroups(): FormArray {
|
get accessItemsGroups(): FormArray {
|
||||||
return this.accessItemsForm ? this.accessItemsForm.get('accessItemsGroups') as FormArray : null;
|
return this.accessItemsForm ? (this.accessItemsForm.get('accessItemsGroups') as FormArray) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
@ -57,10 +61,10 @@ export class AccessItemsManagementComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
setAccessItemsGroups(accessItems: Array<AccessItemWorkbasket>) {
|
setAccessItemsGroups(accessItems: Array<AccessItemWorkbasket>) {
|
||||||
const AccessItemsFormGroups = accessItems.map(accessItem => this.formBuilder.group(accessItem));
|
const AccessItemsFormGroups = accessItems.map((accessItem) => this.formBuilder.group(accessItem));
|
||||||
AccessItemsFormGroups.forEach(accessItemGroup => {
|
AccessItemsFormGroups.forEach((accessItemGroup) => {
|
||||||
accessItemGroup.controls.accessId.setValidators(Validators.required);
|
accessItemGroup.controls.accessId.setValidators(Validators.required);
|
||||||
Object.keys(accessItemGroup.controls).forEach(key => {
|
Object.keys(accessItemGroup.controls).forEach((key) => {
|
||||||
accessItemGroup.controls[key].disable();
|
accessItemGroup.controls[key].disable();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -86,16 +90,20 @@ export class AccessItemsManagementComponent implements OnInit {
|
||||||
if (this.accessIdPrevious !== selected.accessId) {
|
if (this.accessIdPrevious !== selected.accessId) {
|
||||||
this.accessIdPrevious = selected.accessId;
|
this.accessIdPrevious = selected.accessId;
|
||||||
|
|
||||||
this.accessIdsService.getGroupsByAccessId(selected.accessId)
|
this.accessIdsService
|
||||||
.pipe(take(1)).subscribe((groups: AccessIdDefinition[]) => {
|
.getGroupsByAccessId(selected.accessId)
|
||||||
this.accessId = selected;
|
.pipe(take(1))
|
||||||
this.groups = groups;
|
.subscribe(
|
||||||
this.searchForAccessItemsWorkbaskets();
|
(groups: AccessIdDefinition[]) => {
|
||||||
},
|
this.accessId = selected;
|
||||||
error => {
|
this.groups = groups;
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
this.searchForAccessItemsWorkbaskets();
|
||||||
this.notificationService.triggerError(NOTIFICATION_TYPES.FETCH_ERR, error);
|
},
|
||||||
});
|
(error) => {
|
||||||
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
|
this.notificationService.triggerError(NOTIFICATION_TYPES.FETCH_ERR, error);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,41 +118,48 @@ export class AccessItemsManagementComponent implements OnInit {
|
||||||
|
|
||||||
searchForAccessItemsWorkbaskets() {
|
searchForAccessItemsWorkbaskets() {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
this.accessIdsService.getAccessItems(
|
this.accessIdsService
|
||||||
[this.accessId, ...this.groups],
|
.getAccessItems(
|
||||||
this.accessItemsForm ? this.accessItemsForm.value.accessIdFilter : undefined,
|
[this.accessId, ...this.groups],
|
||||||
this.accessItemsForm ? this.accessItemsForm.value.workbasketKeyFilter : undefined,
|
this.accessItemsForm ? this.accessItemsForm.value.accessIdFilter : undefined,
|
||||||
this.sortModel
|
this.accessItemsForm ? this.accessItemsForm.value.workbasketKeyFilter : undefined,
|
||||||
).pipe(take(1)).subscribe((accessItemsResource: AccessItemWorkbasketResource) => {
|
this.sortModel
|
||||||
this.setAccessItemsGroups(accessItemsResource ? accessItemsResource.accessItems : []);
|
)
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
.pipe(take(1))
|
||||||
}, error => {
|
.subscribe(
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
(accessItemsResource: AccessItemWorkbasketResource) => {
|
||||||
this.notificationService.triggerError(NOTIFICATION_TYPES.FETCH_ERR_2, error);
|
this.setAccessItemsGroups(accessItemsResource ? accessItemsResource.accessItems : []);
|
||||||
});
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
|
this.notificationService.triggerError(NOTIFICATION_TYPES.FETCH_ERR_2, error);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
revokeAccess() {
|
revokeAccess() {
|
||||||
this.notificationService.showDialog(
|
this.notificationService.showDialog(
|
||||||
`You are going to delete all access related: ${
|
`You are going to delete all access related: ${this.accessIdSelected}. Can you confirm this action?`,
|
||||||
this.accessIdSelected
|
|
||||||
}. Can you confirm this action?`,
|
|
||||||
this.onRemoveConfirmed.bind(this)
|
this.onRemoveConfirmed.bind(this)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onRemoveConfirmed() {
|
private onRemoveConfirmed() {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
this.accessIdsService.removeAccessItemsPermissions(this.accessIdSelected)
|
this.accessIdsService
|
||||||
.pipe(take(1)).subscribe(
|
.removeAccessItemsPermissions(this.accessIdSelected)
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe(
|
||||||
() => {
|
() => {
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
this.notificationService.showToast(
|
this.notificationService.showToast(
|
||||||
NOTIFICATION_TYPES.SUCCESS_ALERT, new Map<string, string>([['accessId', this.accessIdSelected]])
|
NOTIFICATION_TYPES.SUCCESS_ALERT,
|
||||||
|
new Map<string, string>([['accessId', this.accessIdSelected]])
|
||||||
);
|
);
|
||||||
this.searchForAccessItemsWorkbaskets();
|
this.searchForAccessItemsWorkbaskets();
|
||||||
},
|
},
|
||||||
error => {
|
(error) => {
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
this.notificationService.triggerError(NOTIFICATION_TYPES.DELETE_ERR, error);
|
this.notificationService.triggerError(NOTIFICATION_TYPES.DELETE_ERR, error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.custom-field-row {
|
.custom-field-row {
|
||||||
display:flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 40vh;
|
height: 40vh;
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
.custom-field-wrapper {
|
.custom-field-wrapper {
|
||||||
height: 70px;
|
height: 70px;
|
||||||
padding: 0 15px
|
padding: 0 15px;
|
||||||
}
|
}
|
||||||
.dropdown-menu > li {
|
.dropdown-menu > li {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -22,8 +22,7 @@ import { NotificationService } from '../../../shared/services/notifications/noti
|
||||||
selector: 'taskana-dummy-detail',
|
selector: 'taskana-dummy-detail',
|
||||||
template: 'dummydetail'
|
template: 'dummydetail'
|
||||||
})
|
})
|
||||||
class DummyDetailComponent {
|
class DummyDetailComponent {}
|
||||||
}
|
|
||||||
|
|
||||||
describe('ClassificationDetailsComponent', () => {
|
describe('ClassificationDetailsComponent', () => {
|
||||||
let component: ClassificationDetailsComponent;
|
let component: ClassificationDetailsComponent;
|
||||||
|
@ -38,17 +37,22 @@ describe('ClassificationDetailsComponent', () => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
imports: [FormsModule, HttpClientModule, AngularSvgIconModule, NgxsModule.forRoot()],
|
imports: [FormsModule, HttpClientModule, AngularSvgIconModule, NgxsModule.forRoot()],
|
||||||
declarations: [ClassificationDetailsComponent, DummyDetailComponent],
|
declarations: [ClassificationDetailsComponent, DummyDetailComponent],
|
||||||
providers: [MasterAndDetailService, RequestInProgressService, ClassificationsService,
|
providers: [
|
||||||
HttpClient, NotificationService,
|
MasterAndDetailService,
|
||||||
|
RequestInProgressService,
|
||||||
|
ClassificationsService,
|
||||||
|
HttpClient,
|
||||||
|
NotificationService,
|
||||||
ImportExportService,
|
ImportExportService,
|
||||||
{ provide: Location, useValue: locationSpy },
|
{ provide: Location, useValue: locationSpy },
|
||||||
{ provide: Store, useValue: storeSpy }]
|
{ provide: Store, useValue: storeSpy }
|
||||||
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
storeSpy.select.and.callFake(selector => {
|
storeSpy.select.and.callFake((selector) => {
|
||||||
switch (selector) {
|
switch (selector) {
|
||||||
case EngineConfigurationSelectors.classificationsCustomisation:
|
case EngineConfigurationSelectors.classificationsCustomisation:
|
||||||
return of({ information: {} });
|
return of({ information: {} });
|
||||||
|
@ -99,7 +103,7 @@ describe('ClassificationDetailsComponent', () => {
|
||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should enable editing of key on create and on copy', async done => {
|
it('should enable editing of key on create and on copy', async (done) => {
|
||||||
component.isCreatingNewClassification = true;
|
component.isCreatingNewClassification = true;
|
||||||
await fixture.detectChanges();
|
await fixture.detectChanges();
|
||||||
expect(fixture.debugElement.nativeElement.querySelector('#classification-key').disabled).toEqual(false);
|
expect(fixture.debugElement.nativeElement.querySelector('#classification-key').disabled).toEqual(false);
|
||||||
|
|
|
@ -17,19 +17,19 @@ import { ClassificationSelectors } from 'app/shared/store/classification-store/c
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
||||||
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
||||||
import { ClassificationCategoryImages,
|
import { ClassificationCategoryImages, CustomField, getCustomFields } from '../../../shared/models/customisation';
|
||||||
CustomField,
|
|
||||||
getCustomFields } from '../../../shared/models/customisation';
|
|
||||||
import { Classification } from '../../../shared/models/classification';
|
import { Classification } from '../../../shared/models/classification';
|
||||||
import { customFieldCount } from '../../../shared/models/classification-summary';
|
import { customFieldCount } from '../../../shared/models/classification-summary';
|
||||||
import { CategoriesResponse } from '../../../shared/services/classification-categories/classification-categories.service';
|
import { CategoriesResponse } from '../../../shared/services/classification-categories/classification-categories.service';
|
||||||
|
|
||||||
import { SaveCreatedClassification,
|
import {
|
||||||
|
SaveCreatedClassification,
|
||||||
RemoveSelectedClassification,
|
RemoveSelectedClassification,
|
||||||
RestoreSelectedClassification,
|
RestoreSelectedClassification,
|
||||||
SaveModifiedClassification,
|
SaveModifiedClassification,
|
||||||
SelectClassification,
|
SelectClassification,
|
||||||
CopyClassification } from '../../../shared/store/classification-store/classification.actions';
|
CopyClassification
|
||||||
|
} from '../../../shared/store/classification-store/classification.actions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-administration-classification-details',
|
selector: 'taskana-administration-classification-details',
|
||||||
|
@ -63,29 +63,32 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
|
||||||
private notificationsService: NotificationService,
|
private notificationsService: NotificationService,
|
||||||
private importExportService: ImportExportService,
|
private importExportService: ImportExportService,
|
||||||
private store: Store
|
private store: Store
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.customFields$ = this.store.select(EngineConfigurationSelectors.classificationsCustomisation).pipe(
|
this.customFields$ = this.store.select(EngineConfigurationSelectors.classificationsCustomisation).pipe(
|
||||||
map(customisation => customisation.information),
|
map((customisation) => customisation.information),
|
||||||
getCustomFields(customFieldCount)
|
getCustomFields(customFieldCount)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.selectedClassification$.pipe(takeUntil(this.destroy$))
|
this.selectedClassification$.pipe(takeUntil(this.destroy$)).subscribe((classification) => {
|
||||||
.subscribe(classification => {
|
this.classification = { ...classification };
|
||||||
this.classification = { ...classification };
|
this.isCreatingNewClassification = typeof this.classification.classificationId === 'undefined';
|
||||||
this.isCreatingNewClassification = typeof this.classification.classificationId === 'undefined';
|
|
||||||
});
|
|
||||||
|
|
||||||
this.importExportService.getImportingFinished().pipe(takeUntil(this.destroy$)).subscribe(() => {
|
|
||||||
this.store.dispatch(new SelectClassification(this.classification.classificationId));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.importExportService
|
||||||
|
.getImportingFinished()
|
||||||
|
.pipe(takeUntil(this.destroy$))
|
||||||
|
.subscribe(() => {
|
||||||
|
this.store.dispatch(new SelectClassification(this.classification.classificationId));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
removeClassification() {
|
removeClassification() {
|
||||||
this.notificationsService.showDialog(`You are going to delete classification: ${this.classification.key}. Can you confirm this action?`,
|
this.notificationsService.showDialog(
|
||||||
this.removeClassificationConfirmation.bind(this));
|
`You are going to delete classification: ${this.classification.key}. Can you confirm this action?`,
|
||||||
|
this.removeClassificationConfirmation.bind(this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
isFieldValid(field: string): boolean {
|
isFieldValid(field: string): boolean {
|
||||||
|
@ -94,20 +97,23 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.formsValidatorService.formSubmitAttempt = true;
|
this.formsValidatorService.formSubmitAttempt = true;
|
||||||
this.formsValidatorService.validateFormInformation(this.classificationForm, this.toogleValidationMap).then(value => {
|
this.formsValidatorService
|
||||||
if (value) {
|
.validateFormInformation(this.classificationForm, this.toogleValidationMap)
|
||||||
this.onSave();
|
.then((value) => {
|
||||||
}
|
if (value) {
|
||||||
});
|
this.onSave();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onRestore() {
|
onRestore() {
|
||||||
this.formsValidatorService.formSubmitAttempt = false;
|
this.formsValidatorService.formSubmitAttempt = false;
|
||||||
this.store.dispatch(
|
this.store
|
||||||
new RestoreSelectedClassification(this.classification.classificationId)
|
.dispatch(new RestoreSelectedClassification(this.classification.classificationId))
|
||||||
).pipe(take(1)).subscribe(() => {
|
.pipe(take(1))
|
||||||
this.notificationsService.showToast(NOTIFICATION_TYPES.INFO_ALERT);
|
.subscribe(() => {
|
||||||
});
|
this.notificationsService.showToast(NOTIFICATION_TYPES.INFO_ALERT);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onCopy() {
|
onCopy() {
|
||||||
|
@ -123,11 +129,13 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategoryIcon(category: string): Observable<Pair> {
|
getCategoryIcon(category: string): Observable<Pair> {
|
||||||
return this.categoryIcons$.pipe(map(
|
return this.categoryIcons$.pipe(
|
||||||
iconMap => (iconMap[category]
|
map((iconMap) =>
|
||||||
? new Pair(iconMap[category], category)
|
iconMap[category]
|
||||||
: new Pair(iconMap.missing, 'Category does not match with the configuration'))
|
? new Pair(iconMap[category], category)
|
||||||
));
|
: new Pair(iconMap.missing, 'Category does not match with the configuration')
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
spinnerRunning(value) {
|
spinnerRunning(value) {
|
||||||
|
@ -147,7 +155,10 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
getAvailableCategories(type: string): Observable<string[]> {
|
getAvailableCategories(type: string): Observable<string[]> {
|
||||||
return this.classificationTypes$.pipe(take(1), map(classTypes => classTypes[type]));
|
return this.classificationTypes$.pipe(
|
||||||
|
take(1),
|
||||||
|
map((classTypes) => classTypes[type])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
|
@ -158,26 +169,36 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
|
||||||
private async onSave() {
|
private async onSave() {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
if (typeof this.classification.classificationId === 'undefined') {
|
if (typeof this.classification.classificationId === 'undefined') {
|
||||||
this.store.dispatch(
|
this.store
|
||||||
new SaveCreatedClassification(this.classification)
|
.dispatch(new SaveCreatedClassification(this.classification))
|
||||||
).pipe(take(1)).subscribe(store => {
|
.pipe(take(1))
|
||||||
this.notificationsService.showToast(
|
.subscribe(
|
||||||
NOTIFICATION_TYPES.SUCCESS_ALERT_2,
|
(store) => {
|
||||||
new Map<string, string>([['classificationKey', store.classification.selectedClassification.key]])
|
this.notificationsService.showToast(
|
||||||
|
NOTIFICATION_TYPES.SUCCESS_ALERT_2,
|
||||||
|
new Map<string, string>([['classificationKey', store.classification.selectedClassification.key]])
|
||||||
|
);
|
||||||
|
this.location.go(
|
||||||
|
this.location
|
||||||
|
.path()
|
||||||
|
.replace(
|
||||||
|
/(classifications).*/g,
|
||||||
|
`classifications/(detail:${store.classification.selectedClassification.classificationId})`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
this.afterRequest();
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.notificationsService.triggerError(NOTIFICATION_TYPES.CREATE_ERR, error);
|
||||||
|
this.afterRequest();
|
||||||
|
}
|
||||||
);
|
);
|
||||||
this.location.go(this.location.path().replace(
|
|
||||||
/(classifications).*/g,
|
|
||||||
`classifications/(detail:${store.classification.selectedClassification.classificationId})`
|
|
||||||
));
|
|
||||||
this.afterRequest();
|
|
||||||
}, error => {
|
|
||||||
this.notificationsService.triggerError(NOTIFICATION_TYPES.CREATE_ERR, error);
|
|
||||||
this.afterRequest();
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
this.store.dispatch(new SaveModifiedClassification(this.classification))
|
this.store
|
||||||
.pipe(take(1)).subscribe(() => {
|
.dispatch(new SaveModifiedClassification(this.classification))
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe(() => {
|
||||||
this.afterRequest();
|
this.afterRequest();
|
||||||
this.notificationsService.showToast(
|
this.notificationsService.showToast(
|
||||||
NOTIFICATION_TYPES.SUCCESS_ALERT_3,
|
NOTIFICATION_TYPES.SUCCESS_ALERT_3,
|
||||||
|
@ -202,11 +223,16 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
|
|
||||||
this.store.dispatch(new RemoveSelectedClassification()).pipe(take(1)).subscribe(() => {
|
this.store
|
||||||
this.notificationsService.showToast(NOTIFICATION_TYPES.SUCCESS_ALERT_4,
|
.dispatch(new RemoveSelectedClassification())
|
||||||
new Map<string, string>([['classificationKey', this.classification.key]]));
|
.pipe(take(1))
|
||||||
this.afterRequest();
|
.subscribe(() => {
|
||||||
});
|
this.notificationsService.showToast(
|
||||||
|
NOTIFICATION_TYPES.SUCCESS_ALERT_4,
|
||||||
|
new Map<string, string>([['classificationKey', this.classification.key]])
|
||||||
|
);
|
||||||
|
this.afterRequest();
|
||||||
|
});
|
||||||
this.location.go(this.location.path().replace(/(classifications).*/g, 'classifications'));
|
this.location.go(this.location.path().replace(/(classifications).*/g, 'classifications'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-align{
|
.tab-align {
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
border-bottom: 1px dotted #ddd;
|
border-bottom: 1px dotted #ddd;
|
||||||
padding: 8px 12px 8px 4px;
|
padding: 8px 12px 8px 4px;
|
||||||
&>div{
|
& > div {
|
||||||
margin: 6px 0px;
|
margin: 6px 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,10 +25,10 @@ input.filter-input {
|
||||||
}
|
}
|
||||||
|
|
||||||
.category-filter {
|
.category-filter {
|
||||||
margin: 7px 2px;
|
margin: 7px 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu-classification{
|
.dropdown-menu-classification {
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
min-width: 0px;
|
min-width: 0px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,9 @@ import { NotificationService } from '../../../shared/services/notifications/noti
|
||||||
selector: 'taskana-dummy-detail',
|
selector: 'taskana-dummy-detail',
|
||||||
template: 'dummydetail'
|
template: 'dummydetail'
|
||||||
})
|
})
|
||||||
class DummyDetailComponent {
|
class DummyDetailComponent {}
|
||||||
}
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [{ path: ':id', component: DummyDetailComponent }];
|
||||||
{ path: ':id', component: DummyDetailComponent }
|
|
||||||
];
|
|
||||||
|
|
||||||
describe('ClassificationListComponent', () => {
|
describe('ClassificationListComponent', () => {
|
||||||
let component: ClassificationListComponent;
|
let component: ClassificationListComponent;
|
||||||
|
@ -43,19 +40,35 @@ describe('ClassificationListComponent', () => {
|
||||||
|
|
||||||
const configure = (testBed: TestBed) => {
|
const configure = (testBed: TestBed) => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
declarations: [ClassificationListComponent, ImportExportComponent, ClassificationTypesSelectorComponent,
|
declarations: [
|
||||||
DummyDetailComponent],
|
ClassificationListComponent,
|
||||||
imports: [HttpClientModule, RouterTestingModule.withRoutes(routes), FormsModule, AngularSvgIconModule, NgxsModule.forRoot([]), MatRadioModule],
|
ImportExportComponent,
|
||||||
|
ClassificationTypesSelectorComponent,
|
||||||
|
DummyDetailComponent
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
HttpClientModule,
|
||||||
|
RouterTestingModule.withRoutes(routes),
|
||||||
|
FormsModule,
|
||||||
|
AngularSvgIconModule,
|
||||||
|
NgxsModule.forRoot([]),
|
||||||
|
MatRadioModule
|
||||||
|
],
|
||||||
providers: [
|
providers: [
|
||||||
HttpClient, WorkbasketDefinitionService, NotificationService,
|
HttpClient,
|
||||||
ClassificationsService, DomainService, ClassificationDefinitionService,
|
WorkbasketDefinitionService,
|
||||||
RequestInProgressService, ImportExportService
|
NotificationService,
|
||||||
|
ClassificationsService,
|
||||||
|
DomainService,
|
||||||
|
ClassificationDefinitionService,
|
||||||
|
RequestInProgressService,
|
||||||
|
ImportExportService
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
fixture = testBed.createComponent(ClassificationListComponent);
|
fixture = testBed.createComponent(ClassificationListComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,10 @@ import { ClassificationSelectors } from 'app/shared/store/classification-store/c
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
import { ClassificationCategoryImages } from '../../../shared/models/customisation';
|
import { ClassificationCategoryImages } from '../../../shared/models/customisation';
|
||||||
|
|
||||||
import { GetClassifications,
|
import {
|
||||||
CreateClassification } from '../../../shared/store/classification-store/classification.actions';
|
GetClassifications,
|
||||||
|
CreateClassification
|
||||||
|
} from '../../../shared/store/classification-store/classification.actions';
|
||||||
import { DomainService } from '../../../shared/services/domain/domain.service';
|
import { DomainService } from '../../../shared/services/domain/domain.service';
|
||||||
import { ClassificationSummary } from '../../../shared/models/classification-summary';
|
import { ClassificationSummary } from '../../../shared/models/classification-summary';
|
||||||
|
|
||||||
|
@ -44,40 +46,38 @@ export class ClassificationListComponent implements OnInit, OnDestroy {
|
||||||
private ngxsActions$: Actions,
|
private ngxsActions$: Actions,
|
||||||
private domainService: DomainService
|
private domainService: DomainService
|
||||||
) {
|
) {
|
||||||
this.ngxsActions$.pipe(ofActionDispatched(GetClassifications),
|
this.ngxsActions$.pipe(ofActionDispatched(GetClassifications), takeUntil(this.destroy$)).subscribe(() => {
|
||||||
takeUntil(this.destroy$))
|
this.requestInProgress = true;
|
||||||
.subscribe(() => {
|
});
|
||||||
this.requestInProgress = true;
|
this.ngxsActions$.pipe(ofActionCompleted(GetClassifications), takeUntil(this.destroy$)).subscribe(() => {
|
||||||
});
|
this.requestInProgress = false;
|
||||||
this.ngxsActions$.pipe(ofActionCompleted(GetClassifications),
|
});
|
||||||
takeUntil(this.destroy$))
|
|
||||||
.subscribe(() => {
|
|
||||||
this.requestInProgress = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.classifications$.pipe(takeUntil(this.destroy$)).subscribe(classifications => {
|
this.classifications$.pipe(takeUntil(this.destroy$)).subscribe((classifications) => {
|
||||||
this.classifications = classifications;
|
this.classifications = classifications;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.classificationTypeSelected$
|
this.classificationTypeSelected$.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
||||||
.pipe(takeUntil(this.destroy$))
|
this.store.dispatch(new GetClassifications());
|
||||||
.subscribe(() => {
|
this.selectedCategory = '';
|
||||||
this.store.dispatch(new GetClassifications());
|
});
|
||||||
this.selectedCategory = '';
|
|
||||||
});
|
|
||||||
|
|
||||||
this.importExportService.getImportingFinished()
|
this.importExportService
|
||||||
|
.getImportingFinished()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
this.store.dispatch(new GetClassifications());
|
this.store.dispatch(new GetClassifications());
|
||||||
});
|
});
|
||||||
|
|
||||||
// needed, so that the list updates, when domain gets changed (could be placed anywhere and should be removed, when domain is in store)
|
// needed, so that the list updates, when domain gets changed (could be placed anywhere and should be removed, when domain is in store)
|
||||||
this.domainService.getSelectedDomain().pipe(takeUntil(this.destroy$)).subscribe(domain => {
|
this.domainService
|
||||||
this.store.dispatch(GetClassifications);
|
.getSelectedDomain()
|
||||||
});
|
.pipe(takeUntil(this.destroy$))
|
||||||
|
.subscribe((domain) => {
|
||||||
|
this.store.dispatch(GetClassifications);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addClassification() {
|
addClassification() {
|
||||||
|
@ -91,10 +91,10 @@ export class ClassificationListComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
getCategoryIcon(category: string): Observable<Pair> {
|
getCategoryIcon(category: string): Observable<Pair> {
|
||||||
return this.categoryIcons$.pipe(
|
return this.categoryIcons$.pipe(
|
||||||
map(
|
map((iconMap) =>
|
||||||
iconMap => (iconMap[category]
|
iconMap[category]
|
||||||
? new Pair(iconMap[category], category)
|
? new Pair(iconMap[category], category)
|
||||||
: new Pair(iconMap.missing, 'Category does not match with the configuration'))
|
: new Pair(iconMap.missing, 'Category does not match with the configuration')
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,7 @@ import { ClassificationOverviewComponent } from './classification-overview.compo
|
||||||
selector: 'taskana-dummy-detail',
|
selector: 'taskana-dummy-detail',
|
||||||
template: 'dummydetail'
|
template: 'dummydetail'
|
||||||
})
|
})
|
||||||
export class DummyDetailComponent {
|
export class DummyDetailComponent {}
|
||||||
}
|
|
||||||
|
|
||||||
describe('ClassificationOverviewComponent', () => {
|
describe('ClassificationOverviewComponent', () => {
|
||||||
let component: ClassificationOverviewComponent;
|
let component: ClassificationOverviewComponent;
|
||||||
|
@ -20,21 +19,13 @@ describe('ClassificationOverviewComponent', () => {
|
||||||
let debugElement;
|
let debugElement;
|
||||||
const locationSpy: jasmine.SpyObj<Location> = jasmine.createSpyObj('Location', ['go']);
|
const locationSpy: jasmine.SpyObj<Location> = jasmine.createSpyObj('Location', ['go']);
|
||||||
|
|
||||||
beforeEach((() => {
|
beforeEach(() => {
|
||||||
const routes: Routes = [
|
const routes: Routes = [{ path: ':id', component: DummyDetailComponent }];
|
||||||
{ path: ':id', component: DummyDetailComponent }
|
|
||||||
];
|
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [
|
declarations: [ClassificationOverviewComponent, DummyDetailComponent],
|
||||||
ClassificationOverviewComponent,
|
imports: [RouterTestingModule.withRoutes(routes), NgxsModule.forRoot()],
|
||||||
DummyDetailComponent],
|
providers: [{ provide: Location, useValue: locationSpy }],
|
||||||
imports: [
|
|
||||||
RouterTestingModule.withRoutes(routes),
|
|
||||||
NgxsModule.forRoot()],
|
|
||||||
providers: [
|
|
||||||
{ provide: Location, useValue: locationSpy },
|
|
||||||
],
|
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -44,7 +35,7 @@ describe('ClassificationOverviewComponent', () => {
|
||||||
router = TestBed.get(Router);
|
router = TestBed.get(Router);
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
|
|
|
@ -4,7 +4,11 @@ import { Observable, Subject } from 'rxjs';
|
||||||
import { Select, Store } from '@ngxs/store';
|
import { Select, Store } from '@ngxs/store';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
import { ClassificationSelectors } from '../../../shared/store/classification-store/classification.selectors';
|
import { ClassificationSelectors } from '../../../shared/store/classification-store/classification.selectors';
|
||||||
import { GetClassifications, SelectClassification, CreateClassification } from '../../../shared/store/classification-store/classification.actions';
|
import {
|
||||||
|
GetClassifications,
|
||||||
|
SelectClassification,
|
||||||
|
CreateClassification
|
||||||
|
} from '../../../shared/store/classification-store/classification.actions';
|
||||||
import { Classification } from '../../../shared/models/classification';
|
import { Classification } from '../../../shared/models/classification';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -18,35 +22,28 @@ export class ClassificationOverviewComponent implements OnInit, OnDestroy {
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
routerParams: any;
|
routerParams: any;
|
||||||
|
|
||||||
constructor(
|
constructor(private route: ActivatedRoute, private store: Store) {}
|
||||||
private route: ActivatedRoute,
|
|
||||||
private store: Store
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.route.firstChild) {
|
if (this.route.firstChild) {
|
||||||
this.route.firstChild.params
|
this.route.firstChild.params.pipe(takeUntil(this.destroy$)).subscribe((params) => {
|
||||||
.pipe(takeUntil(this.destroy$))
|
this.routerParams = params;
|
||||||
.subscribe(params => {
|
|
||||||
this.routerParams = params;
|
|
||||||
|
|
||||||
if (this.routerParams.id) {
|
if (this.routerParams.id) {
|
||||||
this.showDetail = true;
|
this.showDetail = true;
|
||||||
this.store.dispatch(new SelectClassification(this.routerParams.id))
|
this.store
|
||||||
.subscribe(() => this.store.dispatch(new GetClassifications()));
|
.dispatch(new SelectClassification(this.routerParams.id))
|
||||||
}
|
.subscribe(() => this.store.dispatch(new GetClassifications()));
|
||||||
if (this.routerParams.id && this.routerParams.id.indexOf('new-classification') !== -1) {
|
}
|
||||||
this.store.dispatch(new CreateClassification());
|
if (this.routerParams.id && this.routerParams.id.indexOf('new-classification') !== -1) {
|
||||||
}
|
this.store.dispatch(new CreateClassification());
|
||||||
});
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.selectedClassification$
|
this.selectedClassification$.pipe(takeUntil(this.destroy$)).subscribe((selectedClassification) => {
|
||||||
.pipe(takeUntil(this.destroy$))
|
this.showDetail = !!selectedClassification;
|
||||||
.subscribe(selectedClassification => {
|
});
|
||||||
this.showDetail = !!selectedClassification;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
|
|
@ -14,9 +14,7 @@ describe('ClassificationTypesSelectorComponent', () => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [NgxsModule.forRoot(), MatRadioModule],
|
imports: [NgxsModule.forRoot(), MatRadioModule],
|
||||||
declarations: [ClassificationTypesSelectorComponent],
|
declarations: [ClassificationTypesSelectorComponent],
|
||||||
providers: [
|
providers: [{ provide: Location, useValue: locationSpy }]
|
||||||
{ provide: Location, useValue: locationSpy },
|
|
||||||
]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -15,16 +15,21 @@ describe('ImportExportComponent', () => {
|
||||||
let fixture: ComponentFixture<ImportExportComponent>;
|
let fixture: ComponentFixture<ImportExportComponent>;
|
||||||
let debugElement;
|
let debugElement;
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
const configure = (testBed: TestBed) => {
|
const configure = (testBed: TestBed) => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
declarations: [ImportExportComponent],
|
declarations: [ImportExportComponent],
|
||||||
imports: [HttpClientModule, AngularSvgIconModule],
|
imports: [HttpClientModule, AngularSvgIconModule],
|
||||||
providers: [WorkbasketService, ClassificationDefinitionService, WorkbasketDefinitionService, NotificationService,
|
providers: [
|
||||||
ImportExportService]
|
WorkbasketService,
|
||||||
|
ClassificationDefinitionService,
|
||||||
|
WorkbasketDefinitionService,
|
||||||
|
NotificationService,
|
||||||
|
ImportExportService
|
||||||
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
fixture = TestBed.createComponent(ImportExportComponent);
|
fixture = TestBed.createComponent(ImportExportComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
debugElement = fixture.debugElement.nativeElement;
|
debugElement = fixture.debugElement.nativeElement;
|
||||||
|
|
|
@ -32,15 +32,12 @@ export class ImportExportComponent implements OnInit {
|
||||||
public uploadservice: UploadService,
|
public uploadservice: UploadService,
|
||||||
private errorsService: NotificationService,
|
private errorsService: NotificationService,
|
||||||
private importExportService: ImportExportService
|
private importExportService: ImportExportService
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.domainService.getDomains().subscribe(
|
this.domainService.getDomains().subscribe((data) => {
|
||||||
data => {
|
this.domains = data;
|
||||||
this.domains = data;
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export(domain = '') {
|
export(domain = '') {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.text-top{
|
.text-top {
|
||||||
vertical-align: text-top;
|
vertical-align: text-top;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg-icon.blue.fa-fw {
|
svg-icon.blue.fa-fw {
|
||||||
|
|
|
@ -37,16 +37,18 @@ describe('TaskanaTreeComponent', () => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
imports: [AngularSvgIconModule, HttpClientModule, NgxsModule.forRoot()],
|
imports: [AngularSvgIconModule, HttpClientModule, NgxsModule.forRoot()],
|
||||||
declarations: [TreeVendorComponent],
|
declarations: [TreeVendorComponent],
|
||||||
providers: [ClassificationsService,
|
providers: [
|
||||||
|
ClassificationsService,
|
||||||
{ provide: Location, useValue: locationSpy },
|
{ provide: Location, useValue: locationSpy },
|
||||||
{ provide: Store, useValue: storeSpy }]
|
{ provide: Store, useValue: storeSpy }
|
||||||
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
locationSpy.path.and.callFake(() => '');
|
locationSpy.path.and.callFake(() => '');
|
||||||
storeSpy.select.and.callFake(selector => {
|
storeSpy.select.and.callFake((selector) => {
|
||||||
switch (selector) {
|
switch (selector) {
|
||||||
case ClassificationSelectors.selectedClassificationId:
|
case ClassificationSelectors.selectedClassificationId:
|
||||||
return of('id4');
|
return of('id4');
|
||||||
|
@ -96,7 +98,7 @@ describe('TaskanaTreeComponent', () => {
|
||||||
name: 'classification4',
|
name: 'classification4',
|
||||||
description: 'description',
|
description: 'description',
|
||||||
priority: 1,
|
priority: 1,
|
||||||
serviceLevel: 'level',
|
serviceLevel: 'level'
|
||||||
};
|
};
|
||||||
|
|
||||||
// using parameter 'any' since getClassification is a private method
|
// using parameter 'any' since getClassification is a private method
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { AfterViewChecked,
|
import {
|
||||||
|
AfterViewChecked,
|
||||||
Component,
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
|
@ -7,7 +8,8 @@ import { AfterViewChecked,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
Output,
|
Output,
|
||||||
ViewChild } from '@angular/core';
|
ViewChild
|
||||||
|
} from '@angular/core';
|
||||||
import { TreeNodeModel } from 'app/administration/models/tree-node';
|
import { TreeNodeModel } from 'app/administration/models/tree-node';
|
||||||
|
|
||||||
import { ITreeOptions, KEYS, TREE_ACTIONS, TreeComponent } from 'angular-tree-component';
|
import { ITreeOptions, KEYS, TREE_ACTIONS, TreeComponent } from 'angular-tree-component';
|
||||||
|
@ -24,15 +26,17 @@ import { Classification } from '../../../shared/models/classification';
|
||||||
import { ClassificationsService } from '../../../shared/services/classifications/classifications.service';
|
import { ClassificationsService } from '../../../shared/services/classifications/classifications.service';
|
||||||
import { ClassificationCategoryImages } from '../../../shared/models/customisation';
|
import { ClassificationCategoryImages } from '../../../shared/models/customisation';
|
||||||
import { ClassificationSelectors } from '../../../shared/store/classification-store/classification.selectors';
|
import { ClassificationSelectors } from '../../../shared/store/classification-store/classification.selectors';
|
||||||
import { DeselectClassification,
|
import {
|
||||||
|
DeselectClassification,
|
||||||
SelectClassification,
|
SelectClassification,
|
||||||
UpdateClassification } from '../../../shared/store/classification-store/classification.actions';
|
UpdateClassification
|
||||||
|
} from '../../../shared/store/classification-store/classification.actions';
|
||||||
import { ClassificationTreeService } from '../../services/classification-tree.service';
|
import { ClassificationTreeService } from '../../services/classification-tree.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-administration-tree',
|
selector: 'taskana-administration-tree',
|
||||||
templateUrl: './tree.component.html',
|
templateUrl: './tree.component.html',
|
||||||
styleUrls: ['./tree.component.scss'],
|
styleUrls: ['./tree.component.scss']
|
||||||
})
|
})
|
||||||
export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy {
|
export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy {
|
||||||
treeNodes: TreeNodeModel[];
|
treeNodes: TreeNodeModel[];
|
||||||
|
@ -75,8 +79,7 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy
|
||||||
private store: Store,
|
private store: Store,
|
||||||
private notificationsService: NotificationService,
|
private notificationsService: NotificationService,
|
||||||
private classificationTreeService: ClassificationTreeService
|
private classificationTreeService: ClassificationTreeService
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
@HostListener('document:click', ['$event'])
|
@HostListener('document:click', ['$event'])
|
||||||
onDocumentClick(event) {
|
onDocumentClick(event) {
|
||||||
|
@ -87,11 +90,12 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
const computedTreeNodes$: Observable<TreeNodeModel[]> = this.classifications$.pipe(
|
const computedTreeNodes$: Observable<TreeNodeModel[]> = this.classifications$.pipe(
|
||||||
filter(classifications => typeof (classifications) !== 'undefined'),
|
filter((classifications) => typeof classifications !== 'undefined'),
|
||||||
map(classifications => this.classificationTreeService.transformToTreeNode(classifications))
|
map((classifications) => this.classificationTreeService.transformToTreeNode(classifications))
|
||||||
);
|
);
|
||||||
|
|
||||||
combineLatest([this.selectedClassificationId$, computedTreeNodes$]).pipe(takeUntil(this.destroy$))
|
combineLatest([this.selectedClassificationId$, computedTreeNodes$])
|
||||||
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe(([selectedClassificationId, treeNodes]) => {
|
.subscribe(([selectedClassificationId, treeNodes]) => {
|
||||||
this.treeNodes = treeNodes;
|
this.treeNodes = treeNodes;
|
||||||
this.selectNodeId = typeof selectedClassificationId !== 'undefined' ? selectedClassificationId : undefined;
|
this.selectNodeId = typeof selectedClassificationId !== 'undefined' ? selectedClassificationId : undefined;
|
||||||
|
@ -122,8 +126,7 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.filterTextOld !== this.filterText
|
if (this.filterTextOld !== this.filterText || this.filterIconOld !== this.filterIcon) {
|
||||||
|| this.filterIconOld !== this.filterIcon) {
|
|
||||||
this.filterIconOld = this.filterIcon;
|
this.filterIconOld = this.filterIcon;
|
||||||
this.filterTextOld = this.filterText;
|
this.filterTextOld = this.filterText;
|
||||||
this.filterNodes(this.filterText ? this.filterText : '', this.filterIcon);
|
this.filterNodes(this.filterText ? this.filterText : '', this.filterIcon);
|
||||||
|
@ -166,11 +169,13 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategoryIcon(category: string): Observable<Pair> {
|
getCategoryIcon(category: string): Observable<Pair> {
|
||||||
return this.categoryIcons$.pipe(map(
|
return this.categoryIcons$.pipe(
|
||||||
iconMap => (iconMap[category]
|
map((iconMap) =>
|
||||||
? new Pair(iconMap[category], category)
|
iconMap[category]
|
||||||
: new Pair(iconMap.missing, 'Category does not match with the configuration'))
|
? new Pair(iconMap[category], category)
|
||||||
));
|
: new Pair(iconMap.missing, 'Category does not match with the configuration')
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
switchTaskanaSpinner(active: boolean) {
|
switchTaskanaSpinner(active: boolean) {
|
||||||
|
@ -203,18 +208,20 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
private filterNodes(text, iconText) {
|
private filterNodes(text, iconText) {
|
||||||
this.tree.treeModel.filterNodes(node => TaskanaTreeComponent.checkNameAndKey(node, text)
|
this.tree.treeModel.filterNodes(
|
||||||
&& TaskanaTreeComponent.checkIcon(node, iconText));
|
(node) => TaskanaTreeComponent.checkNameAndKey(node, text) && TaskanaTreeComponent.checkIcon(node, iconText)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static checkNameAndKey(node: any, text: string): boolean {
|
private static checkNameAndKey(node: any, text: string): boolean {
|
||||||
return (node.data.name.toUpperCase().includes(text.toUpperCase())
|
return (
|
||||||
|| node.data.key.toUpperCase().includes(text.toUpperCase()));
|
node.data.name.toUpperCase().includes(text.toUpperCase()) ||
|
||||||
|
node.data.key.toUpperCase().includes(text.toUpperCase())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static checkIcon(node: any, iconText: string): boolean {
|
private static checkIcon(node: any, iconText: string): boolean {
|
||||||
return (node.data.category.toUpperCase() === iconText.toUpperCase()
|
return node.data.category.toUpperCase() === iconText.toUpperCase() || iconText === '';
|
||||||
|| iconText === '');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private manageTreeState() {
|
private manageTreeState() {
|
||||||
|
@ -225,10 +232,10 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkValidElements(event): boolean {
|
private checkValidElements(event): boolean {
|
||||||
return (this.elementRef.nativeElement.contains(event.target)
|
return (
|
||||||
|| this.elementRef.nativeElement === event.target)
|
(this.elementRef.nativeElement.contains(event.target) || this.elementRef.nativeElement === event.target) &&
|
||||||
&& (event.target.localName === 'tree-viewport'
|
(event.target.localName === 'tree-viewport' || event.target.localName === 'taskana-tree')
|
||||||
|| event.target.localName === 'taskana-tree');
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getClassification(classificationId: string): Promise<Classification> {
|
private getClassification(classificationId: string): Promise<Classification> {
|
||||||
|
@ -236,14 +243,13 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateClassification(classification: Classification) {
|
private updateClassification(classification: Classification) {
|
||||||
this.store.dispatch(new UpdateClassification(classification))
|
this.store.dispatch(new UpdateClassification(classification)).subscribe(() => {
|
||||||
.subscribe(() => {
|
this.notificationsService.showToast(
|
||||||
this.notificationsService.showToast(
|
NOTIFICATION_TYPES.SUCCESS_ALERT_5,
|
||||||
NOTIFICATION_TYPES.SUCCESS_ALERT_5,
|
new Map<string, string>([['classificationKey', classification.key]])
|
||||||
new Map<string, string>([['classificationKey', classification.key]])
|
);
|
||||||
);
|
this.switchTaskanaSpinner(false);
|
||||||
this.switchTaskanaSpinner(false);
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private collapseParentNodeIfItIsTheLastChild(node: any) {
|
private collapseParentNodeIfItIsTheLastChild(node: any) {
|
||||||
|
|
|
@ -9,13 +9,13 @@ describe('IconTypeComponent', () => {
|
||||||
let fixture: ComponentFixture<IconTypeComponent>;
|
let fixture: ComponentFixture<IconTypeComponent>;
|
||||||
let debugElement;
|
let debugElement;
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
const configure = (testBed: TestBed) => {
|
const configure = (testBed: TestBed) => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
imports: [AngularSvgIconModule, HttpClientModule]
|
imports: [AngularSvgIconModule, HttpClientModule]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
fixture = TestBed.createComponent(IconTypeComponent);
|
fixture = TestBed.createComponent(IconTypeComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
debugElement = fixture.debugElement.nativeElement;
|
debugElement = fixture.debugElement.nativeElement;
|
||||||
|
|
|
@ -20,20 +20,28 @@ export class IconTypeComponent implements OnInit {
|
||||||
text: string;
|
text: string;
|
||||||
|
|
||||||
public static get allTypes(): Map<string, string> {
|
public static get allTypes(): Map<string, string> {
|
||||||
return new Map([['PERSONAL', 'Personal'], ['GROUP', 'Group'], ['CLEARANCE', 'Clearance'], ['TOPIC', 'Topic']]);
|
return new Map([
|
||||||
|
['PERSONAL', 'Personal'],
|
||||||
|
['GROUP', 'Group'],
|
||||||
|
['CLEARANCE', 'Clearance'],
|
||||||
|
['TOPIC', 'Topic']
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
getIconPath(type: string) {
|
getIconPath(type: string) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'PERSONAL': return 'user.svg';
|
case 'PERSONAL':
|
||||||
case 'GROUP': return 'users.svg';
|
return 'user.svg';
|
||||||
case 'TOPIC': return 'topic.svg';
|
case 'GROUP':
|
||||||
case 'CLEARANCE': return 'clearance.svg';
|
return 'users.svg';
|
||||||
default: return 'asterisk.svg';
|
case 'TOPIC':
|
||||||
|
return 'topic.svg';
|
||||||
|
case 'CLEARANCE':
|
||||||
|
return 'clearance.svg';
|
||||||
|
default:
|
||||||
|
return 'asterisk.svg';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,33 @@
|
||||||
@import '../../../../theme/colors';
|
@import '../../../../theme/colors';
|
||||||
|
|
||||||
td > input[type="checkbox"] {
|
td > input[type='checkbox'] {
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
}
|
}
|
||||||
.panel-body {
|
.panel-body {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
.text-width{
|
.text-width {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 180px;
|
min-width: 180px;
|
||||||
}
|
}
|
||||||
.required-header {
|
.required-header {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
.required-header:after {
|
.required-header:after {
|
||||||
|
content: ' *';
|
||||||
content:" *";
|
color: red;
|
||||||
color: red;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
vertical-align: bottom !important;
|
vertical-align: bottom !important;
|
||||||
&.has-changes {
|
&.has-changes {
|
||||||
border-bottom: 1px solid #f0ad4e;;
|
border-bottom: 1px solid #f0ad4e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.table > thead > tr > th {
|
.table > thead > tr > th {
|
||||||
max-width: 150px;
|
max-width: 150px;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
taskana-shared-type-ahead {
|
taskana-shared-type-ahead {
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,18 +34,27 @@ describe('WorkbasketAccessItemsComponent', () => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
declarations: [WorkbasketAccessItemsComponent],
|
declarations: [WorkbasketAccessItemsComponent],
|
||||||
imports: [
|
imports: [
|
||||||
FormsModule, AngularSvgIconModule,
|
FormsModule,
|
||||||
HttpClientModule, ReactiveFormsModule,
|
AngularSvgIconModule,
|
||||||
NgxsModule.forRoot([WorkbasketState, EngineConfigurationState])],
|
HttpClientModule,
|
||||||
providers: [WorkbasketService, NotificationService, SavingWorkbasketService, RequestInProgressService,
|
ReactiveFormsModule,
|
||||||
AccessIdsService, FormsValidatorService, ClassificationCategoriesService,
|
NgxsModule.forRoot([WorkbasketState, EngineConfigurationState])
|
||||||
{ provide: Location, useValue: locationSpy },
|
],
|
||||||
|
providers: [
|
||||||
|
WorkbasketService,
|
||||||
|
NotificationService,
|
||||||
|
SavingWorkbasketService,
|
||||||
|
RequestInProgressService,
|
||||||
|
AccessIdsService,
|
||||||
|
FormsValidatorService,
|
||||||
|
ClassificationCategoriesService,
|
||||||
|
{ provide: Location, useValue: locationSpy }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
const store: Store = testBed.get(Store);
|
const store: Store = testBed.get(Store);
|
||||||
store.reset([WorkbasketState, EngineConfigurationState]);
|
store.reset([WorkbasketState, EngineConfigurationState]);
|
||||||
|
|
||||||
|
@ -59,31 +68,33 @@ describe('WorkbasketAccessItemsComponent', () => {
|
||||||
workbasketService = testBed.get(WorkbasketService);
|
workbasketService = testBed.get(WorkbasketService);
|
||||||
notificationsService = testBed.get(NotificationService);
|
notificationsService = testBed.get(NotificationService);
|
||||||
const workbasketAccessItemsRepresentation: WorkbasketAccessItemsRepresentation = {
|
const workbasketAccessItemsRepresentation: WorkbasketAccessItemsRepresentation = {
|
||||||
accessItems: [{
|
accessItems: [
|
||||||
accessId: 'accessID1',
|
{
|
||||||
workbasketId: 'id1',
|
accessId: 'accessID1',
|
||||||
workbasketKey: '1',
|
workbasketId: 'id1',
|
||||||
accessItemId: '',
|
workbasketKey: '1',
|
||||||
accessName: '',
|
accessItemId: '',
|
||||||
permRead: false,
|
accessName: '',
|
||||||
permOpen: false,
|
permRead: false,
|
||||||
permAppend: false,
|
permOpen: false,
|
||||||
permTransfer: false,
|
permAppend: false,
|
||||||
permDistribute: false,
|
permTransfer: false,
|
||||||
permCustom1: false,
|
permDistribute: false,
|
||||||
permCustom2: false,
|
permCustom1: false,
|
||||||
permCustom3: false,
|
permCustom2: false,
|
||||||
permCustom4: false,
|
permCustom3: false,
|
||||||
permCustom5: false,
|
permCustom4: false,
|
||||||
permCustom6: false,
|
permCustom5: false,
|
||||||
permCustom7: false,
|
permCustom6: false,
|
||||||
permCustom8: false,
|
permCustom7: false,
|
||||||
permCustom9: false,
|
permCustom8: false,
|
||||||
permCustom10: false,
|
permCustom9: false,
|
||||||
permCustom11: false,
|
permCustom10: false,
|
||||||
permCustom12: false,
|
permCustom11: false,
|
||||||
_links: {},
|
permCustom12: false,
|
||||||
}],
|
_links: {}
|
||||||
|
}
|
||||||
|
],
|
||||||
_links: { self: { href: 'someurl' } }
|
_links: { self: { href: 'someurl' } }
|
||||||
};
|
};
|
||||||
debugElement = fixture.debugElement.nativeElement;
|
debugElement = fixture.debugElement.nativeElement;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Component,
|
import {
|
||||||
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
Input,
|
Input,
|
||||||
OnChanges,
|
OnChanges,
|
||||||
|
@ -6,7 +7,8 @@ import { Component,
|
||||||
OnInit,
|
OnInit,
|
||||||
QueryList,
|
QueryList,
|
||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
ViewChildren } from '@angular/core';
|
ViewChildren
|
||||||
|
} from '@angular/core';
|
||||||
import { Observable, Subject } from 'rxjs';
|
import { Observable, Subject } from 'rxjs';
|
||||||
import { Select, Store } from '@ngxs/store';
|
import { Select, Store } from '@ngxs/store';
|
||||||
import { FormArray, FormBuilder, Validators } from '@angular/forms';
|
import { FormArray, FormBuilder, Validators } from '@angular/forms';
|
||||||
|
@ -27,8 +29,10 @@ import { takeUntil } from 'rxjs/operators';
|
||||||
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
||||||
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
||||||
import { AccessItemsCustomisation, CustomField, getCustomFields } from '../../../shared/models/customisation';
|
import { AccessItemsCustomisation, CustomField, getCustomFields } from '../../../shared/models/customisation';
|
||||||
import { GetWorkbasketAccessItems,
|
import {
|
||||||
UpdateWorkbasketAccessItems } from '../../../shared/store/workbasket-store/workbasket.actions';
|
GetWorkbasketAccessItems,
|
||||||
|
UpdateWorkbasketAccessItems
|
||||||
|
} from '../../../shared/store/workbasket-store/workbasket.actions';
|
||||||
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -81,8 +85,7 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
|
||||||
private formsValidatorService: FormsValidatorService,
|
private formsValidatorService: FormsValidatorService,
|
||||||
private notificationsService: NotificationService,
|
private notificationsService: NotificationService,
|
||||||
private store: Store
|
private store: Store
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
get accessItemsGroups(): FormArray {
|
get accessItemsGroups(): FormArray {
|
||||||
return this.AccessItemsForm.get('accessItemsGroups') as FormArray;
|
return this.AccessItemsForm.get('accessItemsGroups') as FormArray;
|
||||||
|
@ -90,7 +93,7 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.customFields$ = this.accessItemsCustomization$.pipe(getCustomFields(customFieldCount));
|
this.customFields$ = this.accessItemsCustomization$.pipe(getCustomFields(customFieldCount));
|
||||||
this.accessItemsRepresentation$.subscribe(accessItemsRepresentation => {
|
this.accessItemsRepresentation$.subscribe((accessItemsRepresentation) => {
|
||||||
if (typeof accessItemsRepresentation !== 'undefined') {
|
if (typeof accessItemsRepresentation !== 'undefined') {
|
||||||
this.accessItemsRepresentation = accessItemsRepresentation;
|
this.accessItemsRepresentation = accessItemsRepresentation;
|
||||||
this.setAccessItemsGroups(accessItemsRepresentation.accessItems);
|
this.setAccessItemsGroups(accessItemsRepresentation.accessItems);
|
||||||
|
@ -101,7 +104,7 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
this.inputs.changes.subscribe(next => {
|
this.inputs.changes.subscribe((next) => {
|
||||||
if (typeof next.last !== 'undefined') {
|
if (typeof next.last !== 'undefined') {
|
||||||
if (this.added) next.last.nativeElement.focus();
|
if (this.added) next.last.nativeElement.focus();
|
||||||
}
|
}
|
||||||
|
@ -131,7 +134,8 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
|
||||||
this.requestInProgress = false;
|
this.requestInProgress = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.savingWorkbaskets.triggeredAccessItemsSaving()
|
this.savingWorkbaskets
|
||||||
|
.triggeredAccessItemsSaving()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe((savingInformation: SavingInformation) => {
|
.subscribe((savingInformation: SavingInformation) => {
|
||||||
if (this.action === ACTION.COPY) {
|
if (this.action === ACTION.COPY) {
|
||||||
|
@ -144,8 +148,8 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
|
||||||
}
|
}
|
||||||
|
|
||||||
setAccessItemsGroups(accessItems: Array<WorkbasketAccessItems>) {
|
setAccessItemsGroups(accessItems: Array<WorkbasketAccessItems>) {
|
||||||
const AccessItemsFormGroups = accessItems.map(accessItem => this.formBuilder.group(accessItem));
|
const AccessItemsFormGroups = accessItems.map((accessItem) => this.formBuilder.group(accessItem));
|
||||||
AccessItemsFormGroups.forEach(accessItemGroup => {
|
AccessItemsFormGroups.forEach((accessItemGroup) => {
|
||||||
accessItemGroup.controls.accessId.setValidators(Validators.required);
|
accessItemGroup.controls.accessId.setValidators(Validators.required);
|
||||||
});
|
});
|
||||||
const AccessItemsFormArray = this.formBuilder.array(AccessItemsFormGroups);
|
const AccessItemsFormArray = this.formBuilder.array(AccessItemsFormGroups);
|
||||||
|
@ -176,7 +180,7 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
|
||||||
permCustom10: false,
|
permCustom10: false,
|
||||||
permCustom11: false,
|
permCustom11: false,
|
||||||
permCustom12: false,
|
permCustom12: false,
|
||||||
_links: {},
|
_links: {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,18 +214,25 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.formsValidatorService.formSubmitAttempt = true;
|
this.formsValidatorService.formSubmitAttempt = true;
|
||||||
this.formsValidatorService.validateFormAccess(this.accessItemsGroups, this.toggleValidationAccessIdMap).then(value => {
|
this.formsValidatorService
|
||||||
if (value) {
|
.validateFormAccess(this.accessItemsGroups, this.toggleValidationAccessIdMap)
|
||||||
this.onSave();
|
.then((value) => {
|
||||||
}
|
if (value) {
|
||||||
});
|
this.onSave();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAll(row: number, value: any) {
|
checkAll(row: number, value: any) {
|
||||||
const checkAll = value.target.checked;
|
const checkAll = value.target.checked;
|
||||||
const workbasketAccessItemsObj: WorkbasketAccessItems = this.createWorkbasketAccessItems();
|
const workbasketAccessItemsObj: WorkbasketAccessItems = this.createWorkbasketAccessItems();
|
||||||
Object.keys(workbasketAccessItemsObj).forEach(property => {
|
Object.keys(workbasketAccessItemsObj).forEach((property) => {
|
||||||
if (property !== 'accessId' && property !== '_links' && property !== 'workbasketId' && property !== 'accessItemId') {
|
if (
|
||||||
|
property !== 'accessId' &&
|
||||||
|
property !== '_links' &&
|
||||||
|
property !== 'workbasketId' &&
|
||||||
|
property !== 'accessItemId'
|
||||||
|
) {
|
||||||
this.accessItemsGroups.controls[row].get(property).setValue(checkAll);
|
this.accessItemsGroups.controls[row].get(property).setValue(checkAll);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -234,12 +245,16 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
|
||||||
|
|
||||||
private onSave() {
|
private onSave() {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
this.store.dispatch(new UpdateWorkbasketAccessItems(
|
this.store
|
||||||
this.accessItemsRepresentation._links.self.href,
|
.dispatch(
|
||||||
this.AccessItemsForm.value.accessItemsGroups
|
new UpdateWorkbasketAccessItems(
|
||||||
)).subscribe(() => {
|
this.accessItemsRepresentation._links.self.href,
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
this.AccessItemsForm.value.accessItemsGroups
|
||||||
});
|
)
|
||||||
|
)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private setBadge() {
|
private setBadge() {
|
||||||
|
@ -249,13 +264,13 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
|
||||||
}
|
}
|
||||||
|
|
||||||
private cloneAccessItems(inputaccessItem): Array<WorkbasketAccessItems> {
|
private cloneAccessItems(inputaccessItem): Array<WorkbasketAccessItems> {
|
||||||
return this.AccessItemsForm.value.accessItemsGroups.map(
|
return this.AccessItemsForm.value.accessItemsGroups.map((accessItems: WorkbasketAccessItems) => ({
|
||||||
(accessItems: WorkbasketAccessItems) => ({ ...accessItems })
|
...accessItems
|
||||||
);
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private setWorkbasketIdForCopy(workbasketId: string) {
|
private setWorkbasketIdForCopy(workbasketId: string) {
|
||||||
this.accessItemsGroups.value.forEach(element => {
|
this.accessItemsGroups.value.forEach((element) => {
|
||||||
delete element.accessItemId;
|
delete element.accessItemId;
|
||||||
element.workbasketId = workbasketId;
|
element.workbasketId = workbasketId;
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,12 +33,29 @@ import { NotificationService } from '../../../shared/services/notifications/noti
|
||||||
selector: 'taskana-dummy-detail',
|
selector: 'taskana-dummy-detail',
|
||||||
template: 'dummydetail'
|
template: 'dummydetail'
|
||||||
})
|
})
|
||||||
export class DummyDetailComponent {
|
export class DummyDetailComponent {}
|
||||||
}
|
|
||||||
|
|
||||||
function createWorkbasket(workbasketId?, created?, key?, domain?, type?, modified?, name?, description?,
|
function createWorkbasket(
|
||||||
owner?, custom1?, custom2?, custom3?, custom4?, orgLevel1?, orgLevel2?, orgLevel3?, orgLevel4?,
|
workbasketId?,
|
||||||
_links?: Links, markedForDeletion?: boolean) {
|
created?,
|
||||||
|
key?,
|
||||||
|
domain?,
|
||||||
|
type?,
|
||||||
|
modified?,
|
||||||
|
name?,
|
||||||
|
description?,
|
||||||
|
owner?,
|
||||||
|
custom1?,
|
||||||
|
custom2?,
|
||||||
|
custom3?,
|
||||||
|
custom4?,
|
||||||
|
orgLevel1?,
|
||||||
|
orgLevel2?,
|
||||||
|
orgLevel3?,
|
||||||
|
orgLevel4?,
|
||||||
|
_links?: Links,
|
||||||
|
markedForDeletion?: boolean
|
||||||
|
) {
|
||||||
const workbasket: Workbasket = {
|
const workbasket: Workbasket = {
|
||||||
workbasketId,
|
workbasketId,
|
||||||
created,
|
created,
|
||||||
|
@ -70,29 +87,63 @@ describe('WorkbasketDetailsComponent', () => {
|
||||||
let masterAndDetailService;
|
let masterAndDetailService;
|
||||||
let workbasketService;
|
let workbasketService;
|
||||||
let router;
|
let router;
|
||||||
const workbasket = createWorkbasket('1', '', '', '', ICONTYPES.TOPIC, '', '', '', '', '', '', '', '', '', '', '', '',
|
const workbasket = createWorkbasket(
|
||||||
{});
|
'1',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
ICONTYPES.TOPIC,
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
const workbasketSummaryRepresentation: WorkbasketSummaryRepresentation = { workbaskets: [], _links: {}, page: {} };
|
const workbasketSummaryRepresentation: WorkbasketSummaryRepresentation = { workbaskets: [], _links: {}, page: {} };
|
||||||
|
|
||||||
const workbasketAccessItemsRepresentation: WorkbasketAccessItemsRepresentation = { accessItems: [], _links: {} };
|
const workbasketAccessItemsRepresentation: WorkbasketAccessItemsRepresentation = { accessItems: [], _links: {} };
|
||||||
const routes: Routes = [
|
const routes: Routes = [{ path: '*', component: DummyDetailComponent }];
|
||||||
{ path: '*', component: DummyDetailComponent }
|
|
||||||
];
|
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
const configure = (testBed: TestBed) => {
|
const configure = (testBed: TestBed) => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
imports: [RouterTestingModule.withRoutes(routes), FormsModule, AngularSvgIconModule, HttpClientModule, ReactiveFormsModule,
|
imports: [
|
||||||
InfiniteScrollModule, NgxsModule.forRoot()],
|
RouterTestingModule.withRoutes(routes),
|
||||||
declarations: [WorkbasketDetailsComponent, WorkbasketInformationComponent,
|
FormsModule,
|
||||||
|
AngularSvgIconModule,
|
||||||
|
HttpClientModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
InfiniteScrollModule,
|
||||||
|
NgxsModule.forRoot()
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
WorkbasketDetailsComponent,
|
||||||
|
WorkbasketInformationComponent,
|
||||||
WorkbasketAccessItemsComponent,
|
WorkbasketAccessItemsComponent,
|
||||||
WorkbasketDistributionTargetsComponent, WorkbasketDualListComponent, DummyDetailComponent],
|
WorkbasketDistributionTargetsComponent,
|
||||||
providers: [WorkbasketService, MasterAndDetailService, RequestInProgressService,
|
WorkbasketDualListComponent,
|
||||||
NotificationService, SavingWorkbasketService, ImportExportService]
|
DummyDetailComponent
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
WorkbasketService,
|
||||||
|
MasterAndDetailService,
|
||||||
|
RequestInProgressService,
|
||||||
|
NotificationService,
|
||||||
|
SavingWorkbasketService,
|
||||||
|
ImportExportService
|
||||||
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
fixture = TestBed.createComponent(WorkbasketDetailsComponent);
|
fixture = TestBed.createComponent(WorkbasketDetailsComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
debugElement = fixture.debugElement.nativeElement;
|
debugElement = fixture.debugElement.nativeElement;
|
||||||
|
@ -106,7 +157,9 @@ describe('WorkbasketDetailsComponent', () => {
|
||||||
|
|
||||||
spyOn(workbasketService, 'getWorkBasket').and.callFake(() => of(workbasket));
|
spyOn(workbasketService, 'getWorkBasket').and.callFake(() => of(workbasket));
|
||||||
spyOn(workbasketService, 'getWorkBasketAccessItems').and.callFake(() => of(workbasketAccessItemsRepresentation));
|
spyOn(workbasketService, 'getWorkBasketAccessItems').and.callFake(() => of(workbasketAccessItemsRepresentation));
|
||||||
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => of(workbasketSummaryRepresentation));
|
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() =>
|
||||||
|
of(workbasketSummaryRepresentation)
|
||||||
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -40,34 +40,34 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
destroy$ = new Subject<void>();
|
destroy$ = new Subject<void>();
|
||||||
|
|
||||||
constructor(private service: WorkbasketService,
|
constructor(
|
||||||
|
private service: WorkbasketService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private domainService: DomainService,
|
private domainService: DomainService,
|
||||||
private importExportService: ImportExportService,
|
private importExportService: ImportExportService,
|
||||||
private store: Store) {
|
private store: Store
|
||||||
}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.selectedWorkbasketAndAction$
|
this.selectedWorkbasketAndAction$.pipe(takeUntil(this.destroy$)).subscribe((selectedWorkbasketAndAction) => {
|
||||||
.pipe(takeUntil(this.destroy$))
|
this.action = selectedWorkbasketAndAction.action;
|
||||||
.subscribe(selectedWorkbasketAndAction => {
|
if (this.action === ACTION.CREATE) {
|
||||||
this.action = selectedWorkbasketAndAction.action;
|
this.tabSelected = 'information';
|
||||||
if (this.action === ACTION.CREATE) {
|
this.selectedId = undefined;
|
||||||
this.tabSelected = 'information';
|
this.initWorkbasket();
|
||||||
this.selectedId = undefined;
|
} else if (this.action === ACTION.COPY) {
|
||||||
this.initWorkbasket();
|
// delete this.workbasket.key;
|
||||||
} else if (this.action === ACTION.COPY) {
|
this.workbasketCopy = this.workbasket;
|
||||||
// delete this.workbasket.key;
|
this.getWorkbasketInformation();
|
||||||
this.workbasketCopy = this.workbasket;
|
} else if (typeof selectedWorkbasketAndAction.selectedWorkbasket !== 'undefined') {
|
||||||
this.getWorkbasketInformation();
|
this.workbasket = { ...selectedWorkbasketAndAction.selectedWorkbasket };
|
||||||
} else if (typeof selectedWorkbasketAndAction.selectedWorkbasket !== 'undefined') {
|
this.getWorkbasketInformation(this.workbasket);
|
||||||
this.workbasket = { ...selectedWorkbasketAndAction.selectedWorkbasket };
|
}
|
||||||
this.getWorkbasketInformation(this.workbasket);
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.importExportService.getImportingFinished()
|
this.importExportService
|
||||||
|
.getImportingFinished()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
if (this.workbasket) {
|
if (this.workbasket) {
|
||||||
|
@ -105,15 +105,18 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy {
|
||||||
workbasketIdSelected = selectedWorkbasket.workbasketId;
|
workbasketIdSelected = selectedWorkbasket.workbasketId;
|
||||||
}
|
}
|
||||||
this.requestInProgress = true;
|
this.requestInProgress = true;
|
||||||
if (!workbasketIdSelected && this.action === ACTION.CREATE) { // CREATE
|
if (!workbasketIdSelected && this.action === ACTION.CREATE) {
|
||||||
|
// CREATE
|
||||||
this.workbasket = {};
|
this.workbasket = {};
|
||||||
this.domainService.getSelectedDomain()
|
this.domainService
|
||||||
|
.getSelectedDomain()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe(domain => {
|
.subscribe((domain) => {
|
||||||
this.workbasket.domain = domain;
|
this.workbasket.domain = domain;
|
||||||
});
|
});
|
||||||
this.requestInProgress = false;
|
this.requestInProgress = false;
|
||||||
} else if (!workbasketIdSelected && this.action === ACTION.COPY) { // COPY
|
} else if (!workbasketIdSelected && this.action === ACTION.COPY) {
|
||||||
|
// COPY
|
||||||
this.workbasket = { ...this.workbasketCopy };
|
this.workbasket = { ...this.workbasketCopy };
|
||||||
delete this.workbasket.workbasketId;
|
delete this.workbasket.workbasketId;
|
||||||
this.requestInProgress = false;
|
this.requestInProgress = false;
|
||||||
|
@ -126,9 +129,10 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkDomainAndRedirect() {
|
private checkDomainAndRedirect() {
|
||||||
this.domainService.getSelectedDomain()
|
this.domainService
|
||||||
|
.getSelectedDomain()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe(domain => {
|
.subscribe((domain) => {
|
||||||
if (domain !== '' && this.workbasket && this.workbasket.domain !== domain) {
|
if (domain !== '' && this.workbasket && this.workbasket.domain !== domain) {
|
||||||
this.backClicked();
|
this.backClicked();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
|
|
||||||
.button-margin-top {
|
.button-margin-top {
|
||||||
margin-top: 100px
|
margin-top: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-arrows > button{
|
.list-arrows > button {
|
||||||
margin: 10px 0px;
|
margin: 10px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.col-md-5-6 {
|
.col-md-5-6 {
|
||||||
@media (min-width: 992px){
|
@media (min-width: 992px) {
|
||||||
width: 45.82%;
|
width: 45.82%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,18 +21,55 @@ import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
||||||
import { NgxsModule, Store } from '@ngxs/store';
|
import { NgxsModule, Store } from '@ngxs/store';
|
||||||
import { WorkbasketDistributionTargetsComponent, Side } from './workbasket-distribution-targets.component';
|
import { WorkbasketDistributionTargetsComponent, Side } from './workbasket-distribution-targets.component';
|
||||||
import { WorkbasketDualListComponent } from '../workbasket-dual-list/workbasket-dual-list.component';
|
import { WorkbasketDualListComponent } from '../workbasket-dual-list/workbasket-dual-list.component';
|
||||||
import { NotificationService } from '../../../shared/services/notifications/notification.service'; import { ClassificationSelectors } from '../../../shared/store/classification-store/classification.selectors';
|
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
||||||
|
import { ClassificationSelectors } from '../../../shared/store/classification-store/classification.selectors';
|
||||||
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
||||||
|
|
||||||
describe('WorkbasketDistributionTargetsComponent', () => {
|
describe('WorkbasketDistributionTargetsComponent', () => {
|
||||||
let component: WorkbasketDistributionTargetsComponent;
|
let component: WorkbasketDistributionTargetsComponent;
|
||||||
let fixture: ComponentFixture<WorkbasketDistributionTargetsComponent>;
|
let fixture: ComponentFixture<WorkbasketDistributionTargetsComponent>;
|
||||||
let workbasketService;
|
let workbasketService;
|
||||||
const workbasket = createWorkbasket('1', '', '', '', ICONTYPES.TOPIC, '', '', '', '', '', '', '', '', '', '', '', '',
|
const workbasket = createWorkbasket(
|
||||||
{});
|
'1',
|
||||||
function createWorkbasket(workbasketId?, created?, key?, domain?, type?, modified?, name?, description?,
|
'',
|
||||||
owner?, custom1?, custom2?, custom3?, custom4?, orgLevel1?, orgLevel2?, orgLevel3?, orgLevel4?,
|
'',
|
||||||
_links?: Links, markedForDeletion?: boolean): Workbasket {
|
'',
|
||||||
|
ICONTYPES.TOPIC,
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
function createWorkbasket(
|
||||||
|
workbasketId?,
|
||||||
|
created?,
|
||||||
|
key?,
|
||||||
|
domain?,
|
||||||
|
type?,
|
||||||
|
modified?,
|
||||||
|
name?,
|
||||||
|
description?,
|
||||||
|
owner?,
|
||||||
|
custom1?,
|
||||||
|
custom2?,
|
||||||
|
custom3?,
|
||||||
|
custom4?,
|
||||||
|
orgLevel1?,
|
||||||
|
orgLevel2?,
|
||||||
|
orgLevel3?,
|
||||||
|
orgLevel4?,
|
||||||
|
_links?: Links,
|
||||||
|
markedForDeletion?: boolean
|
||||||
|
): Workbasket {
|
||||||
return {
|
return {
|
||||||
workbasketId,
|
workbasketId,
|
||||||
created,
|
created,
|
||||||
|
@ -56,7 +93,19 @@ describe('WorkbasketDistributionTargetsComponent', () => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWorkbasketSummary(workbasketId, key, name, domain, type, description, owner, custom1, custom2, custom3, custom4) {
|
function createWorkbasketSummary(
|
||||||
|
workbasketId,
|
||||||
|
key,
|
||||||
|
name,
|
||||||
|
domain,
|
||||||
|
type,
|
||||||
|
description,
|
||||||
|
owner,
|
||||||
|
custom1,
|
||||||
|
custom2,
|
||||||
|
custom3,
|
||||||
|
custom4
|
||||||
|
) {
|
||||||
const workbasketSummary: WorkbasketSummary = {
|
const workbasketSummary: WorkbasketSummary = {
|
||||||
workbasketId,
|
workbasketId,
|
||||||
key,
|
key,
|
||||||
|
@ -74,10 +123,8 @@ describe('WorkbasketDistributionTargetsComponent', () => {
|
||||||
}
|
}
|
||||||
const workbasketSummaryResource: WorkbasketSummaryRepresentation = {
|
const workbasketSummaryResource: WorkbasketSummaryRepresentation = {
|
||||||
workbaskets: [
|
workbaskets: [
|
||||||
createWorkbasketSummary('1', 'key1', 'NAME1', '', 'PERSONAL',
|
createWorkbasketSummary('1', 'key1', 'NAME1', '', 'PERSONAL', 'description 1', 'owner1', '', '', '', ''),
|
||||||
'description 1', 'owner1', '', '', '', ''),
|
createWorkbasketSummary('2', 'key2', 'NAME2', '', 'PERSONAL', 'description 2', 'owner2', '', '', '', '')
|
||||||
createWorkbasketSummary('2', 'key2', 'NAME2', '', 'PERSONAL',
|
|
||||||
'description 2', 'owner2', '', '', '', ''),
|
|
||||||
],
|
],
|
||||||
_links: new LinksWorkbasketSummary({ href: 'url' }),
|
_links: new LinksWorkbasketSummary({ href: 'url' }),
|
||||||
page: {}
|
page: {}
|
||||||
|
@ -90,17 +137,22 @@ describe('WorkbasketDistributionTargetsComponent', () => {
|
||||||
|
|
||||||
const storeSpy: jasmine.SpyObj<Store> = jasmine.createSpyObj('Store', ['select', 'dispatch']);
|
const storeSpy: jasmine.SpyObj<Store> = jasmine.createSpyObj('Store', ['select', 'dispatch']);
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
const configure = (testBed: TestBed) => {
|
const configure = (testBed: TestBed) => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
imports: [AngularSvgIconModule, HttpClientModule, InfiniteScrollModule, NgxsModule.forRoot()],
|
imports: [AngularSvgIconModule, HttpClientModule, InfiniteScrollModule, NgxsModule.forRoot()],
|
||||||
declarations: [WorkbasketDistributionTargetsComponent, WorkbasketDualListComponent],
|
declarations: [WorkbasketDistributionTargetsComponent, WorkbasketDualListComponent],
|
||||||
providers: [WorkbasketService, NotificationService, SavingWorkbasketService, RequestInProgressService,
|
providers: [
|
||||||
{ provide: Store, useValue: storeSpy }]
|
WorkbasketService,
|
||||||
|
NotificationService,
|
||||||
|
SavingWorkbasketService,
|
||||||
|
RequestInProgressService,
|
||||||
|
{ provide: Store, useValue: storeSpy }
|
||||||
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
storeSpy.select.and.callFake(selector => {
|
storeSpy.select.and.callFake((selector) => {
|
||||||
switch (selector) {
|
switch (selector) {
|
||||||
case WorkbasketSelectors.workbasketDistributionTargets:
|
case WorkbasketSelectors.workbasketDistributionTargets:
|
||||||
return of(['distributionTargets', '_links']);
|
return of(['distributionTargets', '_links']);
|
||||||
|
@ -113,7 +165,9 @@ describe('WorkbasketDistributionTargetsComponent', () => {
|
||||||
component.workbasket = workbasket;
|
component.workbasket = workbasket;
|
||||||
workbasketService = TestBed.get(WorkbasketService);
|
workbasketService = TestBed.get(WorkbasketService);
|
||||||
spyOn(workbasketService, 'getWorkBasketsSummary').and.callFake(() => of(workbasketSummaryResource));
|
spyOn(workbasketService, 'getWorkBasketsSummary').and.callFake(() => of(workbasketSummaryResource));
|
||||||
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => of(workbasketDistributionTargets));
|
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() =>
|
||||||
|
of(workbasketDistributionTargets)
|
||||||
|
);
|
||||||
component.ngOnChanges({
|
component.ngOnChanges({
|
||||||
active: new SimpleChange(undefined, 'distributionTargets', true)
|
active: new SimpleChange(undefined, 'distributionTargets', true)
|
||||||
});
|
});
|
||||||
|
@ -139,21 +193,19 @@ describe('WorkbasketDistributionTargetsComponent', () => {
|
||||||
let repeteadElemens = false;
|
let repeteadElemens = false;
|
||||||
expect(component.distributionTargetsLeft.length).toBe(2);
|
expect(component.distributionTargetsLeft.length).toBe(2);
|
||||||
expect(component.distributionTargetsRight.length).toBe(2);
|
expect(component.distributionTargetsRight.length).toBe(2);
|
||||||
component.distributionTargetsLeft.forEach(leftElement => {
|
component.distributionTargetsLeft.forEach((leftElement) => {
|
||||||
component.distributionTargetsRight.forEach(rightElement => {
|
component.distributionTargetsRight.forEach((rightElement) => {
|
||||||
if (leftElement.workbasketId === rightElement.workbasketId) { repeteadElemens = true; }
|
if (leftElement.workbasketId === rightElement.workbasketId) {
|
||||||
|
repeteadElemens = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
expect(repeteadElemens).toBeTruthy();
|
expect(repeteadElemens).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reset distribution target and distribution target selected on reset', () => {
|
it('should reset distribution target and distribution target selected on reset', () => {
|
||||||
component.distributionTargetsLeft.push(
|
component.distributionTargetsLeft.push(createWorkbasketSummary('id4', '', '', '', '', '', '', '', '', '', ''));
|
||||||
createWorkbasketSummary('id4', '', '', '', '', '', '', '', '', '', '')
|
component.distributionTargetsRight.push(createWorkbasketSummary('id5', '', '', '', '', '', '', '', '', '', ''));
|
||||||
);
|
|
||||||
component.distributionTargetsRight.push(
|
|
||||||
createWorkbasketSummary('id5', '', '', '', '', '', '', '', '', '', '')
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(component.distributionTargetsLeft.length).toBe(3);
|
expect(component.distributionTargetsLeft.length).toBe(3);
|
||||||
expect(component.distributionTargetsRight.length).toBe(3);
|
expect(component.distributionTargetsRight.length).toBe(3);
|
||||||
|
|
|
@ -1,10 +1,4 @@
|
||||||
import { Component,
|
import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core';
|
||||||
ElementRef,
|
|
||||||
Input,
|
|
||||||
OnChanges,
|
|
||||||
OnDestroy, OnInit,
|
|
||||||
SimpleChanges,
|
|
||||||
ViewChild } from '@angular/core';
|
|
||||||
import { Observable, Subject } from 'rxjs';
|
import { Observable, Subject } from 'rxjs';
|
||||||
|
|
||||||
import { Workbasket } from 'app/shared/models/workbasket';
|
import { Workbasket } from 'app/shared/models/workbasket';
|
||||||
|
@ -24,8 +18,11 @@ import { Select, Store } from '@ngxs/store';
|
||||||
import { take, takeUntil } from 'rxjs/operators';
|
import { take, takeUntil } from 'rxjs/operators';
|
||||||
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
||||||
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
||||||
import { GetWorkbasketDistributionTargets,
|
import {
|
||||||
GetWorkbasketsSummary, UpdateWorkbasketDistributionTargets } from '../../../shared/store/workbasket-store/workbasket.actions';
|
GetWorkbasketDistributionTargets,
|
||||||
|
GetWorkbasketsSummary,
|
||||||
|
UpdateWorkbasketDistributionTargets
|
||||||
|
} from '../../../shared/store/workbasket-store/workbasket.actions';
|
||||||
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
||||||
import { WorkbasketStateModel } from '../../../shared/store/workbasket-store/workbasket.state';
|
import { WorkbasketStateModel } from '../../../shared/store/workbasket-store/workbasket.state';
|
||||||
|
|
||||||
|
@ -82,10 +79,10 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
||||||
private orientationService: OrientationService,
|
private orientationService: OrientationService,
|
||||||
private notificationsService: NotificationService,
|
private notificationsService: NotificationService,
|
||||||
private store: Store
|
private store: Store
|
||||||
) { }
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.workbasketDistributionTargets$.subscribe(workbasketDistributionTargets => {
|
this.workbasketDistributionTargets$.subscribe((workbasketDistributionTargets) => {
|
||||||
if (typeof workbasketDistributionTargets !== 'undefined') {
|
if (typeof workbasketDistributionTargets !== 'undefined') {
|
||||||
this.distributionTargetsSelectedResource = { ...workbasketDistributionTargets };
|
this.distributionTargetsSelectedResource = { ...workbasketDistributionTargets };
|
||||||
this.distributionTargetsSelected = this.distributionTargetsSelectedResource.distributionTargets;
|
this.distributionTargetsSelected = this.distributionTargetsSelectedResource.distributionTargets;
|
||||||
|
@ -120,7 +117,8 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
this.store.dispatch(new GetWorkbasketDistributionTargets(this.workbasket._links.distributionTargets.href));
|
this.store.dispatch(new GetWorkbasketDistributionTargets(this.workbasket._links.distributionTargets.href));
|
||||||
this.savingWorkbaskets.triggeredDistributionTargetsSaving()
|
this.savingWorkbaskets
|
||||||
|
.triggeredDistributionTargetsSaving()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe((savingInformation: SavingInformation) => {
|
.subscribe((savingInformation: SavingInformation) => {
|
||||||
if (this.action === ACTION.COPY) {
|
if (this.action === ACTION.COPY) {
|
||||||
|
@ -129,7 +127,8 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.orientationService.getOrientation()
|
this.orientationService
|
||||||
|
.getOrientation()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
this.calculateNumberItemsList();
|
this.calculateNumberItemsList();
|
||||||
|
@ -144,52 +143,73 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement this into NGXS
|
// TODO: Implement this into NGXS
|
||||||
this.workbasketService.getWorkBasketsSummary(true)
|
this.workbasketService
|
||||||
|
.getWorkBasketsSummary(true)
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe(
|
.subscribe((distributionTargetsAvailable: WorkbasketSummaryRepresentation) => {
|
||||||
(distributionTargetsAvailable: WorkbasketSummaryRepresentation) => {
|
if (TaskanaQueryParameters.page === 1) {
|
||||||
if (TaskanaQueryParameters.page === 1) {
|
this.distributionTargetsLeft = [];
|
||||||
this.distributionTargetsLeft = [];
|
this.page = distributionTargetsAvailable.page;
|
||||||
this.page = distributionTargetsAvailable.page;
|
|
||||||
}
|
|
||||||
if (side === this.side.LEFT) {
|
|
||||||
this.distributionTargetsLeft.push(...distributionTargetsAvailable.workbaskets);
|
|
||||||
} else if (side === this.side.RIGHT) {
|
|
||||||
this.distributionTargetsRight = Object.assign([], distributionTargetsAvailable.workbaskets);
|
|
||||||
} else {
|
|
||||||
this.distributionTargetsLeft.push(...distributionTargetsAvailable.workbaskets);
|
|
||||||
this.distributionTargetsRight = Object.assign([], distributionTargetsAvailable.workbaskets);
|
|
||||||
this.distributionTargetsClone = Object.assign([], distributionTargetsAvailable.workbaskets);
|
|
||||||
}
|
|
||||||
this.onRequest(true);
|
|
||||||
}
|
}
|
||||||
);
|
if (side === this.side.LEFT) {
|
||||||
|
this.distributionTargetsLeft.push(...distributionTargetsAvailable.workbaskets);
|
||||||
|
} else if (side === this.side.RIGHT) {
|
||||||
|
this.distributionTargetsRight = Object.assign([], distributionTargetsAvailable.workbaskets);
|
||||||
|
} else {
|
||||||
|
this.distributionTargetsLeft.push(...distributionTargetsAvailable.workbaskets);
|
||||||
|
this.distributionTargetsRight = Object.assign([], distributionTargetsAvailable.workbaskets);
|
||||||
|
this.distributionTargetsClone = Object.assign([], distributionTargetsAvailable.workbaskets);
|
||||||
|
}
|
||||||
|
this.onRequest(true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
performFilter(dualListFilter: any) {
|
performFilter(dualListFilter: any) {
|
||||||
this.fillDistributionTargets(dualListFilter.side, undefined);
|
this.fillDistributionTargets(dualListFilter.side, undefined);
|
||||||
this.onRequest(false, dualListFilter.side);
|
this.onRequest(false, dualListFilter.side);
|
||||||
this.store.dispatch(new GetWorkbasketsSummary(true, '', '', '',
|
this.store
|
||||||
dualListFilter.filterBy.filterParams.name, dualListFilter.filterBy.filterParams.description, '',
|
.dispatch(
|
||||||
dualListFilter.filterBy.filterParams.owner, dualListFilter.filterBy.filterParams.type, '',
|
new GetWorkbasketsSummary(
|
||||||
dualListFilter.filterBy.filterParams.key, '', true)).subscribe((state: WorkbasketStateModel) => {
|
true,
|
||||||
this.fillDistributionTargets(dualListFilter.side, state.paginatedWorkbasketsSummary.workbaskets);
|
'',
|
||||||
this.onRequest(true, dualListFilter.side);
|
'',
|
||||||
});
|
'',
|
||||||
|
dualListFilter.filterBy.filterParams.name,
|
||||||
|
dualListFilter.filterBy.filterParams.description,
|
||||||
|
'',
|
||||||
|
dualListFilter.filterBy.filterParams.owner,
|
||||||
|
dualListFilter.filterBy.filterParams.type,
|
||||||
|
'',
|
||||||
|
dualListFilter.filterBy.filterParams.key,
|
||||||
|
'',
|
||||||
|
true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.subscribe((state: WorkbasketStateModel) => {
|
||||||
|
this.fillDistributionTargets(dualListFilter.side, state.paginatedWorkbasketsSummary.workbaskets);
|
||||||
|
this.onRequest(true, dualListFilter.side);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onSave() {
|
onSave() {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
this.store.dispatch(new UpdateWorkbasketDistributionTargets(
|
this.store
|
||||||
this.distributionTargetsSelectedResource._links.self.href,
|
.dispatch(
|
||||||
this.getSeletedIds()
|
new UpdateWorkbasketDistributionTargets(
|
||||||
)).subscribe(() => {
|
this.distributionTargetsSelectedResource._links.self.href,
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
this.getSeletedIds()
|
||||||
return true;
|
)
|
||||||
}, error => {
|
)
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
.subscribe(
|
||||||
return false;
|
() => {
|
||||||
});
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
/* TODO: OLD IMPLEMENTATION, KEPT HERE FOR REFERENCE
|
/* TODO: OLD IMPLEMENTATION, KEPT HERE FOR REFERENCE
|
||||||
this.workbasketService.updateWorkBasketsDistributionTargets(
|
this.workbasketService.updateWorkBasketsDistributionTargets(
|
||||||
this.distributionTargetsSelectedResource._links.self.href, this.getSeletedIds()
|
this.distributionTargetsSelectedResource._links.self.href, this.getSeletedIds()
|
||||||
|
@ -220,7 +240,10 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
||||||
const itemsSelected = this.getSelectedItems(this.distributionTargetsLeft);
|
const itemsSelected = this.getSelectedItems(this.distributionTargetsLeft);
|
||||||
this.distributionTargetsSelected = [...this.distributionTargetsSelected, ...itemsSelected];
|
this.distributionTargetsSelected = [...this.distributionTargetsSelected, ...itemsSelected];
|
||||||
this.distributionTargetsRight = this.distributionTargetsRight.concat(itemsSelected);
|
this.distributionTargetsRight = this.distributionTargetsRight.concat(itemsSelected);
|
||||||
if (((itemsLeft - itemsSelected.length) <= TaskanaQueryParameters.pageSize) && ((itemsLeft + itemsRight) < this.page.totalElements)) {
|
if (
|
||||||
|
itemsLeft - itemsSelected.length <= TaskanaQueryParameters.pageSize &&
|
||||||
|
itemsLeft + itemsRight < this.page.totalElements
|
||||||
|
) {
|
||||||
this.getNextPage(side);
|
this.getNextPage(side);
|
||||||
}
|
}
|
||||||
this.unselectItems(this.distributionTargetsSelected);
|
this.unselectItems(this.distributionTargetsSelected);
|
||||||
|
@ -244,9 +267,13 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
||||||
if (this.panelBody) {
|
if (this.panelBody) {
|
||||||
const cardHeight = 72;
|
const cardHeight = 72;
|
||||||
const unusedHeight = 100;
|
const unusedHeight = 100;
|
||||||
this.cards = this.orientationService.calculateNumberItemsList(
|
this.cards =
|
||||||
this.panelBody.nativeElement.offsetHeight, cardHeight, unusedHeight, true
|
this.orientationService.calculateNumberItemsList(
|
||||||
) + 1; // TODO: warum +1
|
this.panelBody.nativeElement.offsetHeight,
|
||||||
|
cardHeight,
|
||||||
|
unusedHeight,
|
||||||
|
true
|
||||||
|
) + 1; // TODO: warum +1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +294,7 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
getSelectedItems(originList: any): Array<any> {
|
getSelectedItems(originList: any): Array<any> {
|
||||||
return originList.filter((item: any) => (item.selected === true));
|
return originList.filter((item: any) => item.selected === true);
|
||||||
}
|
}
|
||||||
|
|
||||||
unselectItems(originList: any): Array<any> {
|
unselectItems(originList: any): Array<any> {
|
||||||
|
@ -282,7 +309,7 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
||||||
|
|
||||||
removeSelectedItems(originList: any, selectedItemList) {
|
removeSelectedItems(originList: any, selectedItemList) {
|
||||||
for (let index = originList.length - 1; index >= 0; index--) {
|
for (let index = originList.length - 1; index >= 0; index--) {
|
||||||
if (selectedItemList.some(itemToRemove => (originList[index].workbasketId === itemToRemove.workbasketId))) {
|
if (selectedItemList.some((itemToRemove) => originList[index].workbasketId === itemToRemove.workbasketId)) {
|
||||||
originList.splice(index, 1);
|
originList.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,9 +320,11 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
||||||
this.loadingItems = false;
|
this.loadingItems = false;
|
||||||
const inProgress = !finished;
|
const inProgress = !finished;
|
||||||
switch (side) {
|
switch (side) {
|
||||||
case Side.LEFT: this.requestInProgressLeft = inProgress;
|
case Side.LEFT:
|
||||||
|
this.requestInProgressLeft = inProgress;
|
||||||
break;
|
break;
|
||||||
case Side.RIGHT: this.requestInProgressRight = inProgress;
|
case Side.RIGHT:
|
||||||
|
this.requestInProgressRight = inProgress;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.requestInProgressLeft = inProgress;
|
this.requestInProgressLeft = inProgress;
|
||||||
|
@ -305,15 +334,19 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
||||||
|
|
||||||
getSeletedIds(): Array<string> {
|
getSeletedIds(): Array<string> {
|
||||||
const distributionTargetsSelelected: Array<string> = [];
|
const distributionTargetsSelelected: Array<string> = [];
|
||||||
this.distributionTargetsSelected.forEach(item => {
|
this.distributionTargetsSelected.forEach((item) => {
|
||||||
distributionTargetsSelelected.push(item.workbasketId);
|
distributionTargetsSelelected.push(item.workbasketId);
|
||||||
});
|
});
|
||||||
return distributionTargetsSelelected;
|
return distributionTargetsSelelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
private uncheckSelectAll(side: number) {
|
private uncheckSelectAll(side: number) {
|
||||||
if (side === Side.LEFT && this.selectAllLeft) { this.selectAllLeft = false; }
|
if (side === Side.LEFT && this.selectAllLeft) {
|
||||||
if (side === Side.RIGHT && this.selectAllRight) { this.selectAllRight = false; }
|
this.selectAllLeft = false;
|
||||||
|
}
|
||||||
|
if (side === Side.RIGHT && this.selectAllRight) {
|
||||||
|
this.selectAllRight = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
|
|
@ -1,49 +1,48 @@
|
||||||
$selected-item: #e3f3f5;
|
$selected-item: #e3f3f5;
|
||||||
|
|
||||||
.dual-list {
|
.dual-list {
|
||||||
min-height: 250px;
|
min-height: 250px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
border: 1px solid #e3e3e3;
|
border: 1px solid #e3e3e3;
|
||||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
|
||||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
|
||||||
& .row {
|
& .row {
|
||||||
padding: 0px 0px 0px 3px;
|
padding: 0px 0px 0px 3px;
|
||||||
}
|
}
|
||||||
& .row:first {
|
& .row:first {
|
||||||
border-top: 1px solid #ddd;
|
border-top: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
& div.pull-right {
|
& div.pull-right {
|
||||||
margin-right: 17px;
|
margin-right: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
& >.list-group {
|
& > .list-group {
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
& > .list-group > li {
|
||||||
|
border-left: none;
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
overflow-x: hidden;
|
||||||
& > .list-group > li {
|
overflow-y: hidden;
|
||||||
border-left: none;
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
overflow-x: hidden;
|
@media screen and (max-width: 991px) {
|
||||||
overflow-y: hidden;
|
height: calc((100vh - 241px) / 2);
|
||||||
|
min-height: 120px;
|
||||||
@media screen and (max-width: 991px){
|
margin-bottom: 0;
|
||||||
height: calc((100vh - 241px) / 2);
|
}
|
||||||
min-height: 120px;
|
max-height: calc(100vh - 194px);
|
||||||
margin-bottom: 0;
|
margin-bottom: 2px;
|
||||||
}
|
|
||||||
max-height: calc(100vh - 194px);
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.infinite-scroll {
|
.infinite-scroll {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
height: calc(100vh - 233px);
|
height: calc(100vh - 233px);
|
||||||
@media screen and (max-width: 991px){
|
@media screen and (max-width: 991px) {
|
||||||
height: calc((100vh - 315px) / 2);
|
height: calc((100vh - 315px) / 2);
|
||||||
min-height: 83px;
|
min-height: 83px;
|
||||||
}
|
}
|
||||||
|
@ -54,60 +53,60 @@ $selected-item: #e3f3f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-group {
|
.list-group {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul > li {
|
||||||
ul>li {
|
&:first-child.list-group-item.selected {
|
||||||
&:first-child.list-group-item.selected {
|
|
||||||
border-color: #ddd;
|
border-color: #ddd;
|
||||||
}
|
}
|
||||||
&.list-group-item.selected {
|
&.list-group-item.selected {
|
||||||
background-color: $selected-item;
|
background-color: $selected-item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-left li {
|
.list-left li {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.no-style{
|
button.no-style {
|
||||||
background: none;
|
background: none;
|
||||||
border:none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row.list-group {
|
.row.list-group {
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-group > li {
|
.list-group > li {
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a > label{
|
a > label {
|
||||||
height: 2em;
|
height: 2em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
dd, dt {
|
dd,
|
||||||
text-overflow: ellipsis;
|
dt {
|
||||||
white-space: nowrap;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
dt > i {
|
dt > i {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
li > div.row > dl {
|
li > div.row > dl {
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
li.list-group-item:hover, {
|
li.list-group-item:hover {
|
||||||
color: #555;
|
color: #555;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ import { Side } from '../workbasket-distribution-targets/workbasket-distribution
|
||||||
export class WorkbasketDualListComponent implements OnInit {
|
export class WorkbasketDualListComponent implements OnInit {
|
||||||
@Input() distributionTargets: WorkbasketSummary[];
|
@Input() distributionTargets: WorkbasketSummary[];
|
||||||
@Input() distributionTargetsSelected: WorkbasketSummary[];
|
@Input() distributionTargetsSelected: WorkbasketSummary[];
|
||||||
@Output() performDualListFilter = new EventEmitter<{ filterBy: Filter, side: Side }>();
|
@Output() performDualListFilter = new EventEmitter<{ filterBy: Filter; side: Side }>();
|
||||||
@Input() requestInProgress = false;
|
@Input() requestInProgress = false;
|
||||||
@Input() loadingItems ? = false;
|
@Input() loadingItems? = false;
|
||||||
@Input() side: Side;
|
@Input() side: Side;
|
||||||
@Input() header: string;
|
@Input() header: string;
|
||||||
@Output() scrolling = new EventEmitter<Side>();
|
@Output() scrolling = new EventEmitter<Side>();
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
min-width: auto;
|
min-width: auto;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,7 @@ import { NotificationService } from '../../../shared/services/notifications/noti
|
||||||
selector: 'taskana-dummy-detail',
|
selector: 'taskana-dummy-detail',
|
||||||
template: 'dummydetail'
|
template: 'dummydetail'
|
||||||
})
|
})
|
||||||
export class DummyDetailComponent {
|
export class DummyDetailComponent {}
|
||||||
}
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: ':id', component: DummyDetailComponent, outlet: 'detail' },
|
{ path: ':id', component: DummyDetailComponent, outlet: 'detail' },
|
||||||
|
@ -44,17 +43,44 @@ describe('WorkbasketInformationComponent', () => {
|
||||||
const configure = (testBed: TestBed) => {
|
const configure = (testBed: TestBed) => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
declarations: [WorkbasketInformationComponent, DummyDetailComponent],
|
declarations: [WorkbasketInformationComponent, DummyDetailComponent],
|
||||||
imports: [FormsModule, AngularSvgIconModule, HttpClientModule, RouterTestingModule.withRoutes(routes),
|
imports: [
|
||||||
NgxsModule.forRoot()],
|
FormsModule,
|
||||||
providers: [WorkbasketService, NotificationService, SavingWorkbasketService,
|
AngularSvgIconModule,
|
||||||
RequestInProgressService, FormsValidatorService]
|
HttpClientModule,
|
||||||
|
RouterTestingModule.withRoutes(routes),
|
||||||
|
NgxsModule.forRoot()
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
WorkbasketService,
|
||||||
|
NotificationService,
|
||||||
|
SavingWorkbasketService,
|
||||||
|
RequestInProgressService,
|
||||||
|
FormsValidatorService
|
||||||
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function createWorkbasket(workbasketId?, created?, key?, domain?, type?, modified?, name?, description?,
|
function createWorkbasket(
|
||||||
owner?, custom1?, custom2?, custom3?, custom4?, orgLevel1?, orgLevel2?, orgLevel3?, orgLevel4?,
|
workbasketId?,
|
||||||
_links?: Links, markedForDeletion?: boolean) {
|
created?,
|
||||||
|
key?,
|
||||||
|
domain?,
|
||||||
|
type?,
|
||||||
|
modified?,
|
||||||
|
name?,
|
||||||
|
description?,
|
||||||
|
owner?,
|
||||||
|
custom1?,
|
||||||
|
custom2?,
|
||||||
|
custom3?,
|
||||||
|
custom4?,
|
||||||
|
orgLevel1?,
|
||||||
|
orgLevel2?,
|
||||||
|
orgLevel3?,
|
||||||
|
orgLevel4?,
|
||||||
|
_links?: Links,
|
||||||
|
markedForDeletion?: boolean
|
||||||
|
) {
|
||||||
if (!type) {
|
if (!type) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
type = 'PERSONAL';
|
type = 'PERSONAL';
|
||||||
|
@ -83,8 +109,8 @@ describe('WorkbasketInformationComponent', () => {
|
||||||
return workbasket;
|
return workbasket;
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
fixture = testBed.createComponent(WorkbasketInformationComponent);
|
fixture = testBed.createComponent(WorkbasketInformationComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
debugElement = fixture.debugElement.nativeElement;
|
debugElement = fixture.debugElement.nativeElement;
|
||||||
|
@ -119,11 +145,26 @@ describe('WorkbasketInformationComponent', () => {
|
||||||
|
|
||||||
it('should create a copy of workbasket when workbasket is selected', () => {
|
it('should create a copy of workbasket when workbasket is selected', () => {
|
||||||
expect(component.workbasketClone).toBeUndefined();
|
expect(component.workbasketClone).toBeUndefined();
|
||||||
component.workbasket = createWorkbasket('id', 'created', 'keyModified', 'domain', ICONTYPES.TOPIC, 'modified', 'name', 'description',
|
component.workbasket = createWorkbasket(
|
||||||
'owner', 'custom1', 'custom2', 'custom3', 'custom4', 'orgLevel1', 'orgLevel2', 'orgLevel3', 'orgLevel4');
|
'id',
|
||||||
component.ngOnChanges(
|
'created',
|
||||||
undefined
|
'keyModified',
|
||||||
|
'domain',
|
||||||
|
ICONTYPES.TOPIC,
|
||||||
|
'modified',
|
||||||
|
'name',
|
||||||
|
'description',
|
||||||
|
'owner',
|
||||||
|
'custom1',
|
||||||
|
'custom2',
|
||||||
|
'custom3',
|
||||||
|
'custom4',
|
||||||
|
'orgLevel1',
|
||||||
|
'orgLevel2',
|
||||||
|
'orgLevel3',
|
||||||
|
'orgLevel4'
|
||||||
);
|
);
|
||||||
|
component.ngOnChanges(undefined);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(component.workbasket.workbasketId).toEqual(component.workbasketClone.workbasketId);
|
expect(component.workbasket.workbasketId).toEqual(component.workbasketClone.workbasketId);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,4 @@
|
||||||
import { Component,
|
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core';
|
||||||
Input,
|
|
||||||
OnChanges,
|
|
||||||
OnDestroy,
|
|
||||||
OnInit,
|
|
||||||
SimpleChanges,
|
|
||||||
ViewChild } from '@angular/core';
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { Observable, Subject, Subscription } from 'rxjs';
|
import { Observable, Subject, Subscription } from 'rxjs';
|
||||||
import { NgForm } from '@angular/forms';
|
import { NgForm } from '@angular/forms';
|
||||||
|
@ -23,20 +17,21 @@ import { map, takeUntil } from 'rxjs/operators';
|
||||||
import { EngineConfigurationSelectors } from 'app/shared/store/engine-configuration-store/engine-configuration.selectors';
|
import { EngineConfigurationSelectors } from 'app/shared/store/engine-configuration-store/engine-configuration.selectors';
|
||||||
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
||||||
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
||||||
import { CustomField,
|
import { CustomField, getCustomFields, WorkbasketsCustomisation } from '../../../shared/models/customisation';
|
||||||
getCustomFields,
|
import {
|
||||||
WorkbasketsCustomisation } from '../../../shared/models/customisation';
|
CopyWorkbasket,
|
||||||
import { CopyWorkbasket, MarkWorkbasketForDeletion,
|
MarkWorkbasketForDeletion,
|
||||||
RemoveDistributionTarget, SaveNewWorkbasket,
|
RemoveDistributionTarget,
|
||||||
UpdateWorkbasket } from '../../../shared/store/workbasket-store/workbasket.actions';
|
SaveNewWorkbasket,
|
||||||
|
UpdateWorkbasket
|
||||||
|
} from '../../../shared/store/workbasket-store/workbasket.actions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-administration-workbasket-information',
|
selector: 'taskana-administration-workbasket-information',
|
||||||
templateUrl: './workbasket-information.component.html',
|
templateUrl: './workbasket-information.component.html',
|
||||||
styleUrls: ['./workbasket-information.component.scss']
|
styleUrls: ['./workbasket-information.component.scss']
|
||||||
})
|
})
|
||||||
export class WorkbasketInformationComponent
|
export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
implements OnInit, OnChanges, OnDestroy {
|
|
||||||
@Input()
|
@Input()
|
||||||
workbasket: Workbasket;
|
workbasket: Workbasket;
|
||||||
|
|
||||||
|
@ -68,8 +63,7 @@ implements OnInit, OnChanges, OnDestroy {
|
||||||
private formsValidatorService: FormsValidatorService,
|
private formsValidatorService: FormsValidatorService,
|
||||||
private notificationService: NotificationService,
|
private notificationService: NotificationService,
|
||||||
private store: Store
|
private store: Store
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.allTypes = new Map([
|
this.allTypes = new Map([
|
||||||
|
@ -79,16 +73,14 @@ implements OnInit, OnChanges, OnDestroy {
|
||||||
['TOPIC', 'Topic']
|
['TOPIC', 'Topic']
|
||||||
]);
|
]);
|
||||||
this.customFields$ = this.workbasketsCustomisation$.pipe(
|
this.customFields$ = this.workbasketsCustomisation$.pipe(
|
||||||
map(customisation => customisation.information),
|
map((customisation) => customisation.information),
|
||||||
getCustomFields(customFieldCount)
|
getCustomFields(customFieldCount)
|
||||||
);
|
);
|
||||||
this.workbasketsCustomisation$
|
this.workbasketsCustomisation$.pipe(takeUntil(this.destroy$)).subscribe((workbasketsCustomization) => {
|
||||||
.pipe(takeUntil(this.destroy$))
|
if (workbasketsCustomization.information.owner) {
|
||||||
.subscribe(workbasketsCustomization => {
|
this.lookupField = workbasketsCustomization.information.owner.lookupField;
|
||||||
if (workbasketsCustomization.information.owner) {
|
}
|
||||||
this.lookupField = workbasketsCustomization.information.owner.lookupField;
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
@ -106,13 +98,11 @@ implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.formsValidatorService.formSubmitAttempt = true;
|
this.formsValidatorService.formSubmitAttempt = true;
|
||||||
this.formsValidatorService
|
this.formsValidatorService.validateFormInformation(this.workbasketForm, this.toogleValidationMap).then((value) => {
|
||||||
.validateFormInformation(this.workbasketForm, this.toogleValidationMap)
|
if (value) {
|
||||||
.then(value => {
|
this.onSave();
|
||||||
if (value) {
|
}
|
||||||
this.onSave();
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isFieldValid(field: string): boolean {
|
isFieldValid(field: string): boolean {
|
||||||
|
@ -146,11 +136,10 @@ implements OnInit, OnChanges, OnDestroy {
|
||||||
this.postNewWorkbasket();
|
this.postNewWorkbasket();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.store.dispatch(new UpdateWorkbasket(this.workbasket._links.self.href, this.workbasket))
|
this.store.dispatch(new UpdateWorkbasket(this.workbasket._links.self.href, this.workbasket)).subscribe((state) => {
|
||||||
.subscribe(state => {
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
this.workbasketClone = { ...this.workbasket };
|
||||||
this.workbasketClone = { ...this.workbasket };
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private beforeRequest() {
|
private beforeRequest() {
|
||||||
|
@ -164,25 +153,17 @@ implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
private postNewWorkbasket() {
|
private postNewWorkbasket() {
|
||||||
this.addDateToWorkbasket();
|
this.addDateToWorkbasket();
|
||||||
this.store.dispatch(new SaveNewWorkbasket(this.workbasket)).subscribe(
|
this.store.dispatch(new SaveNewWorkbasket(this.workbasket)).subscribe(() => {
|
||||||
() => {
|
this.afterRequest();
|
||||||
this.afterRequest();
|
if (this.action === ACTION.COPY) {
|
||||||
if (this.action === ACTION.COPY) {
|
this.savingWorkbasket.triggerDistributionTargetSaving(
|
||||||
this.savingWorkbasket.triggerDistributionTargetSaving(
|
new SavingInformation(this.workbasket._links.distributionTargets.href, this.workbasket.workbasketId)
|
||||||
new SavingInformation(
|
);
|
||||||
this.workbasket._links.distributionTargets.href,
|
this.savingWorkbasket.triggerAccessItemsSaving(
|
||||||
this.workbasket.workbasketId
|
new SavingInformation(this.workbasket._links.accessItems.href, this.workbasket.workbasketId)
|
||||||
)
|
);
|
||||||
);
|
|
||||||
this.savingWorkbasket.triggerAccessItemsSaving(
|
|
||||||
new SavingInformation(
|
|
||||||
this.workbasket._links.accessItems.href,
|
|
||||||
this.workbasket.workbasketId
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private addDateToWorkbasket() {
|
private addDateToWorkbasket() {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
.list-group-item {
|
.list-group-item {
|
||||||
padding: 5px 0px 2px 1px;
|
padding: 5px 0px 2px 1px;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-align{
|
.tab-align {
|
||||||
padding: 8px 12px 8px 4px;
|
padding: 8px 12px 8px 4px;
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
|
|
||||||
&>div{
|
& > div {
|
||||||
margin: 6px 0px;
|
margin: 6px 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,7 @@ import { ICONTYPES } from '../../../shared/models/icon-types';
|
||||||
selector: 'taskana-dummy-detail',
|
selector: 'taskana-dummy-detail',
|
||||||
template: 'dummydetail'
|
template: 'dummydetail'
|
||||||
})
|
})
|
||||||
export class DummyDetailComponent {
|
export class DummyDetailComponent {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('WorkbasketListToolbarComponent', () => {
|
describe('WorkbasketListToolbarComponent', () => {
|
||||||
let component: WorkbasketListToolbarComponent;
|
let component: WorkbasketListToolbarComponent;
|
||||||
|
@ -38,15 +36,20 @@ describe('WorkbasketListToolbarComponent', () => {
|
||||||
let workbasketService;
|
let workbasketService;
|
||||||
let router;
|
let router;
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [{ path: ':id', component: DummyDetailComponent, outlet: 'detail' }];
|
||||||
{ path: ':id', component: DummyDetailComponent, outlet: 'detail' }
|
|
||||||
];
|
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
const configure = (testBed: TestBed) => {
|
const configure = (testBed: TestBed) => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
imports: [FormsModule, ReactiveFormsModule, AngularSvgIconModule,
|
imports: [
|
||||||
HttpClientModule, RouterTestingModule.withRoutes(routes), SharedModule, AppModule],
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
AngularSvgIconModule,
|
||||||
|
HttpClientModule,
|
||||||
|
RouterTestingModule.withRoutes(routes),
|
||||||
|
SharedModule,
|
||||||
|
AppModule
|
||||||
|
],
|
||||||
declarations: [WorkbasketListToolbarComponent, DummyDetailComponent, ImportExportComponent],
|
declarations: [WorkbasketListToolbarComponent, DummyDetailComponent, ImportExportComponent],
|
||||||
providers: [
|
providers: [
|
||||||
WorkbasketService,
|
WorkbasketService,
|
||||||
|
@ -56,7 +59,7 @@ describe('WorkbasketListToolbarComponent', () => {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
fixture = TestBed.createComponent(WorkbasketListToolbarComponent);
|
fixture = TestBed.createComponent(WorkbasketListToolbarComponent);
|
||||||
workbasketService = TestBed.get(WorkbasketService);
|
workbasketService = TestBed.get(WorkbasketService);
|
||||||
router = TestBed.get(Router);
|
router = TestBed.get(Router);
|
||||||
|
@ -65,12 +68,16 @@ describe('WorkbasketListToolbarComponent', () => {
|
||||||
|
|
||||||
debugElement = fixture.debugElement.nativeElement;
|
debugElement = fixture.debugElement.nativeElement;
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
component.workbaskets = [{ workbasketId: '1',
|
component.workbaskets = [
|
||||||
key: 'key1',
|
{
|
||||||
name: 'NAME1',
|
workbasketId: '1',
|
||||||
description: 'description 1',
|
key: 'key1',
|
||||||
owner: 'owner 1',
|
name: 'NAME1',
|
||||||
type: ICONTYPES.PERSONAL }];
|
description: 'description 1',
|
||||||
|
owner: 'owner 1',
|
||||||
|
type: ICONTYPES.PERSONAL
|
||||||
|
}
|
||||||
|
];
|
||||||
component.workbaskets[0].markedForDeletion = false;
|
component.workbaskets[0].markedForDeletion = false;
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
@ -90,7 +97,9 @@ describe('WorkbasketListToolbarComponent', () => {
|
||||||
let sort: Sorting;
|
let sort: Sorting;
|
||||||
const compareSort = new Sorting();
|
const compareSort = new Sorting();
|
||||||
|
|
||||||
component.performSorting.subscribe(value => { sort = value; });
|
component.performSorting.subscribe((value) => {
|
||||||
|
sort = value;
|
||||||
|
});
|
||||||
component.sorting(compareSort);
|
component.sorting(compareSort);
|
||||||
expect(sort).toBe(compareSort);
|
expect(sort).toBe(compareSort);
|
||||||
});
|
});
|
||||||
|
@ -99,7 +108,9 @@ describe('WorkbasketListToolbarComponent', () => {
|
||||||
let filter: Filter;
|
let filter: Filter;
|
||||||
const compareFilter = new Filter();
|
const compareFilter = new Filter();
|
||||||
|
|
||||||
component.performFilter.subscribe(value => { filter = value; });
|
component.performFilter.subscribe((value) => {
|
||||||
|
filter = value;
|
||||||
|
});
|
||||||
component.filtering(compareFilter);
|
component.filtering(compareFilter);
|
||||||
expect(filter).toBe(compareFilter);
|
expect(filter).toBe(compareFilter);
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,9 +29,20 @@ export class WorkbasketListToolbarComponent implements OnInit {
|
||||||
@Output() performFilter = new EventEmitter<Filter>();
|
@Output() performFilter = new EventEmitter<Filter>();
|
||||||
|
|
||||||
selectionToImport = TaskanaType.WORKBASKETS;
|
selectionToImport = TaskanaType.WORKBASKETS;
|
||||||
sortingFields = new Map([['name', 'Name'], ['key', 'Key'], ['description', 'Description'], ['owner', 'Owner'], ['type', 'Type']]);
|
sortingFields = new Map([
|
||||||
filteringTypes = new Map([['ALL', 'All'], ['PERSONAL', 'Personal'], ['GROUP', 'Group'],
|
['name', 'Name'],
|
||||||
['CLEARANCE', 'Clearance'], ['TOPIC', 'Topic']]);
|
['key', 'Key'],
|
||||||
|
['description', 'Description'],
|
||||||
|
['owner', 'Owner'],
|
||||||
|
['type', 'Type']
|
||||||
|
]);
|
||||||
|
filteringTypes = new Map([
|
||||||
|
['ALL', 'All'],
|
||||||
|
['PERSONAL', 'Personal'],
|
||||||
|
['GROUP', 'Group'],
|
||||||
|
['CLEARANCE', 'Clearance'],
|
||||||
|
['TOPIC', 'Topic']
|
||||||
|
]);
|
||||||
|
|
||||||
filterParams = { name: '', key: '', type: '', description: '', owner: '' };
|
filterParams = { name: '', key: '', type: '', description: '', owner: '' };
|
||||||
toolbarState = false;
|
toolbarState = false;
|
||||||
|
@ -49,15 +60,12 @@ export class WorkbasketListToolbarComponent implements OnInit {
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private store: Store,
|
private store: Store,
|
||||||
private location: Location
|
private location: Location
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.workbasketActiveAction$
|
this.workbasketActiveAction$.pipe(takeUntil(this.destroy$)).subscribe((action) => {
|
||||||
.pipe(takeUntil(this.destroy$))
|
this.action = action;
|
||||||
.subscribe(action => {
|
});
|
||||||
this.action = action;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sorting(sort: Sorting) {
|
sorting(sort: Sorting) {
|
||||||
|
|
|
@ -1,37 +1,38 @@
|
||||||
.row.list-group {
|
.row.list-group {
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-group > li {
|
.list-group > li {
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a > label{
|
a > label {
|
||||||
height: 2em;
|
height: 2em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
dd, dt {
|
dd,
|
||||||
text-overflow: ellipsis;
|
dt {
|
||||||
white-space: nowrap;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
dt > i {
|
dt > i {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
li > div.row > dl {
|
li > div.row > dl {
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
li > div.row > dl:first-child {
|
li > div.row > dl:first-child {
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-space {
|
.no-space {
|
||||||
border-top: none;
|
border-top: none;
|
||||||
padding: 0px
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,7 @@ import { WorkbasketListComponent } from './workbasket-list.component';
|
||||||
selector: 'taskana-dummy-detail',
|
selector: 'taskana-dummy-detail',
|
||||||
template: 'dummydetail'
|
template: 'dummydetail'
|
||||||
})
|
})
|
||||||
class DummyDetailComponent {
|
class DummyDetailComponent {}
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-pagination',
|
selector: 'taskana-pagination',
|
||||||
|
@ -45,7 +44,19 @@ class PaginationComponent {
|
||||||
@Output() changePage = new EventEmitter<any>();
|
@Output() changePage = new EventEmitter<any>();
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWorkbasketSummary(workbasketId, key, name, domain, type, description, owner, custom1, custom2, custom3, custom4) {
|
function createWorkbasketSummary(
|
||||||
|
workbasketId,
|
||||||
|
key,
|
||||||
|
name,
|
||||||
|
domain,
|
||||||
|
type,
|
||||||
|
description,
|
||||||
|
owner,
|
||||||
|
custom1,
|
||||||
|
custom2,
|
||||||
|
custom3,
|
||||||
|
custom4
|
||||||
|
) {
|
||||||
const workbasketSummary: WorkbasketSummary = {
|
const workbasketSummary: WorkbasketSummary = {
|
||||||
workbasketId,
|
workbasketId,
|
||||||
key,
|
key,
|
||||||
|
@ -63,10 +74,8 @@ function createWorkbasketSummary(workbasketId, key, name, domain, type, descript
|
||||||
}
|
}
|
||||||
const workbasketSummaryResource: WorkbasketSummaryRepresentation = {
|
const workbasketSummaryResource: WorkbasketSummaryRepresentation = {
|
||||||
workbaskets: [
|
workbaskets: [
|
||||||
createWorkbasketSummary('1', 'key1', 'NAME1', '', 'PERSONAL',
|
createWorkbasketSummary('1', 'key1', 'NAME1', '', 'PERSONAL', 'description 1', 'owner1', '', '', '', ''),
|
||||||
'description 1', 'owner1', '', '', '', ''),
|
createWorkbasketSummary('2', 'key2', 'NAME2', '', 'PERSONAL', 'description 2', 'owner2', '', '', '', '')
|
||||||
createWorkbasketSummary('2', 'key2', 'NAME2', '', 'PERSONAL',
|
|
||||||
'description 2', 'owner2', '', '', '', ''),
|
|
||||||
],
|
],
|
||||||
_links: new LinksWorkbasketSummary({ href: 'url' }),
|
_links: new LinksWorkbasketSummary({ href: 'url' }),
|
||||||
page: {}
|
page: {}
|
||||||
|
@ -84,21 +93,16 @@ describe('WorkbasketListComponent', () => {
|
||||||
{ path: 'workbaskets', component: DummyDetailComponent }
|
{ path: 'workbaskets', component: DummyDetailComponent }
|
||||||
];
|
];
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
const configure = (testBed: TestBed) => {
|
const configure = (testBed: TestBed) => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
WorkbasketListComponent,
|
WorkbasketListComponent,
|
||||||
DummyDetailComponent,
|
DummyDetailComponent,
|
||||||
WorkbasketListToolbarComponent,
|
WorkbasketListToolbarComponent,
|
||||||
ImportExportComponent,
|
ImportExportComponent
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
AngularSvgIconModule,
|
|
||||||
HttpClientModule,
|
|
||||||
RouterTestingModule.withRoutes(routes),
|
|
||||||
NgxsModule.forRoot()
|
|
||||||
],
|
],
|
||||||
|
imports: [AngularSvgIconModule, HttpClientModule, RouterTestingModule.withRoutes(routes), NgxsModule.forRoot()],
|
||||||
providers: [
|
providers: [
|
||||||
WorkbasketService,
|
WorkbasketService,
|
||||||
WorkbasketDefinitionService,
|
WorkbasketDefinitionService,
|
||||||
|
@ -108,7 +112,7 @@ describe('WorkbasketListComponent', () => {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
fixture = TestBed.createComponent(WorkbasketListComponent);
|
fixture = TestBed.createComponent(WorkbasketListComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
Object.defineProperty(component, 'workbasketsSummaryRepresentation$', { writable: true });
|
Object.defineProperty(component, 'workbasketsSummaryRepresentation$', { writable: true });
|
||||||
|
@ -121,7 +125,9 @@ describe('WorkbasketListComponent', () => {
|
||||||
debugElement = fixture.debugElement.nativeElement;
|
debugElement = fixture.debugElement.nativeElement;
|
||||||
workbasketService = TestBed.get(WorkbasketService);
|
workbasketService = TestBed.get(WorkbasketService);
|
||||||
const orientationService = TestBed.get(OrientationService);
|
const orientationService = TestBed.get(OrientationService);
|
||||||
workbasketSummarySpy = spyOn(workbasketService, 'getWorkBasketsSummary').and.returnValue(of(workbasketSummaryResource));
|
workbasketSummarySpy = spyOn(workbasketService, 'getWorkBasketsSummary').and.returnValue(
|
||||||
|
of(workbasketSummaryResource)
|
||||||
|
);
|
||||||
spyOn(workbasketService, 'getSelectedWorkBasket').and.returnValue(of('2'));
|
spyOn(workbasketService, 'getSelectedWorkBasket').and.returnValue(of('2'));
|
||||||
spyOn(orientationService, 'getOrientation').and.returnValue(of(undefined));
|
spyOn(orientationService, 'getOrientation').and.returnValue(of(undefined));
|
||||||
|
|
||||||
|
@ -139,15 +145,18 @@ describe('WorkbasketListComponent', () => {
|
||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have wb-action-toolbar, wb-search-bar, wb-list-container, wb-pagination,'
|
it(
|
||||||
+ ' collapsedMenufilterWb and taskana-filter created in the html', () => {
|
'should have wb-action-toolbar, wb-search-bar, wb-list-container, wb-pagination,' +
|
||||||
expect(debugElement.querySelector('#wb-action-toolbar')).toBeDefined();
|
' collapsedMenufilterWb and taskana-filter created in the html',
|
||||||
expect(debugElement.querySelector('#wb-search-bar')).toBeDefined();
|
() => {
|
||||||
expect(debugElement.querySelector('#wb-pagination')).toBeDefined();
|
expect(debugElement.querySelector('#wb-action-toolbar')).toBeDefined();
|
||||||
expect(debugElement.querySelector('#wb-list-container')).toBeDefined();
|
expect(debugElement.querySelector('#wb-search-bar')).toBeDefined();
|
||||||
expect(debugElement.querySelector('#collapsedMenufilterWb')).toBeDefined();
|
expect(debugElement.querySelector('#wb-pagination')).toBeDefined();
|
||||||
expect(debugElement.querySelector('taskana-filter')).toBeDefined();
|
expect(debugElement.querySelector('#wb-list-container')).toBeDefined();
|
||||||
});
|
expect(debugElement.querySelector('#collapsedMenufilterWb')).toBeDefined();
|
||||||
|
expect(debugElement.querySelector('taskana-filter')).toBeDefined();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
it('should have rendered sort by: name, id, description, owner and type', () => {
|
it('should have rendered sort by: name, id, description, owner and type', () => {
|
||||||
expect(debugElement.querySelector('#sort-by-name')).toBeDefined();
|
expect(debugElement.querySelector('#sort-by-name')).toBeDefined();
|
||||||
|
|
|
@ -13,8 +13,11 @@ import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
||||||
import { ImportExportService } from 'app/administration/services/import-export.service';
|
import { ImportExportService } from 'app/administration/services/import-export.service';
|
||||||
import { Actions, ofActionCompleted, ofActionDispatched, Select, Store } from '@ngxs/store';
|
import { Actions, ofActionCompleted, ofActionDispatched, Select, Store } from '@ngxs/store';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
import { DeselectWorkbasket, GetWorkbasketsSummary,
|
import {
|
||||||
SelectWorkbasket } from '../../../shared/store/workbasket-store/workbasket.actions';
|
DeselectWorkbasket,
|
||||||
|
GetWorkbasketsSummary,
|
||||||
|
SelectWorkbasket
|
||||||
|
} from '../../../shared/store/workbasket-store/workbasket.actions';
|
||||||
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
||||||
import { Workbasket } from '../../../shared/models/workbasket';
|
import { Workbasket } from '../../../shared/models/workbasket';
|
||||||
|
|
||||||
|
@ -53,47 +56,45 @@ export class WorkbasketListComponent implements OnInit, OnDestroy {
|
||||||
private workbasketService: WorkbasketService,
|
private workbasketService: WorkbasketService,
|
||||||
private orientationService: OrientationService,
|
private orientationService: OrientationService,
|
||||||
private importExportService: ImportExportService,
|
private importExportService: ImportExportService,
|
||||||
private ngxsActions$: Actions,
|
private ngxsActions$: Actions
|
||||||
) {
|
) {
|
||||||
this.ngxsActions$.pipe(ofActionDispatched(GetWorkbasketsSummary),
|
this.ngxsActions$.pipe(ofActionDispatched(GetWorkbasketsSummary), takeUntil(this.destroy$)).subscribe(() => {
|
||||||
takeUntil(this.destroy$))
|
this.requestInProgress = true;
|
||||||
.subscribe(() => {
|
});
|
||||||
this.requestInProgress = true;
|
this.ngxsActions$.pipe(ofActionCompleted(GetWorkbasketsSummary), takeUntil(this.destroy$)).subscribe(() => {
|
||||||
});
|
this.requestInProgress = false;
|
||||||
this.ngxsActions$.pipe(ofActionCompleted(GetWorkbasketsSummary),
|
});
|
||||||
takeUntil(this.destroy$))
|
|
||||||
.subscribe(() => {
|
|
||||||
this.requestInProgress = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.requestInProgress = true;
|
this.requestInProgress = true;
|
||||||
|
|
||||||
this.selectedWorkbasket$.pipe(takeUntil(this.destroy$))
|
this.selectedWorkbasket$.pipe(takeUntil(this.destroy$)).subscribe((selectedWorkbasket) => {
|
||||||
.subscribe(selectedWorkbasket => {
|
if (typeof selectedWorkbasket !== 'undefined') {
|
||||||
if (typeof selectedWorkbasket !== 'undefined') {
|
this.selectedId = selectedWorkbasket.workbasketId;
|
||||||
this.selectedId = selectedWorkbasket.workbasketId;
|
} else {
|
||||||
} else {
|
this.selectedId = undefined;
|
||||||
this.selectedId = undefined;
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
TaskanaQueryParameters.page = this.pageSelected;
|
TaskanaQueryParameters.page = this.pageSelected;
|
||||||
TaskanaQueryParameters.pageSize = this.pageSize;
|
TaskanaQueryParameters.pageSize = this.pageSize;
|
||||||
|
|
||||||
this.workbasketService.workbasketSavedTriggered()
|
this.workbasketService
|
||||||
|
.workbasketSavedTriggered()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe(value => {
|
.subscribe((value) => {
|
||||||
this.performRequest();
|
this.performRequest();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.orientationService.getOrientation()
|
this.orientationService
|
||||||
|
.getOrientation()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe((orientation: Orientation) => {
|
.subscribe((orientation: Orientation) => {
|
||||||
this.refreshWorkbasketList();
|
this.refreshWorkbasketList();
|
||||||
});
|
});
|
||||||
this.importExportService.getImportingFinished()
|
this.importExportService
|
||||||
|
.getImportingFinished()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe((value: Boolean) => {
|
.subscribe((value: Boolean) => {
|
||||||
this.refreshWorkbasketList();
|
this.refreshWorkbasketList();
|
||||||
|
@ -125,15 +126,31 @@ export class WorkbasketListComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
refreshWorkbasketList() {
|
refreshWorkbasketList() {
|
||||||
this.cards = this.orientationService.calculateNumberItemsList(
|
this.cards = this.orientationService.calculateNumberItemsList(
|
||||||
window.innerHeight, 72, 170 + this.toolbarElement.nativeElement.offsetHeight, false
|
window.innerHeight,
|
||||||
|
72,
|
||||||
|
170 + this.toolbarElement.nativeElement.offsetHeight,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
this.performRequest();
|
this.performRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
private performRequest(): void {
|
private performRequest(): void {
|
||||||
this.store.dispatch(new GetWorkbasketsSummary(true, this.sort.sortBy, this.sort.sortDirection, '',
|
this.store.dispatch(
|
||||||
this.filterBy.filterParams.name, this.filterBy.filterParams.description, '', this.filterBy.filterParams.owner,
|
new GetWorkbasketsSummary(
|
||||||
this.filterBy.filterParams.type, '', this.filterBy.filterParams.key, ''));
|
true,
|
||||||
|
this.sort.sortBy,
|
||||||
|
this.sort.sortDirection,
|
||||||
|
'',
|
||||||
|
this.filterBy.filterParams.name,
|
||||||
|
this.filterBy.filterParams.description,
|
||||||
|
'',
|
||||||
|
this.filterBy.filterParams.owner,
|
||||||
|
this.filterBy.filterParams.type,
|
||||||
|
'',
|
||||||
|
this.filterBy.filterParams.key,
|
||||||
|
''
|
||||||
|
)
|
||||||
|
);
|
||||||
TaskanaQueryParameters.pageSize = this.cards;
|
TaskanaQueryParameters.pageSize = this.cards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,39 +12,26 @@ import { WorkbasketOverviewComponent } from './workbasket-overview.component';
|
||||||
selector: 'taskana-dummy-detail',
|
selector: 'taskana-dummy-detail',
|
||||||
template: 'dummydetail'
|
template: 'dummydetail'
|
||||||
})
|
})
|
||||||
export class DummyDetailComponent {
|
export class DummyDetailComponent {}
|
||||||
}
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-workbasket-list',
|
selector: 'taskana-workbasket-list',
|
||||||
template: 'dummylist'
|
template: 'dummylist'
|
||||||
})
|
})
|
||||||
export class DummyListComponent {
|
export class DummyListComponent {}
|
||||||
}
|
|
||||||
describe('WorkbasketOverviewComponent', () => {
|
describe('WorkbasketOverviewComponent', () => {
|
||||||
let debugElement: any;
|
let debugElement: any;
|
||||||
let component: WorkbasketOverviewComponent;
|
let component: WorkbasketOverviewComponent;
|
||||||
let fixture: ComponentFixture<WorkbasketOverviewComponent>;
|
let fixture: ComponentFixture<WorkbasketOverviewComponent>;
|
||||||
const locationSpy: jasmine.SpyObj<Location> = jasmine.createSpyObj('Location', ['go']);
|
const locationSpy: jasmine.SpyObj<Location> = jasmine.createSpyObj('Location', ['go']);
|
||||||
const routes: Routes = [
|
const routes: Routes = [{ path: ':id', component: DummyDetailComponent }];
|
||||||
{ path: ':id', component: DummyDetailComponent }
|
|
||||||
];
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule(
|
TestBed.configureTestingModule({
|
||||||
{ imports: [
|
imports: [RouterTestingModule.withRoutes(routes), NgxsModule.forRoot()],
|
||||||
RouterTestingModule.withRoutes(routes),
|
declarations: [WorkbasketOverviewComponent, DummyDetailComponent, DummyListComponent],
|
||||||
NgxsModule.forRoot()
|
providers: [{ provide: Location, useValue: locationSpy }],
|
||||||
],
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
declarations: [
|
}).compileComponents();
|
||||||
WorkbasketOverviewComponent,
|
|
||||||
DummyDetailComponent,
|
|
||||||
DummyListComponent],
|
|
||||||
providers: [
|
|
||||||
{ provide: Location, useValue: locationSpy },
|
|
||||||
],
|
|
||||||
schemas: [NO_ERRORS_SCHEMA] }
|
|
||||||
)
|
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|
|
@ -5,9 +5,11 @@ import { ActivatedRoute } from '@angular/router';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
||||||
|
|
||||||
import { CreateWorkbasket,
|
import {
|
||||||
|
CreateWorkbasket,
|
||||||
SelectWorkbasket,
|
SelectWorkbasket,
|
||||||
SetActiveAction } from '../../../shared/store/workbasket-store/workbasket.actions';
|
SetActiveAction
|
||||||
|
} from '../../../shared/store/workbasket-store/workbasket.actions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-workbasket-overview',
|
selector: 'app-workbasket-overview',
|
||||||
|
@ -20,34 +22,25 @@ export class WorkbasketOverviewComponent implements OnInit {
|
||||||
destroy$ = new Subject<void>();
|
destroy$ = new Subject<void>();
|
||||||
routerParams: any;
|
routerParams: any;
|
||||||
|
|
||||||
constructor(
|
constructor(private route: ActivatedRoute, private store: Store) {}
|
||||||
private route: ActivatedRoute,
|
|
||||||
private store: Store
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.route.firstChild) {
|
if (this.route.firstChild) {
|
||||||
this.route.firstChild.params
|
this.route.firstChild.params.pipe(takeUntil(this.destroy$)).subscribe((params) => {
|
||||||
.pipe(takeUntil(this.destroy$))
|
this.routerParams = params;
|
||||||
.subscribe(params => {
|
if (this.routerParams.id) {
|
||||||
this.routerParams = params;
|
this.showDetail = true;
|
||||||
if (this.routerParams.id) {
|
if (this.routerParams.id === 'new-workbasket') {
|
||||||
this.showDetail = true;
|
this.store.dispatch(new CreateWorkbasket());
|
||||||
if (this.routerParams.id === 'new-workbasket') {
|
} else {
|
||||||
this.store.dispatch(new CreateWorkbasket());
|
this.store.dispatch(new SelectWorkbasket(this.routerParams.id));
|
||||||
} else {
|
|
||||||
this.store.dispatch(new SelectWorkbasket(this.routerParams.id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
|
||||||
this.selectedWorkbasketAndAction$
|
|
||||||
.pipe(takeUntil(this.destroy$))
|
|
||||||
.subscribe(state => {
|
|
||||||
this.showDetail = !!state.selectedWorkbasket || state.action === 1;
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
this.selectedWorkbasketAndAction$.pipe(takeUntil(this.destroy$)).subscribe((state) => {
|
||||||
|
this.showDetail = !!state.selectedWorkbasket || state.action === 1;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Classification } from 'app/shared/models/classification';
|
import { Classification } from 'app/shared/models/classification';
|
||||||
|
|
||||||
export interface TreeNodeModel extends Classification {
|
export interface TreeNodeModel extends Classification {
|
||||||
children: TreeNodeModel[]
|
children: TreeNodeModel[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,11 @@ import { Classification } from '../../shared/models/classification';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ClassificationDefinitionService {
|
export class ClassificationDefinitionService {
|
||||||
url = `${environment.taskanaRestUrl}/v1/classification-definitions`;
|
url = `${environment.taskanaRestUrl}/v1/classification-definitions`;
|
||||||
constructor(private httpClient: HttpClient) { }
|
constructor(private httpClient: HttpClient) {}
|
||||||
|
|
||||||
// GET
|
// GET
|
||||||
async exportClassifications(domain: string) {
|
async exportClassifications(domain: string) {
|
||||||
const domainRequest = (domain ? '' : `?domain=${domain}`);
|
const domainRequest = domain ? '' : `?domain=${domain}`;
|
||||||
const classificationDefinitions = await this.httpClient.get<Classification[]>(this.url + domainRequest).toPromise();
|
const classificationDefinitions = await this.httpClient.get<Classification[]>(this.url + domainRequest).toPromise();
|
||||||
BlobGenerator.saveFile(classificationDefinitions, `Classifications_${TaskanaDate.getDate()}.json`);
|
BlobGenerator.saveFile(classificationDefinitions, `Classifications_${TaskanaDate.getDate()}.json`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,25 +7,27 @@ import { Classification } from '../../shared/models/classification';
|
||||||
})
|
})
|
||||||
export class ClassificationTreeService {
|
export class ClassificationTreeService {
|
||||||
transformToTreeNode(classifications: Classification[]): TreeNodeModel[] {
|
transformToTreeNode(classifications: Classification[]): TreeNodeModel[] {
|
||||||
const classificationsAsTree: TreeNodeModel[] = classifications.map(c => ({
|
const classificationsAsTree: TreeNodeModel[] = classifications
|
||||||
...c,
|
.map((c) => ({
|
||||||
children: []
|
...c,
|
||||||
})).sort((a: TreeNodeModel, b: TreeNodeModel) => a.key.localeCompare(b.key));
|
children: []
|
||||||
|
}))
|
||||||
|
.sort((a: TreeNodeModel, b: TreeNodeModel) => a.key.localeCompare(b.key));
|
||||||
const roots: TreeNodeModel[] = [];
|
const roots: TreeNodeModel[] = [];
|
||||||
const children: TreeNodeModel[] = [];
|
const children: TreeNodeModel[] = [];
|
||||||
classificationsAsTree.forEach(item => {
|
classificationsAsTree.forEach((item) => {
|
||||||
const parent = item.parentId;
|
const parent = item.parentId;
|
||||||
const target = !parent ? roots : (children[parent] || (children[parent] = []));
|
const target = !parent ? roots : children[parent] || (children[parent] = []);
|
||||||
target.push(item);
|
target.push(item);
|
||||||
});
|
});
|
||||||
roots.forEach(parent => this.findChildren(parent, children));
|
roots.forEach((parent) => this.findChildren(parent, children));
|
||||||
return roots;
|
return roots;
|
||||||
}
|
}
|
||||||
|
|
||||||
private findChildren(parent: TreeNodeModel, children: TreeNodeModel[]) {
|
private findChildren(parent: TreeNodeModel, children: TreeNodeModel[]) {
|
||||||
if (children[parent.classificationId]) {
|
if (children[parent.classificationId]) {
|
||||||
parent.children = children[parent.classificationId];
|
parent.children = children[parent.classificationId];
|
||||||
parent.children.forEach(child => this.findChildren(child, children));
|
parent.children.forEach((child) => this.findChildren(child, children));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,7 @@ import { Injectable } from '@angular/core';
|
||||||
import { Subject, Observable } from 'rxjs';
|
import { Subject, Observable } from 'rxjs';
|
||||||
|
|
||||||
export class SavingInformation {
|
export class SavingInformation {
|
||||||
constructor(public url: string,
|
constructor(public url: string, public workbasketId: string) {}
|
||||||
public workbasketId: string) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|
|
@ -9,12 +9,14 @@ import { BlobGenerator } from 'app/shared/util/blob-generator';
|
||||||
export class WorkbasketDefinitionService {
|
export class WorkbasketDefinitionService {
|
||||||
url: string = `${environment.taskanaRestUrl}/v1/workbasket-definitions`;
|
url: string = `${environment.taskanaRestUrl}/v1/workbasket-definitions`;
|
||||||
|
|
||||||
constructor(private httpClient: HttpClient) { }
|
constructor(private httpClient: HttpClient) {}
|
||||||
|
|
||||||
// GET
|
// GET
|
||||||
async exportWorkbaskets(domain: string) {
|
async exportWorkbaskets(domain: string) {
|
||||||
const domainRequest = (domain === '' ? domain : `?domain=${domain}`);
|
const domainRequest = domain === '' ? domain : `?domain=${domain}`;
|
||||||
const workbasketDefinitions = await this.httpClient.get<WorkbasketDefinition[]>(this.url + domainRequest).toPromise();
|
const workbasketDefinitions = await this.httpClient
|
||||||
|
.get<WorkbasketDefinition[]>(this.url + domainRequest)
|
||||||
|
.toPromise();
|
||||||
BlobGenerator.saveFile(workbasketDefinitions, `Workbaskets_${TaskanaDate.getDate()}.json`);
|
BlobGenerator.saveFile(workbasketDefinitions, `Workbaskets_${TaskanaDate.getDate()}.json`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,22 +14,22 @@ const appRoutes: Routes = [
|
||||||
{
|
{
|
||||||
canActivate: [BusinessAdminGuard],
|
canActivate: [BusinessAdminGuard],
|
||||||
path: 'administration',
|
path: 'administration',
|
||||||
loadChildren: () => import('./administration/administration.module').then(m => m.AdministrationModule),
|
loadChildren: () => import('./administration/administration.module').then((m) => m.AdministrationModule)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
canActivate: [MonitorGuard],
|
canActivate: [MonitorGuard],
|
||||||
path: 'monitor',
|
path: 'monitor',
|
||||||
loadChildren: () => import('./monitor/monitor.module').then(m => m.MonitorModule),
|
loadChildren: () => import('./monitor/monitor.module').then((m) => m.MonitorModule)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
canActivate: [UserGuard],
|
canActivate: [UserGuard],
|
||||||
path: 'workplace',
|
path: 'workplace',
|
||||||
loadChildren: () => import('./workplace/workplace.module').then(m => m.WorkplaceModule)
|
loadChildren: () => import('./workplace/workplace.module').then((m) => m.WorkplaceModule)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
canActivate: [HistoryGuard],
|
canActivate: [HistoryGuard],
|
||||||
path: 'history',
|
path: 'history',
|
||||||
loadChildren: () => import('./history/history.module').then(m => m.HistoryModule)
|
loadChildren: () => import('./history/history.module').then((m) => m.HistoryModule)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'no-role',
|
path: 'no-role',
|
||||||
|
@ -37,13 +37,13 @@ const appRoutes: Routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'administration',
|
path: 'administration',
|
||||||
redirectTo: 'administration/workbaskets',
|
redirectTo: 'administration/workbaskets'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '**',
|
path: '**',
|
||||||
redirectTo: 'workplace'
|
redirectTo: 'workplace'
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'no-role',
|
path: 'no-role',
|
||||||
|
@ -52,16 +52,10 @@ const appRoutes: Routes = [
|
||||||
{
|
{
|
||||||
path: '**',
|
path: '**',
|
||||||
redirectTo: 'taskana/workplace'
|
redirectTo: 'taskana/workplace'
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [RouterModule.forRoot(appRoutes, { useHash: true })],
|
||||||
RouterModule.forRoot(
|
exports: [RouterModule]
|
||||||
appRoutes, { useHash: true }
|
|
||||||
)
|
|
||||||
],
|
|
||||||
exports: [
|
|
||||||
RouterModule
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
export class AppRoutingModule { }
|
export class AppRoutingModule {}
|
||||||
|
|
|
@ -13,21 +13,12 @@ describe('AppComponent', () => {
|
||||||
let fixture;
|
let fixture;
|
||||||
let debugElement;
|
let debugElement;
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [{ path: 'classifications', component: AppComponent }];
|
||||||
{ path: 'classifications', component: AppComponent }
|
|
||||||
];
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [
|
declarations: [AppComponent, NavBarComponent],
|
||||||
AppComponent, NavBarComponent
|
imports: [AngularSvgIconModule, RouterTestingModule.withRoutes(routes), HttpClientModule, SharedModule]
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
AngularSvgIconModule,
|
|
||||||
RouterTestingModule.withRoutes(routes),
|
|
||||||
HttpClientModule,
|
|
||||||
SharedModule
|
|
||||||
]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|
||||||
fixture = TestBed.createComponent(AppComponent);
|
fixture = TestBed.createComponent(AppComponent);
|
||||||
|
@ -39,19 +30,22 @@ describe('AppComponent', () => {
|
||||||
document.body.removeChild(debugElement);
|
document.body.removeChild(debugElement);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should create the app', (() => {
|
it('should create the app', () => {
|
||||||
expect(app).toBeTruthy();
|
expect(app).toBeTruthy();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should render title in a <a> tag', (() => {
|
it('should render title in a <a> tag', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(debugElement.querySelector('ul p a').textContent).toContain('Taskana administration');
|
expect(debugElement.querySelector('ul p a').textContent).toContain('Taskana administration');
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should call Router.navigateByUrl("classifications") and workbasketRoute should be false', (inject([Router], (router: Router) => {
|
it('should call Router.navigateByUrl("classifications") and workbasketRoute should be false', inject(
|
||||||
expect(app.workbasketsRoute).toBe(true);
|
[Router],
|
||||||
fixture.detectChanges();
|
(router: Router) => {
|
||||||
router.navigateByUrl('/classifications');
|
expect(app.workbasketsRoute).toBe(true);
|
||||||
expect(app.workbasketsRoute).toBe(false);
|
fixture.detectChanges();
|
||||||
})));
|
router.navigateByUrl('/classifications');
|
||||||
|
expect(app.workbasketsRoute).toBe(false);
|
||||||
|
}
|
||||||
|
));
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,9 +38,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
private formsValidatorService: FormsValidatorService,
|
private formsValidatorService: FormsValidatorService,
|
||||||
private errorService: NotificationService,
|
private errorService: NotificationService,
|
||||||
public uploadService: UploadService
|
public uploadService: UploadService
|
||||||
) {
|
) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@HostListener('window:resize', ['$event'])
|
@HostListener('window:resize', ['$event'])
|
||||||
onResize() {
|
onResize() {
|
||||||
|
@ -48,16 +46,18 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.routerSubscription = this.router.events.subscribe(event => {
|
this.routerSubscription = this.router.events.subscribe((event) => {
|
||||||
if (event instanceof NavigationStart) {
|
if (event instanceof NavigationStart) {
|
||||||
this.selectedRouteService.selectRoute(event);
|
this.selectedRouteService.selectRoute(event);
|
||||||
this.formsValidatorService.formSubmitAttempt = false;
|
this.formsValidatorService.formSubmitAttempt = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.requestInProgressSubscription = this.requestInProgressService.getRequestInProgress().subscribe((value: boolean) => {
|
this.requestInProgressSubscription = this.requestInProgressService
|
||||||
this.requestInProgress = value;
|
.getRequestInProgress()
|
||||||
});
|
.subscribe((value: boolean) => {
|
||||||
|
this.requestInProgress = value;
|
||||||
|
});
|
||||||
|
|
||||||
this.selectedRouteSubscription = this.selectedRouteService.getSelectedRoute().subscribe((value: string) => {
|
this.selectedRouteSubscription = this.selectedRouteService.getSelectedRoute().subscribe((value: string) => {
|
||||||
if (value.indexOf('classifications') !== -1) {
|
if (value.indexOf('classifications') !== -1) {
|
||||||
|
@ -65,7 +65,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
this.selectedRoute = value;
|
this.selectedRoute = value;
|
||||||
});
|
});
|
||||||
this.uploadingFileSubscription = this.uploadService.getCurrentProgressValue().subscribe(value => {
|
this.uploadingFileSubscription = this.uploadService.getCurrentProgressValue().subscribe((value) => {
|
||||||
this.currentProgressValue = value;
|
this.currentProgressValue = value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,12 +66,7 @@ const MODULES = [
|
||||||
NgxsReduxDevtoolsPluginModule.forRoot({ disabled: environment.production, maxAge: 25 })
|
NgxsReduxDevtoolsPluginModule.forRoot({ disabled: environment.production, maxAge: 25 })
|
||||||
];
|
];
|
||||||
|
|
||||||
const DECLARATIONS = [
|
const DECLARATIONS = [AppComponent, NavBarComponent, UserInformationComponent, NoAccessComponent];
|
||||||
AppComponent,
|
|
||||||
NavBarComponent,
|
|
||||||
UserInformationComponent,
|
|
||||||
NoAccessComponent,
|
|
||||||
];
|
|
||||||
|
|
||||||
export function startupServiceFactory(startupService: StartupService): () => Promise<any> {
|
export function startupServiceFactory(startupService: StartupService): () => Promise<any> {
|
||||||
return (): Promise<any> => startupService.load();
|
return (): Promise<any> => startupService.load();
|
||||||
|
@ -102,9 +97,8 @@ export function startupServiceFactory(startupService: StartupService): () => Pro
|
||||||
FormsValidatorService,
|
FormsValidatorService,
|
||||||
UploadService,
|
UploadService,
|
||||||
NotificationService,
|
NotificationService,
|
||||||
ClassificationCategoriesService,
|
ClassificationCategoriesService
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {}
|
||||||
}
|
|
||||||
|
|
|
@ -21,18 +21,28 @@ export const configureTests = (configure: (testBed: TestBed) => void) => {
|
||||||
const testBed = getTestBed();
|
const testBed = getTestBed();
|
||||||
|
|
||||||
if (testBed.platform == null) {
|
if (testBed.platform == null) {
|
||||||
testBed.initTestEnvironment(
|
testBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||||
BrowserDynamicTestingModule,
|
|
||||||
platformBrowserDynamicTesting()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
configure(testBed);
|
configure(testBed);
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
imports: [BrowserAnimationsModule, SharedModule, FormsModule, ReactiveFormsModule, HttpClientModule, AngularSvgIconModule],
|
imports: [
|
||||||
providers: [{ provide: TaskanaEngineService, useClass: TaskanaEngineServiceMock },
|
BrowserAnimationsModule,
|
||||||
{ provide: DomainService, useClass: DomainServiceMock }, NotificationService,
|
SharedModule,
|
||||||
RequestInProgressService, OrientationService, SelectedRouteService, FormsValidatorService]
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
HttpClientModule,
|
||||||
|
AngularSvgIconModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: TaskanaEngineService, useClass: TaskanaEngineServiceMock },
|
||||||
|
{ provide: DomainService, useClass: DomainServiceMock },
|
||||||
|
NotificationService,
|
||||||
|
RequestInProgressService,
|
||||||
|
OrientationService,
|
||||||
|
SelectedRouteService,
|
||||||
|
FormsValidatorService
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
return testBed.compileComponents().then(() => testBed);
|
return testBed.compileComponents().then(() => testBed);
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { TaskanaTypeAheadMockComponent } from 'app/shared/components/type-ahead/type-ahead.mock.component';
|
import { TaskanaTypeAheadMockComponent } from 'app/shared/components/type-ahead/type-ahead.mock.component';
|
||||||
|
|
||||||
const MODULES = [
|
const MODULES = [];
|
||||||
];
|
|
||||||
|
|
||||||
const DECLARATIONS = [
|
const DECLARATIONS = [TaskanaTypeAheadMockComponent];
|
||||||
TaskanaTypeAheadMockComponent
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: DECLARATIONS,
|
declarations: DECLARATIONS,
|
||||||
imports: MODULES,
|
imports: MODULES,
|
||||||
providers: []
|
providers: []
|
||||||
})
|
})
|
||||||
export class AppTestModule {
|
export class AppTestModule {}
|
||||||
}
|
|
||||||
|
|
|
@ -10,10 +10,11 @@ const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: '**',
|
path: '**',
|
||||||
redirectTo: ''
|
redirectTo: ''
|
||||||
}];
|
}
|
||||||
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forChild(routes)],
|
imports: [RouterModule.forChild(routes)],
|
||||||
exports: [RouterModule]
|
exports: [RouterModule]
|
||||||
})
|
})
|
||||||
export class HistoryRoutingModule { }
|
export class HistoryRoutingModule {}
|
||||||
|
|
|
@ -7,13 +7,7 @@ import { HistoryRoutingModule } from './history-routing.module';
|
||||||
import { TaskQueryComponent } from './task-query/task-query.component';
|
import { TaskQueryComponent } from './task-query/task-query.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [CommonModule, HistoryRoutingModule, SharedModule, FormsModule, ReactiveFormsModule],
|
||||||
CommonModule,
|
|
||||||
HistoryRoutingModule,
|
|
||||||
SharedModule,
|
|
||||||
FormsModule,
|
|
||||||
ReactiveFormsModule
|
|
||||||
],
|
|
||||||
declarations: [TaskQueryComponent]
|
declarations: [TaskQueryComponent]
|
||||||
})
|
})
|
||||||
export class HistoryModule { }
|
export class HistoryModule {}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { environment } from 'environments/environment';
|
||||||
export class TaskQueryService {
|
export class TaskQueryService {
|
||||||
private url = environment.taskanaRestUrl;
|
private url = environment.taskanaRestUrl;
|
||||||
|
|
||||||
constructor(private httpClient: HttpClient) { }
|
constructor(private httpClient: HttpClient) {}
|
||||||
|
|
||||||
queryTask(
|
queryTask(
|
||||||
orderBy: string = 'created',
|
orderBy: string = 'created',
|
||||||
|
@ -22,31 +22,33 @@ export class TaskQueryService {
|
||||||
searchForValues: TaskHistoryEventData,
|
searchForValues: TaskHistoryEventData,
|
||||||
allPages: boolean = false
|
allPages: boolean = false
|
||||||
): Observable<TaskHistoryEventResourceData> {
|
): Observable<TaskHistoryEventResourceData> {
|
||||||
return this.httpClient.get<TaskHistoryEventResourceData>(`${this.url}/v1/task-history-event${this.getQueryParameters(
|
return this.httpClient.get<TaskHistoryEventResourceData>(
|
||||||
orderBy,
|
`${this.url}/v1/task-history-event${this.getQueryParameters(
|
||||||
sortDirection,
|
orderBy,
|
||||||
searchForValues.taskId,
|
sortDirection,
|
||||||
searchForValues.parentBusinessProcessId,
|
searchForValues.taskId,
|
||||||
searchForValues.businessProcessId,
|
searchForValues.parentBusinessProcessId,
|
||||||
searchForValues.eventType,
|
searchForValues.businessProcessId,
|
||||||
searchForValues.userId,
|
searchForValues.eventType,
|
||||||
searchForValues.domain,
|
searchForValues.userId,
|
||||||
searchForValues.workbasketKey,
|
searchForValues.domain,
|
||||||
searchForValues.porCompany,
|
searchForValues.workbasketKey,
|
||||||
searchForValues.porSystem,
|
searchForValues.porCompany,
|
||||||
searchForValues.porInstance,
|
searchForValues.porSystem,
|
||||||
searchForValues.porType,
|
searchForValues.porInstance,
|
||||||
searchForValues.porValue,
|
searchForValues.porType,
|
||||||
searchForValues.taskClassificationKey,
|
searchForValues.porValue,
|
||||||
searchForValues.taskClassificationCategory,
|
searchForValues.taskClassificationKey,
|
||||||
searchForValues.attachmentClassificationKey,
|
searchForValues.taskClassificationCategory,
|
||||||
searchForValues.custom1,
|
searchForValues.attachmentClassificationKey,
|
||||||
searchForValues.custom2,
|
searchForValues.custom1,
|
||||||
searchForValues.custom3,
|
searchForValues.custom2,
|
||||||
searchForValues.custom4,
|
searchForValues.custom3,
|
||||||
searchForValues.created,
|
searchForValues.custom4,
|
||||||
allPages
|
searchForValues.created,
|
||||||
)}`);
|
allPages
|
||||||
|
)}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getQueryParameters(
|
private getQueryParameters(
|
||||||
|
@ -98,7 +100,10 @@ export class TaskQueryService {
|
||||||
parameters.CUSTOM_4_LIKE = custom4;
|
parameters.CUSTOM_4_LIKE = custom4;
|
||||||
parameters.CREATED = created;
|
parameters.CREATED = created;
|
||||||
|
|
||||||
if (allPages) { delete TaskanaQueryParameters.page; delete TaskanaQueryParameters.pageSize; }
|
if (allPages) {
|
||||||
|
delete TaskanaQueryParameters.page;
|
||||||
|
delete TaskanaQueryParameters.pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
return TaskanaQueryParameters.getQueryParameters(parameters);
|
return TaskanaQueryParameters.getQueryParameters(parameters);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +1,41 @@
|
||||||
@import '../../../theme/colors';
|
@import '../../../theme/colors';
|
||||||
|
|
||||||
.table {
|
.table {
|
||||||
max-height: calc(100vh - 152px);
|
max-height: calc(100vh - 152px);
|
||||||
padding-right: 15px;
|
padding-right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-header {
|
.table-header {
|
||||||
background-color: $light-grey;
|
background-color: $light-grey;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-footer {
|
.table-footer {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-cell {
|
.table-cell {
|
||||||
height: 35px;
|
height: 35px;
|
||||||
max-height: 35px;
|
max-height: 35px;
|
||||||
min-height: 35px;
|
min-height: 35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.divDate {
|
.divDate {
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-xs{
|
.btn-xs {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table .btn {
|
.table .btn {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-space {
|
.icon-space {
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.divTablePagination {
|
.divTablePagination {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,7 @@ describe('TaskQueryComponent', () => {
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [TaskQueryComponent]
|
declarations: [TaskQueryComponent]
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -31,8 +31,7 @@ export class TaskQueryComponent implements OnInit {
|
||||||
private orientationService: OrientationService,
|
private orientationService: OrientationService,
|
||||||
private requestInProgressService: RequestInProgressService,
|
private requestInProgressService: RequestInProgressService,
|
||||||
private errorsService: NotificationService
|
private errorsService: NotificationService
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.orientationSubscription = this.orientationService.getOrientation().subscribe((orientation: Orientation) => {
|
this.orientationSubscription = this.orientationService.getOrientation().subscribe((orientation: Orientation) => {
|
||||||
|
@ -99,12 +98,18 @@ export class TaskQueryComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
isDate(fieldName: string): boolean {
|
isDate(fieldName: string): boolean {
|
||||||
return (fieldName === 'created');
|
return fieldName === 'created';
|
||||||
}
|
}
|
||||||
|
|
||||||
filterFieldsToAllowQuerying(fieldName: string): boolean {
|
filterFieldsToAllowQuerying(fieldName: string): boolean {
|
||||||
if (!fieldName || fieldName === 'oldData' || fieldName === 'newData' || fieldName === 'comment'
|
if (
|
||||||
|| fieldName === 'oldValue' || fieldName === 'newValue') {
|
!fieldName ||
|
||||||
|
fieldName === 'oldData' ||
|
||||||
|
fieldName === 'newData' ||
|
||||||
|
fieldName === 'comment' ||
|
||||||
|
fieldName === 'oldValue' ||
|
||||||
|
fieldName === 'newValue'
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,9 +124,17 @@ export class TaskQueryComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
filterExpandGroup(fieldName: string): boolean {
|
filterExpandGroup(fieldName: string): boolean {
|
||||||
if (fieldName === 'custom1' || fieldName === 'custom2' || fieldName === 'custom3' || fieldName === 'custom4'
|
if (
|
||||||
|| fieldName === 'oldData' || fieldName === 'newData' || fieldName === 'comment'
|
fieldName === 'custom1' ||
|
||||||
|| fieldName === 'oldValue' || fieldName === 'newValue') {
|
fieldName === 'custom2' ||
|
||||||
|
fieldName === 'custom3' ||
|
||||||
|
fieldName === 'custom4' ||
|
||||||
|
fieldName === 'oldData' ||
|
||||||
|
fieldName === 'newData' ||
|
||||||
|
fieldName === 'comment' ||
|
||||||
|
fieldName === 'oldValue' ||
|
||||||
|
fieldName === 'newValue'
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -179,21 +192,23 @@ export class TaskQueryComponent implements OnInit {
|
||||||
private performRequest() {
|
private performRequest() {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
this.calculateQueryPages();
|
this.calculateQueryPages();
|
||||||
this.taskQuerySubscription = this.taskQueryService.queryTask(
|
this.taskQuerySubscription = this.taskQueryService
|
||||||
this.orderBy.sortBy.replace(/([A-Z])|([0-9])/g, g => `-${g[0].toLowerCase()}`),
|
.queryTask(
|
||||||
this.orderBy.sortDirection,
|
this.orderBy.sortBy.replace(/([A-Z])|([0-9])/g, (g) => `-${g[0].toLowerCase()}`),
|
||||||
new TaskHistoryEventData(this.taskQueryForm.value),
|
this.orderBy.sortDirection,
|
||||||
false
|
new TaskHistoryEventData(this.taskQueryForm.value),
|
||||||
).subscribe(taskQueryResource => {
|
false
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
)
|
||||||
this.taskQueryResource = taskQueryResource.taskHistoryEvents ? taskQueryResource : null;
|
.subscribe((taskQueryResource) => {
|
||||||
this.taskQuery = taskQueryResource.taskHistoryEvents ? taskQueryResource.taskHistoryEvents : null;
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
});
|
this.taskQueryResource = taskQueryResource.taskHistoryEvents ? taskQueryResource : null;
|
||||||
|
this.taskQuery = taskQueryResource.taskHistoryEvents ? taskQueryResource.taskHistoryEvents : null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private initTaskQueryForm() {
|
private initTaskQueryForm() {
|
||||||
const me = this;
|
const me = this;
|
||||||
Object.keys(new TaskHistoryEventData()).forEach(key => {
|
Object.keys(new TaskHistoryEventData()).forEach((key) => {
|
||||||
me.taskQueryForm.addControl(key, new FormControl());
|
me.taskQueryForm.addControl(key, new FormControl());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -202,7 +217,7 @@ export class TaskQueryComponent implements OnInit {
|
||||||
const rowHeight = 34;
|
const rowHeight = 34;
|
||||||
const unusedHeight = 300;
|
const unusedHeight = 300;
|
||||||
const totalHeight = window.innerHeight;
|
const totalHeight = window.innerHeight;
|
||||||
const cards = Math.round((totalHeight - (unusedHeight)) / rowHeight);
|
const cards = Math.round((totalHeight - unusedHeight) / rowHeight);
|
||||||
TaskanaQueryParameters.page = TaskanaQueryParameters.page ? TaskanaQueryParameters.page : 1;
|
TaskanaQueryParameters.page = TaskanaQueryParameters.page ? TaskanaQueryParameters.page : 1;
|
||||||
TaskanaQueryParameters.pageSize = cards > 0 ? cards : 1;
|
TaskanaQueryParameters.pageSize = cards > 0 ? cards : 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,7 @@ describe('ClassificationReportComponent', () => {
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [ClassificationReportComponent]
|
declarations: [ClassificationReportComponent]
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -26,8 +26,7 @@ export class ClassificationReportComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private restConnectorService: RestConnectorService,
|
private restConnectorService: RestConnectorService,
|
||||||
private requestInProgressService: RequestInProgressService
|
private requestInProgressService: RequestInProgressService
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
|
|
|
@ -8,11 +8,9 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
export class MonitorComponent implements OnInit, OnDestroy {
|
export class MonitorComponent implements OnInit, OnDestroy {
|
||||||
tabSelected = 'tasks';
|
tabSelected = 'tasks';
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {}
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {}
|
||||||
}
|
|
||||||
|
|
||||||
selectTab(tab) {
|
selectTab(tab) {
|
||||||
this.tabSelected = tab;
|
this.tabSelected = tab;
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
.report {
|
.report {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-cell--clickable {
|
.table-cell--clickable {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-row--highlight,
|
.table-row--highlight,
|
||||||
.table-row--hover:hover {
|
.table-row--hover:hover {
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-row--highlight > .table-cell {
|
.table-row--highlight > .table-cell {
|
||||||
border-bottom: 2px solid #ddd;
|
border-bottom: 2px solid #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-row--white {
|
.table-row--white {
|
||||||
background-color: white !important;
|
background-color: white !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,24 +12,25 @@ export class ReportTableComponent implements OnInit {
|
||||||
@Input()
|
@Input()
|
||||||
reportData: ReportData;
|
reportData: ReportData;
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {}
|
||||||
}
|
|
||||||
|
|
||||||
toggleFold(indexNumber: number, sumRow: boolean = false) {
|
toggleFold(indexNumber: number, sumRow: boolean = false) {
|
||||||
let rows = sumRow ? this.reportData.sumRow : this.reportData.rows;
|
let rows = sumRow ? this.reportData.sumRow : this.reportData.rows;
|
||||||
let index = indexNumber;
|
let index = indexNumber;
|
||||||
const toggleRow = rows[index += 1];
|
const toggleRow = rows[(index += 1)];
|
||||||
if (toggleRow.depth < this.reportData.meta.rowDesc.length - 1) {
|
if (toggleRow.depth < this.reportData.meta.rowDesc.length - 1) {
|
||||||
const firstChildRow = rows[index += 1];
|
const firstChildRow = rows[(index += 1)];
|
||||||
firstChildRow.display = !firstChildRow.display;
|
firstChildRow.display = !firstChildRow.display;
|
||||||
|
|
||||||
const endIndex = rows.findIndex(row => row.depth <= toggleRow.depth);
|
const endIndex = rows.findIndex((row) => row.depth <= toggleRow.depth);
|
||||||
rows = endIndex >= 0 ? rows.slice(0, endIndex) : rows;
|
rows = endIndex >= 0 ? rows.slice(0, endIndex) : rows;
|
||||||
rows.forEach(row => { row.display = firstChildRow.display && row.depth === firstChildRow.depth; });
|
rows.forEach((row) => {
|
||||||
|
row.display = firstChildRow.display && row.depth === firstChildRow.depth;
|
||||||
|
});
|
||||||
|
|
||||||
this.currentExpHeaders = Math.max(
|
this.currentExpHeaders = Math.max(
|
||||||
...this.reportData.rows.filter(r => r.display).map(r => r.depth),
|
...this.reportData.rows.filter((r) => r.display).map((r) => r.depth),
|
||||||
...this.reportData.sumRow.filter(r => r.display).map(r => r.depth)
|
...this.reportData.sumRow.filter((r) => r.display).map((r) => r.depth)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,7 @@ describe('TaskReportComponent', () => {
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [TaskReportComponent]
|
declarations: [TaskReportComponent]
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { RequestInProgressService } from '../../../shared/services/request-in-pr
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-monitor-task-report',
|
selector: 'taskana-monitor-task-report',
|
||||||
templateUrl: './task-report.component.html',
|
templateUrl: './task-report.component.html',
|
||||||
styleUrls: ['./task-report.component.scss'],
|
styleUrls: ['./task-report.component.scss']
|
||||||
})
|
})
|
||||||
export class TaskReportComponent implements OnInit {
|
export class TaskReportComponent implements OnInit {
|
||||||
pieChartLabels: string[];
|
pieChartLabels: string[];
|
||||||
|
@ -17,14 +17,13 @@ export class TaskReportComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private restConnectorService: RestConnectorService,
|
private restConnectorService: RestConnectorService,
|
||||||
private requestInProgressService: RequestInProgressService
|
private requestInProgressService: RequestInProgressService
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
this.reportData = await this.restConnectorService.getTaskStatusReport().toPromise();
|
this.reportData = await this.restConnectorService.getTaskStatusReport().toPromise();
|
||||||
this.pieChartLabels = this.reportData.meta.header;
|
this.pieChartLabels = this.reportData.meta.header;
|
||||||
this.reportData.sumRow[0].cells.forEach(c => {
|
this.reportData.sumRow[0].cells.forEach((c) => {
|
||||||
this.pieChartData.push(c);
|
this.pieChartData.push(c);
|
||||||
});
|
});
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
|
|
|
@ -10,8 +10,7 @@ import { RestConnectorService } from '../../services/rest-connector.service';
|
||||||
export class TimestampReportComponent implements OnInit {
|
export class TimestampReportComponent implements OnInit {
|
||||||
reportData: ReportData;
|
reportData: ReportData;
|
||||||
|
|
||||||
constructor(private restConnectorService: RestConnectorService) {
|
constructor(private restConnectorService: RestConnectorService) {}
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.restConnectorService.getDailyEntryExitReport().subscribe((data: ReportData) => {
|
this.restConnectorService.getDailyEntryExitReport().subscribe((data: ReportData) => {
|
||||||
|
|
|
@ -9,8 +9,7 @@ describe('WorkbasketReportDueDateComponent', () => {
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [WorkbasketReportDueDateComponent]
|
declarations: [WorkbasketReportDueDateComponent]
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -30,8 +30,7 @@ export class WorkbasketReportDueDateComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private restConnectorService: RestConnectorService,
|
private restConnectorService: RestConnectorService,
|
||||||
private requestInProgressService: RequestInProgressService
|
private requestInProgressService: RequestInProgressService
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
|
|
|
@ -9,8 +9,7 @@ describe('WorkbasketReportPlannedDateComponent', () => {
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [WorkbasketReportPlannedDateComponent]
|
declarations: [WorkbasketReportPlannedDateComponent]
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -23,7 +23,7 @@ export class WorkbasketReportPlannedDateComponent implements OnInit {
|
||||||
lineChartData: Array<ChartData>;
|
lineChartData: Array<ChartData>;
|
||||||
lineChartOptions: any = {
|
lineChartOptions: any = {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
scales: { xAxes: [{}], yAxes: [{}] },
|
scales: { xAxes: [{}], yAxes: [{}] }
|
||||||
};
|
};
|
||||||
|
|
||||||
lineChartColors = ChartColorsDefinition.getColors();
|
lineChartColors = ChartColorsDefinition.getColors();
|
||||||
|
@ -31,8 +31,7 @@ export class WorkbasketReportPlannedDateComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private restConnectorService: RestConnectorService,
|
private restConnectorService: RestConnectorService,
|
||||||
private requestInProgressService: RequestInProgressService
|
private requestInProgressService: RequestInProgressService
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
|
|
|
@ -9,8 +9,7 @@ describe('WorkbasketReportQuerySwitcherComponent', () => {
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [WorkbasketReportQuerySwitcherComponent]
|
declarations: [WorkbasketReportQuerySwitcherComponent]
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -9,8 +9,7 @@ describe('WorkbasketReportComponent', () => {
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [WorkbasketReportComponent]
|
declarations: [WorkbasketReportComponent]
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -12,8 +12,7 @@ export class WorkbasketReportComponent implements OnInit {
|
||||||
showMonitorQueryPlannedDate: Boolean;
|
showMonitorQueryPlannedDate: Boolean;
|
||||||
showMonitorQueryDueDate: Boolean;
|
showMonitorQueryDueDate: Boolean;
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {}
|
||||||
}
|
|
||||||
|
|
||||||
getMetaInformation(metaInformation: MetaInfoData) {
|
getMetaInformation(metaInformation: MetaInfoData) {
|
||||||
this.metaInformation = metaInformation;
|
this.metaInformation = metaInformation;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
export class ChartColorsDefinition {
|
export class ChartColorsDefinition {
|
||||||
public static getColors(): Array<any> {
|
public static getColors(): Array<any> {
|
||||||
return [
|
return [
|
||||||
{ // red
|
{
|
||||||
|
// red
|
||||||
backgroundColor: 'rgba(215, 40, 40, 0.2)',
|
backgroundColor: 'rgba(215, 40, 40, 0.2)',
|
||||||
borderColor: 'rgba(215, 40, 40, 1)',
|
borderColor: 'rgba(215, 40, 40, 1)',
|
||||||
pointBackgroundColor: 'rgba(215, 40, 40, 1)',
|
pointBackgroundColor: 'rgba(215, 40, 40, 1)',
|
||||||
|
@ -9,7 +10,8 @@ export class ChartColorsDefinition {
|
||||||
pointHoverBackgroundColor: '#fff',
|
pointHoverBackgroundColor: '#fff',
|
||||||
pointHoverBorderColor: 'rgba(215, 40, 40, 0.8)'
|
pointHoverBorderColor: 'rgba(215, 40, 40, 0.8)'
|
||||||
},
|
},
|
||||||
{ // yellow
|
{
|
||||||
|
// yellow
|
||||||
backgroundColor: 'rgba(208, 205, 44, 0.2)',
|
backgroundColor: 'rgba(208, 205, 44, 0.2)',
|
||||||
borderColor: 'rgba(208, 205, 44, 1)',
|
borderColor: 'rgba(208, 205, 44, 1)',
|
||||||
pointBackgroundColor: 'rgba(208, 205, 44, 1)',
|
pointBackgroundColor: 'rgba(208, 205, 44, 1)',
|
||||||
|
@ -17,7 +19,8 @@ export class ChartColorsDefinition {
|
||||||
pointHoverBackgroundColor: '#fff',
|
pointHoverBackgroundColor: '#fff',
|
||||||
pointHoverBorderColor: 'rgba(208, 205, 44, 0.8)'
|
pointHoverBorderColor: 'rgba(208, 205, 44, 0.8)'
|
||||||
},
|
},
|
||||||
{ // green
|
{
|
||||||
|
// green
|
||||||
backgroundColor: 'rgba(45, 205, 44, 0.2)',
|
backgroundColor: 'rgba(45, 205, 44, 0.2)',
|
||||||
borderColor: 'rgba(45, 205, 44, 1)',
|
borderColor: 'rgba(45, 205, 44, 1)',
|
||||||
pointBackgroundColor: 'rgba(45, 205, 44, 1)',
|
pointBackgroundColor: 'rgba(45, 205, 44, 1)',
|
||||||
|
@ -25,7 +28,8 @@ export class ChartColorsDefinition {
|
||||||
pointHoverBackgroundColor: '#fff',
|
pointHoverBackgroundColor: '#fff',
|
||||||
pointHoverBorderColor: 'rgba(45, 205, 44, 0.8)'
|
pointHoverBorderColor: 'rgba(45, 205, 44, 0.8)'
|
||||||
},
|
},
|
||||||
{ // blue
|
{
|
||||||
|
// blue
|
||||||
backgroundColor: 'rgba(45, 45, 201, 0.2)',
|
backgroundColor: 'rgba(45, 45, 201, 0.2)',
|
||||||
borderColor: 'rgba(45, 45, 201, 1)',
|
borderColor: 'rgba(45, 45, 201, 1)',
|
||||||
pointBackgroundColor: 'rgba(45, 45, 201, 1)',
|
pointBackgroundColor: 'rgba(45, 45, 201, 1)',
|
||||||
|
@ -33,7 +37,8 @@ export class ChartColorsDefinition {
|
||||||
pointHoverBackgroundColor: '#fff',
|
pointHoverBackgroundColor: '#fff',
|
||||||
pointHoverBorderColor: 'rgba(45, 45, 201, 0.8)'
|
pointHoverBorderColor: 'rgba(45, 45, 201, 0.8)'
|
||||||
},
|
},
|
||||||
{ // cyan
|
{
|
||||||
|
// cyan
|
||||||
backgroundColor: 'rgba(45, 190, 201, 0.2)',
|
backgroundColor: 'rgba(45, 190, 201, 0.2)',
|
||||||
borderColor: 'rgba(45, 190, 201, 1)',
|
borderColor: 'rgba(45, 190, 201, 1)',
|
||||||
pointBackgroundColor: 'rgba(45, 190, 201, 1)',
|
pointBackgroundColor: 'rgba(45, 190, 201, 1)',
|
||||||
|
@ -41,7 +46,8 @@ export class ChartColorsDefinition {
|
||||||
pointHoverBackgroundColor: '#fff',
|
pointHoverBackgroundColor: '#fff',
|
||||||
pointHoverBorderColor: 'rgba(45, 190, 201, 0.8)'
|
pointHoverBorderColor: 'rgba(45, 190, 201, 0.8)'
|
||||||
},
|
},
|
||||||
{ // black-grey
|
{
|
||||||
|
// black-grey
|
||||||
backgroundColor: 'rgba(37, 35, 38, 0.2)',
|
backgroundColor: 'rgba(37, 35, 38, 0.2)',
|
||||||
borderColor: 'rgba(37, 35, 38, 1)',
|
borderColor: 'rgba(37, 35, 38, 1)',
|
||||||
pointBackgroundColor: 'rgba(37, 35, 38, 1)',
|
pointBackgroundColor: 'rgba(37, 35, 38, 1)',
|
||||||
|
@ -49,7 +55,8 @@ export class ChartColorsDefinition {
|
||||||
pointHoverBackgroundColor: '#fff',
|
pointHoverBackgroundColor: '#fff',
|
||||||
pointHoverBorderColor: 'rgba(37, 35, 38, 0.8)'
|
pointHoverBorderColor: 'rgba(37, 35, 38, 0.8)'
|
||||||
},
|
},
|
||||||
{ // orange
|
{
|
||||||
|
// orange
|
||||||
backgroundColor: 'rgba(221, 125, 0, 0.2)',
|
backgroundColor: 'rgba(221, 125, 0, 0.2)',
|
||||||
borderColor: 'rgba(221, 125, 0, 1)',
|
borderColor: 'rgba(221, 125, 0, 1)',
|
||||||
pointBackgroundColor: 'rgba(221, 125, 0, 1)',
|
pointBackgroundColor: 'rgba(221, 125, 0, 1)',
|
||||||
|
@ -57,7 +64,8 @@ export class ChartColorsDefinition {
|
||||||
pointHoverBackgroundColor: '#fff',
|
pointHoverBackgroundColor: '#fff',
|
||||||
pointHoverBorderColor: 'rgba(221, 125, 0, 0.8)'
|
pointHoverBorderColor: 'rgba(221, 125, 0, 0.8)'
|
||||||
},
|
},
|
||||||
{ // lile
|
{
|
||||||
|
// lile
|
||||||
backgroundColor: 'rgba(180, 137, 255, 0.2)',
|
backgroundColor: 'rgba(180, 137, 255, 0.2)',
|
||||||
borderColor: 'rgba(180, 137, 255, 1)',
|
borderColor: 'rgba(180, 137, 255, 1)',
|
||||||
pointBackgroundColor: 'rgba(180, 137, 255, 1)',
|
pointBackgroundColor: 'rgba(180, 137, 255, 1)',
|
||||||
|
|
|
@ -43,7 +43,7 @@ const DECLARATIONS = [
|
||||||
WorkbasketReportDueDateComponent,
|
WorkbasketReportDueDateComponent,
|
||||||
WorkbasketReportQuerySwitcherComponent,
|
WorkbasketReportQuerySwitcherComponent,
|
||||||
TaskReportComponent,
|
TaskReportComponent,
|
||||||
ClassificationReportComponent,
|
ClassificationReportComponent
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -51,5 +51,4 @@ const DECLARATIONS = [
|
||||||
imports: MODULES,
|
imports: MODULES,
|
||||||
providers: [RestConnectorService, MapToIterable]
|
providers: [RestConnectorService, MapToIterable]
|
||||||
})
|
})
|
||||||
export class MonitorModule {
|
export class MonitorModule {}
|
||||||
}
|
|
||||||
|
|
|
@ -9,36 +9,36 @@ const monitorUrl = '/v1/monitor/';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RestConnectorService {
|
export class RestConnectorService {
|
||||||
constructor(private httpClient: HttpClient) {
|
constructor(private httpClient: HttpClient) {}
|
||||||
}
|
|
||||||
|
|
||||||
getTaskStatusReport(): Observable<ReportData> {
|
getTaskStatusReport(): Observable<ReportData> {
|
||||||
return this.httpClient.get<ReportData>(`${environment.taskanaRestUrl + monitorUrl
|
return this.httpClient.get<ReportData>(
|
||||||
}tasks-status-report?states=READY,CLAIMED,COMPLETED`);
|
`${environment.taskanaRestUrl + monitorUrl}tasks-status-report?states=READY,CLAIMED,COMPLETED`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getWorkbasketStatisticsQueryingByDueDate(): Observable<ReportData> {
|
getWorkbasketStatisticsQueryingByDueDate(): Observable<ReportData> {
|
||||||
return this.httpClient.get<ReportData>(`${environment.taskanaRestUrl
|
return this.httpClient.get<ReportData>(
|
||||||
+ monitorUrl}tasks-workbasket-report?states=READY,CLAIMED,COMPLETED`);
|
`${environment.taskanaRestUrl + monitorUrl}tasks-workbasket-report?states=READY,CLAIMED,COMPLETED`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getWorkbasketStatisticsQueryingByPlannedDate(): Observable<ReportData> {
|
getWorkbasketStatisticsQueryingByPlannedDate(): Observable<ReportData> {
|
||||||
return this.httpClient.get<ReportData>(`${environment.taskanaRestUrl
|
return this.httpClient.get<ReportData>(
|
||||||
}/v1/monitor/tasks-workbasket-planned-date-report?daysInPast=7&states=READY,CLAIMED,COMPLETED`);
|
`${environment.taskanaRestUrl}/v1/monitor/tasks-workbasket-planned-date-report?daysInPast=7&states=READY,CLAIMED,COMPLETED`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getClassificationTasksReport(): Observable<ReportData> {
|
getClassificationTasksReport(): Observable<ReportData> {
|
||||||
return this.httpClient.get<ReportData>(`${environment.taskanaRestUrl
|
return this.httpClient.get<ReportData>(`${environment.taskanaRestUrl + monitorUrl}tasks-classification-report`);
|
||||||
+ monitorUrl}tasks-classification-report`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getDailyEntryExitReport(): Observable<ReportData> {
|
getDailyEntryExitReport(): Observable<ReportData> {
|
||||||
return this.httpClient.get<ReportData>(`${environment.taskanaRestUrl
|
return this.httpClient.get<ReportData>(`${environment.taskanaRestUrl + monitorUrl}timestamp-report`);
|
||||||
+ monitorUrl}timestamp-report`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getChartData(source: ReportData): Array<ChartData> {
|
getChartData(source: ReportData): Array<ChartData> {
|
||||||
return source.rows.map(row => {
|
return source.rows.map((row) => {
|
||||||
const rowData = new ChartData();
|
const rowData = new ChartData();
|
||||||
[rowData.label] = row.desc;
|
[rowData.label] = row.desc;
|
||||||
rowData.data = row.cells;
|
rowData.data = row.cells;
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { BsDatepickerModule, BsDatepickerConfig, ComponentLoaderFactory, PositioningService, BsLocaleService } from 'ngx-bootstrap';
|
import {
|
||||||
|
BsDatepickerModule,
|
||||||
|
BsDatepickerConfig,
|
||||||
|
ComponentLoaderFactory,
|
||||||
|
PositioningService,
|
||||||
|
BsLocaleService
|
||||||
|
} from 'ngx-bootstrap';
|
||||||
import { DatePickerComponent } from './date-picker.component';
|
import { DatePickerComponent } from './date-picker.component';
|
||||||
|
|
||||||
describe('DatePickerComponent', () => {
|
describe('DatePickerComponent', () => {
|
||||||
|
@ -11,10 +17,8 @@ describe('DatePickerComponent', () => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [BsDatepickerModule],
|
imports: [BsDatepickerModule],
|
||||||
declarations: [DatePickerComponent],
|
declarations: [DatePickerComponent],
|
||||||
providers: [BsDatepickerConfig, ComponentLoaderFactory, PositioningService,
|
providers: [BsDatepickerConfig, ComponentLoaderFactory, PositioningService, BsLocaleService]
|
||||||
BsLocaleService]
|
}).compileComponents();
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -9,8 +9,7 @@ describe('DropdownComponent', () => {
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [DropdownComponent]
|
declarations: [DropdownComponent]
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -10,8 +10,7 @@ export class DropdownComponent implements OnInit {
|
||||||
@Input() list: any[];
|
@Input() list: any[];
|
||||||
@Output() performClassification = new EventEmitter<any>();
|
@Output() performClassification = new EventEmitter<any>();
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {}
|
||||||
}
|
|
||||||
|
|
||||||
selectItem(item: any) {
|
selectItem(item: any) {
|
||||||
this.itemSelected = item;
|
this.itemSelected = item;
|
||||||
|
|
|
@ -9,8 +9,7 @@ describe('FieldErrorDisplayComponent', () => {
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [FieldErrorDisplayComponent]
|
declarations: [FieldErrorDisplayComponent]
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -17,6 +17,5 @@ export class FieldErrorDisplayComponent implements OnInit {
|
||||||
@Input()
|
@Input()
|
||||||
validationTrigger: boolean;
|
validationTrigger: boolean;
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
.dropdown-menu-users {
|
.dropdown-menu-users {
|
||||||
&>li{
|
& > li {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-group-search {
|
.list-group-search {
|
||||||
padding: 0px 15px;
|
padding: 0px 15px;
|
||||||
border-top: 1px solid #ddd;
|
border-top: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
.list-group-search {
|
.list-group-search {
|
||||||
border-top: none;
|
border-top: none;
|
||||||
}
|
}
|
||||||
row.padding {
|
row.padding {
|
||||||
padding: 1px 0px;
|
padding: 1px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-list {
|
.filter-list {
|
||||||
|
|
|
@ -13,14 +13,14 @@ describe('FilterComponent', () => {
|
||||||
let fixture: ComponentFixture<FilterComponent>;
|
let fixture: ComponentFixture<FilterComponent>;
|
||||||
let debugElement: any;
|
let debugElement: any;
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
const configure = (testBed: TestBed) => {
|
const configure = (testBed: TestBed) => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
providers: [MatSnackBar, Overlay],
|
providers: [MatSnackBar, Overlay],
|
||||||
imports: [AngularSvgIconModule, FormsModule, HttpClientModule]
|
imports: [AngularSvgIconModule, FormsModule, HttpClientModule]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
fixture = TestBed.createComponent(FilterComponent);
|
fixture = TestBed.createComponent(FilterComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
component.filterParams = {
|
component.filterParams = {
|
||||||
|
|
|
@ -9,11 +9,20 @@ import { TaskanaType } from 'app/shared/models/taskana-type';
|
||||||
styleUrls: ['./filter.component.scss']
|
styleUrls: ['./filter.component.scss']
|
||||||
})
|
})
|
||||||
export class FilterComponent implements OnInit {
|
export class FilterComponent implements OnInit {
|
||||||
@Input() allTypes: Map<string, string> = new Map([['ALL', 'All'], ['PERSONAL', 'Personal'], ['GROUP', 'Group'],
|
@Input() allTypes: Map<string, string> = new Map([
|
||||||
['CLEARANCE', 'Clearance'], ['TOPIC', 'Topic']]);
|
['ALL', 'All'],
|
||||||
|
['PERSONAL', 'Personal'],
|
||||||
|
['GROUP', 'Group'],
|
||||||
|
['CLEARANCE', 'Clearance'],
|
||||||
|
['TOPIC', 'Topic']
|
||||||
|
]);
|
||||||
|
|
||||||
@Input() allStates: Map<string, string> = new Map([['ALL', 'All'], ['READY', 'Ready'], ['CLAIMED', 'Claimed'],
|
@Input() allStates: Map<string, string> = new Map([
|
||||||
['COMPLETED', 'Completed']]);
|
['ALL', 'All'],
|
||||||
|
['READY', 'Ready'],
|
||||||
|
['CLAIMED', 'Claimed'],
|
||||||
|
['COMPLETED', 'Completed']
|
||||||
|
]);
|
||||||
|
|
||||||
@Input() filterParams = { name: '', key: '', type: '', description: '', owner: '' };
|
@Input() filterParams = { name: '', key: '', type: '', description: '', owner: '' };
|
||||||
|
|
||||||
|
@ -35,15 +44,17 @@ export class FilterComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
selectType(type: ICONTYPES) {
|
selectType(type: ICONTYPES) {
|
||||||
this.filter.filterParams.type = (type === ICONTYPES.ALL) ? '' : type;
|
this.filter.filterParams.type = type === ICONTYPES.ALL ? '' : type;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectState(state: ICONTYPES) {
|
selectState(state: ICONTYPES) {
|
||||||
this.filter.filterParams.state = (state === 'ALL') ? '' : state;
|
this.filter.filterParams.state = state === 'ALL' ? '' : state;
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
Object.keys(this.filterParams).forEach(key => { this.filterParams[key] = ''; });
|
Object.keys(this.filterParams).forEach((key) => {
|
||||||
|
this.filterParams[key] = '';
|
||||||
|
});
|
||||||
this.initializeFilterModel();
|
this.initializeFilterModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +79,6 @@ export class FilterComponent implements OnInit {
|
||||||
* @returns {string[]}
|
* @returns {string[]}
|
||||||
*/
|
*/
|
||||||
getUnusedKeys(): string[] {
|
getUnusedKeys(): string[] {
|
||||||
return Object.keys(this.filterParamKeys).filter(key => ['name', 'key', 'type'].indexOf(key) < 0);
|
return Object.keys(this.filterParamKeys).filter((key) => ['name', 'key', 'type'].indexOf(key) < 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
.center-block.no-detail {
|
.center-block.no-detail {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,17 +12,13 @@ import { MasterAndDetailComponent } from './master-and-detail.component';
|
||||||
selector: 'taskana-dummy-master',
|
selector: 'taskana-dummy-master',
|
||||||
template: 'dummymaster'
|
template: 'dummymaster'
|
||||||
})
|
})
|
||||||
export class DummyMasterComponent {
|
export class DummyMasterComponent {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-dummy-detail',
|
selector: 'taskana-dummy-detail',
|
||||||
template: 'dummydetail'
|
template: 'dummydetail'
|
||||||
})
|
})
|
||||||
export class DummyDetailComponent {
|
export class DummyDetailComponent {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('MasterAndDetailComponent ', () => {
|
describe('MasterAndDetailComponent ', () => {
|
||||||
let component;
|
let component;
|
||||||
|
@ -51,18 +47,10 @@ describe('MasterAndDetailComponent ', () => {
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [
|
declarations: [MasterAndDetailComponent, DummyMasterComponent, DummyDetailComponent],
|
||||||
MasterAndDetailComponent,
|
imports: [RouterTestingModule.withRoutes(routes), AngularSvgIconModule, HttpClientModule],
|
||||||
DummyMasterComponent,
|
|
||||||
DummyDetailComponent],
|
|
||||||
imports: [
|
|
||||||
RouterTestingModule.withRoutes(routes),
|
|
||||||
AngularSvgIconModule,
|
|
||||||
HttpClientModule
|
|
||||||
],
|
|
||||||
providers: [MasterAndDetailService]
|
providers: [MasterAndDetailService]
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(MasterAndDetailComponent);
|
fixture = TestBed.createComponent(MasterAndDetailComponent);
|
||||||
component = fixture.debugElement.componentInstance;
|
component = fixture.debugElement.componentInstance;
|
||||||
|
|
|
@ -5,8 +5,7 @@ import { MasterAndDetailService } from 'app/shared/services/master-and-detail/ma
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-shared-master-and-detail',
|
selector: 'taskana-shared-master-and-detail',
|
||||||
templateUrl: './master-and-detail.component.html',
|
templateUrl: './master-and-detail.component.html',
|
||||||
styleUrls: ['./master-and-detail.component.scss'],
|
styleUrls: ['./master-and-detail.component.scss']
|
||||||
|
|
||||||
})
|
})
|
||||||
export class MasterAndDetailComponent implements OnInit {
|
export class MasterAndDetailComponent implements OnInit {
|
||||||
private classifications = 'classifications';
|
private classifications = 'classifications';
|
||||||
|
@ -16,13 +15,16 @@ export class MasterAndDetailComponent implements OnInit {
|
||||||
|
|
||||||
showDetail = false;
|
showDetail = false;
|
||||||
currentRoute = '';
|
currentRoute = '';
|
||||||
constructor(private route: ActivatedRoute, private router: Router, private masterAndDetailService: MasterAndDetailService) {
|
constructor(
|
||||||
}
|
private route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
|
private masterAndDetailService: MasterAndDetailService
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.showDetail = this.showDetails();
|
this.showDetail = this.showDetails();
|
||||||
this.masterAndDetailService.setShowDetail(this.showDetail);
|
this.masterAndDetailService.setShowDetail(this.showDetail);
|
||||||
this.router.events.subscribe(event => {
|
this.router.events.subscribe((event) => {
|
||||||
if (event instanceof NavigationStart) {
|
if (event instanceof NavigationStart) {
|
||||||
this.showDetail = this.showDetails(event);
|
this.showDetail = this.showDetails(event);
|
||||||
this.masterAndDetailService.setShowDetail(this.showDetail);
|
this.masterAndDetailService.setShowDetail(this.showDetail);
|
||||||
|
@ -43,7 +45,7 @@ export class MasterAndDetailComponent implements OnInit {
|
||||||
|
|
||||||
private checkUrl(url: string): boolean {
|
private checkUrl(url: string): boolean {
|
||||||
this.checkRoute(url);
|
this.checkRoute(url);
|
||||||
return this.detailRoutes.some(routeDetail => url.indexOf(routeDetail) !== -1);
|
return this.detailRoutes.some((routeDetail) => url.indexOf(routeDetail) !== -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkRoute(url: string) {
|
private checkRoute(url: string) {
|
||||||
|
|
|
@ -1,144 +1,144 @@
|
||||||
@import '../../../../theme/variables';
|
@import '../../../../theme/variables';
|
||||||
|
|
||||||
.navbar.main:before {
|
.navbar.main:before {
|
||||||
@include degraded-bar(right, 100%, 3px)
|
@include degraded-bar(right, 100%, 3px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-inverse {
|
.navbar-inverse {
|
||||||
border:none;
|
border: none;
|
||||||
background-color: $dark-green;
|
background-color: $dark-green;
|
||||||
box-shadow: 0px 1px 5px -1px black;
|
box-shadow: 0px 1px 5px -1px black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-toggle{
|
.navbar-toggle {
|
||||||
margin: 3px 0px;
|
margin: 3px 0px;
|
||||||
|
font-size: 20px;
|
||||||
|
&.logout {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
&.logout{
|
}
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
button.navbar-toggle:hover > span{
|
button.navbar-toggle:hover > span {
|
||||||
color:$aquamarine;
|
color: $aquamarine;
|
||||||
}
|
}
|
||||||
ul.nav > p {
|
ul.nav > p {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
padding-right: 0px;
|
padding-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-inverse .navbar-toggle, .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus {
|
.navbar-inverse .navbar-toggle,
|
||||||
border: none;
|
.navbar-toggle:hover,
|
||||||
background-color: transparent;
|
.navbar-inverse .navbar-toggle:focus {
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg-icon.logo {
|
svg-icon.logo {
|
||||||
float: left;
|
float: left;
|
||||||
width: 150px;
|
width: 150px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
position: initial;
|
position: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2.navbar-brand{
|
h2.navbar-brand {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 15px 0px 0px 0px;
|
padding: 15px 0px 0px 0px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.domain-form {
|
.domain-form {
|
||||||
margin: 13px;
|
margin: 13px;
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
> div{
|
> div {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
> button {
|
> button {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: $dark-green;
|
background-color: $dark-green;
|
||||||
border: none;
|
border: none;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
border-bottom: 1px solid $dark-green;
|
border-bottom: 1px solid $dark-green;
|
||||||
margin-left:5px;
|
margin-left: 5px;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-content{
|
.nav-content {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-version {
|
.nav-version {
|
||||||
color: $grey;
|
color: $grey;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 5px;
|
bottom: 5px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All side bar links styling.
|
* All side bar links styling.
|
||||||
*/
|
*/
|
||||||
.nav-sidebar > li > a {
|
.nav-sidebar > li > a {
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.menu > span:hover,
|
.menu > span:hover,
|
||||||
.submenu > span:hover
|
.submenu > span:hover {
|
||||||
{
|
color: white;
|
||||||
color: white;
|
cursor: pointer;
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidenav {
|
.sidenav {
|
||||||
position:fixed;
|
position: fixed;
|
||||||
z-index:999;
|
z-index: 999;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: $dark-green;
|
background-color: $dark-green;
|
||||||
box-shadow: 3px 0px 10px -1px $dark-green;
|
box-shadow: 3px 0px 10px -1px $dark-green;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
height: 52px;
|
height: 52px;
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu,.submenu > span {
|
.menu,
|
||||||
margin-top: 15px;
|
.submenu > span {
|
||||||
font-size: 20px;
|
margin-top: 15px;
|
||||||
width: 100%;
|
font-size: 20px;
|
||||||
font-family: inherit;
|
width: 100%;
|
||||||
font-weight: 500;
|
font-family: inherit;
|
||||||
line-height: 1.1;
|
font-weight: 500;
|
||||||
|
line-height: 1.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu,.submenu > span {
|
.menu,
|
||||||
padding-left: 12px;
|
.submenu > span {
|
||||||
color: $grey;
|
padding-left: 12px;
|
||||||
outline: none;
|
color: $grey;
|
||||||
|
outline: none;
|
||||||
}
|
}
|
||||||
.menu.selected,.submenu.selected {
|
.menu.selected,
|
||||||
background-color: transparent;
|
.submenu.selected {
|
||||||
&> span{
|
background-color: transparent;
|
||||||
padding-left: 10px;
|
& > span {
|
||||||
border-left: $pallete-green 5px solid;
|
padding-left: 10px;
|
||||||
color: white;
|
border-left: $pallete-green 5px solid;
|
||||||
}
|
color: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu > .submenu{
|
.menu > .submenu {
|
||||||
margin-left: 30px;
|
margin-left: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: $grey;
|
color: $grey;
|
||||||
&:hover{
|
&:hover {
|
||||||
color:white;
|
color: white;
|
||||||
}
|
}
|
||||||
text-decoration: none
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,20 +24,13 @@ describe('NavBarComponent', () => {
|
||||||
let debugElement;
|
let debugElement;
|
||||||
let navBar;
|
let navBar;
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [{ path: 'classifications', component: NavBarComponent }];
|
||||||
{ path: 'classifications', component: NavBarComponent }
|
|
||||||
];
|
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach((done) => {
|
||||||
const configure = (testBed: TestBed) => {
|
const configure = (testBed: TestBed) => {
|
||||||
testBed.configureTestingModule({
|
testBed.configureTestingModule({
|
||||||
declarations: [NavBarComponent, UserInformationComponent],
|
declarations: [NavBarComponent, UserInformationComponent],
|
||||||
imports: [
|
imports: [AngularSvgIconModule, HttpClientModule, RouterTestingModule.withRoutes(routes), SharedModule],
|
||||||
AngularSvgIconModule,
|
|
||||||
HttpClientModule,
|
|
||||||
RouterTestingModule.withRoutes(routes),
|
|
||||||
SharedModule
|
|
||||||
],
|
|
||||||
providers: [
|
providers: [
|
||||||
SelectedRouteService,
|
SelectedRouteService,
|
||||||
BusinessAdminGuard,
|
BusinessAdminGuard,
|
||||||
|
@ -45,10 +38,11 @@ describe('NavBarComponent', () => {
|
||||||
WindowRefService,
|
WindowRefService,
|
||||||
RequestInProgressService,
|
RequestInProgressService,
|
||||||
MatSnackBar,
|
MatSnackBar,
|
||||||
Overlay]
|
Overlay
|
||||||
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
configureTests(configure).then(testBed => {
|
configureTests(configure).then((testBed) => {
|
||||||
fixture = TestBed.createComponent(NavBarComponent);
|
fixture = TestBed.createComponent(NavBarComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
debugElement = fixture.debugElement.nativeElement;
|
debugElement = fixture.debugElement.nativeElement;
|
||||||
|
@ -67,7 +61,7 @@ describe('NavBarComponent', () => {
|
||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have as title \'\'', (() => {
|
it("should have as title ''", () => {
|
||||||
expect(navBar.title).toEqual('');
|
expect(navBar.title).toEqual('');
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue