├── ng-frontend
├── src
│ ├── assets
│ │ ├── .gitkeep
│ │ └── images
│ │ │ └── logo-msg.svg
│ ├── sass
│ │ ├── _sizes.scss
│ │ ├── _colors.scss
│ │ ├── _themes.scss
│ │ └── styles.scss
│ ├── app
│ │ ├── core
│ │ │ ├── sidebar
│ │ │ │ ├── sidebar.component.scss
│ │ │ │ ├── sidebar-interview-list
│ │ │ │ │ ├── sidebar-interview-list.component.scss
│ │ │ │ │ └── sidebar-interview-list.component.html
│ │ │ │ ├── sidebar-interview
│ │ │ │ │ ├── sidebar-interview.component.scss
│ │ │ │ │ ├── sidebar-interview.component.html
│ │ │ │ │ └── sidebar-interview.component.spec.ts
│ │ │ │ ├── sidebar.component.html
│ │ │ │ ├── sidebar.component.ts
│ │ │ │ └── sidebar.component.spec.ts
│ │ │ ├── data
│ │ │ │ ├── models
│ │ │ │ │ ├── question.model.ts
│ │ │ │ │ ├── faccrit.model.ts
│ │ │ │ │ ├── answer.model.ts
│ │ │ │ │ ├── contact-person.model.ts
│ │ │ │ │ ├── interview.model.ts
│ │ │ │ │ └── audit.model.ts
│ │ │ │ └── helpers
│ │ │ │ │ └── date-helpers.ts
│ │ │ ├── http
│ │ │ │ ├── dtos
│ │ │ │ │ ├── put-audit.dto.ts
│ │ │ │ │ ├── audit-scope-change.dto.ts
│ │ │ │ │ ├── post-audit.dto.ts
│ │ │ │ │ ├── post-interview.dto.ts
│ │ │ │ │ ├── put-interview.dto.ts
│ │ │ │ │ ├── interview.dto.ts
│ │ │ │ │ └── audit.dto.ts
│ │ │ │ ├── question.service.ts
│ │ │ │ ├── facCrit.service.ts
│ │ │ │ ├── test
│ │ │ │ │ ├── dummies
│ │ │ │ │ │ ├── contact-persons.ts
│ │ │ │ │ │ ├── answers.ts
│ │ │ │ │ │ └── questions.ts
│ │ │ │ │ └── question.service.spec.ts
│ │ │ │ └── answer.service.ts
│ │ │ ├── not-found
│ │ │ │ ├── not-found.component.scss
│ │ │ │ ├── not-found.component.html
│ │ │ │ ├── not-found.component.ts
│ │ │ │ └── not-found.component.spec.ts
│ │ │ └── ngxs
│ │ │ │ ├── actions
│ │ │ │ ├── router.actions.ts
│ │ │ │ ├── contact-person.action.ts
│ │ │ │ ├── audit.actions.ts
│ │ │ │ └── inteview.actions.ts
│ │ │ │ └── test
│ │ │ │ └── dummies
│ │ │ │ └── audits.ts
│ │ ├── features
│ │ │ ├── audit-overview
│ │ │ │ ├── audit-overview.component.scss
│ │ │ │ ├── audit-info
│ │ │ │ │ ├── audit-info.component.scss
│ │ │ │ │ ├── audit-contact-person-card
│ │ │ │ │ │ ├── contact-person-card.component.ts
│ │ │ │ │ │ ├── contact-person-card.component.scss
│ │ │ │ │ │ ├── contact-person-card.component.spec.ts
│ │ │ │ │ │ └── contact-person-card.component.html
│ │ │ │ │ ├── audit-info.component.ts
│ │ │ │ │ ├── audit-info.component.html
│ │ │ │ │ └── audit-info.component.spec.ts
│ │ │ │ ├── audit-overview.component.spec.ts
│ │ │ │ ├── interview-list
│ │ │ │ │ ├── criteria-by-factor-id.pipe.ts
│ │ │ │ │ ├── interview-card
│ │ │ │ │ │ ├── interview-card.component.ts
│ │ │ │ │ │ ├── interview-card.component.spec.ts
│ │ │ │ │ │ ├── interview-card.component.scss
│ │ │ │ │ │ └── interview-card.component.html
│ │ │ │ │ ├── interviews-by-fac-crit-id.pipe.ts
│ │ │ │ │ ├── finished-interviews-count.pipe.ts
│ │ │ │ │ └── interview-list.component.scss
│ │ │ │ ├── audit-overview.component.html
│ │ │ │ ├── audit-overview-routing.module.ts
│ │ │ │ ├── audit-overview.module.ts
│ │ │ │ └── audit-overview.component.ts
│ │ │ ├── contact-persons
│ │ │ │ ├── contact-persons.component.scss
│ │ │ │ ├── contact-person-card
│ │ │ │ │ ├── contact-person-card.component.ts
│ │ │ │ │ ├── contact-person-card.component.scss
│ │ │ │ │ ├── contact-person-card.component.html
│ │ │ │ │ └── contact-person-card.component.spec.ts
│ │ │ │ ├── contact-persons.component.ts
│ │ │ │ ├── contact-persons.module.ts
│ │ │ │ ├── contact-persons-routing.module.ts
│ │ │ │ ├── contact-persons.component.html
│ │ │ │ └── contact-persons.component.spec.ts
│ │ │ ├── audits
│ │ │ │ ├── audits.component.scss
│ │ │ │ ├── sort-audit.pipe.ts
│ │ │ │ ├── audit-card
│ │ │ │ │ ├── audit-card.component.ts
│ │ │ │ │ ├── audit-card.component.scss
│ │ │ │ │ ├── audit-card.component.html
│ │ │ │ │ └── audit-card.component.spec.ts
│ │ │ │ ├── audits.module.ts
│ │ │ │ ├── audits-routing.module.ts
│ │ │ │ ├── audits.component.ts
│ │ │ │ └── audits.component.spec.ts
│ │ │ └── interview
│ │ │ │ ├── answer-question-list
│ │ │ │ ├── questions-by-id.pipe.ts
│ │ │ │ ├── answer-question-list.component.scss
│ │ │ │ └── answer-question-list.component.spec.ts
│ │ │ │ ├── interview-routing.module.ts
│ │ │ │ ├── answers-by-ids.pipe.ts
│ │ │ │ ├── interview.component.scss
│ │ │ │ ├── interview.module.ts
│ │ │ │ └── interview.component.spec.ts
│ │ ├── shared
│ │ │ ├── components
│ │ │ │ ├── dialogs
│ │ │ │ │ ├── confirm-discard-dialog
│ │ │ │ │ │ ├── confirm-discard-dialog.component.scss
│ │ │ │ │ │ ├── confirm-discard-dialog.component.html
│ │ │ │ │ │ └── confirm-discard-dialog.component.ts
│ │ │ │ │ ├── add-audit-dialog
│ │ │ │ │ │ ├── add-audit-dialog.component.scss
│ │ │ │ │ │ ├── add-audit-dialog.component.html
│ │ │ │ │ │ └── add-audit-dialog.component.ts
│ │ │ │ │ ├── edit-audit-dialog
│ │ │ │ │ │ ├── edit-audit-dialog.component.scss
│ │ │ │ │ │ └── edit-audit-dialog.component.html
│ │ │ │ │ ├── add-interview-dialog
│ │ │ │ │ │ ├── add-interview-dialog.component.scss
│ │ │ │ │ │ └── add-interview-dialog.component.html
│ │ │ │ │ ├── add-contact-person-dialog
│ │ │ │ │ │ ├── add-contact-person-dialog.component.scss
│ │ │ │ │ │ ├── add-contact-person-dialog.component.html
│ │ │ │ │ │ └── add-contact-person-dialog.component.ts
│ │ │ │ │ ├── edit-contact-person-dialog
│ │ │ │ │ │ ├── edit-contact-person-dialog.component.scss
│ │ │ │ │ │ └── edit-contact-person-dialog.component.html
│ │ │ │ │ └── default-dialog-options.ts
│ │ │ │ └── forms
│ │ │ │ │ ├── contact-person-form
│ │ │ │ │ ├── contact-person-form.component.scss
│ │ │ │ │ └── contact-person-form.component.spec.ts
│ │ │ │ │ ├── form-helpers.ts
│ │ │ │ │ ├── interview-form
│ │ │ │ │ └── interview-form.component.scss
│ │ │ │ │ ├── audit-form
│ │ │ │ │ └── audit-form.component.scss
│ │ │ │ │ └── abstract-form-component.ts
│ │ │ └── pipes
│ │ │ │ ├── factors.pipe.ts
│ │ │ │ └── criterias.pipe.ts
│ │ ├── app.component.scss
│ │ ├── app.module.ts
│ │ ├── app.component.ts
│ │ ├── app.component.html
│ │ └── app-routing.module.ts
│ ├── favicon.ico
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── main.ts
│ ├── index.html
│ └── test.ts
├── cypress
│ ├── fixtures
│ │ ├── user-input-data
│ │ │ ├── example-audit.json
│ │ │ ├── example-interview.json
│ │ │ └── example-contact.json
│ │ └── backend-mock-data
│ │ │ ├── questions-2.json
│ │ │ ├── questions-1.json
│ │ │ ├── answers.json
│ │ │ ├── contactPersons.json
│ │ │ └── audits.json
│ ├── integration
│ │ ├── shared
│ │ │ ├── sidebar.spec.ts
│ │ │ └── navbar.spec.ts
│ │ └── pages
│ │ │ └── not-found-page.spec.ts
│ ├── plugins
│ │ └── index.js
│ └── support
│ │ └── index.js
├── cypress.json
├── documentation
│ ├── fonts
│ │ ├── ionicons.eot
│ │ ├── ionicons.ttf
│ │ ├── ionicons.woff
│ │ ├── ionicons.woff2
│ │ ├── roboto-v15-latin-300.eot
│ │ ├── roboto-v15-latin-300.ttf
│ │ ├── roboto-v15-latin-300.woff
│ │ ├── roboto-v15-latin-300.woff2
│ │ ├── roboto-v15-latin-700.eot
│ │ ├── roboto-v15-latin-700.ttf
│ │ ├── roboto-v15-latin-700.woff
│ │ ├── roboto-v15-latin-700.woff2
│ │ ├── roboto-v15-latin-italic.eot
│ │ ├── roboto-v15-latin-italic.ttf
│ │ ├── roboto-v15-latin-italic.woff
│ │ ├── roboto-v15-latin-regular.eot
│ │ ├── roboto-v15-latin-regular.ttf
│ │ ├── roboto-v15-latin-italic.woff2
│ │ ├── roboto-v15-latin-regular.woff
│ │ └── roboto-v15-latin-regular.woff2
│ ├── images
│ │ ├── favicon.ico
│ │ ├── compodoc-vectorise.png
│ │ ├── compodoc-vectorise-inverted.png
│ │ └── coverage-badge-documentation.svg
│ ├── styles
│ │ ├── style.css
│ │ ├── tablesort.css
│ │ ├── original.css
│ │ ├── reset.css
│ │ ├── stripe.css
│ │ └── laravel.css
│ └── js
│ │ ├── compodoc.js
│ │ ├── libs
│ │ ├── tablesort.number.min.js
│ │ ├── EventDispatcher.js
│ │ ├── custom-elements-es5-adapter.js
│ │ └── innersvg.js
│ │ ├── tabs.js
│ │ └── lazy-load-graphs.js
├── tsconfig.app.json
├── tsconfig.spec.json
├── .prettierrc
├── tsconfig.json
├── browserslist
├── .gitignore
└── karma.conf.js
├── java-backend
├── src
│ ├── test
│ │ ├── resources
│ │ │ ├── schema-h2.sql
│ │ │ ├── application.properties
│ │ │ ├── application-test.properties
│ │ │ ├── ContactPersonTest.sql
│ │ │ └── ScopeTest.sql
│ │ └── java
│ │ │ └── com
│ │ │ └── amos2020
│ │ │ └── javabackend
│ │ │ ├── rest_service
│ │ │ └── RestServiceTests.java
│ │ │ ├── integration_tests
│ │ │ └── IntegrationTests.java
│ │ │ ├── AllTests.java
│ │ │ └── repository
│ │ │ └── RepositoryTests.java
│ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── amos2020
│ │ │ └── javabackend
│ │ │ ├── entity
│ │ │ ├── InterviewStatus.java
│ │ │ ├── Salutation.java
│ │ │ ├── package-info.java
│ │ │ ├── AuditStatus.java
│ │ │ ├── ScopePK.java
│ │ │ ├── AnswerPK.java
│ │ │ ├── AuditContactPersonPK.java
│ │ │ └── InterviewContactPersonPK.java
│ │ │ ├── service
│ │ │ ├── package-info.java
│ │ │ └── QuestionService.java
│ │ │ ├── rest_service
│ │ │ ├── response
│ │ │ │ ├── package-info.java
│ │ │ │ ├── BasicQuestionResponse.java
│ │ │ │ ├── BasicFacCritResponse.java
│ │ │ │ ├── BasicScopeResponse.java
│ │ │ │ └── BasicContactPersonResponse.java
│ │ │ ├── controller
│ │ │ │ ├── package-info.java
│ │ │ │ ├── QuestionController.java
│ │ │ │ └── FacCritController.java
│ │ │ ├── request
│ │ │ │ ├── package-info.java
│ │ │ │ ├── answer
│ │ │ │ │ ├── package-info.java
│ │ │ │ │ └── CreateAnswerRequest.java
│ │ │ │ ├── scope
│ │ │ │ │ ├── package-info.java
│ │ │ │ │ ├── AddScopeRequest.java
│ │ │ │ │ └── UpdateScopeRequest.java
│ │ │ │ ├── contactPerson
│ │ │ │ │ └── package-info.java
│ │ │ │ ├── audit
│ │ │ │ │ ├── package-info.java
│ │ │ │ │ ├── DeleteAuditRequest.java
│ │ │ │ │ ├── UpdateAuditScopeRequest.java
│ │ │ │ │ └── UpdateAuditRequest.java
│ │ │ │ └── interview
│ │ │ │ │ ├── package-info.java
│ │ │ │ │ ├── InterviewPerson.java
│ │ │ │ │ ├── InterviewAddContactPersonRequest.java
│ │ │ │ │ └── UpdateInterviewRequest.java
│ │ │ └── package-info.java
│ │ │ ├── repository
│ │ │ ├── package-info.java
│ │ │ ├── AuditRepository.java
│ │ │ ├── ContactPersonRepository.java
│ │ │ ├── InterviewRepository.java
│ │ │ ├── ScopeRepository.java
│ │ │ ├── FacCritRepository.java
│ │ │ ├── QuestionRepository.java
│ │ │ ├── AnswerRepository.java
│ │ │ ├── AuditContactPersonRepository.java
│ │ │ └── InterviewContactPersonRepository.java
│ │ │ ├── Constants.java
│ │ │ ├── JavaBackendApplication.java
│ │ │ ├── WebConfig.java
│ │ │ └── RestServiceExceptionHandler.java
│ │ └── resources
│ │ ├── application.properties
│ │ └── persistence.xml
├── documentation
│ ├── resources
│ │ ├── x.png
│ │ └── glass.png
│ ├── type-search-index.zip
│ ├── member-search-index.zip
│ ├── package-search-index.zip
│ ├── script-dir
│ │ ├── images
│ │ │ ├── ui-icons_222222_256x240.png
│ │ │ ├── ui-icons_2e83ff_256x240.png
│ │ │ ├── ui-icons_454545_256x240.png
│ │ │ ├── ui-icons_888888_256x240.png
│ │ │ ├── ui-icons_cd0a0a_256x240.png
│ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png
│ │ │ ├── ui-bg_glass_65_dadada_1x400.png
│ │ │ ├── ui-bg_glass_75_dadada_1x400.png
│ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png
│ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png
│ │ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png
│ │ ├── jszip-utils
│ │ │ └── dist
│ │ │ │ ├── jszip-utils-ie.min.js
│ │ │ │ └── jszip-utils.min.js
│ │ └── jquery-ui.structure.min.css
│ ├── element-list
│ ├── package-search-index.js
│ └── overview-summary.html
└── .gitignore
├── .github
└── workflows
│ ├── java-backend.yml
│ └── ng-frontend.yml
└── LICENSE
/ng-frontend/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ng-frontend/src/sass/_sizes.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/sidebar/sidebar.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ng-frontend/cypress/fixtures/user-input-data/example-audit.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "BankAudit"
3 | }
4 |
--------------------------------------------------------------------------------
/ng-frontend/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/src/favicon.ico
--------------------------------------------------------------------------------
/ng-frontend/cypress/fixtures/user-input-data/example-interview.json:
--------------------------------------------------------------------------------
1 | {
2 | "criteria": "1. Effektivität"
3 | }
4 |
--------------------------------------------------------------------------------
/java-backend/src/test/resources/schema-h2.sql:
--------------------------------------------------------------------------------
1 | -- CREATE DATABASE IF NOT EXISTS
2 | CREATE SCHEMA IF NOT EXISTS msg_audit_database;
--------------------------------------------------------------------------------
/ng-frontend/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "projectId": "msg-audit-tool",
3 | "video": false,
4 | "baseUrl": "http://localhost:4200"
5 | }
6 |
--------------------------------------------------------------------------------
/ng-frontend/cypress/fixtures/backend-mock-data/questions-2.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 2,
3 | "facCritId": 1,
4 | "textDe": "test"
5 | }
6 |
--------------------------------------------------------------------------------
/java-backend/documentation/resources/x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/resources/x.png
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/ionicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/ionicons.eot
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/ionicons.ttf
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/ionicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/ionicons.woff
--------------------------------------------------------------------------------
/ng-frontend/documentation/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/images/favicon.ico
--------------------------------------------------------------------------------
/java-backend/documentation/resources/glass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/resources/glass.png
--------------------------------------------------------------------------------
/java-backend/documentation/type-search-index.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/type-search-index.zip
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/ionicons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/ionicons.woff2
--------------------------------------------------------------------------------
/ng-frontend/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | baseUrl: 'http://localhost:8080/',
4 | };
5 |
--------------------------------------------------------------------------------
/ng-frontend/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: false,
3 | baseUrl: 'http://localhost:8080/',
4 | };
5 |
--------------------------------------------------------------------------------
/java-backend/documentation/member-search-index.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/member-search-index.zip
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/data/models/question.model.ts:
--------------------------------------------------------------------------------
1 | export interface Question {
2 | id: number;
3 | facCritId: number;
4 | textDe: string;
5 | }
6 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-overview.component.scss:
--------------------------------------------------------------------------------
1 | .header-audit {
2 | display: flex;
3 | justify-content: space-between;
4 | }
5 |
--------------------------------------------------------------------------------
/java-backend/documentation/package-search-index.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/package-search-index.zip
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/dtos/put-audit.dto.ts:
--------------------------------------------------------------------------------
1 | export interface PutAuditDto {
2 | name: string;
3 | startDate: string;
4 | endDate: string;
5 | }
6 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/images/compodoc-vectorise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/images/compodoc-vectorise.png
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-300.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-300.eot
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-300.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-300.ttf
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-300.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-300.woff
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-300.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-300.woff2
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-700.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-700.eot
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-700.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-700.ttf
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-700.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-700.woff
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-700.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-700.woff2
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/sidebar/sidebar-interview-list/sidebar-interview-list.component.scss:
--------------------------------------------------------------------------------
1 | .no-scope-wrapper {
2 | margin-top: 50px;
3 | text-align: center;
4 | }
5 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-italic.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-italic.eot
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-italic.ttf
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-italic.woff
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-regular.eot
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-regular.ttf
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/data/models/faccrit.model.ts:
--------------------------------------------------------------------------------
1 | export interface FacCrit {
2 | id: number;
3 | referenceId: number;
4 | name: string;
5 | goal: string;
6 | }
7 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-italic.woff2
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-regular.woff
--------------------------------------------------------------------------------
/ng-frontend/documentation/fonts/roboto-v15-latin-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/fonts/roboto-v15-latin-regular.woff2
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/not-found/not-found.component.scss:
--------------------------------------------------------------------------------
1 | .container-route-not-found {
2 | max-width: 900px;
3 | margin: 100px auto 0 auto;
4 | text-align: center;
5 | }
6 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/sidebar/sidebar-interview/sidebar-interview.component.scss:
--------------------------------------------------------------------------------
1 | nb-menu {
2 | ul > .menu-item > a > span {
3 | width: 180px !important;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/images/compodoc-vectorise-inverted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/ng-frontend/documentation/images/compodoc-vectorise-inverted.png
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/ngxs/actions/router.actions.ts:
--------------------------------------------------------------------------------
1 | export class Navigate {
2 | static readonly type = '[App] Naviagte to Page';
3 | constructor(public route: string) {}
4 | }
5 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/confirm-discard-dialog/confirm-discard-dialog.component.scss:
--------------------------------------------------------------------------------
1 | .card-footer {
2 | display: flex;
3 | justify-content: space-between;
4 | }
5 |
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/script-dir/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/images/ui-icons_2e83ff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/script-dir/images/ui-icons_2e83ff_256x240.png
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/images/ui-icons_454545_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/script-dir/images/ui-icons_454545_256x240.png
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/images/ui-icons_888888_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/script-dir/images/ui-icons_888888_256x240.png
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/images/ui-icons_cd0a0a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/script-dir/images/ui-icons_cd0a0a_256x240.png
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/entity/InterviewStatus.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.entity;
2 |
3 | public enum InterviewStatus {
4 | ACTIVE,
5 | FINISHED
6 | }
7 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/entity/Salutation.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.entity;
2 |
3 | public enum Salutation {
4 | HERR,
5 | FRAU,
6 | DIVERS
7 | }
8 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/dtos/audit-scope-change.dto.ts:
--------------------------------------------------------------------------------
1 | export interface AuditScopeChangeDto {
2 | facCritId: number;
3 | changeNote: string;
4 | note: string;
5 | removed: boolean;
6 | }
7 |
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/images/ui-bg_glass_65_dadada_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/script-dir/images/ui-bg_glass_65_dadada_1x400.png
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/images/ui-bg_glass_75_dadada_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/script-dir/images/ui-bg_glass_75_dadada_1x400.png
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/images/ui-bg_glass_95_fef1ec_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/script-dir/images/ui-bg_glass_95_fef1ec_1x400.png
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/add-audit-dialog/add-audit-dialog.component.scss:
--------------------------------------------------------------------------------
1 | .scrollable-container {
2 | overflow-y: auto !important;
3 | max-width: 95vw;
4 | max-height: 95vh;
5 | }
6 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/edit-audit-dialog/edit-audit-dialog.component.scss:
--------------------------------------------------------------------------------
1 | .scrollable-container {
2 | overflow-y: auto !important;
3 | max-width: 95vw;
4 | max-height: 95vh;
5 | }
6 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/entity/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes necessary to map the database entities to Java objects
3 | */
4 | package com.amos2020.javabackend.entity;
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/service/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes that wrap the repositories to some easy to user service
3 | */
4 | package com.amos2020.javabackend.service;
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/dtos/post-audit.dto.ts:
--------------------------------------------------------------------------------
1 | export interface PostAuditDto {
2 | name: string;
3 | startDate: string;
4 | endDate: string;
5 | scope: number[];
6 | contactPersons: number[];
7 | }
8 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/add-interview-dialog/add-interview-dialog.component.scss:
--------------------------------------------------------------------------------
1 | .scrollable-container {
2 | overflow-y: auto !important;
3 | max-width: 95vw;
4 | max-height: 95vh;
5 | }
6 |
--------------------------------------------------------------------------------
/ng-frontend/cypress/fixtures/backend-mock-data/questions-1.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 1,
3 | "facCritId": 1,
4 | "textDe": "Werden konkrete Maßnahmen ergriffen, um das Qualitätskriterium in der Anwendung zu steigern?"
5 | }
6 |
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/images/ui-bg_highlight-soft_75_cccccc_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kexplx/msg-audit-tool/HEAD/java-backend/documentation/script-dir/images/ui-bg_highlight-soft_75_cccccc_1x100.png
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/entity/AuditStatus.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.entity;
2 |
3 | public enum AuditStatus {
4 | ACTIVE,
5 | FINISHED,
6 | OPEN,
7 | CANCELED,
8 | }
9 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/sidebar/sidebar.component.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/add-contact-person-dialog/add-contact-person-dialog.component.scss:
--------------------------------------------------------------------------------
1 | .scrollable-container {
2 | overflow-y: auto !important;
3 | max-width: 95vw;
4 | max-height: 95vh;
5 | }
6 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/app.component.scss:
--------------------------------------------------------------------------------
1 | .sidebar-container {
2 | height: 80%;
3 | display: grid;
4 | grid-template-rows: 1fr auto;
5 |
6 | & .sidebar-container-version {
7 | text-align: center;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/sidebar/sidebar-interview/sidebar-interview.component.html:
--------------------------------------------------------------------------------
1 |
Basisfragen
2 |
3 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/edit-contact-person-dialog/edit-contact-person-dialog.component.scss:
--------------------------------------------------------------------------------
1 | .scrollable-container {
2 | overflow-y: auto !important;
3 | max-width: 95vw;
4 | max-height: 95vh;
5 | }
6 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/response/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes for responses from the backend to the frontend.
3 | */
4 | package com.amos2020.javabackend.rest_service.response;
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/controller/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes for the layer that process the actual requests
3 | */
4 | package com.amos2020.javabackend.rest_service.controller;
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes for requests to the backend via the REST-Endpoints.
3 | */
4 | package com.amos2020.javabackend.rest_service.request;
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/answer/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes for requests to create and update answers.
3 | */
4 | package com.amos2020.javabackend.rest_service.request.answer;
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/scope/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes for requests to add and update scope items.
3 | */
4 | package com.amos2020.javabackend.rest_service.request.scope;
--------------------------------------------------------------------------------
/ng-frontend/documentation/styles/style.css:
--------------------------------------------------------------------------------
1 | @import "./reset.css";
2 | @import "./bootstrap.min.css";
3 | @import "./bootstrap-card.css";
4 | @import "./prism.css";
5 | @import "./ionicons.min.css";
6 | @import "./compodoc.css";
7 | @import "./tablesort.css";
8 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/not-found/not-found.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Route /{{ url }} wurde nicht gefunden
4 |
5 |
6 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/contactPerson/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes for requests to create and update contact persons.
3 | */
4 | package com.amos2020.javabackend.rest_service.request.contactPerson;
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/dtos/post-interview.dto.ts:
--------------------------------------------------------------------------------
1 | export interface PostInterviewDto {
2 | auditId: number;
3 | startDate: string;
4 | note: string;
5 | interviewedContactPersons: { id: number; role: string }[];
6 | interviewScope: number[];
7 | }
8 |
--------------------------------------------------------------------------------
/ng-frontend/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "./out-tsc/app",
5 | "types": []
6 | },
7 | "files": ["src/main.ts", "src/polyfills.ts"],
8 | "include": ["src/**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/dtos/put-interview.dto.ts:
--------------------------------------------------------------------------------
1 | import { InterviewStatus } from '../../data/models/interview.model';
2 |
3 | export interface PutInterviewDto {
4 | startDate: string;
5 | endDate: string;
6 | status: InterviewStatus;
7 | note: string;
8 | }
9 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/default-dialog-options.ts:
--------------------------------------------------------------------------------
1 | import { NbDialogConfig } from '@nebular/theme';
2 |
3 | export const defaultDialogOptions: Partial = {
4 | autoFocus: false,
5 | closeOnBackdropClick: false,
6 | closeOnEsc: false,
7 | };
8 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/contact-persons/contact-persons.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../sass/utils';
2 |
3 | nb-card-body {
4 | padding: 0;
5 | }
6 |
7 | .hint-no-contact-persons {
8 | max-width: 900px;
9 | margin: 100px auto 0 auto;
10 | text-align: center;
11 | }
12 |
--------------------------------------------------------------------------------
/ng-frontend/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "./out-tsc/spec",
5 | "types": ["jasmine", "node"]
6 | },
7 | "files": ["src/test.ts", "src/polyfills.ts"],
8 | "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/java-backend/src/test/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.datasource.driver-class-name=org.h2.Driver
2 | spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
3 | spring.datasource.username=sa
4 | spring.datasource.password=sa
5 | spring.datasource.platform=h2
6 | spring.datasource.initialization-mode=embedded
7 |
--------------------------------------------------------------------------------
/ng-frontend/src/sass/_colors.scss:
--------------------------------------------------------------------------------
1 | $msg-100: #e07d94;
2 | $msg-200: #d15471;
3 | $msg-300: #c43c5c;
4 | $msg-400: #b12e4c;
5 | $msg-500: #9b2743; // Pantone 194
6 | $msg-600: #921e39;
7 | $msg-700: #851630;
8 | $msg-800: #750c24;
9 | $msg-gray: #53565a; // Pantone Cool Gray 11
10 | $border-light: #f0f0f0;
11 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/audit/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes for requests to create, delete, and update audits. And classes for requests to update the scope of an existing audit project.
3 | */
4 | package com.amos2020.javabackend.rest_service.request.audit;
--------------------------------------------------------------------------------
/java-backend/src/test/resources/application-test.properties:
--------------------------------------------------------------------------------
1 | spring.datasource.driver-class-name=org.h2.Driver
2 | spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
3 | spring.datasource.username=sa
4 | spring.datasource.password=sa
5 | spring.datasource.platform=h2
6 | spring.datasource.initialization-mode=embedded
7 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/repository/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes necessary to communicate with the database.
3 | *
4 | * Each table from the database scheme has an own repository that is used for queries on that particular table
5 | */
6 | package com.amos2020.javabackend.repository;
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/interview/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes for requests to create and update interviews. And classes for requests to update the contact persons of an existing interview.
3 | */
4 | package com.amos2020.javabackend.rest_service.request.interview;
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Provides the classes for the layer that provides all REST-Endpoints and transfer requests to the contoller layer. It also contains the packages for requests, responses and request controllers.
3 | */
4 | package com.amos2020.javabackend.rest_service;
--------------------------------------------------------------------------------
/java-backend/src/test/resources/ContactPersonTest.sql:
--------------------------------------------------------------------------------
1 |
2 | DELETE FROM contact_person;
3 | insert into contact_person (ID, SALUTATION, TITLE, FORENAME, SURNAME, CONTACT_INFORMATION, COMPANY_NAME, DEPARTMENT, SECTOR, CORPORATE_DIVISION) values (1001, 'HERR', '', 'John', 'Doe', 'john@doe.com', 'msg', 'testDepartment', 'testSector', 'testDivision');
--------------------------------------------------------------------------------
/ng-frontend/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "all",
3 | "tabWidth": 2,
4 | "semi": true,
5 | "singleQuote": true,
6 | "arrowParens": "avoid",
7 | "printWidth": 100,
8 | "overrides": [
9 | {
10 | "files": "*.html",
11 | "options": {
12 | "printWidth": 200
13 | }
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/Constants.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend;
2 |
3 | public class Constants {
4 | public static final int NAME_LENGTH = 256;
5 | public static final int NOTE_LENGTH = 1024;
6 | public static final int GOAL_LENGTH = 2048;
7 | public static final int TEXT_LENGTH = 8096;
8 | }
9 |
--------------------------------------------------------------------------------
/ng-frontend/cypress/fixtures/user-input-data/example-contact.json:
--------------------------------------------------------------------------------
1 | {
2 | "firstName": "Max",
3 | "lastName": "Mustermann",
4 | "information": "+123456789",
5 | "salutation": "Herr",
6 | "title": "Dr.",
7 | "department": "HR",
8 | "companyName": "TestBank",
9 | "sector": "Banking",
10 | "corporateDivision": "Human Resources"
11 | }
12 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/data/models/answer.model.ts:
--------------------------------------------------------------------------------
1 | export interface Answer {
2 | interviewId: number;
3 | faccritId: number;
4 | questionId: number;
5 |
6 | result?: boolean;
7 | responsible?: boolean;
8 | documentation?: boolean;
9 | procedure?: boolean;
10 |
11 | reason?: string;
12 | proof?: string;
13 | annotation?: string;
14 | }
15 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/sidebar/sidebar-interview-list/sidebar-interview-list.component.html:
--------------------------------------------------------------------------------
1 |
Faktoren & Kriterien
2 | 0; else noScope" style="padding-left: 5px;" [items]="items" autoCollapse>
3 |
4 |
5 |
6 | Leerer Scope
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/pipes/factors.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { FacCrit } from 'src/app/core/data/models/faccrit.model';
3 |
4 | @Pipe({
5 | name: 'factors',
6 | })
7 | export class FactorsPipe implements PipeTransform {
8 | transform(facCrits: FacCrit[]) {
9 | return facCrits?.filter(x => !x.referenceId);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/add-audit-dialog/add-audit-dialog.component.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/add-contact-person-dialog/add-contact-person-dialog.component.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/add-interview-dialog/add-interview-dialog.component.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/edit-audit-dialog/edit-audit-dialog.component.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/js/compodoc.js:
--------------------------------------------------------------------------------
1 | var compodoc = {
2 | EVENTS: {
3 | READY: 'compodoc.ready',
4 | SEARCH_READY: 'compodoc.search.ready'
5 | }
6 | };
7 |
8 | Object.assign( compodoc, EventDispatcher.prototype );
9 |
10 | document.addEventListener('DOMContentLoaded', function() {
11 | compodoc.dispatchEvent({
12 | type: compodoc.EVENTS.READY
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/repository/AuditRepository.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.repository;
2 |
3 | import com.amos2020.javabackend.entity.Audit;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | /**
6 | * Interface to access the audit table in the database
7 | */
8 | public interface AuditRepository extends JpaRepository {
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/ng-frontend/cypress/fixtures/backend-mock-data/answers.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "questionId": 123456,
4 | "interviewId": 123456,
5 | "faccritId": 123456,
6 | "annotation": "Some annotation",
7 | "proof": "Some proof",
8 | "reason": "Some reason",
9 | "procedure": true,
10 | "documentation": true,
11 | "responsible": true,
12 | "result": true
13 | }
14 | ]
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audits/audits.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../sass/utils';
2 |
3 | a {
4 | text-decoration: none;
5 | }
6 |
7 | .audit-cards {
8 | display: grid;
9 | gap: 10px;
10 | }
11 |
12 | .hint-no-audits {
13 | max-width: 900px;
14 | margin: 100px auto 0 auto;
15 | text-align: center;
16 | }
17 |
18 | .content-active {
19 | padding-left: 0;
20 | padding-right: 0;
21 | }
22 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audits/sort-audit.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { Audit } from 'src/app/core/data/models/audit.model';
3 |
4 | @Pipe({
5 | name: 'sortAudit',
6 | })
7 | export class SortAuditPipe implements PipeTransform {
8 | transform(audits: Audit[]): Audit[] {
9 | return audits?.sort((a, b) => b.creationDate - a.creationDate);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/edit-contact-person-dialog/edit-contact-person-dialog.component.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/pipes/criterias.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { FacCrit } from 'src/app/core/data/models/faccrit.model';
3 |
4 | @Pipe({
5 | name: 'criterias',
6 | })
7 | export class CriteriasPipe implements PipeTransform {
8 | transform(facCrits: FacCrit[], factorId: number) {
9 | return facCrits?.filter(x => x.referenceId === factorId);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-info/audit-info.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../../sass/utils';
2 |
3 | .edit-icon-bar {
4 | text-align: right;
5 | }
6 |
7 | .audit-params {
8 | margin-top: 7px;
9 | }
10 |
11 | .wrapper-header {
12 | display: flex;
13 | justify-content: space-between;
14 | }
15 |
16 | .hint-no-contacts {
17 | margin: 0 auto;
18 | text-align: center;
19 | padding: 40px;
20 | }
21 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-overview.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { AuditOverviewComponent } from './audit-overview.component';
2 |
3 | describe('AuditOverviewComponent', () => {
4 | it('should create', () => {
5 | const storeSpy = jasmine.createSpyObj('Store', ['dispatch']);
6 |
7 | const component = new AuditOverviewComponent(storeSpy);
8 |
9 | expect(component).toBeTruthy();
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/interview/answer-question-list/questions-by-id.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { Question } from 'src/app/core/data/models/question.model';
3 |
4 | @Pipe({
5 | name: 'questionById',
6 | })
7 | export class QuestionByIdPipe implements PipeTransform {
8 | transform(questions: Question[], id: number): Question {
9 | return questions.find(q => q.id === id);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/repository/ContactPersonRepository.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.repository;
2 |
3 | import com.amos2020.javabackend.entity.ContactPerson;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | /**
6 | * Interface to access the contact_person table in the database
7 | */
8 | public interface ContactPersonRepository extends JpaRepository {
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/ng-frontend/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic()
12 | .bootstrapModule(AppModule)
13 | .catch(err => console.error(err));
14 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/interview/interview-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 | import { InterviewComponent } from './interview.component';
4 |
5 | const routes: Routes = [{ path: '', component: InterviewComponent }];
6 |
7 | @NgModule({
8 | imports: [RouterModule.forChild(routes)],
9 | exports: [RouterModule],
10 | })
11 | export class InterviewRoutingModule {}
12 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/JavaBackendApplication.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class JavaBackendApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(JavaBackendApplication.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/java-backend/src/test/java/com/amos2020/javabackend/rest_service/RestServiceTests.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service;
2 |
3 | import org.junit.runner.RunWith;
4 | import org.junit.runners.Suite;
5 |
6 | @RunWith(Suite.class)
7 | @Suite.SuiteClasses({AnswerRestServiceTest.class, AuditRestServiceTest.class, ContactPersonRestServiceTest.class,
8 | InterviewRestServiceTest.class, ScopeRestServiceTest.class
9 | })
10 | public class RestServiceTests {
11 | }
12 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/interview-list/criteria-by-factor-id.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { FacCrit } from 'src/app/core/data/models/faccrit.model';
3 |
4 | @Pipe({
5 | name: 'criteriaByFactorId',
6 | })
7 | export class CriteriaByFactorIdPipe implements PipeTransform {
8 | transform(facCrits: FacCrit[], factorId: number): FacCrit[] {
9 | return facCrits?.filter(x => x.referenceId === factorId);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/java-backend/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.datasource.url=jdbc:mysql://localhost:3306/msg_audit_database?&serverTimezone=UTC
2 | spring.datasource.username=amos
3 | spring.datasource.password=MsgAuditTool2020!
4 | spring.jpa.show-sql=true
5 | spring.datasource.initialization-mode=always
6 | spring.datasource.sql-script-encoding=UTF-8
7 | spring.datasource.platform=mysql
8 | spring.jpa.hibernate.ddl-auto=none
9 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/data/models/contact-person.model.ts:
--------------------------------------------------------------------------------
1 | export enum Salutation {
2 | Frau = 'FRAU',
3 | Herr = 'HERR',
4 | Divers = 'DIVERS',
5 | }
6 |
7 | export interface ContactPerson {
8 | id?: number;
9 | salutation: Salutation;
10 | title: string;
11 | forename: string;
12 | surname: string;
13 | companyName: string;
14 | role: string;
15 | sector: string;
16 | department: string;
17 | corporateDivision: string;
18 | contactInformation?: string;
19 | }
20 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/interview/answers-by-ids.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { Answer } from 'src/app/core/data/models/answer.model';
3 |
4 | @Pipe({
5 | name: 'answersByIds',
6 | })
7 | export class AnswersByIdsPipe implements PipeTransform {
8 | transform(answers: Answer[], interviewId: number, facCritId: number): Answer[] {
9 | return answers?.filter(a => a.faccritId === facCritId && a.interviewId === interviewId);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ng-frontend/cypress/integration/shared/sidebar.spec.ts:
--------------------------------------------------------------------------------
1 | describe('AppNavbarComponent', () => {
2 | beforeEach(() => {
3 | cy.visit(Cypress.config().baseUrl);
4 | });
5 |
6 | it('is hidden on initial load on mobile', () => {
7 | cy.viewport('iphone-5');
8 | cy.get('[data-cy=sidebar]').should('have.class', 'collapsed');
9 | });
10 |
11 | it('is fixed on mobile', () => {
12 | cy.viewport('iphone-5');
13 | cy.get('[data-cy=sidebar]').should('have.class', 'fixed');
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/data/models/interview.model.ts:
--------------------------------------------------------------------------------
1 | import { ContactPerson } from './contact-person.model';
2 | import { Answer } from './answer.model';
3 |
4 | export enum InterviewStatus {
5 | Active = 'ACTIVE',
6 | Finished = 'FINISHED',
7 | }
8 |
9 | export interface Interview {
10 | id?: number;
11 | auditId?: number;
12 | startDate?: number;
13 | endDate?: number;
14 | status: InterviewStatus;
15 | note?: string;
16 | contactPersons: ContactPerson[];
17 | answers?: Answer[];
18 | }
19 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/ngxs/actions/contact-person.action.ts:
--------------------------------------------------------------------------------
1 | import { ContactPerson } from '../../data/models/contact-person.model';
2 |
3 | export class AddContactPerson {
4 | static readonly type = '[ContactPersonsList] Add Contact Person';
5 | constructor(public contactPerson: ContactPerson) {}
6 | }
7 |
8 | export class UpdateContactPerson {
9 | static readonly type = '[ContactPersonsList] Update Contact Person';
10 | constructor(public id: number, public contactPerson: ContactPerson) {}
11 | }
12 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/contact-persons/contact-person-card/contact-person-card.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 | import { ContactPerson } from 'src/app/core/data/models/contact-person.model';
3 |
4 | @Component({
5 | selector: 'app-contact-person-card',
6 | templateUrl: './contact-person-card.component.html',
7 | styleUrls: ['./contact-person-card.component.scss'],
8 | })
9 | export class ContactPersonCardComponent {
10 | @Input() contactPerson: ContactPerson;
11 | }
12 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/repository/InterviewRepository.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.repository;
2 |
3 | import com.amos2020.javabackend.entity.Interview;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | import java.util.List;
7 | /**
8 | * Interface to access the interview table in the database
9 | */
10 | public interface InterviewRepository extends JpaRepository {
11 | List findAllByAuditId(int auditId);
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/java-backend/src/test/java/com/amos2020/javabackend/integration_tests/IntegrationTests.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.integration_tests;
2 |
3 | import org.junit.runner.RunWith;
4 | import org.junit.runners.Suite;
5 |
6 |
7 | @RunWith(Suite.class)
8 | @Suite.SuiteClasses({AnswerIntegrationTest.class, AuditIntegrationTest.class, ContactPersonIntegrationTest.class, FacCritIntegrationTest.class,
9 | InterviewIntegrationTest.class, ScopeIntegrationTest.class,
10 | })
11 | public class IntegrationTests {
12 | }
13 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/dtos/interview.dto.ts:
--------------------------------------------------------------------------------
1 | import { InterviewStatus } from '../../data/models/interview.model';
2 | import { Answer } from '../../data/models/answer.model';
3 | import { ContactPerson } from '../../data/models/contact-person.model';
4 |
5 | export interface InterviewDto {
6 | id?: number;
7 | auditId: number;
8 | startDate: string;
9 | endDate: string;
10 | note: string;
11 | status: InterviewStatus;
12 | answers: Answer[];
13 | interviewedContactPersons: ContactPerson[];
14 | }
15 |
--------------------------------------------------------------------------------
/ng-frontend/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | .msg Audit Tool
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/confirm-discard-dialog/confirm-discard-dialog.component.html:
--------------------------------------------------------------------------------
1 |
2 | Bestätigung
3 | Wollen sie die Änderungen verwerfen?
4 |
5 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/contact-persons/contact-person-card/contact-person-card.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../../sass/utils';
2 |
3 | :host {
4 | width: 100%;
5 | position: relative;
6 | }
7 |
8 | header {
9 | display: flex;
10 | justify-content: space-between;
11 | }
12 |
13 | .wrapper-contact-person-details {
14 | display: grid;
15 | grid-template-columns: repeat(4, 1fr);
16 | gap: 0 10px;
17 |
18 | @media screen and (max-width: 600px) {
19 | grid-template-columns: repeat(2, 1fr);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ng-frontend/src/sass/_themes.scss:
--------------------------------------------------------------------------------
1 | @import '~@nebular/theme/styles/theming';
2 | @import '~@nebular/theme/styles/themes/default';
3 | @import 'colors';
4 |
5 | $nb-themes: nb-register-theme(
6 | (
7 | color-primary-100: $msg-100,
8 | color-primary-200: $msg-200,
9 | color-primary-300: $msg-300,
10 | color-primary-400: $msg-400,
11 | color-primary-500: $msg-500,
12 | color-primary-600: $msg-600,
13 | color-primary-700: $msg-700,
14 | color-primary-800: $msg-800,
15 | ),
16 | default,
17 | default
18 | );
19 |
--------------------------------------------------------------------------------
/java-backend/src/test/java/com/amos2020/javabackend/AllTests.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend;
2 |
3 | import com.amos2020.javabackend.integration_tests.IntegrationTests;
4 | import com.amos2020.javabackend.repository.RepositoryTests;
5 | import com.amos2020.javabackend.rest_service.RestServiceTests;
6 | import org.junit.runner.RunWith;
7 | import org.junit.runners.Suite;
8 |
9 | @RunWith(Suite.class)
10 | @Suite.SuiteClasses({RestServiceTests.class, RepositoryTests.class, IntegrationTests.class
11 | })
12 | public class AllTests {
13 | }
14 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { AppComponent } from './app.component';
3 | import { CoreModule } from './core/core.module';
4 | import { SharedModule } from './shared/shared.module';
5 | import { AppRouterModule } from './app-routing.module';
6 | import { CommonModule } from '@angular/common';
7 |
8 | @NgModule({
9 | declarations: [AppComponent],
10 | imports: [CommonModule, SharedModule, CoreModule, AppRouterModule],
11 | bootstrap: [AppComponent],
12 | })
13 | export class AppModule {}
14 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/data/models/audit.model.ts:
--------------------------------------------------------------------------------
1 | import { ContactPerson } from './contact-person.model';
2 | import { FacCrit } from './faccrit.model';
3 |
4 | export enum AuditStatus {
5 | Planned = 'OPEN',
6 | Active = 'ACTIVE',
7 | Finished = 'FINISHED',
8 | Cancelled = 'CANCELLED',
9 | }
10 |
11 | export interface Audit {
12 | id?: number;
13 | status: AuditStatus;
14 | creationDate?: number;
15 | name: string;
16 | startDate: number;
17 | endDate?: number;
18 | contactPersons?: ContactPerson[];
19 | scope: FacCrit[];
20 | }
21 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-info/audit-contact-person-card/contact-person-card.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 | import { ContactPerson } from 'src/app/core/data/models/contact-person.model';
3 |
4 | @Component({
5 | selector: 'app-contact-person-card',
6 | templateUrl: './contact-person-card.component.html',
7 | styleUrls: ['./contact-person-card.component.scss'],
8 | })
9 | export class AuditContactPersonCardComponent {
10 | @Input() contactPerson: ContactPerson;
11 | constructor() {}
12 | }
13 |
--------------------------------------------------------------------------------
/.github/workflows/java-backend.yml:
--------------------------------------------------------------------------------
1 | name: Java Backend Build
2 |
3 | on:
4 | push:
5 | paths:
6 | - "java-backend/**"
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | env:
11 | working-directory: ./java-backend
12 |
13 | steps:
14 | - uses: actions/checkout@v2
15 | - name: Set up JDK 1.8
16 | uses: actions/setup-java@v1
17 | with:
18 | java-version: 1.8
19 | - name: Build with Maven
20 | run: mvn -B package --file pom.xml
21 | working-directory: ${{env.working-directory}}
22 |
23 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/repository/ScopeRepository.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.repository;
2 |
3 | import com.amos2020.javabackend.entity.Scope;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | import java.util.List;
7 | /**
8 | * Interface to access the scope table in the database
9 | */
10 | public interface ScopeRepository extends JpaRepository {
11 | Scope findFirstByAuditIdAndFaccritId(int auditId, int facCritId);
12 |
13 | List findAllByAuditId(int auditId);
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/data/helpers/date-helpers.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Parses a timestamp into german date format 'DD.MM.YYYY' e.g. 07.07.2020
3 | *
4 | * @param timestamp The timestamp of a date
5 | */
6 | export function parseTimestamp(timestamp: number) {
7 | if (!timestamp) return null;
8 |
9 | const date = new Date(timestamp);
10 |
11 | const month = date.getMonth() < 9 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
12 | const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
13 |
14 | return `${date.getFullYear()}-${month}-${day}`;
15 | }
16 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/ngxs/actions/audit.actions.ts:
--------------------------------------------------------------------------------
1 | import { Audit } from '../../data/models/audit.model';
2 |
3 | export class AddAudit {
4 | static readonly type = '[AuditList] Add Audit';
5 | constructor(public audit: Audit) {}
6 | }
7 |
8 | export class UpdateAudit {
9 | static readonly type = '[Auditlist] Update Audit';
10 | constructor(public id: number, public audit: Audit) {}
11 | }
12 |
13 | export class LoadFacCritsByInterviewId {
14 | static readonly type = '[Interview] Load all faccrits by interview id';
15 | constructor(public id: number) {}
16 | }
17 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/interview-list/interview-card/interview-card.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 | import { Interview, InterviewStatus } from 'src/app/core/data/models/interview.model';
3 |
4 | @Component({
5 | selector: 'app-interview-card',
6 | templateUrl: './interview-card.component.html',
7 | styleUrls: ['./interview-card.component.scss'],
8 | })
9 | export class InterviewCardComponent {
10 | @Input() interview: Interview;
11 | @Input() facCritId: string;
12 |
13 | interviewStatuses = InterviewStatus;
14 | }
15 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/js/libs/tablesort.number.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * tablesort v5.1.0 (2018-09-14)
3 | * http://tristen.ca/tablesort/demo/
4 | * Copyright (c) 2018 ; Licensed MIT
5 | */
6 | !function(){var a=function(a){return a.replace(/[^\-?0-9.]/g,"")},b=function(a,b){return a=parseFloat(a),b=parseFloat(b),a=isNaN(a)?0:a,b=isNaN(b)?0:b,a-b};Tablesort.extend("number",function(a){return a.match(/^[-+]?[£\x24Û¢´€]?\d+\s*([,\.]\d{0,2})/)||a.match(/^[-+]?\d+\s*([,\.]\d{0,2})?[£\x24Û¢´€]/)||a.match(/^[-+]?(\d)*-?([,\.]){0,1}-?(\d)+([E,e][\-+][\d]+)?%?$/)},function(c,d){return c=a(c),d=a(d),b(d,c)})}();
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audits/audit-card/audit-card.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 | import { Audit, AuditStatus } from 'src/app/core/data/models/audit.model';
3 |
4 | @Component({
5 | selector: 'app-audit-card',
6 | templateUrl: './audit-card.component.html',
7 | styleUrls: ['./audit-card.component.scss'],
8 | })
9 | export class AuditCardComponent {
10 | @Input() audit: Audit;
11 | auditStatus = AuditStatus;
12 |
13 | get contactPerson() {
14 | return this.audit.contactPersons ? this.audit.contactPersons[0] : null;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ng-frontend/cypress/integration/pages/not-found-page.spec.ts:
--------------------------------------------------------------------------------
1 | import { Chance } from 'chance';
2 |
3 | describe('NotFoundPage', () => {
4 | let baseUrl = Cypress.config().baseUrl;
5 | const chance = new Chance();
6 |
7 | beforeEach(() => {
8 | cy.visit(baseUrl);
9 | });
10 |
11 | it('redirects to an 404 error page when a unknown route is requested', () => {
12 | const testString = chance.string({ alpha: true, numeric: true });
13 | cy.visit(baseUrl + '/' + testString);
14 | cy.get('[data-cy=not-found-hint]').contains(/Route .* wurde nicht gefunden/);
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/java-backend/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 | !**/src/main/**
4 | !**/src/test/**
5 |
6 | ### STS ###
7 | .apt_generated
8 | .classpath
9 | .factorypath
10 | .project
11 | .settings
12 | .springBeans
13 | .sts4-cache
14 |
15 | ### IntelliJ IDEA ###
16 | .idea
17 | *.iws
18 | *.iml
19 | *.ipr
20 |
21 | ### NetBeans ###
22 | /nbproject/private/
23 | /nbbuild/
24 | /dist/
25 | /nbdist/
26 | /.nb-gradle/
27 | build/
28 |
29 | ### VS Code ###
30 | .vscode/
31 | /.mvn/wrapper/maven-wrapper.jar
32 | /.mvn/wrapper/maven-wrapper.properties
33 | /.mvn/wrapper/MavenWrapperDownloader.java
34 |
--------------------------------------------------------------------------------
/ng-frontend/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "outDir": "./dist/out-tsc",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "downlevelIteration": true,
9 | "experimentalDecorators": true,
10 | "module": "esnext",
11 | "moduleResolution": "node",
12 | "importHelpers": true,
13 | "target": "es2015",
14 | "types": ["cypress"],
15 | "lib": ["es2018", "dom"]
16 | },
17 | "angularCompilerOptions": {
18 | "fullTemplateTypeCheck": true,
19 | "strictInjectionParameters": true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/dtos/audit.dto.ts:
--------------------------------------------------------------------------------
1 | import { FacCrit } from '../../data/models/faccrit.model';
2 | import { ContactPerson } from '../../data/models/contact-person.model';
3 | import { AuditStatus } from '../../data/models/audit.model';
4 |
5 | export interface AuditDto {
6 | id: number;
7 | name: string;
8 | startDate: string;
9 | endDate: string;
10 | creationDate: string;
11 | status: AuditStatus;
12 | scope: FacCrit[];
13 | contactPersons: ContactPerson[];
14 | cancellationDate: string;
15 | cancellationReason: string;
16 | cancellationContactPerson: ContactPerson;
17 | }
18 |
--------------------------------------------------------------------------------
/java-backend/src/test/java/com/amos2020/javabackend/repository/RepositoryTests.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.repository;
2 |
3 | import org.junit.runner.RunWith;
4 | import org.junit.runners.Suite;
5 |
6 | @RunWith(Suite.class)
7 | @Suite.SuiteClasses({AnswerRepositoryTest.class, AuditContactPersonRepositoryTest.class, AuditRepositoryTest.class,
8 | ContactPersonRepositoryTest.class, FacCritRepositoryTest.class, InterviewContactPersonRepositoryTest.class,
9 | InterviewRepositoryTest.class, QuestionRepositoryTest.class, ScopeRepositoryTest.class,
10 | })
11 | public class RepositoryTests {
12 | }
13 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/not-found/not-found.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute } from '@angular/router';
3 |
4 | @Component({
5 | selector: 'app-not-found',
6 | templateUrl: './not-found.component.html',
7 | styleUrls: ['./not-found.component.scss'],
8 | })
9 | export class NotFoundComponent implements OnInit {
10 | url: string;
11 |
12 | constructor(private route: ActivatedRoute) {}
13 |
14 | ngOnInit(): void {
15 | this.url = this.route.snapshot.url
16 | .map(x => x.path)
17 | .toString()
18 | .replace(/,/g, '/');
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-info/audit-contact-person-card/contact-person-card.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../../../sass/utils';
2 |
3 | .wrapper-contact-person-details {
4 | display: grid;
5 | grid-template-columns: repeat(4, 1fr);
6 | gap: 0 10px;
7 |
8 | @media screen and (max-width: 600px) {
9 | grid-template-columns: repeat(2, 1fr);
10 | }
11 | }
12 |
13 | :host {
14 | width: 100%;
15 | position: relative;
16 | }
17 |
18 | .action-bar {
19 | position: absolute;
20 | top: 0;
21 | right: 0;
22 | display: grid;
23 | grid-template-columns: 1fr 1fr;
24 | gap: 0 10px;
25 | }
26 |
--------------------------------------------------------------------------------
/ng-frontend/browserslist:
--------------------------------------------------------------------------------
1 | # and_chr 80
2 | # and_ff 68
3 | # and_qq 1.2
4 | # and_uc 12.12
5 | # android 80
6 | # baidu 7.12
7 | # chrome 81
8 | # chrome 80
9 | # chrome 79
10 | # edge 80
11 | # edge 79
12 | # edge 18
13 | # firefox 75
14 | # firefox 74
15 | # firefox 73
16 | # firefox 68
17 | # ios_saf 13.3
18 | # ios_saf 13.2
19 | # ios_saf 12.2-12.4
20 | # kaios 2.5
21 | # op_mini all
22 | # op_mob 46
23 | # opera 67
24 | # opera 66
25 | # safari 13
26 | # safari 12.1
27 | # samsung 11.1
28 | # samsung 10.1
29 |
30 | > 0.5%
31 | last 2 versions
32 | Firefox ESR
33 | not dead
34 | not IE 9-11 # For IE 9-11 support, remove 'not'.
--------------------------------------------------------------------------------
/ng-frontend/src/sass/styles.scss:
--------------------------------------------------------------------------------
1 | @import 'themes';
2 | @import 'reset';
3 | @import 'colors';
4 | @import '~@nebular/theme/styles/globals';
5 |
6 | @include nb-install() {
7 | @include nb-theme-global();
8 | }
9 |
10 | // Remove min-width from nb-layouts that container router-outlet
11 | // inside audit-list and audit-overview
12 |
13 | nb-layout:nth-child(3) > div:nth-child(1) > div:nth-child(1) {
14 | min-height: 0;
15 | }
16 |
17 | hr {
18 | border: none;
19 | border-bottom: 1px solid $border-light;
20 | }
21 |
22 | app-sidebar-interview nb-menu {
23 | ul > .menu-item > a > span {
24 | width: 180px !important;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/java-backend/documentation/element-list:
--------------------------------------------------------------------------------
1 | com.amos2020.javabackend
2 | com.amos2020.javabackend.entity
3 | com.amos2020.javabackend.repository
4 | com.amos2020.javabackend.rest_service
5 | com.amos2020.javabackend.rest_service.controller
6 | com.amos2020.javabackend.rest_service.request
7 | com.amos2020.javabackend.rest_service.request.answer
8 | com.amos2020.javabackend.rest_service.request.audit
9 | com.amos2020.javabackend.rest_service.request.contactPerson
10 | com.amos2020.javabackend.rest_service.request.interview
11 | com.amos2020.javabackend.rest_service.request.scope
12 | com.amos2020.javabackend.rest_service.response
13 | com.amos2020.javabackend.service
14 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/interview-list/interviews-by-fac-crit-id.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { Interview } from 'src/app/core/data/models/interview.model';
3 |
4 | @Pipe({
5 | name: 'interviewsByFacCritId',
6 | })
7 | export class InterviewsByFacCritIdPipe implements PipeTransform {
8 | transform(interviews: Interview[], facCritId: number): Interview[] {
9 | const result = interviews?.filter(
10 | interview => interview.answers.findIndex(answer => answer.faccritId === facCritId) != -1,
11 | );
12 |
13 | return result ? (result.length > 0 ? result : null) : null;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audits/audits.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { AuditCardComponent } from './audit-card/audit-card.component';
4 | import { AuditsComponent } from './audits.component';
5 | import { AuditsRoutingModule } from './audits-routing.module';
6 | import { SharedModule } from 'src/app/shared/shared.module';
7 | import { SortAuditPipe } from './sort-audit.pipe';
8 |
9 | @NgModule({
10 | declarations: [AuditCardComponent, SortAuditPipe, AuditsComponent],
11 | imports: [CommonModule, AuditsRoutingModule, SharedModule],
12 | })
13 | export class AuditsModule {}
14 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/forms/contact-person-form/contact-person-form.component.scss:
--------------------------------------------------------------------------------
1 | @import 'src/sass/utils';
2 |
3 | nb-card {
4 | margin: 0 10px;
5 | }
6 |
7 | nb-card-footer {
8 | display: flex;
9 | justify-content: space-between;
10 | border-radius: 0;
11 | padding: 10px 20px 10px 20px;
12 | }
13 |
14 | .criteria-container {
15 | display: grid;
16 | grid-template-columns: repeat(2, 1fr);
17 | gap: 20px;
18 |
19 | @media screen and (max-width: 600px) {
20 | grid-template-columns: 1fr;
21 | }
22 | }
23 |
24 | .field-item-audit-name {
25 | margin-bottom: 20px;
26 | }
27 |
28 | textarea {
29 | resize: vertical;
30 | }
31 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/contact-persons/contact-persons.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Select } from '@ngxs/store';
3 | import { Observable } from 'rxjs';
4 | import { ContactPerson } from 'src/app/core/data/models/contact-person.model';
5 | import { ContactPersonState } from 'src/app/core/ngxs/contact-person.state';
6 |
7 | @Component({
8 | selector: 'app-contact-persons-list',
9 | templateUrl: './contact-persons.component.html',
10 | styleUrls: ['./contact-persons.component.scss'],
11 | })
12 | export class ContactPersonsComponent {
13 | @Select(ContactPersonState.contactPersons) contactPersons$: Observable;
14 | }
15 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/contact-persons/contact-persons.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 |
4 | import { ContactPersonsRoutingModule } from './contact-persons-routing.module';
5 | import { SharedModule } from 'src/app/shared/shared.module';
6 | import { ContactPersonCardComponent } from './contact-person-card/contact-person-card.component';
7 | import { ContactPersonsComponent } from './contact-persons.component';
8 |
9 | @NgModule({
10 | declarations: [ContactPersonsComponent, ContactPersonCardComponent],
11 | imports: [CommonModule, ContactPersonsRoutingModule, SharedModule],
12 | })
13 | export class ContactPersonsModule {}
14 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { NbSidebarService } from '@nebular/theme';
3 | import { Select } from '@ngxs/store';
4 | import { AuditState } from './core/ngxs/audit.state';
5 | import { Observable } from 'rxjs';
6 | import { Audit } from './core/data/models/audit.model';
7 |
8 | @Component({
9 | selector: 'app-root',
10 | templateUrl: './app.component.html',
11 | styleUrls: ['./app.component.scss'],
12 | })
13 | export class AppComponent {
14 | @Select(AuditState.audits) audits$: Observable;
15 |
16 | constructor(private sidebarService: NbSidebarService) {}
17 |
18 | toggleSidebar() {
19 | this.sidebarService.toggle();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/interview-list/finished-interviews-count.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { Interview, InterviewStatus } from 'src/app/core/data/models/interview.model';
3 |
4 | @Pipe({
5 | name: 'finishedInterviewsCount',
6 | })
7 | export class FinishedInterviewsCountPipe implements PipeTransform {
8 | /**
9 | * Checks if all interviews are finished and returns true if they are.
10 | *
11 | * @param interviews The interviews to check.
12 | */
13 | transform(interviews: Interview[]): number {
14 | if (!interviews || interviews?.length === 0) return 0;
15 | return interviews.filter(i => i.status === InterviewStatus.Finished).length;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/scope/AddScopeRequest.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.request.scope;
2 |
3 | import com.amos2020.javabackend.rest_service.request.BasicRequest;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import lombok.Getter;
6 | import lombok.Setter;
7 |
8 | import javax.validation.constraints.Min;
9 | import java.util.List;
10 | /**
11 | * Request object for adding elements to the scope of an existing audit project.
12 | */
13 | public class AddScopeRequest extends BasicRequest {
14 |
15 | @Getter
16 | @Setter
17 | @Schema(type = "Array", name = "scope", example = "[1]", required = true)
18 | private List<@Min(1) Integer> scope;
19 | }
20 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/ngxs/actions/inteview.actions.ts:
--------------------------------------------------------------------------------
1 | import { Interview } from '../../data/models/interview.model';
2 | import { FacCrit } from '../../data/models/faccrit.model';
3 | import { Answer } from '../../data/models/answer.model';
4 |
5 | export class AddInterview {
6 | static readonly type = '[AuditOverview] Add Interview';
7 | constructor(public interview: Interview, public interviewScope: FacCrit[]) {}
8 | }
9 |
10 | export class UpdateInterview {
11 | static readonly type = '[Interview] Update Interview';
12 | constructor(public id: number, public interview: Partial) {}
13 | }
14 |
15 | export class UpdateAnswer {
16 | static readonly type = '[Interview] Update Answer';
17 | constructor(public answer: Answer) {}
18 | }
19 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/forms/form-helpers.ts:
--------------------------------------------------------------------------------
1 | import { FormGroup } from '@angular/forms';
2 |
3 | /**
4 | * Validator for two dates: A start date has to be before the end date.
5 | *
6 | * @param startDate string of form group attribute for start date
7 | * @param endDate string of form group attribute for end date
8 | */
9 | export function dateRangeValidator(startDate: string, endDate: string) {
10 | return (group: FormGroup): { [key: string]: any } => {
11 | const start = group.get(startDate).value;
12 | const end = group.get(endDate).value;
13 | if (!start || !end) {
14 | return null;
15 | }
16 | if (start > end) {
17 | return {
18 | dateRangeValidator: true,
19 | };
20 | }
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/sidebar/sidebar.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Select } from '@ngxs/store';
3 | import { AppRouterState } from 'src/app/core/ngxs/app-router.state';
4 | import { Observable } from 'rxjs';
5 |
6 | @Component({
7 | selector: 'app-sidebar',
8 | templateUrl: './sidebar.component.html',
9 | styleUrls: ['./sidebar.component.scss'],
10 | })
11 | export class SidebarComponent {
12 | @Select(AppRouterState.inInterview) inInterview$: Observable;
13 | @Select(AppRouterState.inInterviewsList) inInterviewsList$: Observable;
14 | @Select(AppRouterState.inAuditList) inAuditList$: Observable;
15 | @Select(AppRouterState.inContactPersonsList) inContactPersonsList$: Observable;
16 | }
17 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/interview/answer-question-list/answer-question-list.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../../sass/utils';
2 | @import 'src/sass/colors';
3 |
4 | nb-accordion-item-header,
5 | nb-card-header {
6 | background: #f7f9fc !important;
7 | }
8 | .header-container-1 {
9 | display: flex;
10 | justify-content: space-between;
11 | }
12 |
13 | .container-checkboxes {
14 | grid-row: 1 / 3;
15 | display: grid;
16 | }
17 |
18 | .container-inputs-item-1 {
19 | grid-column: 2 / 4;
20 | }
21 |
22 | .container-inputs-item-2 {
23 | grid-column: 2 / 3;
24 | }
25 |
26 | .container-inputs-item-3 {
27 | grid-column: 3 / 4;
28 | }
29 |
30 | .container-interview-form {
31 | display: grid;
32 | grid-template-columns: auto 1fr 1fr;
33 | gap: 20px;
34 | }
35 |
--------------------------------------------------------------------------------
/java-backend/documentation/package-search-index.js:
--------------------------------------------------------------------------------
1 | packageSearchIndex = [{"l":"All Packages","url":"allpackages-index.html"},{"l":"com.amos2020.javabackend"},{"l":"com.amos2020.javabackend.entity"},{"l":"com.amos2020.javabackend.repository"},{"l":"com.amos2020.javabackend.rest_service"},{"l":"com.amos2020.javabackend.rest_service.controller"},{"l":"com.amos2020.javabackend.rest_service.request"},{"l":"com.amos2020.javabackend.rest_service.request.answer"},{"l":"com.amos2020.javabackend.rest_service.request.audit"},{"l":"com.amos2020.javabackend.rest_service.request.contactPerson"},{"l":"com.amos2020.javabackend.rest_service.request.interview"},{"l":"com.amos2020.javabackend.rest_service.request.scope"},{"l":"com.amos2020.javabackend.rest_service.response"},{"l":"com.amos2020.javabackend.service"}]
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/repository/FacCritRepository.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.repository;
2 |
3 | import com.amos2020.javabackend.entity.FacCrit;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Query;
6 | import org.springframework.data.repository.query.Param;
7 |
8 | import java.util.List;
9 | /**
10 | * Interface to access the fac_crit table in the database
11 | */
12 | public interface FacCritRepository extends JpaRepository {
13 |
14 | @Query("select f from FacCrit f where f.id in (select a.faccritId from Answer a where a.interviewId=:interviewId)")
15 | List getFacCritsByInterviewId(@Param("interviewId") int interviewId);
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/repository/QuestionRepository.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.repository;
2 |
3 | import com.amos2020.javabackend.entity.Question;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Modifying;
6 | import org.springframework.data.jpa.repository.Query;
7 | import org.springframework.data.repository.query.Param;
8 |
9 | import java.util.List;
10 | /**
11 | * Interface to access the question table in the database
12 | */
13 | public interface QuestionRepository extends JpaRepository {
14 | @Query("select a from Question a where a.faccritId=:faccritId")
15 | List getQuestionsByFaccritId(@Param("faccritId") int faccritId);
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/interview/InterviewPerson.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.request.interview;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | import javax.validation.constraints.Min;
7 | import javax.validation.constraints.NotBlank;
8 | import javax.validation.constraints.NotNull;
9 | import javax.validation.constraints.Size;
10 |
11 | public class InterviewPerson {
12 | @Getter
13 | @Setter
14 | @Min(1)
15 | private int id;
16 | @Getter
17 | @Setter
18 | @NotNull
19 | @NotBlank
20 | @Size(min = 1, max = 256)
21 | private String role;
22 |
23 | public InterviewPerson(int id, String role) {
24 | this.id = id;
25 | this.role = role;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/js/libs/EventDispatcher.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 |
5 | var EventDispatcher=function(){};Object.assign(EventDispatcher.prototype,{addEventListener:function(i,t){void 0===this._listeners&&(this._listeners={});var e=this._listeners;void 0===e[i]&&(e[i]=[]),-1===e[i].indexOf(t)&&e[i].push(t)},hasEventListener:function(i,t){if(void 0===this._listeners)return!1;var e=this._listeners;return void 0!==e[i]&&-1!==e[i].indexOf(t)},removeEventListener:function(i,t){if(void 0!==this._listeners){var e=this._listeners[i];if(void 0!==e){var s=e.indexOf(t);-1!==s&&e.splice(s,1)}}},dispatchEvent:function(i){if(void 0!==this._listeners){var t=this._listeners[i.type];if(void 0!==t){i.target=this;var e=[],s=0,n=t.length;for(s=0;s {
2 | beforeEach(() => {
3 | cy.visit(Cypress.config().baseUrl);
4 | });
5 |
6 | it('contains Menu Icon Button', () => {
7 | cy.get('[data-cy=toggle-sidebar]');
8 | });
9 |
10 | it('contains home button', () => {
11 | cy.get('[data-cy=home]').click();
12 | cy.url().should('contain', 'audits');
13 | });
14 |
15 | it('contains contacts button', () => {
16 | cy.get('[data-cy=contacts]').click();
17 | cy.url().should('contain', 'contact-persons');
18 | });
19 |
20 | it('opens the sidebar when clicking the sidebar toggle button', () => {
21 | cy.viewport('iphone-5');
22 | cy.get('[data-cy=toggle-sidebar]').click();
23 | cy.get('[data-cy=sidebar]').should('have.class', 'expanded');
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/question.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 | import { Question } from '../data/models/question.model';
4 | import { Observable } from 'rxjs';
5 | import { environment } from 'src/environments/environment';
6 |
7 | @Injectable({
8 | providedIn: 'root',
9 | })
10 | export class QuestionService {
11 | constructor(private http: HttpClient) {}
12 |
13 | /**
14 | * Builds an observable for making a GET request to get a question.
15 | *
16 | * @param id The question's id.
17 | * @returns An Observable of the question.
18 | */
19 | getQuestion(id: number): Observable {
20 | const url = environment.baseUrl + 'questions/' + id;
21 |
22 | return this.http.get(url);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ng-frontend/cypress/plugins/index.js:
--------------------------------------------------------------------------------
1 | ///
2 | // ***********************************************************
3 | // This example plugins/index.js can be used to load plugins
4 | //
5 | // You can change the location of this file or turn off loading
6 | // the plugins file with the 'pluginsFile' configuration option.
7 | //
8 | // You can read more here:
9 | // https://on.cypress.io/plugins-guide
10 | // ***********************************************************
11 |
12 | // This function is called when a project is opened or re-opened (e.g. due to
13 | // the project's config changing)
14 |
15 | /**
16 | * @type {Cypress.PluginConfig}
17 | */
18 | module.exports = (on, config) => {
19 | // `on` is used to hook into various events Cypress emits
20 | // `config` is the resolved Cypress config
21 | }
22 |
--------------------------------------------------------------------------------
/ng-frontend/cypress/fixtures/backend-mock-data/contactPersons.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "salutation": "HERR",
5 | "title": "Prof",
6 | "forename": "Max",
7 | "surname": "Mustermann",
8 | "contactInformation": "max.mustermann@gmx.de, tel: 0123456789",
9 | "companyName": "msg systems AG",
10 | "department": "Softwareentwicklung",
11 | "sector": "msg Public Sector",
12 | "corporateDivision": "Software"
13 | },
14 | {
15 | "id": 2,
16 | "salutation": "FRAU",
17 | "title": "Prof",
18 | "forename": "Maxi",
19 | "surname": "Mustermann",
20 | "contactInformation": "maxi.mustermann@gmx.de, tel: 0123456789",
21 | "companyName": "msg systems AG",
22 | "department": "Softwareentwicklung",
23 | "sector": "msg Public Sector",
24 | "corporateDivision": "Software"
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------
/ng-frontend/cypress/support/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import './commands';
18 |
19 | // Alternatively you can use CommonJS syntax:
20 | // require('./commands')
21 | Cypress.Screenshot.defaults({
22 | screenshotOnRunFailure: false,
23 | });
24 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/interview-list/interview-card/interview-card.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 | import { InterviewCardComponent } from './interview-card.component';
4 |
5 | describe('InterviewCardComponent', () => {
6 | let component: InterviewCardComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [InterviewCardComponent],
12 | }).compileComponents();
13 | }));
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(InterviewCardComponent);
17 | component = fixture.componentInstance;
18 | });
19 |
20 | it('should create', () => {
21 | expect(component).toBeTruthy();
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/ng-frontend/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 | # Only exists if Bazel was run
8 | /bazel-out
9 |
10 | # dependencies
11 | /node_modules
12 |
13 | # profiling files
14 | chrome-profiler-events*.json
15 | speed-measure-plugin*.json
16 |
17 | # IDEs and editors
18 | /.idea
19 | .project
20 | .classpath
21 | .c9/
22 | *.launch
23 | .settings/
24 | *.sublime-workspace
25 |
26 | # IDE - VSCode
27 | .vscode
28 | .vscode/*
29 | !.vscode/settings.json
30 | !.vscode/tasks.json
31 | !.vscode/launch.json
32 | !.vscode/extensions.json
33 | .history/*
34 | .vscode/*.json
35 |
36 | # misc
37 | /.sass-cache
38 | /connect.lock
39 | /coverage
40 | /libpeerconnection.log
41 | npm-debug.log
42 | yarn-error.log
43 | testem.log
44 | /typings
45 |
46 | # System Files
47 | .DS_Store
48 | Thumbs.db
49 |
--------------------------------------------------------------------------------
/ng-frontend/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone-testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting,
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: {
11 | context(
12 | path: string,
13 | deep?: boolean,
14 | filter?: RegExp,
15 | ): {
16 | keys(): string[];
17 | (id: string): T;
18 | };
19 | };
20 |
21 | // First, initialize the Angular testing environment.
22 | getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
23 | // Then we find all the tests.
24 | const context = require.context('./', true, /\.spec\.ts$/);
25 | // And load the modules.
26 | context.keys().map(context);
27 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-info/audit-contact-person-card/contact-person-card.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { AuditContactPersonCardComponent } from './contact-person-card.component';
4 |
5 | describe('ContactPersonCardComponent', () => {
6 | let component: AuditContactPersonCardComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [AuditContactPersonCardComponent],
12 | }).compileComponents();
13 | }));
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(AuditContactPersonCardComponent);
17 | component = fixture.componentInstance;
18 | });
19 |
20 | it('should create', () => {
21 | expect(component).toBeTruthy();
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/js/tabs.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('DOMContentLoaded', function() {
2 | var tabs = document.getElementsByClassName('nav-tabs'),
3 | updateAddress = function(e) {
4 | if(history.pushState && e.target.dataset.link) {
5 | history.pushState(null, null, '#' + e.target.dataset.link);
6 | }
7 | };
8 | if (tabs.length > 0) {
9 | tabs = tabs[0].querySelectorAll('li');
10 | for (var i = 0; i < tabs.length; i++) {
11 | tabs[i].addEventListener('click', updateAddress);
12 | var linkTag = tabs[i].querySelector('a');
13 | if (location.hash !== '') {
14 | var currentHash = location.hash.substr(1);
15 | if (currentHash === linkTag.dataset.link) {
16 | linkTag.click();
17 | }
18 | }
19 | }
20 | }
21 | });
22 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audits/audits-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 | import { AuditsComponent } from './audits.component';
4 | import { AddAuditDialogComponent } from 'src/app/shared/components/dialogs/add-audit-dialog/add-audit-dialog.component';
5 | import { EditAuditDialogComponent } from 'src/app/shared/components/dialogs/edit-audit-dialog/edit-audit-dialog.component';
6 |
7 | const routes: Routes = [
8 | {
9 | path: '',
10 | component: AuditsComponent,
11 | children: [
12 | { path: 'new', component: AddAuditDialogComponent },
13 | { path: ':id/edit', component: EditAuditDialogComponent },
14 | ],
15 | },
16 | ];
17 |
18 | @NgModule({
19 | declarations: [],
20 | imports: [RouterModule.forChild(routes)],
21 | exports: [RouterModule],
22 | })
23 | export class AuditsRoutingModule {}
24 |
--------------------------------------------------------------------------------
/java-backend/src/test/resources/ScopeTest.sql:
--------------------------------------------------------------------------------
1 | DELETE FROM scope;
2 | DELETE FROM audit;
3 | DELETE FROM fac_crit;
4 | insert into audit (ID, NAME, START_DATE, STATUS, CREATION_DATE) values (1001, 'TestAudit', '2020-06-20', 'ACTIVE', '2020-06-20');
5 | insert into fac_crit (ID, NAME, GOAL) values(1001, 'TestFactor', 'TestGoal');
6 | insert into fac_crit (ID, NAME, GOAL) values(1002, 'AnotherTestFactor', 'AnotherTestGoal');
7 | insert into fac_crit (ID, REFERENCE_ID, NAME, GOAL) values(1003, 1001,'TestCriteria', 'TestCriteriaGoal');
8 | insert into fac_crit (ID, REFERENCE_ID, NAME, GOAL) values(1004, 1001,'RandomTestCriteria', 'RandomTestCriteriaGoal');
9 | insert into fac_crit (ID, REFERENCE_ID, NAME, GOAL) values(1005, 1001,'AnotherTestCriteria', 'AnotherTestCriteriaGoal');
10 | insert into scope (AUDIT_ID, FACCRIT_ID, REMOVED) values(1001,1002, false);
11 | insert into scope (AUDIT_ID, FACCRIT_ID, REMOVED) values(1001,1003, false)
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-info/audit-info.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Observable } from 'rxjs';
3 | import { Audit } from 'src/app/core/data/models/audit.model';
4 | import { Store, Select } from '@ngxs/store';
5 | import { AuditState } from 'src/app/core/ngxs/audit.state';
6 | import { AppRouterState } from 'src/app/core/ngxs/app-router.state';
7 |
8 | @Component({
9 | selector: 'app-audit-info',
10 | templateUrl: './audit-info.component.html',
11 | styleUrls: ['./audit-info.component.scss'],
12 | })
13 | export class AuditInfoComponent implements OnInit {
14 | @Select(AppRouterState.auditId) auditId$: Observable;
15 |
16 | audit$: Observable;
17 | constructor(private store: Store) {}
18 |
19 | ngOnInit() {
20 | this.auditId$.subscribe(id => (this.audit$ = this.store.select(AuditState.audit(id))));
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/confirm-discard-dialog/confirm-discard-dialog.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Output, EventEmitter } from '@angular/core';
2 | import { NbDialogRef } from '@nebular/theme';
3 |
4 | @Component({
5 | selector: 'app-confirm-discard-dialog',
6 | templateUrl: './confirm-discard-dialog.component.html',
7 | styleUrls: ['./confirm-discard-dialog.component.scss'],
8 | })
9 | export class ConfirmDiscardDialogComponent implements OnInit {
10 | @Output() onDiscardConfirm = new EventEmitter();
11 | constructor(private dialogRef: NbDialogRef) {}
12 |
13 | ngOnInit(): void {}
14 |
15 | onOk() {
16 | this.onDiscardConfirm.emit(true);
17 | this.closeDialog();
18 | }
19 |
20 | onCancel() {
21 | this.onDiscardConfirm.emit(false);
22 | this.closeDialog();
23 | }
24 |
25 | closeDialog() {
26 | this.dialogRef.close();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/interview/interview.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../sass/utils';
2 | @import '../../../../node_modules/@nebular/theme/styles/theming';
3 | @import '../../../../node_modules/@nebular/theme/styles/themes/default';
4 |
5 | nb-card-body {
6 | padding: 7px !important;
7 | }
8 | nb-accordion-item-header,
9 | nb-card-header {
10 | background: #f7f9fc !important;
11 | }
12 |
13 | textarea {
14 | resize: vertical;
15 | }
16 |
17 | #fac-crit-goal {
18 | position: sticky !important;
19 | top: 77px !important;
20 | z-index: 1;
21 |
22 | nb-accordion-item-header {
23 | height: 40px !important;
24 | }
25 | }
26 |
27 | .header-main {
28 | display: flex;
29 | justify-content: space-between;
30 | }
31 |
32 | .nb-card-header-navigation {
33 | display: grid;
34 | grid-template-columns: auto 1fr auto;
35 | gap: 0 5px;
36 |
37 | justify-items: center;
38 | align-items: center;
39 | }
40 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/repository/AnswerRepository.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.repository;
2 |
3 | import com.amos2020.javabackend.entity.Answer;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Query;
6 | import org.springframework.data.repository.query.Param;
7 |
8 | import java.util.List;
9 | /**
10 | * Interface to access the answer table in the database
11 | */
12 | public interface AnswerRepository extends JpaRepository {
13 |
14 | @Query("select a from Answer a where a.interviewId=:interviewId")
15 | List getAnswersByInterviewId(@Param("interviewId") int interviewId);
16 |
17 | @Query("select a from Answer a where a.interviewId=:interviewId and a.questionId=:questionId")
18 | Answer findFirstByQuestionIdAndInterviewId(@Param("questionId") int questionId, @Param("interviewId") int interviewId);
19 | }
20 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/interview/interview.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 |
4 | import { InterviewRoutingModule } from './interview-routing.module';
5 | import { InterviewComponent } from './interview.component';
6 | import { AnswerQuestionListComponent } from './answer-question-list/answer-question-list.component';
7 | import { ReactiveFormsModule } from '@angular/forms';
8 | import { SharedModule } from 'src/app/shared/shared.module';
9 | import { QuestionByIdPipe } from './answer-question-list/questions-by-id.pipe';
10 | import { AnswersByIdsPipe } from './answers-by-ids.pipe';
11 |
12 | @NgModule({
13 | declarations: [
14 | InterviewComponent,
15 | AnswerQuestionListComponent,
16 | QuestionByIdPipe,
17 | AnswersByIdsPipe,
18 | ],
19 | imports: [CommonModule, ReactiveFormsModule, SharedModule, InterviewRoutingModule],
20 | })
21 | export class InterviewModule {}
22 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/forms/audit-form/audit-form.component.scss:
--------------------------------------------------------------------------------
1 | @import 'src/sass/utils';
2 |
3 | nb-accordion {
4 | box-shadow: none;
5 | border: 1px solid rgb(228, 233, 242);
6 | }
7 |
8 | nb-card-footer {
9 | display: flex;
10 | justify-content: space-between;
11 | border-radius: 0;
12 | padding: 10px 20px 10px 20px;
13 | }
14 |
15 | .wrapper-facCrits {
16 | max-width: 600px;
17 | display: grid;
18 | grid-template-columns: 1fr 1fr;
19 | gap: 10px;
20 |
21 | @media screen and(max-width: 500px) {
22 | grid-template-columns: 1fr;
23 |
24 | nb-checkbox {
25 | margin: 0px 10px 0px 0px;
26 | }
27 | }
28 |
29 | & > div {
30 | nb-checkbox {
31 | display: block;
32 | }
33 |
34 | & nb-checkbox:not(:first-child) {
35 | margin-left: 20px;
36 | }
37 | }
38 | }
39 |
40 | .wrapper-selected-person {
41 | display: flex;
42 | justify-content: space-between;
43 | width: 100%;
44 | }
45 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/not-found/not-found.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { NotFoundComponent } from './not-found.component';
4 | import { RouterModule } from '@angular/router';
5 | import { SharedModule } from '../../shared/shared.module';
6 |
7 | describe('NotFoundComponent', () => {
8 | let component: NotFoundComponent;
9 | let fixture: ComponentFixture;
10 |
11 | beforeEach(async(() => {
12 | TestBed.configureTestingModule({
13 | declarations: [NotFoundComponent],
14 | imports: [SharedModule, RouterModule.forRoot([])],
15 | }).compileComponents();
16 | }));
17 |
18 | beforeEach(() => {
19 | fixture = TestBed.createComponent(NotFoundComponent);
20 | component = fixture.componentInstance;
21 | fixture.detectChanges();
22 | });
23 |
24 | it('should create', () => {
25 | expect(component).toBeTruthy();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/images/coverage-badge-documentation.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/repository/AuditContactPersonRepository.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.repository;
2 |
3 | import com.amos2020.javabackend.entity.AuditContactPerson;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Modifying;
6 | import org.springframework.data.jpa.repository.Query;
7 | import org.springframework.data.repository.query.Param;
8 | /**
9 | * Interface to access the answer_contact_person table in the database
10 | */
11 | public interface AuditContactPersonRepository extends JpaRepository {
12 | @Modifying
13 | @Query("delete from AuditContactPerson a where a.auditId=:auditId and a.contactPersonId=:contactPersonId")
14 | void deleteByAuditIdAndContactPersonId(@Param("auditId") int auditId, @Param("contactPersonId") int contactPersonId);
15 |
16 | AuditContactPerson findFirstByAuditIdAndContactPersonId(int auditId, int contactPersonId);
17 | }
18 |
--------------------------------------------------------------------------------
/java-backend/documentation/overview-summary.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Generated Documentation (Untitled)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
23 | index.html
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hello
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/answer/CreateAnswerRequest.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.request.answer;
2 |
3 | import com.amos2020.javabackend.rest_service.request.BasicRequest;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import lombok.Getter;
6 | import lombok.Setter;
7 |
8 | import javax.validation.constraints.Min;
9 | import javax.validation.constraints.NotNull;
10 | /**
11 | * Request object for creating a new answer
12 | */
13 | public class CreateAnswerRequest extends BasicRequest {
14 |
15 | @Getter
16 | @Setter
17 | @NotNull
18 | @Min(message = "Question Id", value = 1)
19 | @Schema(type = "Integer", name = "questionId", example = "1", required = true)
20 | private int questionId;
21 | @Getter
22 | @Setter
23 | @NotNull
24 | @Min(message = "Interview Id", value = 1)
25 | @Schema(type = "Integer", name = "interviewId", example = "1", required = true)
26 | private int interviewId;
27 | }
28 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/js/libs/custom-elements-es5-adapter.js:
--------------------------------------------------------------------------------
1 | /**
2 | @license @nocompile
3 | Copyright (c) 2018 The Polymer Project Authors. All rights reserved.
4 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7 | Code distributed by Google as part of the polymer project is also
8 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9 | */
10 | (function () {
11 | 'use strict';
12 |
13 | (function(){if(void 0===window.Reflect||void 0===window.customElements||window.customElements.hasOwnProperty('polyfillWrapFlushCallback'))return;const a=HTMLElement;window.HTMLElement=function(){return Reflect.construct(a,[],this.constructor)},HTMLElement.prototype=a.prototype,HTMLElement.prototype.constructor=HTMLElement,Object.setPrototypeOf(HTMLElement,a);})();
14 |
15 | }());
16 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/response/BasicQuestionResponse.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.response;
2 |
3 | import com.amos2020.javabackend.entity.Question;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import lombok.Getter;
6 | import lombok.Setter;
7 |
8 | public class BasicQuestionResponse {
9 |
10 | @Getter
11 | @Setter
12 | @Schema(type = "Integer", name = "id", example = "15")
13 | private int id;
14 |
15 | @Getter
16 | @Setter
17 | @Schema(type = "Integer", name = "facCritId", example = "2")
18 | private int facCritId;
19 |
20 | @Getter
21 | @Setter
22 | @Schema(type = "String", name = "textDe", example = "Werden konkrete Maßnahmen ergriffen, um das Qualitätskriterium in der Anwendung zu steigern?")
23 | private String textDe;
24 |
25 | public BasicQuestionResponse(Question question) {
26 | id = question.getId();
27 | facCritId = question.getFaccritId();
28 | textDe = question.getTextDe();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/repository/InterviewContactPersonRepository.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.repository;
2 |
3 | import com.amos2020.javabackend.entity.InterviewContactPerson;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Modifying;
6 | import org.springframework.data.jpa.repository.Query;
7 | import org.springframework.data.repository.query.Param;
8 | /**
9 | * Interface to access the interview_contact_person table in the database
10 | */
11 | public interface InterviewContactPersonRepository extends JpaRepository {
12 | @Modifying
13 | @Query("delete from InterviewContactPerson a where a.interviewId=:interviewId and a.contactPersonId=:contactPersonId")
14 | void deleteByInterviewIdAndContactPersonId(@Param("interviewId") int interviewId, @Param("contactPersonId") int contactPersonId);
15 |
16 | InterviewContactPerson findFirstByInterviewIdAndContactPersonId(int interviewId, int contactPersonId);
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/contact-persons/contact-persons-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 | import { ContactPersonsComponent } from './contact-persons.component';
4 | import { AddContactPersonDialogComponent } from 'src/app/shared/components/dialogs/add-contact-person-dialog/add-contact-person-dialog.component';
5 | import { EditContactPersonDialogComponent } from 'src/app/shared/components/dialogs/edit-contact-person-dialog/edit-contact-person-dialog.component';
6 |
7 | const routes: Routes = [
8 | {
9 | path: '',
10 | component: ContactPersonsComponent,
11 | children: [
12 | {
13 | path: 'new',
14 | component: AddContactPersonDialogComponent,
15 | },
16 | {
17 | path: ':id/edit',
18 | component: EditContactPersonDialogComponent,
19 | },
20 | ],
21 | },
22 | ];
23 |
24 | @NgModule({
25 | imports: [RouterModule.forChild(routes)],
26 | exports: [RouterModule],
27 | })
28 | export class ContactPersonsRoutingModule {}
29 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/interview-list/interview-card/interview-card.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../../../sass/utils';
2 | @import '../../../../../../node_modules/@nebular/theme/styles/theming';
3 | @import '../../../../../../node_modules/@nebular/theme/styles/themes/default';
4 |
5 | nb-card-header {
6 | display: grid;
7 | grid-template-columns: auto 1fr auto;
8 | align-items: center;
9 | gap: 0 10px;
10 | border: none;
11 | }
12 |
13 | a {
14 | display: grid;
15 | text-decoration: none;
16 | }
17 |
18 | .banner-status {
19 | position: absolute;
20 | top: 0;
21 | left: 0;
22 | bottom: 0;
23 | height: 100%;
24 | width: 12px;
25 | -webkit-box-shadow: 3px 3px 3px 0px rgba(44, 51, 73, 0.1);
26 | -moz-box-shadow: 3px 3px 3px 0px rgba(44, 51, 73, 0.1);
27 | box-shadow: 3px 3px 3px 0px rgba(44, 51, 73, 0.1);
28 | border-radius: 2px;
29 | }
30 | .banner-status-in-action {
31 | background-color: nb-theme(color-warning-default);
32 | }
33 |
34 | .banner-status-is-finished {
35 | background-color: nb-theme(color-success-default);
36 | }
37 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/facCrit.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 | import { Observable } from 'rxjs';
4 | import { FacCrit } from '../data/models/faccrit.model';
5 | import { environment } from 'src/environments/environment';
6 |
7 | @Injectable({
8 | providedIn: 'root',
9 | })
10 | export class FacCritService {
11 | constructor(private http: HttpClient) {}
12 |
13 | /**
14 | * Builds an observable for making a GET request to get all facCrits.
15 | *
16 | * @returns An Observable of facCrits.
17 | */
18 | getFacCrits(): Observable {
19 | return this.http.get(environment.baseUrl + 'faccrits');
20 | }
21 |
22 | /**
23 | * Builds an observable for making a GET request to get facCrits that belong to an interview.
24 | *
25 | * @param id The interview's id.
26 | * @returns An Observable of facCrits.
27 | */
28 | getFacCritsByInterviewId(id: number): Observable {
29 | return this.http.get(environment.baseUrl + 'faccrits/interview/' + id);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/scope/UpdateScopeRequest.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.request.scope;
2 |
3 | import com.amos2020.javabackend.Constants;
4 | import com.amos2020.javabackend.rest_service.request.BasicRequest;
5 | import io.swagger.v3.oas.annotations.media.Schema;
6 | import lombok.Getter;
7 | import lombok.Setter;
8 |
9 | import javax.validation.constraints.Size;
10 | /**
11 | * Request object for updating a specific scope item
12 | */
13 | public class UpdateScopeRequest extends BasicRequest {
14 |
15 | @Getter
16 | @Setter
17 | @Schema(type = "boolean", name = "removed", example = "true")
18 | private boolean removed;
19 |
20 | @Getter
21 | @Setter
22 | @Size(message = "change note", max = Constants.NOTE_LENGTH)
23 | @Schema(type = "String", name = "change_note", example = "Some change note")
24 | private String change_note;
25 |
26 | @Getter
27 | @Setter
28 | @Size(message = "note", max = Constants.NOTE_LENGTH)
29 | @Schema(type = "String", name = "note", example = "Some note")
30 | private String note;
31 | }
32 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/styles/original.css:
--------------------------------------------------------------------------------
1 | .navbar-default .navbar-brand, .menu ul.list li.title {
2 | font-weight: bold;
3 | color: #3c3c3c;
4 | padding-bottom: 5px;
5 | }
6 |
7 | .menu ul.list li a[data-type="chapter-link"], .menu ul.list li.chapter .simple {
8 | font-weight: bold;
9 | border-top: 1px solid #ddd;
10 | border-bottom: 1px solid #ddd;
11 | font-size: 14px;
12 | }
13 |
14 | .menu ul.list li a[href="./routes.html"] {
15 | border-bottom: none;
16 | }
17 |
18 | .menu ul.list > li:nth-child(2) {
19 | display: none;
20 | }
21 |
22 | .menu ul.list li.chapter ul.links {
23 | background: #fff;
24 | padding-left: 0;
25 | }
26 |
27 | .menu ul.list li.chapter ul.links li {
28 | border-bottom: 1px solid #ddd;
29 | padding-left: 20px;
30 | }
31 |
32 | .menu ul.list li.chapter ul.links li:last-child {
33 | border-bottom: none;
34 | }
35 |
36 | .menu ul.list li a.active {
37 | color: inherit;
38 | font-weight: bold;
39 | }
40 |
41 | #book-search-input {
42 | margin-bottom: 0;
43 | border-bottom: none;
44 | }
45 | .menu ul.list li.divider {
46 | margin: 0;
47 | }
48 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audits/audits.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Select } from '@ngxs/store';
3 | import { Observable } from 'rxjs';
4 | import { AuditState } from 'src/app/core/ngxs/audit.state';
5 | import { AuditStatus, Audit } from 'src/app/core/data/models/audit.model';
6 | import { filter } from 'rxjs/operators';
7 |
8 | @Component({
9 | selector: 'app-audit-list',
10 | templateUrl: './audits.component.html',
11 | styleUrls: ['./audits.component.scss'],
12 | })
13 | export class AuditsComponent implements OnInit {
14 | @Select(AuditState.audits) audits$: Observable;
15 |
16 | activeAudits: Audit[];
17 | archivedAudits: Audit[];
18 |
19 | ngOnInit() {
20 | this.audits$.pipe(filter(audits => audits != undefined)).subscribe(audits => {
21 | this.activeAudits = audits.filter(
22 | a => a.status === AuditStatus.Active || a.status === AuditStatus.Planned,
23 | );
24 |
25 | this.archivedAudits = audits.filter(
26 | a => a.status === AuditStatus.Finished || a.status === AuditStatus.Cancelled,
27 | );
28 | });
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/controller/QuestionController.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.controller;
2 |
3 | import com.amos2020.javabackend.entity.Question;
4 | import com.amos2020.javabackend.rest_service.response.BasicQuestionResponse;
5 | import com.amos2020.javabackend.service.QuestionService;
6 | import javassist.NotFoundException;
7 | import org.springframework.stereotype.Service;
8 |
9 | @Service
10 | public class QuestionController {
11 | final QuestionService questionService;
12 |
13 | public QuestionController(QuestionService questionService) {
14 | this.questionService = questionService;
15 | }
16 |
17 | /**
18 | * Get a specific question by an id
19 | *
20 | * @param questionId int
21 | * @return Question or Exception
22 | * @throws NotFoundException if question does not exist
23 | */
24 | public BasicQuestionResponse getInterviewById(int questionId) throws NotFoundException {
25 | Question question = questionService.getQuestionById(questionId);
26 | return new BasicQuestionResponse(question);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/java-backend/src/main/resources/persistence.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.amos2020.javabackend.entity.Answer
6 | com.amos2020.javabackend.entity.Audit
7 | com.amos2020.javabackend.entity.AuditContactPerson
8 | com.amos2020.javabackend.entity.ContactPerson
9 | com.amos2020.javabackend.entity.FacCrit
10 | com.amos2020.javabackend.entity.Interview
11 | com.amos2020.javabackend.entity.InterviewContactPerson
12 | com.amos2020.javabackend.entity.Question
13 | com.amos2020.javabackend.entity.Scope
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/contact-persons/contact-persons.component.html:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 | Registrierte Kontaktpersonen ({{ contactPersons.length }})
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
Keine Kontaktpersonen registriert
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ng-frontend/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular-devkit/build-angular/plugins/karma'),
14 | ],
15 | client: {
16 | clearContext: false, // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, './coverage/ng-frontend'),
20 | reports: ['html', 'lcovonly', 'text-summary'],
21 | fixWebpackSourcePaths: true,
22 | },
23 | reporters: ['progress', 'kjhtml'],
24 | port: 9876,
25 | colors: true,
26 | logLevel: config.LOG_INFO,
27 | autoWatch: true,
28 | browsers: ['Chrome'],
29 | singleRun: false,
30 | restartOnFileChange: true,
31 | });
32 | };
33 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/interview/InterviewAddContactPersonRequest.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.request.interview;
2 |
3 | import com.amos2020.javabackend.rest_service.request.BasicRequest;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import lombok.Getter;
6 | import lombok.Setter;
7 |
8 | import javax.validation.constraints.Min;
9 | import javax.validation.constraints.NotBlank;
10 | import javax.validation.constraints.NotNull;
11 | import javax.validation.constraints.Size;
12 |
13 | /**
14 | * Request object for adding an existing contact person to an existing interview.
15 | */
16 | public class InterviewAddContactPersonRequest extends BasicRequest {
17 |
18 | @Getter
19 | @Setter
20 | @NotNull
21 | @Min(1)
22 | @Schema(type = "Integer", name = "contactPersonId", example = "1", required = true)
23 | private int contactPersonId;
24 |
25 | @Getter
26 | @Setter
27 | @NotNull
28 | @NotBlank
29 | @Size(max = MAX_NAME_LENGTH)
30 | @Schema(type = "String", name = "role", example = "Software architect", required = true)
31 | private String role;
32 | }
33 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/response/BasicFacCritResponse.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.response;
2 |
3 | import com.amos2020.javabackend.entity.FacCrit;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import lombok.Getter;
6 | import lombok.Setter;
7 |
8 | public class BasicFacCritResponse {
9 | @Getter
10 | @Setter
11 | @Schema(type = "Integer", name = "id", example = "15")
12 | private int id;
13 | @Getter
14 | @Setter
15 | @Schema(type = "Integer", name = "referenceId", example = "3")
16 | private Integer referenceId;
17 | @Getter
18 | @Setter
19 | @Schema(type = "String", name = "name", example = "Nützlichkeit")
20 | private String name;
21 | @Getter
22 | @Setter
23 | @Schema(type = "String", name = "goal", example = "Das Ziel dieses Kriteriums ist....")
24 | private String goal;
25 |
26 | public BasicFacCritResponse(){
27 | //empty
28 | }
29 |
30 | public BasicFacCritResponse(FacCrit facCrit) {
31 | this.id = facCrit.getId();
32 | this.referenceId = facCrit.getReferenceId();
33 | this.name = facCrit.getName();
34 | this.goal = facCrit.getGoal();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/forms/abstract-form-component.ts:
--------------------------------------------------------------------------------
1 | import { NbDialogService } from '@nebular/theme';
2 | import { FormGroup } from '@angular/forms';
3 | import { ConfirmDiscardDialogComponent } from '../dialogs/confirm-discard-dialog/confirm-discard-dialog.component';
4 | import { Output, EventEmitter, Input } from '@angular/core';
5 |
6 | export abstract class AbstractFormComponent {
7 | @Input() submitButtonName: string;
8 | @Input() cancelButtonName: string;
9 | @Output() cancelled = new EventEmitter();
10 |
11 | formGroup: FormGroup;
12 |
13 | constructor(protected dialogService: NbDialogService) {}
14 |
15 | onCancel() {
16 | if (this.formGroup.dirty && this.formGroup.touched) {
17 | const confirmDiscardComponentRef = this.dialogService.open(ConfirmDiscardDialogComponent, {
18 | autoFocus: false,
19 | closeOnBackdropClick: false,
20 | });
21 |
22 | confirmDiscardComponentRef.componentRef.instance.onDiscardConfirm.subscribe(
23 | (cancelConfirmed: boolean) => {
24 | if (cancelConfirmed) {
25 | this.cancelled.emit();
26 | }
27 | },
28 | );
29 | } else {
30 | this.cancelled.emit();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/test/dummies/contact-persons.ts:
--------------------------------------------------------------------------------
1 | import { ContactPerson, Salutation } from 'src/app/core/data/models/contact-person.model';
2 |
3 | export const CONTACTPERSON_DTO_DUMMY: ContactPerson[] = [
4 | {
5 | id: 1,
6 | role: 'Default Role',
7 | salutation: Salutation.Herr,
8 | title: 'string',
9 | forename: 'string',
10 | surname: 'string',
11 | contactInformation: 'string',
12 | companyName: 'string',
13 | department: 'string',
14 | sector: 'string',
15 | corporateDivision: 'string',
16 | },
17 | {
18 | id: 2,
19 | role: 'Default Role',
20 | salutation: Salutation.Herr,
21 | title: 'string',
22 | forename: 'string',
23 | surname: 'string',
24 | contactInformation: 'string',
25 | companyName: 'string',
26 | department: 'string',
27 | sector: 'string',
28 | corporateDivision: 'string',
29 | },
30 | {
31 | id: 3,
32 | role: 'Default Role',
33 | salutation: Salutation.Herr,
34 | title: 'string',
35 | forename: 'string',
36 | surname: 'string',
37 | contactInformation: 'string',
38 | companyName: 'string',
39 | department: 'string',
40 | sector: 'string',
41 | corporateDivision: 'string',
42 | },
43 | ];
44 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-info/audit-contact-person-card/contact-person-card.component.html:
--------------------------------------------------------------------------------
1 |
2 | {{ contactPerson.forename + ' ' + contactPerson.surname }}
3 |
4 |
5 |
26 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { RouterModule, Routes } from '@angular/router';
3 | import { NotFoundComponent } from './core/not-found/not-found.component';
4 | import { SharedModule } from './shared/shared.module';
5 |
6 | const routes: Routes = [
7 | { path: '', pathMatch: 'full', redirectTo: 'audits' },
8 | {
9 | path: 'audits',
10 | loadChildren: () => import('./features/audits/audits.module').then(m => m.AuditsModule),
11 | },
12 | {
13 | path: 'audits/:auditId',
14 | loadChildren: () =>
15 | import('./features/audit-overview/audit-overview.module').then(m => m.AuditOverviewModule),
16 | },
17 | {
18 | path: 'contact-persons',
19 | loadChildren: () =>
20 | import('./features/contact-persons/contact-persons.module').then(m => m.ContactPersonsModule),
21 | },
22 | {
23 | path: 'audits/:auditId/interviews/:interviewId/:facCritId',
24 | loadChildren: () =>
25 | import('./features/interview/interview.module').then(m => m.InterviewModule),
26 | },
27 | { path: '**', component: NotFoundComponent },
28 | ];
29 |
30 | @NgModule({
31 | declarations: [],
32 | imports: [RouterModule.forRoot(routes), SharedModule],
33 | exports: [RouterModule],
34 | })
35 | export class AppRouterModule {}
36 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/entity/ScopePK.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.entity;
2 |
3 | import javax.persistence.Column;
4 | import javax.persistence.Id;
5 | import java.io.Serializable;
6 |
7 | public class ScopePK implements Serializable {
8 | private int auditId;
9 | private int faccritId;
10 |
11 | @Column(name = "audit_id")
12 | @Id
13 | public int getAuditId() {
14 | return auditId;
15 | }
16 |
17 | public void setAuditId(int auditId) {
18 | this.auditId = auditId;
19 | }
20 |
21 | @Column(name = "faccrit_id")
22 | @Id
23 | public int getFaccritId() {
24 | return faccritId;
25 | }
26 |
27 | public void setFaccritId(int faccritId) {
28 | this.faccritId = faccritId;
29 | }
30 |
31 | @Override
32 | public boolean equals(Object o) {
33 | if (this == o) return true;
34 | if (o == null || getClass() != o.getClass()) return false;
35 |
36 | ScopePK scopePK = (ScopePK) o;
37 |
38 | if (auditId != scopePK.auditId) return false;
39 | return faccritId == scopePK.faccritId;
40 | }
41 |
42 | @Override
43 | public int hashCode() {
44 | int result = auditId;
45 | result = 31 * result + faccritId;
46 | return result;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/styles/reset.css:
--------------------------------------------------------------------------------
1 | /* http://meyerweb.com/eric/tools/css/reset/
2 | v2.0 | 20110126
3 | License: none (public domain)
4 | */
5 |
6 | html, body, div, span, applet, object, iframe,
7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8 | a, abbr, acronym, address, big, cite, code,
9 | del, dfn, em, img, ins, kbd, q, s, samp,
10 | small, strike, strong, sub, sup, tt, var,
11 | b, u, i, center,
12 | dl, dt, dd, ol, ul, li,
13 | fieldset, form, label, legend,
14 | table, caption, tbody, tfoot, thead, tr, th, td,
15 | article, aside, canvas, details, embed,
16 | figure, figcaption, footer, header, hgroup,
17 | menu, nav, output, ruby, section, summary,
18 | time, mark, audio, video {
19 | margin: 0;
20 | padding: 0;
21 | border: 0;
22 | font-size: 100%;
23 | font: inherit;
24 | vertical-align: baseline;
25 | }
26 | /* HTML5 display-role reset for older browsers */
27 | article, aside, details, figcaption, figure,
28 | footer, header, hgroup, menu, nav, section {
29 | display: block;
30 | }
31 | body {
32 | line-height: 1;
33 | }
34 | ol, ul {
35 | list-style: none;
36 | }
37 | blockquote, q {
38 | quotes: none;
39 | }
40 | blockquote:before, blockquote:after,
41 | q:before, q:after {
42 | content: '';
43 | content: none;
44 | }
45 | table {
46 | border-collapse: collapse;
47 | border-spacing: 0;
48 | }
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-overview.component.html:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/test/question.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
3 | import { environment } from 'src/environments/environment';
4 | import { QuestionService } from '../question.service';
5 | import { Question } from '../../data/models/question.model';
6 | import { QUESTIONS_DTO_DUMMY } from './dummies/questions';
7 |
8 | describe('QuestionService', () => {
9 | let service: QuestionService;
10 | let httpMock: HttpTestingController;
11 |
12 | beforeEach(() => {
13 | TestBed.configureTestingModule({
14 | imports: [HttpClientTestingModule],
15 | providers: [QuestionService],
16 | });
17 |
18 | service = TestBed.inject(QuestionService);
19 | httpMock = TestBed.inject(HttpTestingController);
20 | });
21 |
22 | it('#getQuestion should return an observable of a question', () => {
23 | const questionDto: Question = QUESTIONS_DTO_DUMMY[0];
24 | service.getQuestion(1).subscribe(question => {
25 | expect(question).toEqual(questionDto);
26 | });
27 |
28 | const req = httpMock.expectOne(environment.baseUrl + 'questions/1');
29 | expect(req.request.method).toEqual('GET');
30 |
31 | req.flush(questionDto);
32 | httpMock.verify();
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/test/dummies/answers.ts:
--------------------------------------------------------------------------------
1 | import { Answer } from 'src/app/core/data/models/answer.model';
2 |
3 | export const ANSWERS_DTO_DUMMY: Answer[] = [
4 | {
5 | questionId: 1,
6 | interviewId: 2,
7 | faccritId: 3,
8 | annotation: 'Some annotation',
9 | proof: 'Some proof',
10 | reason: 'Some reason',
11 | procedure: true,
12 | documentation: true,
13 | responsible: true,
14 | result: true,
15 | },
16 | {
17 | questionId: 3,
18 | interviewId: 4,
19 | faccritId: 5,
20 | annotation: 'Some annotation',
21 | proof: 'Some proof',
22 | reason: 'Some reason',
23 | procedure: true,
24 | documentation: true,
25 | responsible: true,
26 | result: true,
27 | },
28 | {
29 | questionId: 6,
30 | interviewId: 7,
31 | faccritId: 8,
32 | annotation: 'Some annotation',
33 | proof: 'Some proof',
34 | reason: 'Some reason',
35 | procedure: true,
36 | documentation: true,
37 | responsible: true,
38 | result: true,
39 | },
40 | {
41 | questionId: 12,
42 | interviewId: 123,
43 | faccritId: 321,
44 | annotation: 'Some annotation',
45 | proof: 'Some proof',
46 | reason: 'Some reason',
47 | procedure: true,
48 | documentation: true,
49 | responsible: true,
50 | result: true,
51 | },
52 | ];
53 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/audit/DeleteAuditRequest.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.request.audit;
2 |
3 | import com.amos2020.javabackend.Constants;
4 | import com.amos2020.javabackend.rest_service.request.BasicRequest;
5 | import io.swagger.v3.oas.annotations.media.Schema;
6 | import lombok.Getter;
7 | import lombok.Setter;
8 |
9 | import javax.validation.constraints.Min;
10 | import javax.validation.constraints.NotBlank;
11 | import javax.validation.constraints.NotNull;
12 | import javax.validation.constraints.Size;
13 | import java.sql.Date;
14 | /**
15 | * Request object for deleting an audit
16 | */
17 | public class DeleteAuditRequest extends BasicRequest {
18 | @Getter
19 | @Setter
20 | @NotNull
21 | @Size(min = 1, max = Constants.NAME_LENGTH)
22 | @NotBlank
23 | @Schema(type = "String", name = "reason", example = "Client canceled the audit", required = true)
24 | private String reason;
25 |
26 | @Getter
27 | @Setter
28 | @Min(1)
29 | @NotNull
30 | @Schema(type = "Integer", name = "contactPerson", example = "1", required = true)
31 | private Integer contactPerson;
32 |
33 | @Getter
34 | @Setter
35 | @NotNull
36 | @Schema(type = "string", name = "date", format = "date", required = true)
37 | private Date date;
38 | }
--------------------------------------------------------------------------------
/ng-frontend/documentation/js/libs/innersvg.js:
--------------------------------------------------------------------------------
1 | /**
2 | * innerHTML property for SVGElement
3 | * Copyright(c) 2010, Jeff Schiller
4 | *
5 | * Licensed under the Apache License, Version 2
6 | *
7 | * Minor modifications by Chris Price to only polyfill when required.
8 | */
9 | !function(e){if(e&&!("innerHTML"in e.prototype)){var t=function(e,r){var i=e.nodeType;if(3==i)r.push(e.textContent.replace(/&/,"&").replace(/,"<").replace(">",">"));else if(1==i){if(r.push("<",e.tagName),e.hasAttributes())for(var n=e.attributes,s=0,o=n.length;s");for(var h=e.childNodes,s=0,o=h.length;s")}else r.push("/>")}else{if(8!=i)throw"Error serializing XML. Unhandled node of type: "+i;r.push("\x3c!--",e.nodeValue,"--\x3e")}};Object.defineProperty(e.prototype,"innerHTML",{get:function(){for(var e=[],r=this.firstChild;r;)t(r,e),r=r.nextSibling;return e.join("")},set:function(e){for(;this.firstChild;)this.removeChild(this.firstChild);try{var t=new DOMParser;t.async=!1,sXML="";for(var r=t.parseFromString(sXML,"text/xml").documentElement.firstChild;r;)this.appendChild(this.ownerDocument.importNode(r,!0)),r=r.nextSibling}catch(e){throw new Error("Error parsing XML string")}}})}}((0,eval)("this").SVGElement);
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Oscar Rosner
4 | Copyright (c) 2020 Sebastian Kuhn
5 | Copyright (c) 2020 Cathy Hu
6 | Copyright (c) 2020 Dennis Possart
7 | Copyright (c) 2020 David Leicht
8 | Copyright (c) 2020 Benjamin Zenke
9 | Copyright (c) 2020 Markus Goller
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining a copy
12 | of this software and associated documentation files (the "Software"), to deal
13 | in the Software without restriction, including without limitation the rights
14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | copies of the Software, and to permit persons to whom the Software is
16 | furnished to do so, subject to the following conditions:
17 |
18 | The above copyright notice and this permission notice shall be included in all
19 | copies or substantial portions of the Software.
20 |
21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | SOFTWARE.
28 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/entity/AnswerPK.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.entity;
2 |
3 | import javax.persistence.Column;
4 | import javax.persistence.Id;
5 | import java.io.Serializable;
6 |
7 | public class AnswerPK implements Serializable {
8 | private int questionId;
9 | private int interviewId;
10 |
11 | @Column(name = "question_id")
12 | @Id
13 | public int getQuestionId() {
14 | return questionId;
15 | }
16 |
17 | public void setQuestionId(int questionId) {
18 | this.questionId = questionId;
19 | }
20 |
21 | @Column(name = "interview_id")
22 | @Id
23 | public int getInterviewId() {
24 | return interviewId;
25 | }
26 |
27 | public void setInterviewId(int interviewId) {
28 | this.interviewId = interviewId;
29 | }
30 |
31 | @Override
32 | public boolean equals(Object o) {
33 | if (this == o) return true;
34 | if (o == null || getClass() != o.getClass()) return false;
35 |
36 | AnswerPK answerPK = (AnswerPK) o;
37 |
38 | if (questionId != answerPK.questionId) return false;
39 | return interviewId == answerPK.interviewId;
40 | }
41 |
42 | @Override
43 | public int hashCode() {
44 | int result = questionId;
45 | result = 31 * result + interviewId;
46 | return result;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/styles/stripe.css:
--------------------------------------------------------------------------------
1 | .navbar-default .navbar-brand {
2 | color: #0099e5;
3 | }
4 |
5 | .menu ul.list li a[data-type="chapter-link"], .menu ul.list li.chapter .simple {
6 | color: #939da3;
7 | text-transform: uppercase;
8 | }
9 |
10 | .content h1, .content h2, .content h3, .content h4, .content h5 {
11 | color: #292e31;
12 | font-weight: normal;
13 | }
14 |
15 | .content {
16 | color: #4c555a;
17 | }
18 |
19 | .menu ul.list li.title {
20 | padding: 5px 0;
21 | }
22 |
23 | a {
24 | color: #0099e5;
25 | text-decoration: none;
26 | }
27 | a:hover {
28 | color: #292e31;
29 | text-decoration: none;
30 | }
31 |
32 | .menu ul.list li:nth-child(2) {
33 | margin-top: 0;
34 | }
35 |
36 | .menu ul.list li.title a, .navbar a {
37 | color: #0099e5;
38 | text-decoration: none;
39 | font-size: 16px;
40 | }
41 |
42 | .menu ul.list li a.active {
43 | color: #0099e5;
44 | }
45 |
46 | code {
47 | box-sizing: border-box;
48 | display: inline-block;
49 | padding: 0 5px;
50 | background: #fafcfc;
51 | border-radius: 4px;
52 | color: #b93d6a;
53 | font-size: 13px;
54 | line-height: 20px
55 | }
56 |
57 | pre {
58 | margin: 0;
59 | padding: 12px 12px;
60 | background: #272b2d;
61 | border-radius: 5px;
62 | font-size: 13px;
63 | line-height: 1.5em;
64 | font-weight: 500
65 | }
66 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audits/audit-card/audit-card.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../../sass/utils';
2 | @import '../../../../../node_modules/@nebular/theme/styles/theming';
3 | @import '../../../../../node_modules/@nebular/theme/styles/themes/default';
4 |
5 | nb-card-header {
6 | display: grid;
7 | grid-template-columns: auto 1fr auto;
8 | align-items: center;
9 | gap: 0 10px;
10 | }
11 |
12 | nb-card {
13 | position: relative;
14 | margin-bottom: 10px;
15 | cursor: pointer;
16 | }
17 |
18 | a {
19 | text-decoration: none;
20 | }
21 |
22 | .banner-status {
23 | position: absolute;
24 | top: 0;
25 | left: 0;
26 | bottom: 0;
27 | height: 100%;
28 | width: 12px;
29 | -webkit-box-shadow: 3px 0px 3px 0px rgba(44, 51, 73, 0.1);
30 | -moz-box-shadow: 3px 0px 3px 0px rgba(44, 51, 73, 0.1);
31 | box-shadow: 3px 0px 3px 0px rgba(44, 51, 73, 0.1);
32 | border-bottom-left-radius: nb-theme(card-border-radius);
33 | border-top-left-radius: nb-theme(card-border-radius);
34 | }
35 |
36 | .banner-status-is-planned {
37 | background-color: nb-theme(color-basic-100);
38 | }
39 |
40 | .banner-status-in-action {
41 | background-color: nb-theme(color-warning-default);
42 | }
43 |
44 | .banner-status-is-finished {
45 | background-color: nb-theme(color-success-default);
46 | }
47 |
48 | .banner-status-is-canceled {
49 | background-color: nb-theme(color-danger-default);
50 | }
51 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-info/audit-info.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/entity/AuditContactPersonPK.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.entity;
2 |
3 | import javax.persistence.Column;
4 | import javax.persistence.Id;
5 | import java.io.Serializable;
6 |
7 | public class AuditContactPersonPK implements Serializable {
8 | private int auditId;
9 | private int contactPersonId;
10 |
11 | @Column(name = "audit_id")
12 | @Id
13 | public int getAuditId() {
14 | return auditId;
15 | }
16 |
17 | public void setAuditId(int auditId) {
18 | this.auditId = auditId;
19 | }
20 |
21 | @Column(name = "contact_person_id")
22 | @Id
23 | public int getContactPersonId() {
24 | return contactPersonId;
25 | }
26 |
27 | public void setContactPersonId(int contactPersonId) {
28 | this.contactPersonId = contactPersonId;
29 | }
30 |
31 | @Override
32 | public boolean equals(Object o) {
33 | if (this == o) return true;
34 | if (o == null || getClass() != o.getClass()) return false;
35 |
36 | AuditContactPersonPK that = (AuditContactPersonPK) o;
37 |
38 | if (auditId != that.auditId) return false;
39 | return contactPersonId == that.contactPersonId;
40 | }
41 |
42 | @Override
43 | public int hashCode() {
44 | int result = auditId;
45 | result = 31 * result + contactPersonId;
46 | return result;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-overview-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 | import { AuditOverviewComponent } from './audit-overview.component';
4 | import { AddInterviewDialogComponent } from '../../shared/components/dialogs/add-interview-dialog/add-interview-dialog.component';
5 | import { InterviewListComponent } from './interview-list/interview-list.component';
6 | import { AuditInfoComponent } from './audit-info/audit-info.component';
7 | import { EditAuditDialogComponent } from 'src/app/shared/components/dialogs/edit-audit-dialog/edit-audit-dialog.component';
8 |
9 | const routes: Routes = [
10 | {
11 | path: '',
12 | component: AuditOverviewComponent,
13 | children: [
14 | {
15 | path: '',
16 | redirectTo: 'interviews',
17 | pathMatch: 'full',
18 | },
19 | {
20 | path: 'interviews',
21 | component: InterviewListComponent,
22 | children: [{ path: 'new', component: AddInterviewDialogComponent }],
23 | },
24 | {
25 | path: 'contact-persons',
26 | component: AuditInfoComponent,
27 | children: [{ path: 'edit', component: EditAuditDialogComponent }],
28 | },
29 | ],
30 | },
31 | ];
32 |
33 | @NgModule({
34 | imports: [RouterModule.forChild(routes)],
35 | exports: [RouterModule],
36 | })
37 | export class AuditOverviewRoutingModule {}
38 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/entity/InterviewContactPersonPK.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.entity;
2 |
3 | import javax.persistence.Column;
4 | import javax.persistence.Id;
5 | import java.io.Serializable;
6 |
7 | public class InterviewContactPersonPK implements Serializable {
8 | private int interviewId;
9 | private int contactpersonId;
10 |
11 | @Column(name = "interview_id")
12 | @Id
13 | public int getInterviewId() {
14 | return interviewId;
15 | }
16 |
17 | public void setInterviewId(int interviewId) {
18 | this.interviewId = interviewId;
19 | }
20 |
21 | @Column(name = "contact_person_id")
22 | @Id
23 | public int getContactPersonId() {
24 | return contactpersonId;
25 | }
26 |
27 | public void setContactPersonId(int contactPersonId) {
28 | this.contactpersonId = contactPersonId;
29 | }
30 |
31 | @Override
32 | public boolean equals(Object o) {
33 | if (this == o) return true;
34 | if (o == null || getClass() != o.getClass()) return false;
35 |
36 | InterviewContactPersonPK that = (InterviewContactPersonPK) o;
37 |
38 | if (interviewId != that.interviewId) return false;
39 | return contactpersonId == that.contactpersonId;
40 | }
41 |
42 | @Override
43 | public int hashCode() {
44 | int result = interviewId;
45 | result = 31 * result + contactpersonId;
46 | return result;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/contact-persons/contact-person-card/contact-person-card.component.html:
--------------------------------------------------------------------------------
1 |
9 |
30 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/interview-list/interview-list.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../../sass/utils';
2 | @import '../../../../../node_modules/@nebular/theme/styles/theming';
3 | @import '../../../../../node_modules/@nebular/theme/styles/themes/default';
4 |
5 | header {
6 | margin: 20px 0 10px 0;
7 | display: grid;
8 | justify-items: right;
9 | }
10 |
11 | nb-accordion {
12 | margin-bottom: 15px;
13 | }
14 |
15 | app-interview-card {
16 | position: relative;
17 | padding-left: 30px;
18 | }
19 |
20 | nb-card {
21 | margin-bottom: 0px;
22 | }
23 |
24 | li {
25 | margin-left: 20px;
26 | }
27 |
28 | nb-list-item {
29 | display: grid;
30 | }
31 |
32 | nb-accordion-item-header,
33 | nb-card-header {
34 | background: #f7f9fc !important;
35 | position: relative;
36 | }
37 |
38 | .banner-status {
39 | position: absolute;
40 | top: 0;
41 | left: 0;
42 | bottom: 0;
43 | height: 100%;
44 | width: 12px;
45 | -webkit-box-shadow: 3px 0px 3px 0px rgba(44, 51, 73, 0.1);
46 | -moz-box-shadow: 3px 0px 3px 0px rgba(44, 51, 73, 0.1);
47 | box-shadow: 3px 0px 3px 0px rgba(44, 51, 73, 0.1);
48 | }
49 |
50 | nb-card,
51 | nb-card-header {
52 | border: none !important;
53 | }
54 |
55 | .banner-status-in-action {
56 | background-color: nb-theme(color-warning-default);
57 | }
58 |
59 | .banner-status-is-finished {
60 | background-color: nb-theme(color-success-default);
61 | }
62 |
63 | .hint-no-interviews {
64 | margin: 0 auto;
65 | text-align: center;
66 | }
67 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/add-contact-person-dialog/add-contact-person-dialog.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ViewChild, TemplateRef } from '@angular/core';
2 | import { NbDialogRef, NbDialogService } from '@nebular/theme';
3 | import { Store } from '@ngxs/store';
4 | import { defaultDialogOptions } from '../default-dialog-options';
5 | import { Location } from '@angular/common';
6 | import { ContactPerson } from 'src/app/core/data/models/contact-person.model';
7 | import { AddContactPerson } from 'src/app/core/ngxs/actions/contact-person.action';
8 |
9 | @Component({
10 | selector: 'app-add-contact-person-dialog',
11 | templateUrl: './add-contact-person-dialog.component.html',
12 | styleUrls: ['./add-contact-person-dialog.component.scss'],
13 | })
14 | export class AddContactPersonDialogComponent {
15 | @ViewChild('dialog') dialog: TemplateRef;
16 | dialogRef: NbDialogRef;
17 |
18 | constructor(
19 | private dialogService: NbDialogService,
20 | private store: Store,
21 | private location: Location,
22 | ) {}
23 |
24 | ngAfterViewInit() {
25 | this.dialogRef = this.dialogService.open(this.dialog, defaultDialogOptions);
26 | this.dialogRef.onClose.subscribe(() => {
27 | this.location.back();
28 | });
29 | }
30 |
31 | onSubmit(contactPerson: ContactPerson) {
32 | this.store
33 | .dispatch(new AddContactPerson(contactPerson))
34 | .subscribe(() => this.dialogRef.close());
35 | }
36 |
37 | onCancel() {
38 | this.dialogRef.close();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/audit/UpdateAuditScopeRequest.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.request.audit;
2 |
3 | import com.amos2020.javabackend.Constants;
4 | import com.amos2020.javabackend.rest_service.request.BasicRequest;
5 | import io.swagger.v3.oas.annotations.media.Schema;
6 | import lombok.Getter;
7 | import lombok.Setter;
8 |
9 | import javax.validation.constraints.Min;
10 | import javax.validation.constraints.NotNull;
11 | import javax.validation.constraints.Size;
12 | /**
13 | * Request object for updating the scope of an existing audit
14 | */
15 | public class UpdateAuditScopeRequest extends BasicRequest {
16 | @Getter
17 | @Setter
18 | @NotNull
19 | @Min(message = "facccrit ID", value = 1)
20 | @Schema(type = "Integer", name = "facCritId", example = "1", required = true)
21 | private int facCritId;
22 |
23 | @Getter
24 | @Setter
25 | @Size(message = "change note", max = Constants.NOTE_LENGTH)
26 | @Schema(type = "String", name = "changeNote", example = "Change note for a scope item", required = true)
27 | private String changeNote;
28 |
29 | @Getter
30 | @Setter
31 | @NotNull
32 | @Schema(type = "boolean", name = "removed", example = "true", required = true)
33 | private boolean removed;
34 |
35 | @Getter
36 | @Setter
37 | @Size(message = "normal note", max = Constants.TEXT_LENGTH)
38 | @Schema(type = "String", name = "note", example = "Note for a scope item", required = true)
39 | private String note;
40 | }
41 |
--------------------------------------------------------------------------------
/.github/workflows/ng-frontend.yml:
--------------------------------------------------------------------------------
1 | name: Angular Frontend Build
2 | on:
3 | push:
4 | paths:
5 | - "ng-frontend/**"
6 | jobs:
7 | ubuntu-build:
8 | runs-on: ubuntu-16.04
9 | env:
10 | working-directory: ./ng-frontend
11 |
12 | strategy:
13 | matrix:
14 | node-version: [12.x]
15 |
16 | steps:
17 | - uses: actions/checkout@v2
18 | - name: Use Node.js ${{ matrix.node-version }}
19 | uses: actions/setup-node@v1
20 | with:
21 | node-version: ${{ matrix.node-version }}
22 |
23 | - name: Install Packages
24 | run: npm i
25 | working-directory: ${{env.working-directory}}
26 |
27 | - name: Install Angular CLI
28 | run: npm i -g @angular/cli
29 | working-directory: ${{env.working-directory}}
30 |
31 | - name: Run e2e Tests
32 | uses: cypress-io/github-action@v1
33 | with:
34 | working-directory: ${{env.working-directory}}
35 | browser: chrome
36 | headless: true
37 | start: ng serve
38 | wait-on: http://localhost:4200
39 | wait-on-timeout: 300
40 |
41 | - name: Run Unit Tests
42 | run: ng test --watch=false --browsers=ChromeHeadless
43 | working-directory: ${{env.working-directory}}
44 |
45 | - name: Deploy Documentation to GitHub Pages
46 | uses: JamesIves/github-pages-deploy-action@3.4.9
47 | with:
48 | ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
49 | branch: gh-pages
50 | folder: ng-frontend/documentation
51 |
--------------------------------------------------------------------------------
/ng-frontend/documentation/styles/laravel.css:
--------------------------------------------------------------------------------
1 | .navbar-default .navbar-brand {
2 | color: #f4645f;
3 | text-decoration: none;
4 | font-size: 16px;
5 | }
6 |
7 | .menu ul.list li a[data-type="chapter-link"], .menu ul.list li.chapter .simple {
8 | color: #525252;
9 | border-bottom: 1px dashed rgba(0,0,0,.1);
10 | }
11 |
12 | .content h1, .content h2, .content h3, .content h4, .content h5 {
13 | color: #292e31;
14 | font-weight: normal;
15 | }
16 |
17 | .content {
18 | color: #4c555a;
19 | }
20 |
21 | a {
22 | color: #f4645f;
23 | text-decoration: underline;
24 | }
25 | a:hover {
26 | color: #f1362f;
27 | }
28 |
29 | .menu ul.list li:nth-child(2) {
30 | margin-top: 0;
31 | }
32 |
33 | .menu ul.list li.title a {
34 | color: #f4645f;
35 | text-decoration: none;
36 | font-size: 16px;
37 | }
38 |
39 | .menu ul.list li a {
40 | color: #f4645f;
41 | text-decoration: none;
42 | }
43 | .menu ul.list li a.active {
44 | color: #f4645f;
45 | font-weight: bold;
46 | }
47 |
48 | code {
49 | box-sizing: border-box;
50 | display: inline-block;
51 | padding: 0 5px;
52 | background: #f0f2f1;
53 | border-radius: 3px;
54 | color: #b93d6a;
55 | font-size: 13px;
56 | line-height: 20px;
57 | box-shadow: 0 1px 1px rgba(0,0,0,.125);
58 | }
59 |
60 | pre {
61 | margin: 0;
62 | padding: 12px 12px;
63 | background: rgba(238,238,238,.35);
64 | border-radius: 3px;
65 | font-size: 13px;
66 | line-height: 1.5em;
67 | font-weight: 500;
68 | box-shadow: 0 1px 1px rgba(0,0,0,.125);
69 | }
70 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/service/QuestionService.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.service;
2 |
3 | import com.amos2020.javabackend.entity.Question;
4 | import com.amos2020.javabackend.repository.QuestionRepository;
5 | import javassist.NotFoundException;
6 | import org.springframework.stereotype.Service;
7 | import org.springframework.transaction.annotation.Transactional;
8 |
9 | import java.util.List;
10 | import java.util.Optional;
11 |
12 | @Service
13 | public class QuestionService {
14 | final QuestionRepository repository;
15 |
16 | public QuestionService(QuestionRepository repository) {
17 | this.repository = repository;
18 | }
19 |
20 | /**
21 | * Get a all Questions for a facCrit by the facCrit id
22 | *
23 | * @param faccritId int
24 | * @return List
25 | */
26 | @Transactional
27 | public List getQuestionsByFacCritId(int faccritId) {
28 | return repository.getQuestionsByFaccritId(faccritId);
29 | }
30 |
31 | /**
32 | * Get a question by id
33 | *
34 | * @param questionId int
35 | * @return Question
36 | * @throws NotFoundException If the question id is invalid and can not be found
37 | */
38 | public Question getQuestionById(int questionId) throws NotFoundException {
39 | Optional question = repository.findById(questionId);
40 | if (!question.isPresent()) {
41 | throw new NotFoundException("No question found with id " + question);
42 | }
43 | return question.get();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/test/dummies/questions.ts:
--------------------------------------------------------------------------------
1 | import { Question } from 'src/app/core/data/models/question.model';
2 |
3 | export const QUESTIONS_DTO_DUMMY: Question[] = [
4 | {
5 | id: 1,
6 | facCritId: 2,
7 | textDe:
8 | 'Werden konkrete Maßnahmen ergriffen, um das Qualitätskriterium in der Anwendung zu steigern?',
9 | },
10 | {
11 | id: 2,
12 | facCritId: 3,
13 | textDe:
14 | 'Werden konkrete Maßnahmen ergriffen, um das Qualitätskriterium in der Anwendung zu steigern?',
15 | },
16 | {
17 | id: 3,
18 | facCritId: 4,
19 | textDe:
20 | 'Werden konkrete Maßnahmen ergriffen, um das Qualitätskriterium in der Anwendung zu steigern?',
21 | },
22 | {
23 | id: 4,
24 | facCritId: 5,
25 | textDe:
26 | 'Werden konkrete Maßnahmen ergriffen, um das Qualitätskriterium in der Anwendung zu steigern?',
27 | },
28 | {
29 | id: 5,
30 | facCritId: 21,
31 | textDe:
32 | 'Werden konkrete Maßnahmen ergriffen, um das Qualitätskriterium in der Anwendung zu steigern?',
33 | },
34 | {
35 | id: 6,
36 | facCritId: 222,
37 | textDe:
38 | 'Werden konkrete Maßnahmen ergriffen, um das Qualitätskriterium in der Anwendung zu steigern?',
39 | },
40 | {
41 | id: 7,
42 | facCritId: 212,
43 | textDe:
44 | 'Werden konkrete Maßnahmen ergriffen, um das Qualitätskriterium in der Anwendung zu steigern?',
45 | },
46 | {
47 | id: 8,
48 | facCritId: 253,
49 | textDe:
50 | 'Werden konkrete Maßnahmen ergriffen, um das Qualitätskriterium in der Anwendung zu steigern?',
51 | },
52 | ];
53 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/http/answer.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 | import { Answer } from '../data/models/answer.model';
4 | import { Observable } from 'rxjs';
5 | import { environment } from 'src/environments/environment';
6 |
7 | @Injectable({
8 | providedIn: 'root',
9 | })
10 | export class AnswerService {
11 | constructor(private http: HttpClient) {}
12 |
13 | /**
14 | * Builds an observable for making a GET request to get all answers.
15 | */
16 | getAnswers(): Observable {
17 | const url = environment.baseUrl + 'answers';
18 | return this.http.get(url);
19 | }
20 |
21 | /**
22 | * Builds an observable for making a GET request to get answers by their interview id.
23 | *
24 | * @param id The interviews's id.
25 | * @returns An Observable of the answers.
26 | */
27 | getAnswersByInterviewId(interviewId: number): Observable {
28 | const url = environment.baseUrl + 'answers/interview/' + interviewId;
29 | return this.http.get(url);
30 | }
31 |
32 | /**
33 | * Builds an observable for making a POST request to update an answer.
34 | *
35 | * @param answer The updated answer.
36 | * @returns An Observable of the answers.
37 | */
38 | putAnswer(answer: Answer): Observable {
39 | const url =
40 | environment.baseUrl +
41 | 'answers/' +
42 | 'interview/' +
43 | answer.interviewId +
44 | '/question/' +
45 | answer.questionId;
46 |
47 | return this.http.put(url, answer);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/interview/UpdateInterviewRequest.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.request.interview;
2 |
3 | import com.amos2020.javabackend.entity.InterviewStatus;
4 | import com.amos2020.javabackend.rest_service.request.BasicRequest;
5 | import io.swagger.v3.oas.annotations.media.Schema;
6 | import lombok.Getter;
7 | import lombok.Setter;
8 |
9 | import javax.validation.constraints.NotBlank;
10 | import javax.validation.constraints.NotNull;
11 | import javax.validation.constraints.Size;
12 | import java.sql.Date;
13 | /**
14 | * Request object for updating an existing interview.
15 | */
16 | public class UpdateInterviewRequest extends BasicRequest {
17 |
18 | @Getter
19 | @Setter
20 | @NotNull
21 | @Schema(type = "string", name = "startDate", format = "date", required = true)
22 | private Date startDate;
23 | @Getter
24 | @Setter
25 | @Schema(type = "string", name = "endDate", format = "date", required = true)
26 | private Date endDate;
27 | @Getter
28 | @Setter
29 | @NotNull
30 | @Schema(type = "String", name = "status", example = "ACTIVE", required = true)
31 | private InterviewStatus status;
32 | @Getter
33 | @Setter
34 | @NotNull
35 | @Size(max = MAX_SMALL_TEXT_LENGTH)
36 | @Schema(type = "String", name = "note", example = "Some changed note", required = true)
37 | private String note;
38 |
39 | /**
40 | * Checks if provided startDate is before endDate
41 | */
42 | public void isValid() {
43 | assertDatesAreValid(startDate, endDate);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audits/audit-card/audit-card.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | {{ audit.name }}
11 | | {{ contactPerson.companyName }}
12 |
13 | {{ audit.startDate | date: 'dd.MM.yyyy' }} - {{ audit.endDate ? (audit.endDate | date: 'dd.MM.yyyy') : 'TBD' }}
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-overview.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 |
4 | import { AuditOverviewRoutingModule } from './audit-overview-routing.module';
5 | import { SharedModule } from 'src/app/shared/shared.module';
6 | import { AuditOverviewComponent } from './audit-overview.component';
7 | import { InterviewCardComponent } from './interview-list/interview-card/interview-card.component';
8 | import { ReactiveFormsModule, FormsModule } from '@angular/forms';
9 | import { InterviewListComponent } from './interview-list/interview-list.component';
10 | import { AuditInfoComponent } from './audit-info/audit-info.component';
11 | import { AuditContactPersonCardComponent } from './audit-info/audit-contact-person-card/contact-person-card.component';
12 | import { CriteriaByFactorIdPipe } from './interview-list/criteria-by-factor-id.pipe';
13 | import { InterviewsByFacCritIdPipe } from './interview-list/interviews-by-fac-crit-id.pipe';
14 | import { FinishedInterviewsCountPipe } from './interview-list/finished-interviews-count.pipe';
15 |
16 | @NgModule({
17 | declarations: [
18 | AuditOverviewComponent,
19 | InterviewCardComponent,
20 | AuditInfoComponent,
21 | FinishedInterviewsCountPipe,
22 | InterviewListComponent,
23 | AuditContactPersonCardComponent,
24 | CriteriaByFactorIdPipe,
25 | InterviewsByFacCritIdPipe,
26 | ],
27 | imports: [
28 | CommonModule,
29 | ReactiveFormsModule,
30 | FormsModule,
31 | AuditOverviewRoutingModule,
32 | SharedModule,
33 | ],
34 | })
35 | export class AuditOverviewModule {}
36 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/interview-list/interview-card/interview-card.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
19 |
20 |
21 |
22 | 0; else noContactPerson">
23 | {{ interview.contactPersons[0].forename + ' ' + interview.contactPersons[0].surname }}
24 | {{ interview.contactPersons[0].role }}
25 | 1"> | + {{ interview.contactPersons.length - 1 }}
26 |
27 |
28 | Keine Kontaktperson gewählt
29 |
30 | {{ interview.startDate | date: 'dd.MM.yyyy' }}
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/controller/FacCritController.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.controller;
2 |
3 | import com.amos2020.javabackend.entity.FacCrit;
4 | import com.amos2020.javabackend.rest_service.response.BasicFacCritResponse;
5 | import com.amos2020.javabackend.service.FacCritService;
6 | import org.springframework.stereotype.Service;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | @Service
12 | public class FacCritController {
13 |
14 | final FacCritService facCritService;
15 |
16 | public FacCritController(FacCritService facCritService) {
17 | this.facCritService = facCritService;
18 | }
19 |
20 | /**
21 | * Get all existing facCrits
22 | *
23 | * @return all facCrits
24 | */
25 | public List getAllFacCrits() {
26 | List responses = new ArrayList<>();
27 | for (FacCrit facCrit : facCritService.getAllFacCrits()) {
28 | responses.add(new BasicFacCritResponse(facCrit));
29 | }
30 | return responses;
31 | }
32 |
33 | /**
34 | * get all Faccrits for an Interview
35 | *
36 | * @param interviewId
37 | * @return List with Faccrits
38 | */
39 | public List getAllFacCritsByInterviewId(int interviewId){
40 | List responses = new ArrayList<>();
41 | List facCrits = facCritService.getAllFacCritsByInterviewId(interviewId);
42 | facCrits.forEach(facCrit -> responses.add(new BasicFacCritResponse(facCrit)));
43 | return responses;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/jszip-utils/dist/jszip-utils-ie.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 |
3 | JSZipUtils - A collection of cross-browser utilities to go along with JSZip.
4 |
5 |
6 | (c) 2014 Stuart Knightley, David Duponchel
7 | Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip-utils/master/LICENSE.markdown.
8 |
9 | */
10 | !function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g\r\n\r\n";document.write(b),a.JSZipUtils._getBinaryFromXHR=function(a){for(var b=a.responseBody,c={},d=0;256>d;d++)for(var e=0;256>e;e++)c[String.fromCharCode(d+(e<<8))]=String.fromCharCode(d)+String.fromCharCode(e);var f=IEBinaryToArray_ByteStr(b),g=IEBinaryToArray_ByteStr_Last(b);return f.replace(/[\s\S]/g,function(a){return c[a]})+g}},{}]},{},[1]);
11 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/request/audit/UpdateAuditRequest.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.request.audit;
2 |
3 | import com.amos2020.javabackend.entity.AuditStatus;
4 | import com.amos2020.javabackend.Constants;
5 | import com.amos2020.javabackend.rest_service.request.BasicRequest;
6 | import io.swagger.v3.oas.annotations.media.Schema;
7 | import lombok.Getter;
8 | import lombok.Setter;
9 |
10 | import javax.validation.constraints.NotBlank;
11 | import javax.validation.constraints.NotNull;
12 | import javax.validation.constraints.Size;
13 | import java.sql.Date;
14 |
15 | /**
16 | * Request object for updating an existing audit
17 | */
18 | public class UpdateAuditRequest extends BasicRequest {
19 | @Getter
20 | @Setter
21 | @NotNull
22 | @NotBlank
23 | @Size(min = 1, max = Constants.NAME_LENGTH)
24 | @Schema(type = "string", name = "name", example = "updated audit name", required = true)
25 | private String name;
26 | @Getter
27 | @Setter
28 | @NotNull
29 | @Schema(type = "string", name = "startDate", format = "date", required = true)
30 | private Date startDate;
31 | @Getter
32 | @Setter
33 | @Schema(type = "string", name = "endDate", format = "date")
34 | private Date endDate;
35 | @Getter
36 | @Setter
37 | @NotNull
38 | @Schema(type = "String", name = "status", example = "ACTIVE", required = true)
39 | private AuditStatus status;
40 |
41 | /**
42 | * Checks if provided startDate is before endDate
43 | */
44 | public void isValid() throws IllegalArgumentException {
45 | assertDatesAreValid(startDate, endDate);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/RestServiceExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend;
2 |
3 | import org.springframework.lang.Nullable;
4 | import org.springframework.stereotype.Component;
5 | import org.springframework.web.bind.annotation.ExceptionHandler;
6 | import org.springframework.web.bind.annotation.RestControllerAdvice;
7 | import org.springframework.web.servlet.ModelAndView;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 | import javax.servlet.http.HttpServletResponse;
11 | import javax.validation.ConstraintViolationException;
12 | import javax.validation.ValidationException;
13 | import java.io.IOException;
14 |
15 | @Component
16 | @RestControllerAdvice
17 | public class RestServiceExceptionHandler {
18 |
19 | @ExceptionHandler(value = ValidationException.class)
20 | protected ModelAndView handleValidationException(
21 | ValidationException ex, HttpServletRequest request, HttpServletResponse response, @Nullable Object handler)
22 | throws IOException {
23 | System.out.println("In CustomExceptionHandlerResolver");
24 | response.sendError(HttpServletResponse.SC_BAD_REQUEST);
25 | return new ModelAndView();
26 | }
27 |
28 | @ExceptionHandler(value = ConstraintViolationException.class)
29 | protected ModelAndView handleConstraintViolationException(
30 | ConstraintViolationException ex, HttpServletRequest request, HttpServletResponse response, @Nullable Object handler)
31 | throws IOException {
32 | System.out.println("In CustomExceptionHandlerResolver");
33 | response.sendError(HttpServletResponse.SC_BAD_REQUEST);
34 | return new ModelAndView();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/response/BasicScopeResponse.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.response;
2 |
3 |
4 | import com.amos2020.javabackend.entity.Scope;
5 | import io.swagger.v3.oas.annotations.media.Schema;
6 | import lombok.Getter;
7 | import lombok.Setter;
8 |
9 | public class BasicScopeResponse {
10 |
11 | @Getter
12 | @Setter
13 | @Schema(type = "Integer", name = "auditId", example = "123456")
14 | private int auditId;
15 | @Getter
16 | @Setter
17 | @Schema(type = "Integer", name = "facCritId", example = "123456")
18 | private int facCritId;
19 | @Getter
20 | @Setter
21 | @Schema(type = "boolean", name = "removed", example = "true")
22 | private boolean removed;
23 | @Getter
24 | @Setter
25 | @Schema(type = "String", name = "change_note", example = "Some change note")
26 | private String change_note;
27 | @Getter
28 | @Setter
29 | @Schema(type = "String", name = "note", example = "Some note")
30 | private String note;
31 |
32 | public BasicScopeResponse() {
33 | //empty constructor
34 | }
35 |
36 | public BasicScopeResponse(int auditId, int facCritId, boolean removed, String change_note, String note) {
37 | this.auditId = auditId;
38 | this.facCritId = facCritId;
39 | this.removed = removed;
40 | this.change_note = change_note;
41 | this.note = note;
42 | }
43 |
44 | public BasicScopeResponse(Scope scope) {
45 | this.auditId = scope.getAuditId();
46 | this.facCritId = scope.getFaccritId();
47 | this.removed = scope.getRemoved();
48 | this.change_note = scope.getChangeNote();
49 | this.note = scope.getNote();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/dialogs/add-audit-dialog/add-audit-dialog.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ViewChild, TemplateRef, AfterViewInit } from '@angular/core';
2 | import { NbDialogRef, NbDialogService } from '@nebular/theme';
3 | import { Store, Select } from '@ngxs/store';
4 | import { defaultDialogOptions } from '../default-dialog-options';
5 | import { Audit } from 'src/app/core/data/models/audit.model';
6 | import { AddAudit } from 'src/app/core/ngxs/actions/audit.actions';
7 | import { Location } from '@angular/common';
8 | import { Observable } from 'rxjs';
9 | import { ContactPerson } from 'src/app/core/data/models/contact-person.model';
10 | import { ContactPersonState } from 'src/app/core/ngxs/contact-person.state';
11 |
12 | @Component({
13 | selector: 'app-add-audit-dialog',
14 | templateUrl: './add-audit-dialog.component.html',
15 | styleUrls: ['./add-audit-dialog.component.scss'],
16 | })
17 | export class AddAuditDialogComponent implements AfterViewInit {
18 | @ViewChild('dialog') dialog: TemplateRef;
19 | @Select(ContactPersonState.contactPersons) contactPersons$: Observable;
20 | dialogRef: NbDialogRef;
21 |
22 | constructor(
23 | private dialogService: NbDialogService,
24 | private store: Store,
25 | private location: Location,
26 | ) {}
27 |
28 | ngAfterViewInit() {
29 | this.dialogRef = this.dialogService.open(this.dialog, {
30 | ...defaultDialogOptions,
31 | autoFocus: true,
32 | });
33 | this.dialogRef.onClose.subscribe(() => {
34 | this.location.back();
35 | });
36 | }
37 |
38 | onSubmit(audit: Audit) {
39 | this.store.dispatch(new AddAudit(audit)).subscribe(() => this.dialogRef.close());
40 | }
41 |
42 | onCancel() {
43 | this.dialogRef.close();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/java-backend/src/main/java/com/amos2020/javabackend/rest_service/response/BasicContactPersonResponse.java:
--------------------------------------------------------------------------------
1 | package com.amos2020.javabackend.rest_service.response;
2 |
3 | import com.amos2020.javabackend.entity.ContactPerson;
4 | import com.amos2020.javabackend.entity.Salutation;
5 | import lombok.Getter;
6 | import lombok.Setter;
7 |
8 | public class BasicContactPersonResponse {
9 | @Getter
10 | @Setter
11 | private int id;
12 | @Getter
13 | @Setter
14 | private Salutation salutation;
15 | @Getter
16 | @Setter
17 | private String title;
18 | @Getter
19 | @Setter
20 | private String forename;
21 | @Getter
22 | @Setter
23 | private String surname;
24 | @Getter
25 | @Setter
26 | private String contactInformation;
27 | @Getter
28 | @Setter
29 | private String companyName;
30 | @Getter
31 | @Setter
32 | private String department;
33 | @Getter
34 | @Setter
35 | private String sector;
36 | @Getter
37 | @Setter
38 | private String corporateDivision;
39 |
40 | public BasicContactPersonResponse(ContactPerson contactperson) {
41 | this.id = contactperson.getId();
42 | this.salutation = contactperson.getSalutation();
43 | this.title = contactperson.getTitle();
44 | this.forename = contactperson.getForename();
45 | this.surname = contactperson.getSurname();
46 | this.companyName = contactperson.getCompanyName();
47 | this.department = contactperson.getDepartment();
48 | this.sector = contactperson.getSector();
49 | this.corporateDivision = contactperson.getCorporateDivision();
50 | this.contactInformation = contactperson.getContactInformation();
51 | }
52 |
53 | public BasicContactPersonResponse() {
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ng-frontend/cypress/fixtures/backend-mock-data/audits.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 123456,
4 | "name": "MSG project audit",
5 | "startDate": "2020-07-07",
6 | "endDate": "2020-07-07",
7 | "creationDate": "2020-07-07T10:23:34.169Z",
8 | "status": "ACTIVE",
9 | "scope": [
10 | { "id": 1, "referenceId": null, "name": "Effektivität" },
11 | {
12 | "id": 4,
13 | "referenceId": null,
14 | "name": "Risikofreiheit"
15 | },
16 | {
17 | "id": 20,
18 | "referenceId": 4,
19 | "name": "Verringerung der Risiken hinsichtlich Gesundheit und Sicherheit"
20 | },
21 | {
22 | "id": 21,
23 | "referenceId": 4,
24 | "name": "Verringerung der Umweltrisiken"
25 | }
26 | ],
27 | "contactPersons": [
28 | {
29 | "id": 1,
30 | "salutation": "HERR",
31 | "title": "Prof",
32 | "forename": "Max",
33 | "surname": "Mustermann",
34 | "contactInformation": "max.mustermann@gmx.de, tel: 0123456789",
35 | "companyName": "msg systems AG",
36 | "department": "Softwareentwicklung",
37 | "sector": "msg Public Sector",
38 | "corporateDivision": "Software"
39 | }
40 | ],
41 | "cancellationDate": "2020-07-07",
42 | "cancellationReason": "Project got canceled",
43 | "cancellationContactPerson": {
44 | "id": 1,
45 | "salutation": "HERR",
46 | "title": "Prof",
47 | "forename": "Max",
48 | "surname": "Mustermann",
49 | "contactInformation": "max.mustermann@gmx.de, tel: 0123456789",
50 | "companyName": "msg systems AG",
51 | "department": "Softwareentwicklung",
52 | "sector": "msg Public Sector",
53 | "corporateDivision": "Software"
54 | }
55 | }
56 | ]
57 |
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/jquery-ui.structure.min.css:
--------------------------------------------------------------------------------
1 | /*! jQuery UI - v1.12.1 - 2018-12-06
2 | * http://jqueryui.com
3 | * Copyright jQuery Foundation and other contributors; Licensed MIT */
4 |
5 | .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}
--------------------------------------------------------------------------------
/ng-frontend/documentation/js/lazy-load-graphs.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('DOMContentLoaded', function() {
2 | var lazyGraphs = [].slice.call(document.querySelectorAll('[lazy]'));
3 | var active = false;
4 |
5 | var lazyLoad = function() {
6 | if (active === false) {
7 | active = true;
8 |
9 | setTimeout(function() {
10 | lazyGraphs.forEach(function(lazyGraph) {
11 | if (
12 | lazyGraph.getBoundingClientRect().top <= window.innerHeight &&
13 | lazyGraph.getBoundingClientRect().bottom >= 0 &&
14 | getComputedStyle(lazyGraph).display !== 'none'
15 | ) {
16 | lazyGraph.data = lazyGraph.getAttribute('lazy');
17 | lazyGraph.removeAttribute('lazy');
18 |
19 | lazyGraphs = lazyGraphs.filter(function(image) { return image !== lazyGraph});
20 |
21 | if (lazyGraphs.length === 0) {
22 | document.removeEventListener('scroll', lazyLoad);
23 | window.removeEventListener('resize', lazyLoad);
24 | window.removeEventListener('orientationchange', lazyLoad);
25 | }
26 | }
27 | });
28 |
29 | active = false;
30 | }, 200);
31 | }
32 | };
33 |
34 | // initial load
35 | lazyLoad();
36 |
37 | var container = document.querySelector('.container-fluid.modules');
38 | if (container) {
39 | container.addEventListener('scroll', lazyLoad);
40 | window.addEventListener('resize', lazyLoad);
41 | window.addEventListener('orientationchange', lazyLoad);
42 | }
43 |
44 | });
45 |
--------------------------------------------------------------------------------
/java-backend/documentation/script-dir/jszip-utils/dist/jszip-utils.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 |
3 | JSZipUtils - A collection of cross-browser utilities to go along with JSZip.
4 |
5 |
6 | (c) 2014 Stuart Knightley, David Duponchel
7 | Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip-utils/master/LICENSE.markdown.
8 |
9 | */
10 | !function(a){"object"==typeof exports?module.exports=a():"function"==typeof define&&define.amd?define(a):"undefined"!=typeof window?window.JSZipUtils=a():"undefined"!=typeof global?global.JSZipUtils=a():"undefined"!=typeof self&&(self.JSZipUtils=a())}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g {
19 | let component: ContactPersonsComponent;
20 | let fixture: ComponentFixture;
21 |
22 | beforeEach(async(() => {
23 | TestBed.configureTestingModule({
24 | declarations: [ContactPersonsComponent],
25 | providers: [
26 | { provide: ContactPersonService, useValue: contactPersonServiceSpy },
27 | { provide: InterviewService, useValue: interviewServiceSpy },
28 | { provide: QuestionService, useValue: questionServiceSpy },
29 | { provide: FacCritService, useValue: facCritServiceSpy },
30 | { provide: AuditService, useValue: auditServiceSpy },
31 | ],
32 | }).compileComponents();
33 | }));
34 |
35 | beforeEach(() => {
36 | fixture = TestBed.createComponent(ContactPersonsComponent);
37 | component = fixture.componentInstance;
38 | fixture.detectChanges();
39 | });
40 |
41 | // it('should create', () => {
42 | // expect(component).toBeTruthy();
43 | // });
44 | });
45 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-overview.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Observable } from 'rxjs';
3 | import { Store, Select } from '@ngxs/store';
4 | import { Audit, AuditStatus } from 'src/app/core/data/models/audit.model';
5 | import { AuditState } from 'src/app/core/ngxs/audit.state';
6 | import { AppRouterState } from 'src/app/core/ngxs/app-router.state';
7 | import { UpdateAudit } from 'src/app/core/ngxs/actions/audit.actions';
8 | import { filter } from 'rxjs/operators';
9 |
10 | @Component({
11 | selector: 'app-audit-overview',
12 | templateUrl: './audit-overview.component.html',
13 | styleUrls: ['./audit-overview.component.scss'],
14 | })
15 | export class AuditOverviewComponent implements OnInit {
16 | @Select(AppRouterState.auditId) auditId$: Observable;
17 |
18 | auditStatuses = AuditStatus;
19 | selectedAuditStatus: AuditStatus;
20 | audit: Audit;
21 |
22 | tabs: any[] = [
23 | {
24 | title: 'Interviews',
25 | icon: 'attach-2-outline',
26 | route: './interviews',
27 | responsive: true,
28 | active: true,
29 | },
30 | {
31 | title: 'Kontakte',
32 | icon: 'person-outline',
33 | route: './contact-persons',
34 | responsive: true,
35 | },
36 | ];
37 |
38 | constructor(private store: Store) {}
39 |
40 | ngOnInit(): void {
41 | this.auditId$.subscribe(id => {
42 | this.store
43 | .select(AuditState.audit(id))
44 | .pipe(filter(audit => audit != undefined))
45 | .subscribe(a => {
46 | this.audit = a;
47 | this.selectedAuditStatus = a.status;
48 | });
49 | });
50 | }
51 |
52 | onStatusChange() {
53 | this.store.dispatch(
54 | new UpdateAudit(this.audit.id, { ...this.audit, status: this.selectedAuditStatus }),
55 | );
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audits/audits.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { AuditsComponent } from './audits.component';
2 | import { TestBed, ComponentFixture } from '@angular/core/testing';
3 | import { RouterModule } from '@angular/router';
4 | import { AppModule } from 'src/app/app.module';
5 | import { SharedModule } from 'src/app/shared/shared.module';
6 | import { ContactPersonService } from 'src/app/core/http/contact-person.service';
7 | import {
8 | contactPersonServiceSpy,
9 | interviewServiceSpy,
10 | questionServiceSpy,
11 | facCritServiceSpy,
12 | auditServiceSpy,
13 | } from 'src/app/core/ngxs/test/service-spies';
14 | import { InterviewService } from 'src/app/core/http/interview.service';
15 | import { QuestionService } from 'src/app/core/http/question.service';
16 | import { FacCritService } from 'src/app/core/http/facCrit.service';
17 | import { AuditService } from 'src/app/core/http/audit.service';
18 |
19 | describe('AuditListComponent', () => {
20 | let component: AuditsComponent;
21 | let fixture: ComponentFixture;
22 |
23 | beforeEach(() => {
24 | TestBed.configureTestingModule({
25 | declarations: [AuditsComponent],
26 | imports: [RouterModule.forRoot([]), SharedModule, AppModule],
27 | providers: [
28 | { provide: ContactPersonService, useValue: contactPersonServiceSpy },
29 | { provide: InterviewService, useValue: interviewServiceSpy },
30 | { provide: QuestionService, useValue: questionServiceSpy },
31 | { provide: FacCritService, useValue: facCritServiceSpy },
32 | { provide: AuditService, useValue: auditServiceSpy },
33 | ],
34 | });
35 |
36 | fixture = TestBed.createComponent(AuditsComponent);
37 | component = fixture.componentInstance;
38 | });
39 |
40 | it('should create', () => {
41 | expect(component).toBeTruthy();
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/ng-frontend/src/assets/images/logo-msg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/sidebar/sidebar.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 |
4 | import { SidebarComponent } from './sidebar.component';
5 | import { RouterModule } from '@angular/router';
6 | import { CoreModule } from '../core.module';
7 | import { ContactPersonService } from '../http/contact-person.service';
8 | import { InterviewService } from '../http/interview.service';
9 | import {
10 | contactPersonServiceSpy,
11 | interviewServiceSpy,
12 | questionServiceSpy,
13 | facCritServiceSpy,
14 | auditServiceSpy,
15 | } from '../ngxs/test/service-spies';
16 | import { QuestionService } from '../http/question.service';
17 | import { FacCritService } from '../http/facCrit.service';
18 | import { AuditService } from '../http/audit.service';
19 |
20 | describe('SidebarComponent', () => {
21 | let component: SidebarComponent;
22 | let fixture: ComponentFixture;
23 |
24 | beforeEach(async(() => {
25 | TestBed.configureTestingModule({
26 | declarations: [SidebarComponent],
27 | imports: [RouterModule.forRoot([]), CoreModule],
28 | providers: [
29 | { provide: ContactPersonService, useValue: contactPersonServiceSpy },
30 | { provide: InterviewService, useValue: interviewServiceSpy },
31 | { provide: QuestionService, useValue: questionServiceSpy },
32 | { provide: FacCritService, useValue: facCritServiceSpy },
33 | { provide: AuditService, useValue: auditServiceSpy },
34 | ],
35 | }).compileComponents();
36 | }));
37 |
38 | beforeEach(() => {
39 | fixture = TestBed.createComponent(SidebarComponent);
40 | component = fixture.componentInstance;
41 | fixture.detectChanges();
42 | });
43 |
44 | it('should create', () => {
45 | expect(component).toBeTruthy();
46 | });
47 | });
48 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/contact-persons/contact-person-card/contact-person-card.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 |
4 | import { ContactPersonCardComponent } from './contact-person-card.component';
5 | import { ContactPersonService } from 'src/app/core/http/contact-person.service';
6 | import {
7 | contactPersonServiceSpy,
8 | interviewServiceSpy,
9 | questionServiceSpy,
10 | facCritServiceSpy,
11 | auditServiceSpy,
12 | } from 'src/app/core/ngxs/test/service-spies';
13 | import { InterviewService } from 'src/app/core/http/interview.service';
14 | import { QuestionService } from 'src/app/core/http/question.service';
15 | import { FacCritService } from 'src/app/core/http/facCrit.service';
16 | import { AuditService } from 'src/app/core/http/audit.service';
17 |
18 | describe('ContactPersonCardComponent', () => {
19 | let component: ContactPersonCardComponent;
20 | let fixture: ComponentFixture;
21 |
22 | beforeEach(async(() => {
23 | TestBed.configureTestingModule({
24 | declarations: [ContactPersonCardComponent],
25 | providers: [
26 | { provide: ContactPersonService, useValue: contactPersonServiceSpy },
27 | { provide: InterviewService, useValue: interviewServiceSpy },
28 | { provide: QuestionService, useValue: questionServiceSpy },
29 | { provide: FacCritService, useValue: facCritServiceSpy },
30 | { provide: AuditService, useValue: auditServiceSpy },
31 | ],
32 | }).compileComponents();
33 | }));
34 |
35 | beforeEach(() => {
36 | fixture = TestBed.createComponent(ContactPersonCardComponent);
37 | component = fixture.componentInstance;
38 | fixture.detectChanges();
39 | });
40 |
41 | // it('should create', () => {
42 | // expect(component).toBeTruthy();
43 | // });
44 | });
45 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/interview/interview.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { InterviewComponent } from './interview.component';
4 | import { CoreModule } from 'src/app/core/core.module';
5 | import { RouterModule } from '@angular/router';
6 | import { ContactPersonService } from 'src/app/core/http/contact-person.service';
7 | import {
8 | contactPersonServiceSpy,
9 | interviewServiceSpy,
10 | questionServiceSpy,
11 | facCritServiceSpy,
12 | auditServiceSpy,
13 | } from 'src/app/core/ngxs/test/service-spies';
14 | import { InterviewService } from 'src/app/core/http/interview.service';
15 | import { QuestionService } from 'src/app/core/http/question.service';
16 | import { FacCritService } from 'src/app/core/http/facCrit.service';
17 | import { AuditService } from 'src/app/core/http/audit.service';
18 |
19 | describe('InterviewComponent', () => {
20 | let component: InterviewComponent;
21 | let fixture: ComponentFixture;
22 |
23 | beforeEach(async(() => {
24 | TestBed.configureTestingModule({
25 | declarations: [InterviewComponent],
26 | imports: [CoreModule, RouterModule.forRoot([])],
27 | providers: [
28 | { provide: ContactPersonService, useValue: contactPersonServiceSpy },
29 | { provide: InterviewService, useValue: interviewServiceSpy },
30 | { provide: QuestionService, useValue: questionServiceSpy },
31 | { provide: FacCritService, useValue: facCritServiceSpy },
32 | { provide: AuditService, useValue: auditServiceSpy },
33 | ],
34 | }).compileComponents();
35 | }));
36 |
37 | beforeEach(() => {
38 | fixture = TestBed.createComponent(InterviewComponent);
39 | component = fixture.componentInstance;
40 | fixture.detectChanges();
41 | });
42 |
43 | it('should create', () => {
44 | expect(component).toBeTruthy();
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audits/audit-card/audit-card.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { AuditCardComponent } from './audit-card.component';
4 | import { RouterModule } from '@angular/router';
5 | import { SharedModule } from 'src/app/shared/shared.module';
6 | import { CoreModule } from 'src/app/core/core.module';
7 | import { ContactPersonService } from 'src/app/core/http/contact-person.service';
8 | import {
9 | contactPersonServiceSpy,
10 | interviewServiceSpy,
11 | questionServiceSpy,
12 | facCritServiceSpy,
13 | auditServiceSpy,
14 | } from 'src/app/core/ngxs/test/service-spies';
15 | import { InterviewService } from 'src/app/core/http/interview.service';
16 | import { QuestionService } from 'src/app/core/http/question.service';
17 | import { FacCritService } from 'src/app/core/http/facCrit.service';
18 | import { AuditService } from 'src/app/core/http/audit.service';
19 |
20 | describe('AuditCardComponent', () => {
21 | let component: AuditCardComponent;
22 | let fixture: ComponentFixture;
23 |
24 | beforeEach(() => {
25 | TestBed.configureTestingModule({
26 | declarations: [AuditCardComponent],
27 | imports: [RouterModule.forRoot([]), SharedModule, CoreModule],
28 | providers: [
29 | { provide: ContactPersonService, useValue: contactPersonServiceSpy },
30 | { provide: InterviewService, useValue: interviewServiceSpy },
31 | { provide: QuestionService, useValue: questionServiceSpy },
32 | { provide: FacCritService, useValue: facCritServiceSpy },
33 | { provide: AuditService, useValue: auditServiceSpy },
34 | ],
35 | }).compileComponents();
36 |
37 | fixture = TestBed.createComponent(AuditCardComponent);
38 | component = fixture.componentInstance;
39 | });
40 |
41 | it('should create', () => {
42 | expect(component).toBeTruthy();
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/ngxs/test/dummies/audits.ts:
--------------------------------------------------------------------------------
1 | import { AuditStatus, Audit } from '../../../data/models/audit.model';
2 | import { Salutation } from '../../../data/models/contact-person.model';
3 |
4 | export const AUDITS_DUMMY: Audit[] = [
5 | {
6 | id: 1,
7 | name: 'MSG project audit',
8 | startDate: Date.now(),
9 | endDate: Date.now(),
10 | creationDate: Date.now(),
11 | status: AuditStatus.Active,
12 | scope: [
13 | {
14 | id: 2,
15 | referenceId: 3,
16 | goal: 'asd',
17 | name: 'Modifizierbarkeit',
18 | },
19 | ],
20 | contactPersons: [
21 | {
22 | id: 4,
23 | salutation: Salutation.Herr,
24 | title: 'Prof',
25 | forename: 'Max',
26 | role: 'asds',
27 | surname: 'Mustermann',
28 | contactInformation: 'max.mustermann@gmx.de, tel: 0123456789',
29 | companyName: 'msg systems AG',
30 | department: 'Softwareentwicklung',
31 | sector: 'msg Public Sector',
32 | corporateDivision: 'Software',
33 | },
34 | ],
35 | },
36 | {
37 | id: 2,
38 | name: 'MSG project audit',
39 | startDate: Date.now(),
40 | endDate: Date.now(),
41 | creationDate: Date.now(),
42 | status: AuditStatus.Active,
43 | scope: [
44 | {
45 | id: 2,
46 | referenceId: 12,
47 | name: 'Modifizierbarkeit',
48 | goal: 'asd',
49 | },
50 | ],
51 | contactPersons: [
52 | {
53 | id: 1,
54 | salutation: Salutation.Herr,
55 | title: 'Prof',
56 | forename: 'Max',
57 | role: 'asds',
58 | surname: 'Mustermann',
59 | contactInformation: 'max.mustermann@gmx.de, tel: 0123456789',
60 | companyName: 'msg systems AG',
61 | department: 'Softwareentwicklung',
62 | sector: 'msg Public Sector',
63 | corporateDivision: 'Software',
64 | },
65 | ],
66 | },
67 | ];
68 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/interview/answer-question-list/answer-question-list.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { AnswerQuestionListComponent } from './answer-question-list.component';
4 | import { CoreModule } from 'src/app/core/core.module';
5 | import { RouterModule } from '@angular/router';
6 | import { ContactPersonService } from 'src/app/core/http/contact-person.service';
7 | import {
8 | contactPersonServiceSpy,
9 | interviewServiceSpy,
10 | questionServiceSpy,
11 | facCritServiceSpy,
12 | auditServiceSpy,
13 | } from 'src/app/core/ngxs/test/service-spies';
14 | import { InterviewService } from 'src/app/core/http/interview.service';
15 | import { QuestionService } from 'src/app/core/http/question.service';
16 | import { FacCritService } from 'src/app/core/http/facCrit.service';
17 | import { AuditService } from 'src/app/core/http/audit.service';
18 |
19 | describe('AnswerQuestionListComponent', () => {
20 | let component: AnswerQuestionListComponent;
21 | let fixture: ComponentFixture;
22 |
23 | beforeEach(async(() => {
24 | TestBed.configureTestingModule({
25 | declarations: [AnswerQuestionListComponent],
26 | imports: [CoreModule, RouterModule.forRoot([])],
27 | providers: [
28 | { provide: ContactPersonService, useValue: contactPersonServiceSpy },
29 | { provide: InterviewService, useValue: interviewServiceSpy },
30 | { provide: QuestionService, useValue: questionServiceSpy },
31 | { provide: FacCritService, useValue: facCritServiceSpy },
32 | { provide: AuditService, useValue: auditServiceSpy },
33 | ],
34 | }).compileComponents();
35 | }));
36 |
37 | beforeEach(() => {
38 | fixture = TestBed.createComponent(AnswerQuestionListComponent);
39 | component = fixture.componentInstance;
40 | });
41 |
42 | it('should create', () => {
43 | expect(component).toBeTruthy();
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/core/sidebar/sidebar-interview/sidebar-interview.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { SidebarInterviewComponent } from './sidebar-interview.component';
4 | import { CoreModule } from 'src/app/core/core.module';
5 | import { RouterModule } from '@angular/router';
6 | import { SharedModule } from '../../../shared/shared.module';
7 | import { ContactPersonService } from '../../http/contact-person.service';
8 | import {
9 | contactPersonServiceSpy,
10 | interviewServiceSpy,
11 | questionServiceSpy,
12 | facCritServiceSpy,
13 | auditServiceSpy,
14 | } from '../../ngxs/test/service-spies';
15 | import { InterviewService } from '../../http/interview.service';
16 | import { QuestionService } from '../../http/question.service';
17 | import { FacCritService } from '../../http/facCrit.service';
18 | import { AuditService } from '../../http/audit.service';
19 |
20 | describe('SidebarInterviewComponent', () => {
21 | let component: SidebarInterviewComponent;
22 | let fixture: ComponentFixture;
23 |
24 | beforeEach(async(() => {
25 | TestBed.configureTestingModule({
26 | declarations: [SidebarInterviewComponent],
27 | imports: [CoreModule, RouterModule.forRoot([]), SharedModule],
28 | providers: [
29 | { provide: ContactPersonService, useValue: contactPersonServiceSpy },
30 | { provide: InterviewService, useValue: interviewServiceSpy },
31 | { provide: QuestionService, useValue: questionServiceSpy },
32 | { provide: FacCritService, useValue: facCritServiceSpy },
33 | { provide: AuditService, useValue: auditServiceSpy },
34 | ],
35 | }).compileComponents();
36 | }));
37 |
38 | beforeEach(() => {
39 | fixture = TestBed.createComponent(SidebarInterviewComponent);
40 | component = fixture.componentInstance;
41 | });
42 |
43 | it('should create', () => {
44 | expect(component).toBeTruthy();
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/features/audit-overview/audit-info/audit-info.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { CoreModule } from 'src/app/core/core.module';
4 | import { AuditInfoComponent } from './audit-info.component';
5 | import { Router } from '@angular/router';
6 | import { ContactPersonService } from 'src/app/core/http/contact-person.service';
7 | import {
8 | contactPersonServiceSpy,
9 | interviewServiceSpy,
10 | questionServiceSpy,
11 | facCritServiceSpy,
12 | auditServiceSpy,
13 | } from 'src/app/core/ngxs/test/service-spies';
14 | import { InterviewService } from 'src/app/core/http/interview.service';
15 | import { QuestionService } from 'src/app/core/http/question.service';
16 | import { FacCritService } from 'src/app/core/http/facCrit.service';
17 | import { AuditService } from 'src/app/core/http/audit.service';
18 |
19 | describe('AuditInfoComponent', () => {
20 | let component: AuditInfoComponent;
21 | let fixture: ComponentFixture;
22 |
23 | beforeEach(async(() => {
24 | const routerStub = { url: '/audits/123/interviews' };
25 |
26 | TestBed.configureTestingModule({
27 | declarations: [AuditInfoComponent],
28 | imports: [CoreModule],
29 | providers: [
30 | { provide: Router, useValue: routerStub },
31 | { provide: ContactPersonService, useValue: contactPersonServiceSpy },
32 | { provide: InterviewService, useValue: interviewServiceSpy },
33 | { provide: QuestionService, useValue: questionServiceSpy },
34 | { provide: FacCritService, useValue: facCritServiceSpy },
35 | { provide: AuditService, useValue: auditServiceSpy },
36 | ],
37 | }).compileComponents();
38 | }));
39 |
40 | beforeEach(() => {
41 | fixture = TestBed.createComponent(AuditInfoComponent);
42 | component = fixture.componentInstance;
43 | });
44 |
45 | it('should create', () => {
46 | expect(component).toBeTruthy();
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/ng-frontend/src/app/shared/components/forms/contact-person-form/contact-person-form.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 |
4 | import { ContactPersonFormComponent } from './contact-person-form.component';
5 | import { FormBuilder } from '@angular/forms';
6 | import { SharedModule } from 'src/app/shared/shared.module';
7 | import { ContactPersonService } from 'src/app/core/http/contact-person.service';
8 | import {
9 | contactPersonServiceSpy,
10 | interviewServiceSpy,
11 | questionServiceSpy,
12 | facCritServiceSpy,
13 | auditServiceSpy,
14 | } from 'src/app/core/ngxs/test/service-spies';
15 | import { InterviewService } from 'src/app/core/http/interview.service';
16 | import { QuestionService } from 'src/app/core/http/question.service';
17 | import { FacCritService } from 'src/app/core/http/facCrit.service';
18 | import { AuditService } from 'src/app/core/http/audit.service';
19 |
20 | describe('ContactPersonFormComponent', () => {
21 | let component: ContactPersonFormComponent;
22 | let fixture: ComponentFixture;
23 |
24 | beforeEach(async(() => {
25 | TestBed.configureTestingModule({
26 | declarations: [ContactPersonFormComponent],
27 | providers: [
28 | FormBuilder,
29 | { provide: ContactPersonService, useValue: contactPersonServiceSpy },
30 | { provide: InterviewService, useValue: interviewServiceSpy },
31 | { provide: QuestionService, useValue: questionServiceSpy },
32 | { provide: FacCritService, useValue: facCritServiceSpy },
33 | { provide: AuditService, useValue: auditServiceSpy },
34 | ],
35 | imports: [SharedModule],
36 | }).compileComponents();
37 | }));
38 |
39 | beforeEach(() => {
40 | fixture = TestBed.createComponent(ContactPersonFormComponent);
41 | component = fixture.componentInstance;
42 | });
43 |
44 | it('should create', () => {
45 | expect(component).toBeTruthy();
46 | });
47 | });
48 |
--------------------------------------------------------------------------------