Initial commit
This commit is contained in:
parent
4b10f32cff
commit
802f0ce554
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -1 +1,7 @@
|
||||||
# taskana
|
[](https://travis-ci.org/Taskana/hackathon)
|
||||||
|
[](http://www.apache.org/licenses/LICENSE-2.0.html)
|
||||||
|
|
||||||
|
# Hackathon
|
||||||
|
|
||||||
|
## Link to UI
|
||||||
|
http://taskana-workplace.mybluemix.net
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"project": {
|
||||||
|
"name": "admin"
|
||||||
|
},
|
||||||
|
"apps": [
|
||||||
|
{
|
||||||
|
"root": "src",
|
||||||
|
"outDir": "dist",
|
||||||
|
"assets": [
|
||||||
|
"assets",
|
||||||
|
"favicon.ico"
|
||||||
|
],
|
||||||
|
"index": "index.html",
|
||||||
|
"main": "main.ts",
|
||||||
|
"polyfills": "polyfills.ts",
|
||||||
|
"test": "test.ts",
|
||||||
|
"tsconfig": "tsconfig.app.json",
|
||||||
|
"testTsconfig": "tsconfig.spec.json",
|
||||||
|
"prefix": "app",
|
||||||
|
"styles": [
|
||||||
|
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||||
|
"../node_modules/bootstrap-vertical-tabs/bootstrap.vertical-tabs.css",
|
||||||
|
"styles.css"
|
||||||
|
],
|
||||||
|
"scripts": [],
|
||||||
|
"environmentSource": "environments/environment.ts",
|
||||||
|
"environments": {
|
||||||
|
"dev": "environments/environment.ts",
|
||||||
|
"prod": "environments/environment.prod.ts"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"e2e": {
|
||||||
|
"protractor": {
|
||||||
|
"config": "./protractor.conf.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": [
|
||||||
|
{
|
||||||
|
"project": "src/tsconfig.app.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"project": "src/tsconfig.spec.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"project": "e2e/tsconfig.e2e.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"test": {
|
||||||
|
"karma": {
|
||||||
|
"config": "./karma.conf.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaults": {
|
||||||
|
"styleExt": "css",
|
||||||
|
"component": {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Editor configuration, see http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
max_line_length = off
|
||||||
|
trim_trailing_whitespace = false
|
|
@ -0,0 +1,42 @@
|
||||||
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# compiled output
|
||||||
|
/dist
|
||||||
|
/tmp
|
||||||
|
/out-tsc
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
/.idea
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# IDE - VSCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
# misc
|
||||||
|
/.sass-cache
|
||||||
|
/connect.lock
|
||||||
|
/coverage
|
||||||
|
/libpeerconnection.log
|
||||||
|
npm-debug.log
|
||||||
|
testem.log
|
||||||
|
/typings
|
||||||
|
|
||||||
|
# e2e
|
||||||
|
/e2e/*.js
|
||||||
|
/e2e/*.map
|
||||||
|
|
||||||
|
# System Files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
// Verwendet IntelliSense zum Ermitteln möglicher Node.js-Debugattribute.
|
||||||
|
// Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen.
|
||||||
|
// Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Programm starten",
|
||||||
|
"program": "${file}",
|
||||||
|
"outFiles": [
|
||||||
|
"${workspaceRoot}/out/**/*.js"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Admin
|
||||||
|
|
||||||
|
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.3.
|
||||||
|
|
||||||
|
## Development server
|
||||||
|
|
||||||
|
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||||
|
|
||||||
|
## Code scaffolding
|
||||||
|
|
||||||
|
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|module`.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||||
|
|
||||||
|
## Running end-to-end tests
|
||||||
|
|
||||||
|
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
||||||
|
Before running the tests make sure you are serving the app via `ng serve`.
|
||||||
|
|
||||||
|
## Further help
|
||||||
|
|
||||||
|
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { AdminPage } from './app.po';
|
||||||
|
|
||||||
|
describe('admin App', () => {
|
||||||
|
let page: AdminPage;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
page = new AdminPage();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display message saying app works', () => {
|
||||||
|
page.navigateTo();
|
||||||
|
expect(page.getParagraphText()).toEqual('app works!');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { browser, by, element } from 'protractor';
|
||||||
|
|
||||||
|
export class AdminPage {
|
||||||
|
navigateTo() {
|
||||||
|
return browser.get('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
getParagraphText() {
|
||||||
|
return element(by.css('app-root h1')).getText();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../out-tsc/e2e",
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"types": [
|
||||||
|
"jasmine",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Karma configuration file, see link for more information
|
||||||
|
// https://karma-runner.github.io/0.13/config/configuration-file.html
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
config.set({
|
||||||
|
basePath: '',
|
||||||
|
frameworks: ['jasmine', '@angular/cli'],
|
||||||
|
plugins: [
|
||||||
|
require('karma-jasmine'),
|
||||||
|
require('karma-chrome-launcher'),
|
||||||
|
require('karma-jasmine-html-reporter'),
|
||||||
|
require('karma-coverage-istanbul-reporter'),
|
||||||
|
require('@angular/cli/plugins/karma')
|
||||||
|
],
|
||||||
|
client:{
|
||||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
|
},
|
||||||
|
files: [
|
||||||
|
{ pattern: './src/test.ts', watched: false }
|
||||||
|
],
|
||||||
|
preprocessors: {
|
||||||
|
'./src/test.ts': ['@angular/cli']
|
||||||
|
},
|
||||||
|
mime: {
|
||||||
|
'text/x-typescript': ['ts','tsx']
|
||||||
|
},
|
||||||
|
coverageIstanbulReporter: {
|
||||||
|
reports: [ 'html', 'lcovonly' ],
|
||||||
|
fixWebpackSourcePaths: true
|
||||||
|
},
|
||||||
|
angularCli: {
|
||||||
|
environment: 'dev'
|
||||||
|
},
|
||||||
|
reporters: config.angularCli && config.angularCli.codeCoverage
|
||||||
|
? ['progress', 'coverage-istanbul']
|
||||||
|
: ['progress', 'kjhtml'],
|
||||||
|
port: 9876,
|
||||||
|
colors: true,
|
||||||
|
logLevel: config.LOG_INFO,
|
||||||
|
autoWatch: true,
|
||||||
|
browsers: ['Chrome'],
|
||||||
|
singleRun: false
|
||||||
|
});
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
||||||
|
{
|
||||||
|
"name": "admin",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"start": "ng serve",
|
||||||
|
"build": "ng build",
|
||||||
|
"test": "ng test",
|
||||||
|
"lint": "ng lint",
|
||||||
|
"e2e": "ng e2e"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/common": "^4.0.0",
|
||||||
|
"@angular/compiler": "^4.0.0",
|
||||||
|
"@angular/core": "^4.0.0",
|
||||||
|
"@angular/forms": "^4.0.0",
|
||||||
|
"@angular/http": "^4.0.0",
|
||||||
|
"@angular/platform-browser": "^4.0.0",
|
||||||
|
"@angular/platform-browser-dynamic": "^4.0.0",
|
||||||
|
"@angular/router": "^4.0.0",
|
||||||
|
"angular-tree-component": "^3.6.0",
|
||||||
|
"bootstrap": "^3.3.7",
|
||||||
|
"bootstrap-vertical-tabs": "^1.2.2",
|
||||||
|
"core-js": "^2.4.1",
|
||||||
|
"ngx-bootstrap": "^1.7.1",
|
||||||
|
"rxjs": "^5.1.0",
|
||||||
|
"zone.js": "^0.8.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@angular/cli": "1.0.3",
|
||||||
|
"@angular/compiler-cli": "^4.0.0",
|
||||||
|
"@types/jasmine": "2.5.38",
|
||||||
|
"@types/node": "~6.0.60",
|
||||||
|
"codelyzer": "~2.0.0",
|
||||||
|
"jasmine-core": "~2.5.2",
|
||||||
|
"jasmine-spec-reporter": "~3.2.0",
|
||||||
|
"karma": "~1.4.1",
|
||||||
|
"karma-chrome-launcher": "~2.1.1",
|
||||||
|
"karma-cli": "~1.0.1",
|
||||||
|
"karma-jasmine": "~1.1.0",
|
||||||
|
"karma-jasmine-html-reporter": "^0.2.2",
|
||||||
|
"karma-coverage-istanbul-reporter": "^0.2.0",
|
||||||
|
"protractor": "~5.1.0",
|
||||||
|
"ts-node": "~2.0.0",
|
||||||
|
"tslint": "~4.5.0",
|
||||||
|
"typescript": "~2.2.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Protractor configuration file, see link for more information
|
||||||
|
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||||
|
|
||||||
|
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||||
|
|
||||||
|
exports.config = {
|
||||||
|
allScriptsTimeout: 11000,
|
||||||
|
specs: [
|
||||||
|
'./e2e/**/*.e2e-spec.ts'
|
||||||
|
],
|
||||||
|
capabilities: {
|
||||||
|
'browserName': 'chrome'
|
||||||
|
},
|
||||||
|
directConnect: true,
|
||||||
|
baseUrl: 'http://localhost:4200/',
|
||||||
|
framework: 'jasmine',
|
||||||
|
jasmineNodeOpts: {
|
||||||
|
showColors: true,
|
||||||
|
defaultTimeoutInterval: 30000,
|
||||||
|
print: function() {}
|
||||||
|
},
|
||||||
|
beforeLaunch: function() {
|
||||||
|
require('ts-node').register({
|
||||||
|
project: 'e2e/tsconfig.e2e.json'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onPrepare() {
|
||||||
|
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
import { WorkbasketadministrationComponent } from './workbasketadministration/workbasketadministration.component';
|
||||||
|
import { CategoriesadministrationComponent } from './categoriesadministration/categoriesadministration.component';
|
||||||
|
|
||||||
|
const appRoutes: Routes = [
|
||||||
|
{
|
||||||
|
path: 'workbaskets',
|
||||||
|
component: WorkbasketadministrationComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'workbaskets/:id',
|
||||||
|
component: WorkbasketadministrationComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'categories',
|
||||||
|
component: CategoriesadministrationComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
redirectTo: 'workbaskets',
|
||||||
|
pathMatch: 'full'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forRoot(
|
||||||
|
appRoutes
|
||||||
|
)
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
RouterModule
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class AppRoutingModule { }
|
|
@ -0,0 +1,20 @@
|
||||||
|
<nav class="navbar navbar-default">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<a class="navbar-brand" href="#">
|
||||||
|
<p>Taskana Administration</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
<li><a [href]="monitorUrl">Monitor</a></li>
|
||||||
|
<li><a [href]="workplaceUrl">Workplace</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
<li role="presentation" routerLinkActive="active"><a routerLink="/workbaskets">Workbaskets</a></li>
|
||||||
|
<li role="presentation" routerLinkActive="active"><a routerLink="/categories">Categories</a></li>
|
||||||
|
</ul>
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { TestBed, async } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
describe('AppComponent', () => {
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent
|
||||||
|
],
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should create the app', async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app).toBeTruthy();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it(`should have as title 'app works!'`, async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app.title).toEqual('app works!');
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should render title in a h1 tag', async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
fixture.detectChanges();
|
||||||
|
const compiled = fixture.debugElement.nativeElement;
|
||||||
|
expect(compiled.querySelector('h1').textContent).toContain('app works!');
|
||||||
|
}));
|
||||||
|
});
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { environment } from '../environments/environment';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.css']
|
||||||
|
})
|
||||||
|
export class AppComponent {
|
||||||
|
title = 'Taskana Administration';
|
||||||
|
|
||||||
|
monitorUrl: string = environment.taskanaMonitorUrl;
|
||||||
|
workplaceUrl: string = environment.taskanaWorkplaceUrl;
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { HttpModule, JsonpModule } from '@angular/http';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
import { TabsModule } from 'ngx-bootstrap/tabs';
|
||||||
|
import { TreeModule } from 'angular-tree-component';
|
||||||
|
import { WorkbasketlistComponent } from './workbasketlist/workbasketlist.component';
|
||||||
|
import { WorkbasketeditorComponent } from './workbasketeditor/workbasketeditor.component';
|
||||||
|
import { CategorieslistComponent } from './categorieslist/categorieslist.component';
|
||||||
|
import { CategoriestreeComponent } from './categoriestree/categoriestree.component';
|
||||||
|
import { CategoryeditorComponent } from './categoryeditor/categoryeditor.component';
|
||||||
|
import { CategoriesadministrationComponent } from './categoriesadministration/categoriesadministration.component';
|
||||||
|
import { WorkbasketadministrationComponent } from './workbasketadministration/workbasketadministration.component';
|
||||||
|
import { WorkbasketAuthorizationComponent } from './workbasket-authorization/workbasket-authorization.component';
|
||||||
|
import { WorkbasketDetailsComponent } from './workbasket-details/workbasket-details.component';
|
||||||
|
import { WorkbasketDistributiontargetsComponent } from './workbasket-distributiontargets/workbasket-distributiontargets.component';
|
||||||
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
|
import { AlertModule } from 'ngx-bootstrap';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent,
|
||||||
|
WorkbasketlistComponent,
|
||||||
|
WorkbasketeditorComponent,
|
||||||
|
CategorieslistComponent,
|
||||||
|
CategoriestreeComponent,
|
||||||
|
CategoryeditorComponent,
|
||||||
|
CategoriesadministrationComponent,
|
||||||
|
WorkbasketadministrationComponent,
|
||||||
|
WorkbasketAuthorizationComponent,
|
||||||
|
WorkbasketDetailsComponent,
|
||||||
|
WorkbasketDistributiontargetsComponent
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
FormsModule,
|
||||||
|
HttpModule,
|
||||||
|
JsonpModule,
|
||||||
|
TabsModule.forRoot(),
|
||||||
|
TreeModule,
|
||||||
|
AppRoutingModule,
|
||||||
|
AlertModule.forRoot()
|
||||||
|
],
|
||||||
|
providers: [],
|
||||||
|
bootstrap: [AppComponent]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
|
@ -0,0 +1,6 @@
|
||||||
|
<div class="col-md-3">
|
||||||
|
<app-categoriestree (categorySelected)="onCategorySelected($event)"></app-categoriestree>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<app-categoryeditor [categorySelected]="categorySelected"></app-categoryeditor>
|
||||||
|
</div>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CategoriesadministrationComponent } from './categoriesadministration.component';
|
||||||
|
|
||||||
|
describe('CategoriesadministrattionComponent', () => {
|
||||||
|
let component: CategoriesadministrationComponent;
|
||||||
|
let fixture: ComponentFixture<CategoriesadministrationComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CategoriesadministrationComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CategoriesadministrationComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-categoriesadministration',
|
||||||
|
templateUrl: './categoriesadministration.component.html',
|
||||||
|
styleUrls: ['./categoriesadministration.component.css']
|
||||||
|
})
|
||||||
|
export class CategoriesadministrationComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
categorySelected: any;
|
||||||
|
|
||||||
|
onCategorySelected(arg) {
|
||||||
|
console.log("Event angekommen: ",arg);
|
||||||
|
this.categorySelected = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
export class Category {
|
||||||
|
constructor(
|
||||||
|
public id: string,
|
||||||
|
public name: string,
|
||||||
|
public description: string,
|
||||||
|
public priorty: number,
|
||||||
|
public serviceLevel: string) { }
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</thead>
|
||||||
|
<tr *ngFor="let category of categories">
|
||||||
|
<td>{{ category.id }}</td>
|
||||||
|
<td>{{ category.name }}</td>
|
||||||
|
<td>{{ category.description }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CategorieslistComponent } from './categorieslist.component';
|
||||||
|
|
||||||
|
describe('CategorieslistComponent', () => {
|
||||||
|
let component: CategorieslistComponent;
|
||||||
|
let fixture: ComponentFixture<CategorieslistComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CategorieslistComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CategorieslistComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-categorieslist',
|
||||||
|
templateUrl: './categorieslist.component.html',
|
||||||
|
styleUrls: ['./categorieslist.component.css']
|
||||||
|
})
|
||||||
|
export class CategorieslistComponent implements OnInit {
|
||||||
|
|
||||||
|
categories = [ {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Category 1",
|
||||||
|
"description": "Das ist die erste Business Category."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"name": "Category 2",
|
||||||
|
"description": "Das ist die erste Business Category."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3",
|
||||||
|
"name": "Category 3",
|
||||||
|
"description": "Das ist die erste Business Category."
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
<tree-root [nodes]="nodes"
|
||||||
|
(onActivate)="onCategorySelected($event)">
|
||||||
|
</tree-root>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CategoriestreeComponent } from './categoriestree.component';
|
||||||
|
|
||||||
|
describe('CategoriestreeComponent', () => {
|
||||||
|
let component: CategoriestreeComponent;
|
||||||
|
let fixture: ComponentFixture<CategoriestreeComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CategoriestreeComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CategoriestreeComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,87 @@
|
||||||
|
import { Component, OnInit, EventEmitter, Output } from '@angular/core';
|
||||||
|
import { Category } from '../categoriesadministration/category';
|
||||||
|
import { CategoryService } from '../services/category.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-categoriestree',
|
||||||
|
templateUrl: './categoriestree.component.html',
|
||||||
|
styleUrls: ['./categoriestree.component.css'],
|
||||||
|
providers: [CategoryService]
|
||||||
|
})
|
||||||
|
export class CategoriestreeComponent implements OnInit {
|
||||||
|
|
||||||
|
categories: Category[];
|
||||||
|
errorMessage: string;
|
||||||
|
|
||||||
|
nodes = [];
|
||||||
|
|
||||||
|
/*
|
||||||
|
nodes = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
name: 'Category 1',
|
||||||
|
children: [
|
||||||
|
{ id: '2', name: 'Category 2' },
|
||||||
|
{ id: '3', name: 'Category 3' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '4',
|
||||||
|
name: 'Category 4',
|
||||||
|
children: [
|
||||||
|
{ id: '5', name: 'Category 5' },
|
||||||
|
{
|
||||||
|
id: '6',
|
||||||
|
name: 'Category 6',
|
||||||
|
children: [
|
||||||
|
{ id: '7', name: 'Category 7' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
constructor(private categoryService: CategoryService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.getCategories();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
categorySelected = new EventEmitter<Category>();
|
||||||
|
|
||||||
|
onCategorySelected(arg) {
|
||||||
|
console.log("Selected: ", arg);
|
||||||
|
var category: Category = arg.node.data;
|
||||||
|
this.categorySelected.next(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
getCategories() {
|
||||||
|
console.log("Going to load categories...");
|
||||||
|
this.categoryService.getCategories()
|
||||||
|
.subscribe(c => {
|
||||||
|
this.categories = c;
|
||||||
|
console.log("RESPONSE: ", c);
|
||||||
|
this.nodes = c;
|
||||||
|
if (this.categories != null && this.categories.length > 0) {
|
||||||
|
// this.nodes = [];
|
||||||
|
this.categories.forEach(category => {
|
||||||
|
console.log("Geladene Category: ", category);
|
||||||
|
// let count = 1;
|
||||||
|
// this.nodes.push({'1', 'NAME'});
|
||||||
|
// count++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// this.autoCompleteData.push(workbasket.name);
|
||||||
|
// categories => this.categories = heroes,
|
||||||
|
// error => this.errorMessage = <any>error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<h3>Category Details of {{categorySelected?.name}} (ID: {{categorySelected?.id}})</h3>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-2 control-label" for="name">Name</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" id="name" placeholder="Name" [(ngModel)]="categorySelected.name" name="name">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-2 control-label" for="descrption">Description</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" id="description" placeholder="Description" [(ngModel)]="categorySelected.description" name="description">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-2 control-label" for="owner">Owner</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" id="owner" placeholder="Owner" [(ngModel)]="categorySelected.owner" name="owner">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-2 control-label" for="priority">Priority</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" id="priority" placeholder="Priority" [(ngModel)]="categorySelected.priority" name="priority">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-2 control-label" for="servicelevel">Service Level</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" id="servicelevel" placeholder="Service Level" [(ngModel)]="categorySelected.serviceLevel" name="servicelevel">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-2 col-sm-10">
|
||||||
|
<button type="submit" class="btn btn-default btn-primary">Save changes</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CategoryeditorComponent } from './categoryeditor.component';
|
||||||
|
|
||||||
|
describe('CategoryeditorComponent', () => {
|
||||||
|
let component: CategoryeditorComponent;
|
||||||
|
let fixture: ComponentFixture<CategoryeditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CategoryeditorComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CategoryeditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { Category } from '../categoriesadministration/category';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-categoryeditor',
|
||||||
|
templateUrl: './categoryeditor.component.html',
|
||||||
|
styleUrls: ['./categoryeditor.component.css']
|
||||||
|
})
|
||||||
|
export class CategoryeditorComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.categorySelected = new Category('', '', '', 0,'');
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
categorySelected: Category;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
export class WorkbasketAuthorization {
|
||||||
|
id: string;
|
||||||
|
workbasketId: string;
|
||||||
|
userId: string;
|
||||||
|
groupId: string;
|
||||||
|
read: boolean;
|
||||||
|
open: boolean;
|
||||||
|
append: boolean;
|
||||||
|
transfer: boolean;
|
||||||
|
distribute: boolean;
|
||||||
|
|
||||||
|
constructor(id: string,
|
||||||
|
workbasketId: string,
|
||||||
|
userId: string,
|
||||||
|
groupId: string,
|
||||||
|
read: boolean,
|
||||||
|
open: boolean,
|
||||||
|
append: boolean,
|
||||||
|
transfer: boolean,
|
||||||
|
distribute: boolean) { }
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
export class Workbasket {
|
||||||
|
constructor(
|
||||||
|
public id: string,
|
||||||
|
public tenantId: string,
|
||||||
|
public created: string,
|
||||||
|
public modified: string,
|
||||||
|
public name: string,
|
||||||
|
public description: string,
|
||||||
|
public owner: string,
|
||||||
|
public distributionTargets: [string]) { }
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CategoryService } from './category.service';
|
||||||
|
|
||||||
|
describe('CategoryService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [CategoryService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([CategoryService], (service: CategoryService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { RequestOptions, Headers, Http, Response } from '@angular/http';
|
||||||
|
import { environment } from '../../environments/environment';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import 'rxjs/add/operator/catch';
|
||||||
|
import 'rxjs/add/operator/map';
|
||||||
|
|
||||||
|
import { Category } from '../categoriesadministration/category';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CategoryService {
|
||||||
|
private categoryServiceUrl = environment.taskanaRestUrl + '/v1/categories'; // URL to web API
|
||||||
|
constructor(private http: Http) { }
|
||||||
|
getCategories(): Observable<Category[]> {
|
||||||
|
return this.http.get(this.categoryServiceUrl, this.createAuthorizationHeader())
|
||||||
|
.map(this.extractData)
|
||||||
|
.catch(this.handleError);
|
||||||
|
}
|
||||||
|
private extractData(res: Response) {
|
||||||
|
let body = res.json();
|
||||||
|
console.log("Body: ", body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
private handleError(error: Response | any) {
|
||||||
|
// In a real world app, you might use a remote logging infrastructure
|
||||||
|
let errMsg: string;
|
||||||
|
if (error instanceof Response) {
|
||||||
|
const body = error.json() || '';
|
||||||
|
const err = body.error || JSON.stringify(body);
|
||||||
|
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
|
||||||
|
} else {
|
||||||
|
errMsg = error.message ? error.message : error.toString();
|
||||||
|
}
|
||||||
|
console.error(errMsg);
|
||||||
|
return Observable.throw(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private createAuthorizationHeader() {
|
||||||
|
let headers: Headers = new Headers();
|
||||||
|
headers.append("Authorization", "Basic TWF4OnRlc3Q=");
|
||||||
|
|
||||||
|
return new RequestOptions({ headers: headers });
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { WorkbasketserviceService } from './workbasketservice.service';
|
||||||
|
|
||||||
|
describe('WorkbasketserviceService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [WorkbasketserviceService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([WorkbasketserviceService], (service: WorkbasketserviceService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { RequestOptions, Headers, Http, Response } from '@angular/http';
|
||||||
|
import { Workbasket } from '../model/workbasket';
|
||||||
|
import { WorkbasketAuthorization } from '../model/workbasket-authorization';
|
||||||
|
import { environment } from '../../environments/environment';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import 'rxjs/Rx';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class WorkbasketserviceService {
|
||||||
|
|
||||||
|
constructor(private http: Http) { }
|
||||||
|
|
||||||
|
getAllWorkBaskets(): Observable<Workbasket[]> {
|
||||||
|
return this.http.get(environment.taskanaRestUrl + "/v1/workbaskets", this.createAuthorizationHeader())
|
||||||
|
.map(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
createWorkbasket(workbasket: Workbasket): Observable<Workbasket> {
|
||||||
|
return this.http.post(environment.taskanaRestUrl + "/v1/workbaskets", workbasket, this.createAuthorizationHeader())
|
||||||
|
.map(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteWorkbasket(id: string) {
|
||||||
|
return this.http.delete(environment.taskanaRestUrl + "/v1/workbaskets/" + id, this.createAuthorizationHeader())
|
||||||
|
.map(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
updateWorkbasket(workbasket: Workbasket): Observable<Workbasket> {
|
||||||
|
return this.http.put(environment.taskanaRestUrl + "/v1/workbaskets/" + workbasket.id, workbasket, this.createAuthorizationHeader())
|
||||||
|
.map(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllWorkBasketAuthorizations(id: String): Observable<WorkbasketAuthorization[]> {
|
||||||
|
return this.http.get(environment.taskanaRestUrl + "/v1/workbaskets/" + id + "/authorizations", this.createAuthorizationHeader())
|
||||||
|
.map(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
createWorkBasketAuthorization(workbasketAuthorization: WorkbasketAuthorization): Observable<WorkbasketAuthorization> {
|
||||||
|
return this.http.post(environment.taskanaRestUrl + "/v1/workbaskets/authorizations", workbasketAuthorization, this.createAuthorizationHeader())
|
||||||
|
.map(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
updateWorkBasketAuthorization(workbasketAuthorization: WorkbasketAuthorization): Observable<WorkbasketAuthorization> {
|
||||||
|
return this.http.put(environment.taskanaRestUrl + "/v1/workbaskets/authorizations/" + workbasketAuthorization.id, workbasketAuthorization, this.createAuthorizationHeader())
|
||||||
|
.map(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteWorkBasketAuthorization(workbasketAuthorization: WorkbasketAuthorization) {
|
||||||
|
return this.http.delete(environment.taskanaRestUrl + "/v1/workbaskets/authorizations/" + workbasketAuthorization.id, this.createAuthorizationHeader());
|
||||||
|
}
|
||||||
|
|
||||||
|
private createAuthorizationHeader() {
|
||||||
|
let headers: Headers = new Headers();
|
||||||
|
headers.append("Authorization", "Basic TWF4OnRlc3Q=");
|
||||||
|
headers.append("content-type", "application/json");
|
||||||
|
|
||||||
|
return new RequestOptions({ headers: headers });
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
<h2>Authorizations</h2>
|
||||||
|
<table class="table table-condensed table-hover">
|
||||||
|
<thead>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>UserID</th>
|
||||||
|
<th>GroupID</th>
|
||||||
|
<th>READ</th>
|
||||||
|
<th>OPEN</th>
|
||||||
|
<th>APPEND</th>
|
||||||
|
<th>TRANSFER</th>
|
||||||
|
<th>DISTRIBUTE</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<input class="form-control" placeholder="UserId" name="name" [(ngModel)]="workbasketAuthorization.userId" required>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input class="form-control" placeholder="GroupId" name="description" [(ngModel)]="workbasketAuthorization.groupId">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" [(ngModel)]="workbasketAuthorization.read">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" [(ngModel)]="workbasketAuthorization.open">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" [(ngModel)]="workbasketAuthorization.append">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" [(ngModel)]="workbasketAuthorization.transfer">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" [(ngModel)]="workbasketAuthorization.distribute">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onAdd()">
|
||||||
|
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onClear()">
|
||||||
|
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr *ngFor="let workbasketAuthorization of workbasketAuthorizations">
|
||||||
|
<td *ngIf="workbasketAuthorization.id != editing.id">{{ workbasketAuthorization.id }}</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id == editing.id">
|
||||||
|
<input class="form-control" placeholder="Id" name="editid" [(ngModel)]="editing.id" readonly>
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id != editing.id">{{ workbasketAuthorization.userId }}</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id == editing.id">
|
||||||
|
<input class="form-control" placeholder="UserId" name="edituserId" [(ngModel)]="editing.userId">
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id != editing.id">{{ workbasketAuthorization.groupId }}</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id == editing.id">
|
||||||
|
<input class="form-control" placeholder="GroupId" name="editgroupId" [(ngModel)]="editing.groupId">
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id != editing.id">
|
||||||
|
<input type="checkbox" [checked]="workbasketAuthorization.read" disabled>
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id == editing.id">
|
||||||
|
<input type="checkbox" [(ngModel)]="workbasketAuthorization.read">
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id != editing.id">
|
||||||
|
<input type="checkbox" [checked]="workbasketAuthorization.open" disabled>
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id == editing.id">
|
||||||
|
<input type="checkbox" [(ngModel)]="workbasketAuthorization.open">
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id != editing.id">
|
||||||
|
<input type="checkbox" [checked]="workbasketAuthorization.append" disabled>
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id == editing.id">
|
||||||
|
<input type="checkbox" [(ngModel)]="workbasketAuthorization.append">
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id != editing.id">
|
||||||
|
<input type="checkbox" [checked]="workbasketAuthorization.transfer" disabled>
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id == editing.id">
|
||||||
|
<input type="checkbox" [(ngModel)]="workbasketAuthorization.transfer">
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id != editing.id">
|
||||||
|
<input type="checkbox" [checked]="workbasketAuthorization.distribute" disabled>
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id == editing.id">
|
||||||
|
<input type="checkbox" [(ngModel)]="workbasketAuthorization.distribute">
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id != editing.id">
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onEdit(workbasketAuthorization)">
|
||||||
|
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onDelete(workbasketAuthorization)">
|
||||||
|
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasketAuthorization.id == editing.id">
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onSave(workbasketAuthorization)">
|
||||||
|
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onCancel(workbasketAuthorization)">
|
||||||
|
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { WorkbasketAuthorizationComponent } from './workbasket-authorization.component';
|
||||||
|
|
||||||
|
describe('WorkbasketAuthorizationComponent', () => {
|
||||||
|
let component: WorkbasketAuthorizationComponent;
|
||||||
|
let fixture: ComponentFixture<WorkbasketAuthorizationComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ WorkbasketAuthorizationComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(WorkbasketAuthorizationComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,101 @@
|
||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
|
import { WorkbasketserviceService } from '../services/workbasketservice.service';
|
||||||
|
import { WorkbasketAuthorization } from '../model/workbasket-authorization';
|
||||||
|
import { Workbasket } from '../model/workbasket';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-workbasket-authorization',
|
||||||
|
templateUrl: './workbasket-authorization.component.html',
|
||||||
|
styleUrls: ['./workbasket-authorization.component.css'],
|
||||||
|
providers: [WorkbasketserviceService]
|
||||||
|
})
|
||||||
|
export class WorkbasketAuthorizationComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
workbasket: Workbasket;
|
||||||
|
|
||||||
|
workbasketAuthorization: WorkbasketAuthorization = this.getEmptyObject();
|
||||||
|
selected: WorkbasketAuthorization = this.getEmptyObject();
|
||||||
|
editing: WorkbasketAuthorization = this.getEmptyObject();
|
||||||
|
isEditing: boolean = false;
|
||||||
|
|
||||||
|
constructor(private service: WorkbasketserviceService, private route: ActivatedRoute) { }
|
||||||
|
|
||||||
|
workbasketAuthorizations: WorkbasketAuthorization[];
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.route.params.switchMap((params: Params) => this.service.getAllWorkBasketAuthorizations(params['id']))
|
||||||
|
.subscribe(resultList => {
|
||||||
|
this.workbasketAuthorizations = resultList;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getEmptyObject() {
|
||||||
|
return new WorkbasketAuthorization("", "", "", "", false, false, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDelete(workbasket: WorkbasketAuthorization) {
|
||||||
|
this.service.deleteWorkBasketAuthorization(workbasket).subscribe(result => {
|
||||||
|
var index = this.workbasketAuthorizations.indexOf(workbasket);
|
||||||
|
if (index > -1) {
|
||||||
|
this.workbasketAuthorizations.splice(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onAdd() {
|
||||||
|
console.log(this.workbasketAuthorization);
|
||||||
|
this.workbasketAuthorization.workbasketId = this.workbasket.id;
|
||||||
|
this.service.createWorkBasketAuthorization(this.workbasketAuthorization).subscribe(result => {
|
||||||
|
this.workbasketAuthorizations.push(result);
|
||||||
|
this.onClear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onEdit(workbasketAuthorizations: WorkbasketAuthorization) {
|
||||||
|
this.editing = { ...workbasketAuthorizations };
|
||||||
|
this.isEditing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelect(workbasketAuthorizations: WorkbasketAuthorization) {
|
||||||
|
if (!this.isEditing) {
|
||||||
|
this.selected = workbasketAuthorizations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClear() {
|
||||||
|
this.workbasketAuthorization.id = "";
|
||||||
|
this.workbasketAuthorization.workbasketId = "";
|
||||||
|
this.workbasketAuthorization.userId = "";
|
||||||
|
this.workbasketAuthorization.groupId = "";
|
||||||
|
this.workbasketAuthorization.read = false;
|
||||||
|
this.workbasketAuthorization.open = false;
|
||||||
|
this.workbasketAuthorization.append = false;
|
||||||
|
this.workbasketAuthorization.transfer = false;
|
||||||
|
this.workbasketAuthorization.distribute = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSave() {
|
||||||
|
if (this.isEditing) {
|
||||||
|
this.service.updateWorkBasketAuthorization(this.editing).subscribe(result => {
|
||||||
|
this.selected.id = result.id;
|
||||||
|
this.selected.workbasketId = result.workbasketId;
|
||||||
|
this.selected.userId = result.userId;
|
||||||
|
this.selected.groupId = result.groupId;
|
||||||
|
this.selected.read = result.read;
|
||||||
|
this.selected.open = result.open;
|
||||||
|
this.selected.append = result.append;
|
||||||
|
this.selected.transfer = result.transfer;
|
||||||
|
this.selected.distribute = result.distribute;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.isEditing = false;
|
||||||
|
this.editing = this.getEmptyObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
onCancel() {
|
||||||
|
this.editing = this.getEmptyObject();
|
||||||
|
this.isEditing = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h2>Details</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onEdit()">
|
||||||
|
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onSave()">
|
||||||
|
<span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>Id</dt>
|
||||||
|
<dd>{{ workbasketClone.id }}</dd>
|
||||||
|
<dt>Tenant Id</dt>
|
||||||
|
<dd *ngIf="!editMode">{{ workbasketClone.tenantId }}</dd>
|
||||||
|
<dd *ngIf="editMode"><input class="form-control" placeholder="Name" name="editName" [(ngModel)]="workbasketClone.tenantId"></dd>
|
||||||
|
<dt>Created Date</dt>
|
||||||
|
<dd>{{ workbasketClone.created | date: 'dd/MM/yyyy HH:mm' }}</dd>
|
||||||
|
<dt>Modified Date</dt>
|
||||||
|
<dd>{{ workbasketClone.modified | date: 'dd/MM/yyyy HH:mm' }}</dd>
|
||||||
|
<dt>Name</dt>
|
||||||
|
<dd *ngIf="!editMode">{{ workbasketClone.name }}</dd>
|
||||||
|
<dd *ngIf="editMode"><input class="form-control" placeholder="Name" name="editName" [(ngModel)]="workbasketClone.name" required></dd>
|
||||||
|
<dt>Owner</dt>
|
||||||
|
<dd *ngIf="!editMode">{{ workbasketClone.owner }}</dd>
|
||||||
|
<dd *ngIf="editMode"><input class="form-control" placeholder="Owner" name="editOwner" [(ngModel)]="workbasketClone.owner" required></dd>
|
||||||
|
<dt>Description</dt>
|
||||||
|
<dd *ngIf="!editMode">{{ workbasketClone.description }}</dd>
|
||||||
|
<dd *ngIf="editMode"><textarea class="form-control" rows="3" placeholder="Description" name="editDescription" [(ngModel)]="workbasketClone.description"></textarea></dd>
|
||||||
|
</dl>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { WorkbasketDetailsComponent } from './workbasket-details.component';
|
||||||
|
|
||||||
|
describe('WorkbasketDetailsComponent', () => {
|
||||||
|
let component: WorkbasketDetailsComponent;
|
||||||
|
let fixture: ComponentFixture<WorkbasketDetailsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ WorkbasketDetailsComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(WorkbasketDetailsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
import { Workbasket } from '../model/workbasket';
|
||||||
|
import { WorkbasketserviceService } from '../services/workbasketservice.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-workbasket-details',
|
||||||
|
templateUrl: './workbasket-details.component.html',
|
||||||
|
styleUrls: ['./workbasket-details.component.css']
|
||||||
|
})
|
||||||
|
export class WorkbasketDetailsComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
workbasket: Workbasket;
|
||||||
|
workbasketClone: Workbasket;
|
||||||
|
|
||||||
|
allWorkbasket: Workbasket[];
|
||||||
|
editMode: boolean = false;
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
onSaved = new EventEmitter<Workbasket>();
|
||||||
|
|
||||||
|
constructor(private service: WorkbasketserviceService) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.workbasketClone = { ...this.workbasket };
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges() {
|
||||||
|
this.workbasketClone = { ...this.workbasket };
|
||||||
|
this.editMode = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onEdit() {
|
||||||
|
this.editMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSave() {
|
||||||
|
this.onSaved.emit(this.workbasketClone);
|
||||||
|
this.editMode = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<h2>Distribution Targets</h2>
|
||||||
|
<div *ngFor="let alert of alerts">
|
||||||
|
<alert [type]="alert.type" dismissible="true" [dismissOnTimeout]="5000">{{ alert.msg }}</alert>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-6 col-md-6">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<th>All Workbaskets</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</thead>
|
||||||
|
<tr *ngFor="let workbasket of workbaskets">
|
||||||
|
<td>{{ workbasket.name }}</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onAdd(workbasket)">
|
||||||
|
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-6 col-md-6">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<th>Selected Workbaskets</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</thead>
|
||||||
|
<tr *ngFor="let workbasket of workbasket.distributionTargets">
|
||||||
|
<td>{{ resolveName(workbasket) }}</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onDelete(workbasket)">
|
||||||
|
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { WorkbasketDistributiontargetsComponent } from './workbasket-distributiontargets.component';
|
||||||
|
|
||||||
|
describe('WorkbasketDistributiontargetsComponent', () => {
|
||||||
|
let component: WorkbasketDistributiontargetsComponent;
|
||||||
|
let fixture: ComponentFixture<WorkbasketDistributiontargetsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ WorkbasketDistributiontargetsComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(WorkbasketDistributiontargetsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,107 @@
|
||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { Workbasket } from '../model/workbasket';
|
||||||
|
import { WorkbasketserviceService } from '../services/workbasketservice.service'
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-workbasket-distributiontargets',
|
||||||
|
templateUrl: './workbasket-distributiontargets.component.html',
|
||||||
|
styleUrls: ['./workbasket-distributiontargets.component.css']
|
||||||
|
})
|
||||||
|
export class WorkbasketDistributiontargetsComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
workbasket: Workbasket;
|
||||||
|
workbaskets: Workbasket[];
|
||||||
|
public alerts: any = [];
|
||||||
|
|
||||||
|
constructor(private service: WorkbasketserviceService) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.prepareData();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChange() {
|
||||||
|
this.prepareData();
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareData() {
|
||||||
|
this.service.getAllWorkBaskets().subscribe(resultList => {
|
||||||
|
this.workbaskets = resultList;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onAdd(w: Workbasket) {
|
||||||
|
if (this.workbasket.distributionTargets.length > 0) {
|
||||||
|
let found: boolean = false;
|
||||||
|
for (var i = 0, len = this.workbasket.distributionTargets.length; i < len; i++) {
|
||||||
|
if (this.workbasket.distributionTargets[i] === w.id) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
this.onSaved(w, true);
|
||||||
|
} else {
|
||||||
|
this.alerts = [{
|
||||||
|
type: "danger",
|
||||||
|
msg: "This workbasket is already mapped!"
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.onSaved(w, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDelete(id: string) {
|
||||||
|
this.onSaved(this.resolveObject(id), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get workbasket name
|
||||||
|
resolveName(id: string): any {
|
||||||
|
if (this.workbaskets != null) {
|
||||||
|
return this.workbaskets.filter(item => item.id === id)[0].name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create an Workbasket
|
||||||
|
resolveObject(id: string): any {
|
||||||
|
if (this.workbaskets != null) {
|
||||||
|
return this.workbaskets.filter(item => item.id === id)[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSaved(w: Workbasket, isUpdate: boolean) {
|
||||||
|
if (w != null) {
|
||||||
|
// add changes
|
||||||
|
if (isUpdate) {
|
||||||
|
this.workbasket.distributionTargets.push(w.id);
|
||||||
|
} else {
|
||||||
|
let index = this.workbasket.distributionTargets.indexOf(w.id);
|
||||||
|
this.workbasket.distributionTargets.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to save changes
|
||||||
|
this.service.updateWorkbasket(this.workbasket).subscribe(result => {
|
||||||
|
this.workbasket.id = result.id;
|
||||||
|
this.workbasket.name = result.name;
|
||||||
|
this.workbasket.description = result.description;
|
||||||
|
this.workbasket.owner = result.owner;
|
||||||
|
this.workbasket.tenantId = result.tenantId;
|
||||||
|
this.workbasket.distributionTargets = result.distributionTargets;
|
||||||
|
}, (err) => {
|
||||||
|
this.alerts = [{
|
||||||
|
type: "danger",
|
||||||
|
msg: "You are not authorized."
|
||||||
|
}];
|
||||||
|
// reset changes
|
||||||
|
if (isUpdate) {
|
||||||
|
this.workbasket.distributionTargets.pop();
|
||||||
|
} else {
|
||||||
|
this.workbasket.distributionTargets.push(w.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
<!-- app-workbasketeditor [workbasket]="selectedWorkbasket" (workbasketSaved)="onWorkbasketSaved($event)"></app-workbasketeditor -->
|
||||||
|
<app-workbasketlist (selectedWorkbasket)="onWorkbasketSelected($event)"></app-workbasketlist>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { WorkbasketadministrationComponent } from './workbasketadministration.component';
|
||||||
|
|
||||||
|
describe('WorkbasketadministrationComponent', () => {
|
||||||
|
let component: WorkbasketadministrationComponent;
|
||||||
|
let fixture: ComponentFixture<WorkbasketadministrationComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ WorkbasketadministrationComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(WorkbasketadministrationComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Workbasket } from '../model/workbasket';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-workbasketadministration',
|
||||||
|
templateUrl: './workbasketadministration.component.html',
|
||||||
|
styleUrls: ['./workbasketadministration.component.css']
|
||||||
|
})
|
||||||
|
export class WorkbasketadministrationComponent implements OnInit {
|
||||||
|
selectedWorkbasket: Workbasket;
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
onWorkbasketSelected(workbasket: Workbasket) {
|
||||||
|
console.log("got new selected workbasket: " + workbasket.id);
|
||||||
|
this.selectedWorkbasket = workbasket;
|
||||||
|
}
|
||||||
|
|
||||||
|
onWorkbasketSaved(workbasket: Workbasket) {
|
||||||
|
console.log("got saved workbasket: " + workbasket);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<h1>Edit Workbasket</h1>
|
||||||
|
<form class="form-horizontal" #workbasketForm="ngForm">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-2 control-label" for="id">ID</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" id="id" placeholder="ID" [(ngModel)]="workbasket.id" name="id" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-2 control-label" for="name">Name</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" id="name" placeholder="Name" [(ngModel)]="workbasket.name" name="name" #name="ngModel" required>
|
||||||
|
<div [hidden]="name.valid || name.pristine" class="alert alert-danger">
|
||||||
|
The workbasket name is required
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-2 control-label" for="description">Description</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" id="description" placeholder="Description" [(ngModel)]="workbasket.description" name="description">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-2 control-label" for="owner">Owner</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" id="owner" placeholder="Owner" [(ngModel)]="workbasket.owner" name="owner" #owner="ngModel" required>
|
||||||
|
<div [hidden]="owner.valid || owner.pristine" class="alert alert-danger">
|
||||||
|
The workbasket owner is required
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-2 col-sm-10">
|
||||||
|
<button type="submit" class="btn btn-default btn-primary" (click)="onSubmit()">Save changes</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { WorkbasketeditorComponent } from './workbasketeditor.component';
|
||||||
|
|
||||||
|
describe('WorkbasketeditorComponent', () => {
|
||||||
|
let component: WorkbasketeditorComponent;
|
||||||
|
let fixture: ComponentFixture<WorkbasketeditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ WorkbasketeditorComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(WorkbasketeditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { Component, OnInit, EventEmitter } from '@angular/core';
|
||||||
|
import { Workbasket } from '../model/workbasket';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-workbasketeditor',
|
||||||
|
inputs: ['workbasket'],
|
||||||
|
outputs: ['workbasketSaved'],
|
||||||
|
templateUrl: './workbasketeditor.component.html',
|
||||||
|
styleUrls: ['./workbasketeditor.component.css']
|
||||||
|
})
|
||||||
|
export class WorkbasketeditorComponent implements OnInit {
|
||||||
|
public workbasket: Workbasket;
|
||||||
|
public workbasketSaved: EventEmitter<Workbasket> = new EventEmitter();
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.workbasket = new Workbasket("", "", "", "", "", "", "", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
// TODO save values
|
||||||
|
console.log("changed " + this.workbasket.name);
|
||||||
|
this.workbasketSaved.next(this.workbasket);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
<h1>Workbaskets</h1>
|
||||||
|
<form #workbasketForm="ngForm">
|
||||||
|
<table class="table table-condensed table-hover">
|
||||||
|
<thead>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Owner</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<input class="form-control" placeholder="Name" name="name" [(ngModel)]="workbasket.name" required>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input class="form-control" placeholder="Description" name="description" [(ngModel)]="workbasket.description">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input class="form-control" placeholder="Owner" name="owner" [(ngModel)]="workbasket.owner" required>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onAdd()">
|
||||||
|
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onClear()">
|
||||||
|
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr *ngFor="let workbasket of workbaskets" (click)="onSelect(workbasket)" [class.active]="workbasket.id == selected.id" [routerLink]="['/workbaskets', workbasket.id]">
|
||||||
|
<td *ngIf="workbasket.id != editing.id">{{ workbasket.id }}</td>
|
||||||
|
<td *ngIf="workbasket.id == editing.id">
|
||||||
|
<input class="form-control" placeholder="Id" name="editid" [(ngModel)]="editing.id" readonly>
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasket.id != editing.id">{{ workbasket.name }}</td>
|
||||||
|
<td *ngIf="workbasket.id == editing.id">
|
||||||
|
<input class="form-control" placeholder="Name" name="editname" [(ngModel)]="editing.name" required>
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasket.id != editing.id">{{ workbasket.description }}</td>
|
||||||
|
<td *ngIf="workbasket.id == editing.id">
|
||||||
|
<input class="form-control" placeholder="Description" name="editdescription" [(ngModel)]="editing.description">
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasket.id != editing.id">{{ workbasket.owner }}</td>
|
||||||
|
<td *ngIf="workbasket.id == editing.id">
|
||||||
|
<input class="form-control" placeholder="Owner" name="editowner" [(ngModel)]="editing.owner" required>
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasket.id != editing.id">
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onEdit(workbasket)">
|
||||||
|
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onDelete(workbasket)">
|
||||||
|
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td *ngIf="workbasket.id == editing.id">
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onSave(workbasket)">
|
||||||
|
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onCancel(workbasket)">
|
||||||
|
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
<div class="col-xs-1" *ngIf="workbasket.id != selected.id">
|
||||||
|
<ul class="nav nav-tabs tabs-left sideways">
|
||||||
|
<li [class.active]="wbClicked"><a href="javascript:void(0)" data-toggle="tab" (click)="onClickWB()"><br>Details</a></li>
|
||||||
|
<li [class.active]="authClicked"><a href="javascript:void(0)" data-toggle="tab" (click)="onClickAuth()"><br>Authorizations</a></li>
|
||||||
|
<li [class.active]="dtClicked"><a href="javascript:void(0)" data-toggle="tab" (click)="onClickDt()">Distribution Targets</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-10" *ngIf="workbasket.id != selected.id">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane" [class.active]="wbClicked">
|
||||||
|
<app-workbasket-details [workbasket]="selected"></app-workbasket-details>
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane" [class.active]="authClicked">
|
||||||
|
<app-workbasket-authorization [workbasket]="selected"></app-workbasket-authorization>
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane" [class.active]="dtClicked">
|
||||||
|
<app-workbasket-distributiontargets [workbasket]="selected"></app-workbasket-distributiontargets>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { WorkbasketlistComponent } from './workbasketlist.component';
|
||||||
|
|
||||||
|
describe('WorkbasketlistComponent', () => {
|
||||||
|
let component: WorkbasketlistComponent;
|
||||||
|
let fixture: ComponentFixture<WorkbasketlistComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ WorkbasketlistComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(WorkbasketlistComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,115 @@
|
||||||
|
import { Component, OnInit, EventEmitter } from '@angular/core';
|
||||||
|
import { Workbasket } from '../model/workbasket';
|
||||||
|
import { WorkbasketserviceService } from '../services/workbasketservice.service'
|
||||||
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-workbasketlist',
|
||||||
|
outputs: ['selectedWorkbasket'],
|
||||||
|
templateUrl: './workbasketlist.component.html',
|
||||||
|
styleUrls: ['./workbasketlist.component.css'],
|
||||||
|
providers: [WorkbasketserviceService]
|
||||||
|
})
|
||||||
|
export class WorkbasketlistComponent implements OnInit {
|
||||||
|
public selectedWorkbasket: EventEmitter<Workbasket> = new EventEmitter();
|
||||||
|
|
||||||
|
workbasket: Workbasket = this.getEmptyObject();
|
||||||
|
selected: Workbasket = this.getEmptyObject();
|
||||||
|
editing: Workbasket = this.getEmptyObject();
|
||||||
|
isEditing: boolean = false;
|
||||||
|
|
||||||
|
wbClicked = true;
|
||||||
|
authClicked = false;
|
||||||
|
dtClicked = false
|
||||||
|
|
||||||
|
workbaskets = [];
|
||||||
|
|
||||||
|
public alerts: any = [];
|
||||||
|
|
||||||
|
constructor(private service: WorkbasketserviceService, private route: ActivatedRoute) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.service.getAllWorkBaskets().subscribe(resultList => {
|
||||||
|
this.workbaskets = resultList;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onDelete(workbasket: Workbasket) {
|
||||||
|
this.service.deleteWorkbasket(workbasket.id).subscribe(result => {
|
||||||
|
var index = this.workbaskets.indexOf(workbasket);
|
||||||
|
if (index > -1) {
|
||||||
|
this.workbaskets.splice(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onAdd() {
|
||||||
|
this.service.createWorkbasket(this.workbasket).subscribe(result => {
|
||||||
|
this.workbaskets.push(result);
|
||||||
|
this.onClear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onEdit(workbasket: Workbasket) {
|
||||||
|
this.editing = { ...workbasket };
|
||||||
|
this.isEditing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelect(workbasket: Workbasket) {
|
||||||
|
if (!this.isEditing) {
|
||||||
|
this.selected = workbasket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClear() {
|
||||||
|
this.workbasket.id = "";
|
||||||
|
this.workbasket.name = "";
|
||||||
|
this.workbasket.description = "";
|
||||||
|
this.workbasket.owner = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
onSave() {
|
||||||
|
if (this.isEditing) {
|
||||||
|
this.service.updateWorkbasket(this.editing).subscribe(result => {
|
||||||
|
this.selected.id = result.id;
|
||||||
|
this.selected.name = result.name;
|
||||||
|
this.selected.description = result.description;
|
||||||
|
this.selected.owner = result.owner;
|
||||||
|
}, (err) => {
|
||||||
|
this.alerts = [{
|
||||||
|
type: "danger",
|
||||||
|
msg: "You are not authorized."
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.isEditing = false;
|
||||||
|
this.editing = this.getEmptyObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
onCancel() {
|
||||||
|
this.editing = this.getEmptyObject();
|
||||||
|
this.isEditing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEmptyObject() {
|
||||||
|
return new Workbasket("", "", "", "", "", "", "", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickWB() {
|
||||||
|
this.wbClicked = !this.wbClicked;
|
||||||
|
this.authClicked = false;
|
||||||
|
this.dtClicked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickAuth() {
|
||||||
|
this.authClicked = !this.authClicked;
|
||||||
|
this.wbClicked = false;
|
||||||
|
this.dtClicked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickDt() {
|
||||||
|
this.dtClicked = !this.dtClicked;
|
||||||
|
this.wbClicked = false;
|
||||||
|
this.authClicked = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
export const environment = {
|
||||||
|
production: true,
|
||||||
|
taskanaWorkplaceUrl: 'http://taskana-workplace.mybluemix.net',
|
||||||
|
taskanaMonitorUrl: 'http://taskana-monitor.mybluemix.net',
|
||||||
|
taskanaRestUrl: 'http://taskana-rest.mybluemix.net'
|
||||||
|
};
|
|
@ -0,0 +1,11 @@
|
||||||
|
// The file contents for the current environment will overwrite these during build.
|
||||||
|
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
|
||||||
|
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
|
||||||
|
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
||||||
|
|
||||||
|
export const environment = {
|
||||||
|
production: false,
|
||||||
|
taskanaWorkplaceUrl: 'http://localhost:4200',
|
||||||
|
taskanaMonitorUrl: 'http://localhost:4202',
|
||||||
|
taskanaRestUrl: 'http://localhost:8080'
|
||||||
|
};
|
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
|
@ -0,0 +1,17 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Admin</title>
|
||||||
|
<base href="/">
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<app-root>Loading...</app-root>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { enableProdMode } from '@angular/core';
|
||||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
import { AppModule } from './app/app.module';
|
||||||
|
import { environment } from './environments/environment';
|
||||||
|
|
||||||
|
if (environment.production) {
|
||||||
|
enableProdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
platformBrowserDynamic().bootstrapModule(AppModule);
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||||
|
* You can add your own extra polyfills to this file.
|
||||||
|
*
|
||||||
|
* This file is divided into 2 sections:
|
||||||
|
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||||
|
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||||
|
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
||||||
|
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
||||||
|
*
|
||||||
|
* Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* BROWSER POLYFILLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
|
||||||
|
// import 'core-js/es6/symbol';
|
||||||
|
// import 'core-js/es6/object';
|
||||||
|
// import 'core-js/es6/function';
|
||||||
|
// import 'core-js/es6/parse-int';
|
||||||
|
// import 'core-js/es6/parse-float';
|
||||||
|
// import 'core-js/es6/number';
|
||||||
|
// import 'core-js/es6/math';
|
||||||
|
// import 'core-js/es6/string';
|
||||||
|
// import 'core-js/es6/date';
|
||||||
|
// import 'core-js/es6/array';
|
||||||
|
// import 'core-js/es6/regexp';
|
||||||
|
// import 'core-js/es6/map';
|
||||||
|
// import 'core-js/es6/set';
|
||||||
|
|
||||||
|
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
||||||
|
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||||
|
|
||||||
|
/** IE10 and IE11 requires the following to support `@angular/animation`. */
|
||||||
|
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||||
|
|
||||||
|
|
||||||
|
/** Evergreen browsers require these. **/
|
||||||
|
import 'core-js/es6/reflect';
|
||||||
|
import 'core-js/es7/reflect';
|
||||||
|
|
||||||
|
|
||||||
|
/** ALL Firefox browsers require the following to support `@angular/animation`. **/
|
||||||
|
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* Zone JS is required by Angular itself.
|
||||||
|
*/
|
||||||
|
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* APPLICATION IMPORTS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date, currency, decimal and percent pipes.
|
||||||
|
* Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
|
||||||
|
*/
|
||||||
|
// import 'intl'; // Run `npm install --save intl`.
|
||||||
|
/**
|
||||||
|
* Need to import at least one locale-data with intl.
|
||||||
|
*/
|
||||||
|
// import 'intl/locale-data/jsonp/en';
|
|
@ -0,0 +1,7 @@
|
||||||
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
.ng-valid[required], .ng-valid.required {
|
||||||
|
border-left: 5px solid #42A948; /* green */
|
||||||
|
}
|
||||||
|
.ng-invalid:not(form) {
|
||||||
|
border-left: 5px solid #a94442; /* red */
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||||
|
|
||||||
|
import 'zone.js/dist/long-stack-trace-zone';
|
||||||
|
import 'zone.js/dist/proxy.js';
|
||||||
|
import 'zone.js/dist/sync-test';
|
||||||
|
import 'zone.js/dist/jasmine-patch';
|
||||||
|
import 'zone.js/dist/async-test';
|
||||||
|
import 'zone.js/dist/fake-async-test';
|
||||||
|
import { getTestBed } from '@angular/core/testing';
|
||||||
|
import {
|
||||||
|
BrowserDynamicTestingModule,
|
||||||
|
platformBrowserDynamicTesting
|
||||||
|
} from '@angular/platform-browser-dynamic/testing';
|
||||||
|
|
||||||
|
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
|
||||||
|
declare var __karma__: any;
|
||||||
|
declare var require: any;
|
||||||
|
|
||||||
|
// Prevent Karma from running prematurely.
|
||||||
|
__karma__.loaded = function () {};
|
||||||
|
|
||||||
|
// First, initialize the Angular testing environment.
|
||||||
|
getTestBed().initTestEnvironment(
|
||||||
|
BrowserDynamicTestingModule,
|
||||||
|
platformBrowserDynamicTesting()
|
||||||
|
);
|
||||||
|
// Then we find all the tests.
|
||||||
|
const context = require.context('./', true, /\.spec\.ts$/);
|
||||||
|
// And load the modules.
|
||||||
|
context.keys().map(context);
|
||||||
|
// Finally, start Karma to run the tests.
|
||||||
|
__karma__.start();
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../out-tsc/app",
|
||||||
|
"module": "es2015",
|
||||||
|
"baseUrl": "",
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"test.ts",
|
||||||
|
"**/*.spec.ts"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../out-tsc/spec",
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"baseUrl": "",
|
||||||
|
"types": [
|
||||||
|
"jasmine",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"test.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
/* SystemJS module definition */
|
||||||
|
declare var module: NodeModule;
|
||||||
|
interface NodeModule {
|
||||||
|
id: string;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"compileOnSave": false,
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./dist/out-tsc",
|
||||||
|
"baseUrl": "src",
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": false,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"target": "es5",
|
||||||
|
"typeRoots": [
|
||||||
|
"node_modules/@types"
|
||||||
|
],
|
||||||
|
"lib": [
|
||||||
|
"es2016",
|
||||||
|
"dom"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
{
|
||||||
|
"rulesDirectory": [
|
||||||
|
"node_modules/codelyzer"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"callable-types": true,
|
||||||
|
"class-name": true,
|
||||||
|
"comment-format": [
|
||||||
|
true,
|
||||||
|
"check-space"
|
||||||
|
],
|
||||||
|
"curly": true,
|
||||||
|
"eofline": true,
|
||||||
|
"forin": true,
|
||||||
|
"import-blacklist": [
|
||||||
|
true,
|
||||||
|
"rxjs"
|
||||||
|
],
|
||||||
|
"import-spacing": true,
|
||||||
|
"indent": [
|
||||||
|
true,
|
||||||
|
"spaces"
|
||||||
|
],
|
||||||
|
"interface-over-type-literal": true,
|
||||||
|
"label-position": true,
|
||||||
|
"max-line-length": [
|
||||||
|
true,
|
||||||
|
140
|
||||||
|
],
|
||||||
|
"member-access": false,
|
||||||
|
"member-ordering": [
|
||||||
|
true,
|
||||||
|
"static-before-instance",
|
||||||
|
"variables-before-functions"
|
||||||
|
],
|
||||||
|
"no-arg": true,
|
||||||
|
"no-bitwise": true,
|
||||||
|
"no-console": [
|
||||||
|
true,
|
||||||
|
"debug",
|
||||||
|
"info",
|
||||||
|
"time",
|
||||||
|
"timeEnd",
|
||||||
|
"trace"
|
||||||
|
],
|
||||||
|
"no-construct": true,
|
||||||
|
"no-debugger": true,
|
||||||
|
"no-empty": false,
|
||||||
|
"no-empty-interface": true,
|
||||||
|
"no-eval": true,
|
||||||
|
"no-inferrable-types": [
|
||||||
|
true,
|
||||||
|
"ignore-params"
|
||||||
|
],
|
||||||
|
"no-shadowed-variable": true,
|
||||||
|
"no-string-literal": false,
|
||||||
|
"no-string-throw": true,
|
||||||
|
"no-switch-case-fall-through": true,
|
||||||
|
"no-trailing-whitespace": true,
|
||||||
|
"no-unused-expression": true,
|
||||||
|
"no-use-before-declare": true,
|
||||||
|
"no-var-keyword": true,
|
||||||
|
"object-literal-sort-keys": false,
|
||||||
|
"one-line": [
|
||||||
|
true,
|
||||||
|
"check-open-brace",
|
||||||
|
"check-catch",
|
||||||
|
"check-else",
|
||||||
|
"check-whitespace"
|
||||||
|
],
|
||||||
|
"prefer-const": true,
|
||||||
|
"quotemark": [
|
||||||
|
true,
|
||||||
|
"single"
|
||||||
|
],
|
||||||
|
"radix": true,
|
||||||
|
"semicolon": [
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"triple-equals": [
|
||||||
|
true,
|
||||||
|
"allow-null-check"
|
||||||
|
],
|
||||||
|
"typedef-whitespace": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"call-signature": "nospace",
|
||||||
|
"index-signature": "nospace",
|
||||||
|
"parameter": "nospace",
|
||||||
|
"property-declaration": "nospace",
|
||||||
|
"variable-declaration": "nospace"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeof-compare": true,
|
||||||
|
"unified-signatures": true,
|
||||||
|
"variable-name": false,
|
||||||
|
"whitespace": [
|
||||||
|
true,
|
||||||
|
"check-branch",
|
||||||
|
"check-decl",
|
||||||
|
"check-operator",
|
||||||
|
"check-separator",
|
||||||
|
"check-type"
|
||||||
|
],
|
||||||
|
"directive-selector": [
|
||||||
|
true,
|
||||||
|
"attribute",
|
||||||
|
"app",
|
||||||
|
"camelCase"
|
||||||
|
],
|
||||||
|
"component-selector": [
|
||||||
|
true,
|
||||||
|
"element",
|
||||||
|
"app",
|
||||||
|
"kebab-case"
|
||||||
|
],
|
||||||
|
"use-input-property-decorator": true,
|
||||||
|
"use-output-property-decorator": true,
|
||||||
|
"use-host-property-decorator": true,
|
||||||
|
"no-input-rename": true,
|
||||||
|
"no-output-rename": true,
|
||||||
|
"use-life-cycle-interface": true,
|
||||||
|
"use-pipe-transform-interface": true,
|
||||||
|
"component-class-suffix": true,
|
||||||
|
"directive-class-suffix": true,
|
||||||
|
"no-access-missing-member": true,
|
||||||
|
"templates-use-public": true,
|
||||||
|
"invoke-injectable": true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
*/target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
*.orig
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
nbproject/private/
|
||||||
|
build/
|
||||||
|
nbbuild/
|
||||||
|
dist/
|
||||||
|
nbdist/
|
||||||
|
.nb-gradle/
|
|
@ -0,0 +1,20 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.taskana</groupId>
|
||||||
|
<artifactId>taskana-parent</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>taskana-core</module>
|
||||||
|
<module>taskana-cdi</module>
|
||||||
|
<module>taskana-spring</module>
|
||||||
|
<module>taskana-cdi-example</module>
|
||||||
|
<module>taskana-spring-example</module>
|
||||||
|
</modules>
|
||||||
|
</project>
|
|
@ -0,0 +1,2 @@
|
||||||
|
TODO
|
||||||
|
- Framework design checken
|
|
@ -0,0 +1,2 @@
|
||||||
|
/.apt_generated/
|
||||||
|
/target/
|
|
@ -0,0 +1,35 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.taskana</groupId>
|
||||||
|
<artifactId>taskana-cdi-example</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax</groupId>
|
||||||
|
<artifactId>javaee-api</artifactId>
|
||||||
|
<version>7.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.taskana</groupId>
|
||||||
|
<artifactId>taskana-core</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.taskana</groupId>
|
||||||
|
<artifactId>taskana-cdi</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,32 @@
|
||||||
|
package org.taskana;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.ejb.EJB;
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.enterprise.context.Initialized;
|
||||||
|
import javax.enterprise.event.Observes;
|
||||||
|
|
||||||
|
import org.taskana.exceptions.NotAuthorizedException;
|
||||||
|
import org.taskana.exceptions.TaskNotFoundException;
|
||||||
|
import org.taskana.model.Task;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class ExampleBootstrap {
|
||||||
|
|
||||||
|
@EJB
|
||||||
|
private TaskanaEjb taskanaEjb;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init(@Observes @Initialized(ApplicationScoped.class) Object init) throws TaskNotFoundException, NotAuthorizedException {
|
||||||
|
System.out.println("---------------------------> Start App");
|
||||||
|
Task task = taskanaEjb.getTaskService().create(new Task());
|
||||||
|
System.out.println("---------------------------> Task started: " + task.getId());
|
||||||
|
taskanaEjb.getTaskService().claim(task.getId(), "John Doe");
|
||||||
|
System.out.println(
|
||||||
|
"---------------------------> Task claimed: "
|
||||||
|
+ taskanaEjb.getTaskService().getTaskById(task.getId()).getOwner());
|
||||||
|
// taskService.complete(task.getId());
|
||||||
|
// System.out.println("---------------------------> Task completed");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package org.taskana;
|
||||||
|
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@Stateless
|
||||||
|
public class TaskanaEjb {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TaskService taskService;
|
||||||
|
|
||||||
|
public TaskService getTaskService() {
|
||||||
|
return taskService;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
datasource.jndi=java:jboss/datasources/Taskana
|
|
@ -0,0 +1,3 @@
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
Class-Path:
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
|
||||||
|
</web-app>
|
|
@ -0,0 +1,2 @@
|
||||||
|
/.apt_generated/
|
||||||
|
/target/
|
|
@ -0,0 +1,111 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.taskana</groupId>
|
||||||
|
<artifactId>taskana-cdi</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<version.wildfly.swarm>2017.4.0</version.wildfly.swarm>
|
||||||
|
<version.resteasy>3.1.2.Final</version.resteasy>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wildfly.swarm</groupId>
|
||||||
|
<artifactId>bom</artifactId>
|
||||||
|
<version>${version.wildfly.swarm}</version>
|
||||||
|
<scope>import</scope>
|
||||||
|
<type>pom</type>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.arquillian</groupId>
|
||||||
|
<artifactId>arquillian-bom</artifactId>
|
||||||
|
<version>1.1.10.Final</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>jboss</id>
|
||||||
|
<url>http://repository.jboss.org/nexus/content/groups/public-jboss/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax</groupId>
|
||||||
|
<artifactId>javaee-api</artifactId>
|
||||||
|
<version>7.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.taskana</groupId>
|
||||||
|
<artifactId>taskana-core</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wildfly.swarm</groupId>
|
||||||
|
<artifactId>jaxrs</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wildfly.swarm</groupId>
|
||||||
|
<artifactId>cdi</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
|
<artifactId>resteasy-client</artifactId>
|
||||||
|
<version>${version.resteasy}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<version>1.4.194</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- Brought in via WildFly Swarm `bom` -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wildfly.swarm</groupId>
|
||||||
|
<artifactId>arquillian</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- Brought in via Arquillian BOM, see dependencyManagement section above -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.arquillian.junit</groupId>
|
||||||
|
<artifactId>arquillian-junit-container</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.wildfly.swarm</groupId>
|
||||||
|
<artifactId>wildfly-swarm-plugin</artifactId>
|
||||||
|
<version>${version.wildfly.swarm}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>package</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,64 @@
|
||||||
|
package org.taskana;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.naming.Context;
|
||||||
|
import javax.naming.InitialContext;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.taskana.configuration.TaskanaEngineConfiguration;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class TaskanaProducers {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(TaskanaProducers.class);
|
||||||
|
|
||||||
|
private static final String TASKANA_PROPERTIES = "taskana.properties";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TaskanaEngine taskanaEngine;
|
||||||
|
|
||||||
|
private TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
// Load Properties and get Datasource via Context
|
||||||
|
// Load DataSource via Container
|
||||||
|
Context ctx;
|
||||||
|
DataSource dataSource;
|
||||||
|
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
|
||||||
|
try (InputStream propertyStream = classloader.getResourceAsStream(TASKANA_PROPERTIES)) {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
ctx = new InitialContext();
|
||||||
|
properties.load(propertyStream);
|
||||||
|
dataSource = (DataSource) ctx.lookup(properties.getProperty("datasource.jndi"));
|
||||||
|
logger.debug("---------------> " + dataSource.getConnection().getMetaData());
|
||||||
|
this.taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, true, false);
|
||||||
|
} catch (NamingException | SQLException | IOException e) {
|
||||||
|
logger.error("Could not start Taskana: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
@Produces
|
||||||
|
public TaskanaEngine generateTaskEngine() throws SQLException {
|
||||||
|
return taskanaEngineConfiguration.buildTaskanaEngine();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
@Produces
|
||||||
|
public TaskService generateTaskService() {
|
||||||
|
return taskanaEngine.getTaskService();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://java.sun.com/xml/ns/javaee
|
||||||
|
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
|
||||||
|
<interceptors>
|
||||||
|
<class>org.mybatis.cdi.JtaTransactionInterceptor</class>
|
||||||
|
</interceptors>
|
||||||
|
</beans>
|
|
@ -0,0 +1,8 @@
|
||||||
|
package org.taskana;
|
||||||
|
|
||||||
|
import javax.ws.rs.ApplicationPath;
|
||||||
|
import javax.ws.rs.core.Application;
|
||||||
|
|
||||||
|
@ApplicationPath("/rest")
|
||||||
|
public class RestApplication extends Application {
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.taskana;
|
||||||
|
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.taskana.exceptions.NotAuthorizedException;
|
||||||
|
import org.taskana.model.Task;
|
||||||
|
|
||||||
|
@Stateless
|
||||||
|
public class TaskanaEjb {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TaskService taskService;
|
||||||
|
|
||||||
|
public TaskService getTaskService() {
|
||||||
|
return taskService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void triggerRollback() throws NotAuthorizedException {
|
||||||
|
Task t = taskService.create(new Task());
|
||||||
|
System.out.println("---------------->" + t.getId());
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
package org.taskana;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.ws.rs.client.Client;
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.junit.Arquillian;
|
||||||
|
import org.jboss.shrinkwrap.api.Archive;
|
||||||
|
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.wildfly.swarm.Swarm;
|
||||||
|
import org.wildfly.swarm.arquillian.CreateSwarm;
|
||||||
|
import org.wildfly.swarm.undertow.WARArchive;
|
||||||
|
|
||||||
|
@RunWith(Arquillian.class)
|
||||||
|
public class TaskanaProducersTest {
|
||||||
|
|
||||||
|
@Deployment(testable = false)
|
||||||
|
public static Archive<?> createDeployment() throws Exception {
|
||||||
|
WARArchive deployment = ShrinkWrap.create(WARArchive.class);
|
||||||
|
deployment.addPackage("org.taskana");
|
||||||
|
deployment.addClass(TaskanaProducers.class);
|
||||||
|
deployment.addAllDependencies();
|
||||||
|
deployment.addDependency("org.mybatis:mybatis:3.4.2");
|
||||||
|
deployment.addDependency("org.mybatis:mybatis-cdi:1.0.0");
|
||||||
|
deployment.addDependency("org.taskana:taskana-core:0.0.1-SNAPSHOT");
|
||||||
|
deployment.addAsResource("META-INF/beans.xml");
|
||||||
|
deployment.addAsResource("taskana.properties");
|
||||||
|
deployment.addAsResource("project-defaults.yml");
|
||||||
|
return deployment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@CreateSwarm
|
||||||
|
public static Swarm newContainer() throws Exception {
|
||||||
|
Swarm swarm = new Swarm();
|
||||||
|
return swarm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() throws SQLException, ClassNotFoundException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCommit() throws SQLException, ClassNotFoundException, NamingException {
|
||||||
|
|
||||||
|
Client client = ClientBuilder.newClient();
|
||||||
|
client.target("http://127.0.0.1:8090/rest/test").request().get();
|
||||||
|
|
||||||
|
Class.forName("org.h2.Driver");
|
||||||
|
int resultCount = 0;
|
||||||
|
try (Connection conn = DriverManager.getConnection("jdbc:h2:~/data/testdb;AUTO_SERVER=TRUE", "SA", "SA")) {
|
||||||
|
ResultSet rs = conn.createStatement().executeQuery("SELECT ID, OWNER FROM TASK");
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
resultCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(1, resultCount);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRollback() throws SQLException, ClassNotFoundException, NamingException {
|
||||||
|
Client client = ClientBuilder.newClient();
|
||||||
|
client.target("http://127.0.0.1:8090/rest/test").request().post(null);
|
||||||
|
|
||||||
|
Class.forName("org.h2.Driver");
|
||||||
|
int resultCount = 0;
|
||||||
|
try (Connection conn = DriverManager.getConnection("jdbc:h2:~/data/testdb;AUTO_SERVER=TRUE", "SA", "SA")) {
|
||||||
|
ResultSet rs = conn.createStatement().executeQuery("SELECT ID, OWNER FROM TASK");
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
resultCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(0, resultCount);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package org.taskana;
|
||||||
|
|
||||||
|
import javax.ejb.EJB;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.taskana.exceptions.NotAuthorizedException;
|
||||||
|
import org.taskana.exceptions.TaskNotFoundException;
|
||||||
|
import org.taskana.model.Task;
|
||||||
|
|
||||||
|
@Path("/test")
|
||||||
|
public class TaskanaRestTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(TaskanaRestTest.class);
|
||||||
|
|
||||||
|
@EJB
|
||||||
|
private TaskanaEjb taskanaEjb;
|
||||||
|
|
||||||
|
@GET
|
||||||
|
public Response startTask() throws NotAuthorizedException {
|
||||||
|
Task result = taskanaEjb.getTaskService().create(new Task());
|
||||||
|
logger.info(result.getId() + ":" + result.getOwner());
|
||||||
|
return Response.status(200).entity(result.getId()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
public Response rollbackTask() throws NotAuthorizedException {
|
||||||
|
taskanaEjb.triggerRollback();
|
||||||
|
return Response.status(204).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{id}")
|
||||||
|
public void completeTask(@PathParam("id") String id) throws TaskNotFoundException {
|
||||||
|
logger.info(id);
|
||||||
|
taskanaEjb.getTaskService().complete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue