This commit is contained in:
parent
a6cf0429aa
commit
a333400673
36 changed files with 18820 additions and 1 deletions
28
.forgejo/workflows/qs.yml
Normal file
28
.forgejo/workflows/qs.yml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
name: "Quality Check"
|
||||||
|
|
||||||
|
on:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linting:
|
||||||
|
name: "Linting"
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
container:
|
||||||
|
image: "git.euph.dev/actions/runner-basic:latest"
|
||||||
|
steps:
|
||||||
|
- name: "Checkout"
|
||||||
|
uses: "https://git.euph.dev/actions/checkout@v3"
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ~/.node_modules
|
||||||
|
key: ${{ runner.os }}-${{ hashFiles('package-lock.json', 'eslint.config.mjs', '.stylelintrc', '.stylelintignore') }}
|
||||||
|
restore-keys: ${{ runner.os }}-
|
||||||
|
- name: "NPM install"
|
||||||
|
run: npm i
|
||||||
|
- name: "Linting TS"
|
||||||
|
run: npm run lint:ts
|
||||||
|
- name: "Linting SCSS"
|
||||||
|
run: npm run lint:scss
|
||||||
|
|
||||||
|
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
node_modules/
|
||||||
|
.angular/
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
1
.prettierignore
Normal file
1
.prettierignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*
|
3
.stylelintignore
Normal file
3
.stylelintignore
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
*.*
|
||||||
|
!*.css
|
||||||
|
!*.scss
|
14
.stylelintrc.json
Normal file
14
.stylelintrc.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"extends": "stylelint-config-standard-scss",
|
||||||
|
"plugins": [
|
||||||
|
"stylelint-scss"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"custom-property-empty-line-before": null,
|
||||||
|
"declaration-empty-line-before": null,
|
||||||
|
"media-feature-range-notation": null,
|
||||||
|
"import-notation": "string",
|
||||||
|
"scss/no-global-function-names": null,
|
||||||
|
"no-empty-source": null
|
||||||
|
}
|
||||||
|
}
|
13
Justfile
Normal file
13
Justfile
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
_choose:
|
||||||
|
just --choose
|
||||||
|
|
||||||
|
up:
|
||||||
|
docker compose up -d
|
||||||
|
ng serve
|
||||||
|
|
||||||
|
down:
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
lint:
|
||||||
|
-npm run lint:ts:fix
|
||||||
|
-npm run lint:scss:fix
|
17
README.md
17
README.md
|
@ -1,3 +1,18 @@
|
||||||
|
![QS Badge](https://git.euph.dev//SZUT/EMS//actions/workflows/qs.yml/badge.svg?branch=trunk)
|
||||||
|
|
||||||
# EMS
|
# EMS
|
||||||
|
|
||||||
https://hb.itslearning.com/LearningToolElement/ViewLearningToolElement.aspx?LearningToolElementId=21843391
|
## Links
|
||||||
|
|
||||||
|
- [Ausgangslage](https://hb.itslearning.com/LearningToolElement/ViewLearningToolElement.aspx?LearningToolElementId=21843391)
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Dieses Projekt hat ein [Justfile](https://just.systems)
|
||||||
|
|
||||||
|
1. Projekt Clonen
|
||||||
|
1. NPM install
|
||||||
|
1. Docker Container Hochfahren
|
||||||
|
1. Angular App starten
|
||||||
|
|
||||||
|
|
102
angular.json
Normal file
102
angular.json
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"version": 1,
|
||||||
|
"newProjectRoot": "projects",
|
||||||
|
"projects": {
|
||||||
|
"a": {
|
||||||
|
"projectType": "application",
|
||||||
|
"schematics": {
|
||||||
|
"@schematics/angular:component": {
|
||||||
|
"style": "scss"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"prefix": "app",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-angular:application",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "dist/a",
|
||||||
|
"index": "src/index.html",
|
||||||
|
"browser": "src/main.ts",
|
||||||
|
"polyfills": [
|
||||||
|
"zone.js"
|
||||||
|
],
|
||||||
|
"tsConfig": "tsconfig.app.json",
|
||||||
|
"inlineStyleLanguage": "scss",
|
||||||
|
"assets": [
|
||||||
|
{
|
||||||
|
"glob": "**/*",
|
||||||
|
"input": "public"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"src/styles.scss"
|
||||||
|
],
|
||||||
|
"scripts": []
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"type": "initial",
|
||||||
|
"maximumWarning": "500kB",
|
||||||
|
"maximumError": "1MB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "4kB",
|
||||||
|
"maximumError": "8kB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputHashing": "all"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"optimization": false,
|
||||||
|
"extractLicenses": false,
|
||||||
|
"sourceMap": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "production"
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"buildTarget": "a:build:production"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"buildTarget": "a:build:development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "development"
|
||||||
|
},
|
||||||
|
"extract-i18n": {
|
||||||
|
"builder": "@angular-devkit/build-angular:extract-i18n"
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"polyfills": [
|
||||||
|
"zone.js",
|
||||||
|
"zone.js/testing"
|
||||||
|
],
|
||||||
|
"tsConfig": "tsconfig.spec.json",
|
||||||
|
"inlineStyleLanguage": "scss",
|
||||||
|
"assets": [
|
||||||
|
{
|
||||||
|
"glob": "**/*",
|
||||||
|
"input": "public"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"src/styles.scss"
|
||||||
|
],
|
||||||
|
"scripts": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
compose.yml
Normal file
27
compose.yml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
container_name: ems_postgres
|
||||||
|
image: postgres:17.2
|
||||||
|
volumes:
|
||||||
|
- ems_data:/var/lib/postgresql/data
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: employee_db
|
||||||
|
POSTGRES_USER: employee
|
||||||
|
POSTGRES_PASSWORD: secret
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
|
||||||
|
api:
|
||||||
|
container_name: ems_api
|
||||||
|
image: berndheidemann/employee-management-service:1.1.3.1
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
spring.datasource.url: jdbc:postgresql://ems_postgres:5432/employee_db
|
||||||
|
spring.datasource.username: employee
|
||||||
|
spring.datasource.password: secret
|
||||||
|
ports:
|
||||||
|
- "8080:8089"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
ems_data:
|
63
eslint.config.mjs
Normal file
63
eslint.config.mjs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
||||||
|
import typescriptEslint from "@typescript-eslint/eslint-plugin";
|
||||||
|
import globals from "globals";
|
||||||
|
import tsParser from "@typescript-eslint/parser";
|
||||||
|
import path from "node:path";
|
||||||
|
import {fileURLToPath} from "node:url";
|
||||||
|
import js from "@eslint/js";
|
||||||
|
import {FlatCompat} from "@eslint/eslintrc";
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
const compat = new FlatCompat({
|
||||||
|
baseDirectory: __dirname,
|
||||||
|
recommendedConfig: js.configs.recommended,
|
||||||
|
allConfig: js.configs.all,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
ignores: ["src/app/core/ems"],
|
||||||
|
},
|
||||||
|
...compat.extends("eslint:recommended", "plugin:@typescript-eslint/strict"),
|
||||||
|
{
|
||||||
|
plugins: {
|
||||||
|
"simple-import-sort": simpleImportSort,
|
||||||
|
"@typescript-eslint": typescriptEslint,
|
||||||
|
},
|
||||||
|
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
},
|
||||||
|
|
||||||
|
parser: tsParser,
|
||||||
|
ecmaVersion: "latest",
|
||||||
|
sourceType: "module",
|
||||||
|
},
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
indent: ["error", 4],
|
||||||
|
"linebreak-style": ["error", "unix"],
|
||||||
|
quotes: ["error", "single"],
|
||||||
|
semi: ["error", "always"],
|
||||||
|
strict: "error",
|
||||||
|
"array-bracket-newline": "error",
|
||||||
|
yoda: "error",
|
||||||
|
|
||||||
|
"@typescript-eslint/array-type": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
default: "generic",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
"@typescript-eslint/ban-tslint-comment": "off",
|
||||||
|
"@typescript-eslint/no-non-null-assertion": "off",
|
||||||
|
"@typescript-eslint/no-extraneous-class": "off",
|
||||||
|
"simple-import-sort/imports": "error",
|
||||||
|
"simple-import-sort/exports": "error",
|
||||||
|
"no-mixed-spaces-and-tabs": "off",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
4
getBearerToken.http
Normal file
4
getBearerToken.http
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
POST http://authproxy.szut.dev
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
grant_type=password&client_id=employee-management-service&username=user&password=test
|
16934
package-lock.json
generated
Normal file
16934
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
55
package.json
Normal file
55
package.json
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"start": "ng serve",
|
||||||
|
"build": "ng build",
|
||||||
|
"lint:ts": "eslint src",
|
||||||
|
"lint:scss": "stylelint src",
|
||||||
|
"lint:ts:fix": "eslint src --fix",
|
||||||
|
"lint:scss:fix": "stylelint src --fix"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/animations": "^19.0.0",
|
||||||
|
"@angular/common": "^19.0.0",
|
||||||
|
"@angular/compiler": "^19.0.0",
|
||||||
|
"@angular/core": "^19.0.0",
|
||||||
|
"@angular/forms": "^19.0.0",
|
||||||
|
"@angular/platform-browser": "^19.0.0",
|
||||||
|
"@angular/platform-browser-dynamic": "^19.0.0",
|
||||||
|
"@angular/router": "^19.0.0",
|
||||||
|
"rxjs": "~7.8.0",
|
||||||
|
"tslib": "^2.3.0",
|
||||||
|
"zone.js": "~0.15.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@angular-devkit/build-angular": "^19.0.2",
|
||||||
|
"@angular/cli": "^19.0.2",
|
||||||
|
"@angular/compiler-cli": "^19.0.0",
|
||||||
|
"@eslint/eslintrc": "^3.2.0",
|
||||||
|
"@eslint/js": "^9.17.0",
|
||||||
|
"@hey-api/openapi-ts": "^0.52.9",
|
||||||
|
"@types/jasmine": "~5.1.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.18.1",
|
||||||
|
"@typescript-eslint/parser": "^8.18.1",
|
||||||
|
"eslint": "^9.17.0",
|
||||||
|
"eslint-plugin-autofix": "^2.2.0",
|
||||||
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||||
|
"globals": "^15.13.0",
|
||||||
|
"jasmine-core": "~5.4.0",
|
||||||
|
"karma": "~6.4.0",
|
||||||
|
"karma-chrome-launcher": "~3.2.0",
|
||||||
|
"karma-coverage": "~2.2.0",
|
||||||
|
"karma-jasmine": "~5.1.0",
|
||||||
|
"karma-jasmine-html-reporter": "~2.1.0",
|
||||||
|
"stylelint": "^16.12.0",
|
||||||
|
"stylelint-config-standard-scss": "^14.0.0",
|
||||||
|
"stylelint-scss": "^6.10.0",
|
||||||
|
"typescript": "~5.6.2"
|
||||||
|
},
|
||||||
|
"volta": {
|
||||||
|
"node": "22.12.0"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
8
src/app/app.component.html
Normal file
8
src/app/app.component.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
@for (employee of $employees | async ; track employee.id) {
|
||||||
|
<code style="white-space: pre-wrap">
|
||||||
|
{{ employee | json}}
|
||||||
|
</code>
|
||||||
|
<hr>
|
||||||
|
}
|
||||||
|
|
||||||
|
<router-outlet />
|
0
src/app/app.component.scss
Normal file
0
src/app/app.component.scss
Normal file
19
src/app/app.component.ts
Normal file
19
src/app/app.component.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import {AsyncPipe, JsonPipe} from '@angular/common';
|
||||||
|
import {Component} from '@angular/core';
|
||||||
|
import { RouterOutlet } from '@angular/router';
|
||||||
|
import { EmployeeControllerService, FindAll1Response } from '@core/ems';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
imports: [RouterOutlet, JsonPipe, AsyncPipe],
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrl: './app.component.scss'
|
||||||
|
})
|
||||||
|
export class AppComponent{
|
||||||
|
readonly $employees: Observable<FindAll1Response>;
|
||||||
|
|
||||||
|
constructor(private apiClient: EmployeeControllerService) {
|
||||||
|
this.$employees = this.apiClient.findAll1();
|
||||||
|
}
|
||||||
|
}
|
17
src/app/app.config.ts
Normal file
17
src/app/app.config.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import { provideHttpClient } from '@angular/common/http';
|
||||||
|
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
||||||
|
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
|
||||||
|
import { provideRouter } from '@angular/router';
|
||||||
|
import { routes } from '@app/app.routes';
|
||||||
|
import { OpenAPI } from '@core/ems/core/OpenAPI';
|
||||||
|
OpenAPI.BASE = 'http://localhost:8080';
|
||||||
|
OpenAPI.TOKEN = 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIzUFQ0dldiNno5MnlQWk1EWnBqT1U0RjFVN0lwNi1ELUlqQWVGczJPbGU0In0.eyJleHAiOjE3MzQ1MTY5MTQsImlhdCI6MTczNDUxMzMxNCwianRpIjoiMjk2MzAwNTQtMWI2Ni00ODIyLWFiMGItNmI5NjlkZDg4MTRkIiwiaXNzIjoiaHR0cHM6Ly9rZXljbG9hay5zenV0LmRldi9hdXRoL3JlYWxtcy9zenV0IiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjU1NDZjZDIxLTk4NTQtNDMyZi1hNDY3LTRkZTNlZWRmNTg4OSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImVtcGxveWVlLW1hbmFnZW1lbnQtc2VydmljZSIsInNlc3Npb25fc3RhdGUiOiJhMDIzMmNhMy0yZjM3LTQ3OTctYThkMC0zNjJhNzBlODY1MDMiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NDIwMCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsicHJvZHVjdF9vd25lciIsIm9mZmxpbmVfYWNjZXNzIiwiZGVmYXVsdC1yb2xlcy1zenV0IiwidW1hX2F1dGhvcml6YXRpb24iLCJ1c2VyIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsInByZWZlcnJlZF91c2VybmFtZSI6InVzZXIifQ.evYkQetnwJWgzHjSRrZyN1Ls-fpdBsM0KYwp0RKcsgrg4w4p-WMnFGDch_1kFWflMq9i3J_sAhsPcFhvCiKEpo5xca9yj0-20GMUZXH7aNwCneqGur2f9wh3k8nQdoYsuwKTfKpGSsNWTQ20rV7CqHIne-lD2rayhb2wHwOsbklsSf0K9s37EKPwASfln4g1KGTbBpwFDz8p75Vhr5HqlaCJUxN-NMYKM41_2ao8ykhCVkKRk7cZwjKfB3MOk5Xk8l0NHcPBp8G_pOyrjyqC-fGekcxEF1ucYSWqw4r_PsUTeLkO8M-RK0h798JWq7l-OcODgxr4qhx-ungUPnGFxw';
|
||||||
|
|
||||||
|
export const appConfig: ApplicationConfig = {
|
||||||
|
providers: [
|
||||||
|
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||||
|
provideRouter(routes),
|
||||||
|
provideHttpClient(),
|
||||||
|
provideAnimationsAsync()
|
||||||
|
],
|
||||||
|
};
|
3
src/app/app.routes.ts
Normal file
3
src/app/app.routes.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { Routes } from '@angular/router';
|
||||||
|
|
||||||
|
export const routes: Routes = [];
|
11
src/app/core/ems/config.ts
Normal file
11
src/app/core/ems/config.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import {defineConfig} from '@hey-api/openapi-ts';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
input: 'src/app/core/ems/ems.yml',
|
||||||
|
output: 'src/app/core/ems',
|
||||||
|
schemas: false,
|
||||||
|
services: {
|
||||||
|
asClass: true
|
||||||
|
},
|
||||||
|
client: 'angular',
|
||||||
|
});
|
21
src/app/core/ems/core/ApiError.ts
Normal file
21
src/app/core/ems/core/ApiError.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||||
|
import type { ApiResult } from './ApiResult';
|
||||||
|
|
||||||
|
export class ApiError extends Error {
|
||||||
|
public readonly url: string;
|
||||||
|
public readonly status: number;
|
||||||
|
public readonly statusText: string;
|
||||||
|
public readonly body: unknown;
|
||||||
|
public readonly request: ApiRequestOptions;
|
||||||
|
|
||||||
|
constructor(request: ApiRequestOptions, response: ApiResult, message: string) {
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.name = 'ApiError';
|
||||||
|
this.url = response.url;
|
||||||
|
this.status = response.status;
|
||||||
|
this.statusText = response.statusText;
|
||||||
|
this.body = response.body;
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
}
|
21
src/app/core/ems/core/ApiRequestOptions.ts
Normal file
21
src/app/core/ems/core/ApiRequestOptions.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
export type ApiRequestOptions<T = unknown> = {
|
||||||
|
readonly body?: any;
|
||||||
|
readonly cookies?: Record<string, unknown>;
|
||||||
|
readonly errors?: Record<number | string, string>;
|
||||||
|
readonly formData?: Record<string, unknown> | any[] | Blob | File;
|
||||||
|
readonly headers?: Record<string, unknown>;
|
||||||
|
readonly mediaType?: string;
|
||||||
|
readonly method:
|
||||||
|
| 'DELETE'
|
||||||
|
| 'GET'
|
||||||
|
| 'HEAD'
|
||||||
|
| 'OPTIONS'
|
||||||
|
| 'PATCH'
|
||||||
|
| 'POST'
|
||||||
|
| 'PUT';
|
||||||
|
readonly path?: Record<string, unknown>;
|
||||||
|
readonly query?: Record<string, unknown>;
|
||||||
|
readonly responseHeader?: string;
|
||||||
|
readonly responseTransformer?: (data: unknown) => Promise<T>;
|
||||||
|
readonly url: string;
|
||||||
|
};
|
7
src/app/core/ems/core/ApiResult.ts
Normal file
7
src/app/core/ems/core/ApiResult.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export type ApiResult<TData = any> = {
|
||||||
|
readonly body: TData;
|
||||||
|
readonly ok: boolean;
|
||||||
|
readonly status: number;
|
||||||
|
readonly statusText: string;
|
||||||
|
readonly url: string;
|
||||||
|
};
|
55
src/app/core/ems/core/OpenAPI.ts
Normal file
55
src/app/core/ems/core/OpenAPI.ts
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import type { HttpResponse } from '@angular/common/http';
|
||||||
|
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||||
|
|
||||||
|
type Headers = Record<string, string>;
|
||||||
|
type Middleware<T> = (value: T) => T | Promise<T>;
|
||||||
|
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>;
|
||||||
|
|
||||||
|
export class Interceptors<T> {
|
||||||
|
_fns: Middleware<T>[];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this._fns = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
eject(fn: Middleware<T>): void {
|
||||||
|
const index = this._fns.indexOf(fn);
|
||||||
|
if (index !== -1) {
|
||||||
|
this._fns = [...this._fns.slice(0, index), ...this._fns.slice(index + 1)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use(fn: Middleware<T>): void {
|
||||||
|
this._fns = [...this._fns, fn];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type OpenAPIConfig = {
|
||||||
|
BASE: string;
|
||||||
|
CREDENTIALS: 'include' | 'omit' | 'same-origin';
|
||||||
|
ENCODE_PATH?: ((path: string) => string) | undefined;
|
||||||
|
HEADERS?: Headers | Resolver<Headers> | undefined;
|
||||||
|
PASSWORD?: string | Resolver<string> | undefined;
|
||||||
|
TOKEN?: string | Resolver<string> | undefined;
|
||||||
|
USERNAME?: string | Resolver<string> | undefined;
|
||||||
|
VERSION: string;
|
||||||
|
WITH_CREDENTIALS: boolean;
|
||||||
|
interceptors: {
|
||||||
|
response: Interceptors<HttpResponse<any>>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const OpenAPI: OpenAPIConfig = {
|
||||||
|
BASE: '',
|
||||||
|
CREDENTIALS: 'include',
|
||||||
|
ENCODE_PATH: undefined,
|
||||||
|
HEADERS: undefined,
|
||||||
|
PASSWORD: undefined,
|
||||||
|
TOKEN: undefined,
|
||||||
|
USERNAME: undefined,
|
||||||
|
VERSION: '1.1.2',
|
||||||
|
WITH_CREDENTIALS: false,
|
||||||
|
interceptors: {
|
||||||
|
response: new Interceptors(),
|
||||||
|
},
|
||||||
|
};
|
337
src/app/core/ems/core/request.ts
Normal file
337
src/app/core/ems/core/request.ts
Normal file
|
@ -0,0 +1,337 @@
|
||||||
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||||
|
import type { HttpResponse, HttpErrorResponse } from '@angular/common/http';
|
||||||
|
import { forkJoin, of, throwError } from 'rxjs';
|
||||||
|
import { catchError, map, switchMap } from 'rxjs/operators';
|
||||||
|
import type { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
import { ApiError } from './ApiError';
|
||||||
|
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||||
|
import type { ApiResult } from './ApiResult';
|
||||||
|
import type { OpenAPIConfig } from './OpenAPI';
|
||||||
|
|
||||||
|
export const isString = (value: unknown): value is string => {
|
||||||
|
return typeof value === 'string';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isStringWithValue = (value: unknown): value is string => {
|
||||||
|
return isString(value) && value !== '';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isBlob = (value: any): value is Blob => {
|
||||||
|
return value instanceof Blob;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isFormData = (value: unknown): value is FormData => {
|
||||||
|
return value instanceof FormData;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const base64 = (str: string): string => {
|
||||||
|
try {
|
||||||
|
return btoa(str);
|
||||||
|
} catch (err) {
|
||||||
|
// @ts-ignore
|
||||||
|
return Buffer.from(str).toString('base64');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getQueryString = (params: Record<string, unknown>): string => {
|
||||||
|
const qs: string[] = [];
|
||||||
|
|
||||||
|
const append = (key: string, value: unknown) => {
|
||||||
|
qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const encodePair = (key: string, value: unknown) => {
|
||||||
|
if (value === undefined || value === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value instanceof Date) {
|
||||||
|
append(key, value.toISOString());
|
||||||
|
} else if (Array.isArray(value)) {
|
||||||
|
value.forEach(v => encodePair(key, v));
|
||||||
|
} else if (typeof value === 'object') {
|
||||||
|
Object.entries(value).forEach(([k, v]) => encodePair(`${key}[${k}]`, v));
|
||||||
|
} else {
|
||||||
|
append(key, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(params).forEach(([key, value]) => encodePair(key, value));
|
||||||
|
|
||||||
|
return qs.length ? `?${qs.join('&')}` : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
|
||||||
|
const encoder = config.ENCODE_PATH || encodeURI;
|
||||||
|
|
||||||
|
const path = options.url
|
||||||
|
.replace('{api-version}', config.VERSION)
|
||||||
|
.replace(/{(.*?)}/g, (substring: string, group: string) => {
|
||||||
|
if (options.path?.hasOwnProperty(group)) {
|
||||||
|
return encoder(String(options.path[group]));
|
||||||
|
}
|
||||||
|
return substring;
|
||||||
|
});
|
||||||
|
|
||||||
|
const url = config.BASE + path;
|
||||||
|
return options.query ? url + getQueryString(options.query) : url;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getFormData = (options: ApiRequestOptions): FormData | undefined => {
|
||||||
|
if (options.formData) {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
const process = (key: string, value: unknown) => {
|
||||||
|
if (isString(value) || isBlob(value)) {
|
||||||
|
formData.append(key, value);
|
||||||
|
} else {
|
||||||
|
formData.append(key, JSON.stringify(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(options.formData)
|
||||||
|
.filter(([, value]) => value !== undefined && value !== null)
|
||||||
|
.forEach(([key, value]) => {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
value.forEach(v => process(key, v));
|
||||||
|
} else {
|
||||||
|
process(key, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>;
|
||||||
|
|
||||||
|
export const resolve = async <T>(options: ApiRequestOptions<T>, resolver?: T | Resolver<T>): Promise<T | undefined> => {
|
||||||
|
if (typeof resolver === 'function') {
|
||||||
|
return (resolver as Resolver<T>)(options);
|
||||||
|
}
|
||||||
|
return resolver;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getHeaders = <T>(config: OpenAPIConfig, options: ApiRequestOptions<T>): Observable<HttpHeaders> => {
|
||||||
|
return forkJoin({
|
||||||
|
// @ts-ignore
|
||||||
|
token: resolve(options, config.TOKEN),
|
||||||
|
// @ts-ignore
|
||||||
|
username: resolve(options, config.USERNAME),
|
||||||
|
// @ts-ignore
|
||||||
|
password: resolve(options, config.PASSWORD),
|
||||||
|
// @ts-ignore
|
||||||
|
additionalHeaders: resolve(options, config.HEADERS),
|
||||||
|
}).pipe(
|
||||||
|
map(({ token, username, password, additionalHeaders }) => {
|
||||||
|
const headers = Object.entries({
|
||||||
|
Accept: 'application/json',
|
||||||
|
...additionalHeaders,
|
||||||
|
...options.headers,
|
||||||
|
})
|
||||||
|
.filter(([, value]) => value !== undefined && value !== null)
|
||||||
|
.reduce((headers, [key, value]) => ({
|
||||||
|
...headers,
|
||||||
|
[key]: String(value),
|
||||||
|
}), {} as Record<string, string>);
|
||||||
|
|
||||||
|
if (isStringWithValue(token)) {
|
||||||
|
headers['Authorization'] = `Bearer ${token}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStringWithValue(username) && isStringWithValue(password)) {
|
||||||
|
const credentials = base64(`${username}:${password}`);
|
||||||
|
headers['Authorization'] = `Basic ${credentials}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.body !== undefined) {
|
||||||
|
if (options.mediaType) {
|
||||||
|
headers['Content-Type'] = options.mediaType;
|
||||||
|
} else if (isBlob(options.body)) {
|
||||||
|
headers['Content-Type'] = options.body.type || 'application/octet-stream';
|
||||||
|
} else if (isString(options.body)) {
|
||||||
|
headers['Content-Type'] = 'text/plain';
|
||||||
|
} else if (!isFormData(options.body)) {
|
||||||
|
headers['Content-Type'] = 'application/json';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HttpHeaders(headers);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getRequestBody = (options: ApiRequestOptions): unknown => {
|
||||||
|
if (options.body) {
|
||||||
|
if (options.mediaType?.includes('application/json') || options.mediaType?.includes('+json')) {
|
||||||
|
return JSON.stringify(options.body);
|
||||||
|
} else if (isString(options.body) || isBlob(options.body) || isFormData(options.body)) {
|
||||||
|
return options.body;
|
||||||
|
} else {
|
||||||
|
return JSON.stringify(options.body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendRequest = <T>(
|
||||||
|
config: OpenAPIConfig,
|
||||||
|
options: ApiRequestOptions<T>,
|
||||||
|
http: HttpClient,
|
||||||
|
url: string,
|
||||||
|
body: unknown,
|
||||||
|
formData: FormData | undefined,
|
||||||
|
headers: HttpHeaders
|
||||||
|
): Observable<HttpResponse<T>> => {
|
||||||
|
return http.request<T>(options.method, url, {
|
||||||
|
headers,
|
||||||
|
body: body ?? formData,
|
||||||
|
withCredentials: config.WITH_CREDENTIALS,
|
||||||
|
observe: 'response',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getResponseHeader = <T>(response: HttpResponse<T>, responseHeader?: string): string | undefined => {
|
||||||
|
if (responseHeader) {
|
||||||
|
const value = response.headers.get(responseHeader);
|
||||||
|
if (isString(value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getResponseBody = <T>(response: HttpResponse<T>): T | undefined => {
|
||||||
|
if (response.status !== 204 && response.body !== null) {
|
||||||
|
return response.body;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => {
|
||||||
|
const errors: Record<number, string> = {
|
||||||
|
400: 'Bad Request',
|
||||||
|
401: 'Unauthorized',
|
||||||
|
402: 'Payment Required',
|
||||||
|
403: 'Forbidden',
|
||||||
|
404: 'Not Found',
|
||||||
|
405: 'Method Not Allowed',
|
||||||
|
406: 'Not Acceptable',
|
||||||
|
407: 'Proxy Authentication Required',
|
||||||
|
408: 'Request Timeout',
|
||||||
|
409: 'Conflict',
|
||||||
|
410: 'Gone',
|
||||||
|
411: 'Length Required',
|
||||||
|
412: 'Precondition Failed',
|
||||||
|
413: 'Payload Too Large',
|
||||||
|
414: 'URI Too Long',
|
||||||
|
415: 'Unsupported Media Type',
|
||||||
|
416: 'Range Not Satisfiable',
|
||||||
|
417: 'Expectation Failed',
|
||||||
|
418: 'Im a teapot',
|
||||||
|
421: 'Misdirected Request',
|
||||||
|
422: 'Unprocessable Content',
|
||||||
|
423: 'Locked',
|
||||||
|
424: 'Failed Dependency',
|
||||||
|
425: 'Too Early',
|
||||||
|
426: 'Upgrade Required',
|
||||||
|
428: 'Precondition Required',
|
||||||
|
429: 'Too Many Requests',
|
||||||
|
431: 'Request Header Fields Too Large',
|
||||||
|
451: 'Unavailable For Legal Reasons',
|
||||||
|
500: 'Internal Server Error',
|
||||||
|
501: 'Not Implemented',
|
||||||
|
502: 'Bad Gateway',
|
||||||
|
503: 'Service Unavailable',
|
||||||
|
504: 'Gateway Timeout',
|
||||||
|
505: 'HTTP Version Not Supported',
|
||||||
|
506: 'Variant Also Negotiates',
|
||||||
|
507: 'Insufficient Storage',
|
||||||
|
508: 'Loop Detected',
|
||||||
|
510: 'Not Extended',
|
||||||
|
511: 'Network Authentication Required',
|
||||||
|
...options.errors,
|
||||||
|
}
|
||||||
|
|
||||||
|
const error = errors[result.status];
|
||||||
|
if (error) {
|
||||||
|
throw new ApiError(options, result, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.ok) {
|
||||||
|
const errorStatus = result.status ?? 'unknown';
|
||||||
|
const errorStatusText = result.statusText ?? 'unknown';
|
||||||
|
const errorBody = (() => {
|
||||||
|
try {
|
||||||
|
return JSON.stringify(result.body, null, 2);
|
||||||
|
} catch (e) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
throw new ApiError(options, result,
|
||||||
|
`Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request method
|
||||||
|
* @param config The OpenAPI configuration object
|
||||||
|
* @param http The Angular HTTP client
|
||||||
|
* @param options The request options from the service
|
||||||
|
* @returns Observable<T>
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
export const request = <T>(config: OpenAPIConfig, http: HttpClient, options: ApiRequestOptions<T>): Observable<T> => {
|
||||||
|
const url = getUrl(config, options);
|
||||||
|
const formData = getFormData(options);
|
||||||
|
const body = getRequestBody(options);
|
||||||
|
|
||||||
|
return getHeaders(config, options).pipe(
|
||||||
|
switchMap(headers => {
|
||||||
|
return sendRequest<T>(config, options, http, url, body, formData, headers);
|
||||||
|
}),
|
||||||
|
switchMap(async response => {
|
||||||
|
for (const fn of config.interceptors.response._fns) {
|
||||||
|
response = await fn(response);
|
||||||
|
}
|
||||||
|
const responseBody = getResponseBody(response);
|
||||||
|
const responseHeader = getResponseHeader(response, options.responseHeader);
|
||||||
|
|
||||||
|
let transformedBody = responseBody;
|
||||||
|
if (options.responseTransformer && response.ok) {
|
||||||
|
transformedBody = await options.responseTransformer(responseBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
url,
|
||||||
|
ok: response.ok,
|
||||||
|
status: response.status,
|
||||||
|
statusText: response.statusText,
|
||||||
|
body: responseHeader ?? transformedBody,
|
||||||
|
} as ApiResult;
|
||||||
|
}),
|
||||||
|
catchError((error: HttpErrorResponse) => {
|
||||||
|
if (!error.status) {
|
||||||
|
return throwError(() => error);
|
||||||
|
}
|
||||||
|
return of({
|
||||||
|
url,
|
||||||
|
ok: error.ok,
|
||||||
|
status: error.status,
|
||||||
|
statusText: error.statusText,
|
||||||
|
body: error.error ?? error.statusText,
|
||||||
|
} as ApiResult);
|
||||||
|
}),
|
||||||
|
map(result => {
|
||||||
|
catchErrorCodes(options, result);
|
||||||
|
return result.body as T;
|
||||||
|
}),
|
||||||
|
catchError((error: ApiError) => {
|
||||||
|
return throwError(() => error);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
493
src/app/core/ems/ems.yml
Normal file
493
src/app/core/ems/ems.yml
Normal file
|
@ -0,0 +1,493 @@
|
||||||
|
openapi: 3.0.1
|
||||||
|
info:
|
||||||
|
title: Employees Management Micro-Service
|
||||||
|
description: "\n## Overview\n\nEmployees Management Service API manages the employees\
|
||||||
|
\ of HighTec Gmbh including their qualifications. It offers the possibility to\
|
||||||
|
\ create, read, update and delete employees and qualifications. Existing employees\
|
||||||
|
\ can be assigned new qualifications or have them withdrawn. \nThe API is organized\
|
||||||
|
\ around REST. It has predictable resource-oriented URLs, accepts JSON-encoded\
|
||||||
|
\ request bodies, returns JSON-encoded responses, uses standard HTTP response\
|
||||||
|
\ codes and authentication.\n"
|
||||||
|
version: 1.1.2
|
||||||
|
servers:
|
||||||
|
- url: ""
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
paths:
|
||||||
|
/qualifications/{id}:
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- qualification-controller
|
||||||
|
summary: updates a qualification
|
||||||
|
operationId: updateQualification
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/QualificationPostDTO'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: updated qualification
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/QualificationPostDTO'
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"404":
|
||||||
|
description: resource not found
|
||||||
|
"400":
|
||||||
|
description: invalid JSON posted
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- qualification-controller
|
||||||
|
summary: deletes a qualification by id
|
||||||
|
operationId: deleteQualificationByDesignation
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"404":
|
||||||
|
description: resource not found
|
||||||
|
"204":
|
||||||
|
description: delete successful
|
||||||
|
"403":
|
||||||
|
description: qualification is in use
|
||||||
|
/employees/{id}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- employee-controller
|
||||||
|
summary: find employee by id
|
||||||
|
operationId: findById
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: employee
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EmployeeResponseDTO'
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"404":
|
||||||
|
description: resource not found
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- employee-controller
|
||||||
|
summary: updates employee by id
|
||||||
|
operationId: updateEmployee
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EmployeeRequestPutDTO'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: employee
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EmployeeResponseDTO'
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"404":
|
||||||
|
description: resource not found
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- employee-controller
|
||||||
|
summary: deletes a employee by id
|
||||||
|
operationId: deleteCustomer
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"404":
|
||||||
|
description: resource not found
|
||||||
|
"204":
|
||||||
|
description: delete successful
|
||||||
|
patch:
|
||||||
|
tags:
|
||||||
|
- employee-controller
|
||||||
|
summary: updates employee by id
|
||||||
|
operationId: patchEmployee
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EmployeeRequestPutDTO'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: employee
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EmployeeResponseDTO'
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"404":
|
||||||
|
description: resource not found
|
||||||
|
/qualifications:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- qualification-controller
|
||||||
|
summary: delivers a list of all available qualifications
|
||||||
|
operationId: findAll
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"200":
|
||||||
|
description: list of qualifications
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/QualificationGetDTO'
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- qualification-controller
|
||||||
|
summary: creates a new qualification with its id and designation
|
||||||
|
operationId: createQualification
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/QualificationPostDTO'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: created qualification
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/QualificationPostDTO'
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"400":
|
||||||
|
description: invalid JSON posted
|
||||||
|
/employees:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- employee-controller
|
||||||
|
summary: delivers a list of all employees
|
||||||
|
operationId: findAll_1
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"200":
|
||||||
|
description: list of employees
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/EmployeeResponseDTO'
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- employee-controller
|
||||||
|
summary: creates a new employee
|
||||||
|
operationId: createEmployee
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EmployeeRequestDTO'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"201":
|
||||||
|
description: created employee
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EmployeeResponseDTO'
|
||||||
|
"400":
|
||||||
|
description: invalid JSON posted
|
||||||
|
/employees/{id}/qualifications:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- employee-controller
|
||||||
|
summary: finds all qualifications of an employee by id
|
||||||
|
operationId: findAllQualificationOfAEmployeeById
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"404":
|
||||||
|
description: resource not found
|
||||||
|
"200":
|
||||||
|
description: employee with a list of his qualifications
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EmployeeNameAndSkillDataDTO'
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- employee-controller
|
||||||
|
summary: adds a qualification to an employee by id
|
||||||
|
operationId: addQualificationToEmployeeById
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/QualificationPostDTO'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"404":
|
||||||
|
description: resource not found
|
||||||
|
"400":
|
||||||
|
description: invalid JSON posted or employee already has this qualification
|
||||||
|
"200":
|
||||||
|
description: employee with a list of his qualifications
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EmployeeNameAndSkillDataDTO'
|
||||||
|
/qualifications/{id}/employees:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- qualification-controller
|
||||||
|
summary: find employees by qualification id
|
||||||
|
operationId: findAllEmployeesByQualification
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"200":
|
||||||
|
description: List of employees who have the desired qualification
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EmployeesForAQualificationDTO'
|
||||||
|
"404":
|
||||||
|
description: qualification id does not exist
|
||||||
|
/employees/{eid}/qualifications/{qid}:
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- employee-controller
|
||||||
|
summary: deletes a qualification of an employee by id
|
||||||
|
operationId: removeQualificationFromEmployee
|
||||||
|
parameters:
|
||||||
|
- name: eid
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
- name: qid
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
description: not authorized
|
||||||
|
"404":
|
||||||
|
description: resource not found
|
||||||
|
"200":
|
||||||
|
description: employee with a list of his qualifications
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EmployeeNameAndSkillDataDTO'
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
QualificationPostDTO:
|
||||||
|
required:
|
||||||
|
- skill
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
skill:
|
||||||
|
type: string
|
||||||
|
EmployeeRequestPutDTO:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
street:
|
||||||
|
type: string
|
||||||
|
postcode:
|
||||||
|
type: string
|
||||||
|
city:
|
||||||
|
type: string
|
||||||
|
phone:
|
||||||
|
type: string
|
||||||
|
skillSet:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
EmployeeResponseDTO:
|
||||||
|
required:
|
||||||
|
- city
|
||||||
|
- firstName
|
||||||
|
- lastName
|
||||||
|
- phone
|
||||||
|
- postcode
|
||||||
|
- street
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
street:
|
||||||
|
type: string
|
||||||
|
postcode:
|
||||||
|
maxLength: 5
|
||||||
|
minLength: 5
|
||||||
|
type: string
|
||||||
|
city:
|
||||||
|
type: string
|
||||||
|
phone:
|
||||||
|
type: string
|
||||||
|
skillSet:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/QualificationGetDTO'
|
||||||
|
QualificationGetDTO:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
skill:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
EmployeeRequestDTO:
|
||||||
|
required:
|
||||||
|
- city
|
||||||
|
- firstName
|
||||||
|
- lastName
|
||||||
|
- phone
|
||||||
|
- postcode
|
||||||
|
- street
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
street:
|
||||||
|
type: string
|
||||||
|
postcode:
|
||||||
|
maxLength: 5
|
||||||
|
minLength: 5
|
||||||
|
type: string
|
||||||
|
city:
|
||||||
|
type: string
|
||||||
|
phone:
|
||||||
|
type: string
|
||||||
|
skillSet:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
EmployeeNameAndSkillDataDTO:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
skillSet:
|
||||||
|
uniqueItems: true
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/QualificationGetDTO'
|
||||||
|
EmployeeNameDataDTO:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
EmployeesForAQualificationDTO:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
qualification:
|
||||||
|
$ref: '#/components/schemas/QualificationGetDTO'
|
||||||
|
employees:
|
||||||
|
uniqueItems: true
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/EmployeeNameDataDTO'
|
||||||
|
securitySchemes:
|
||||||
|
bearerAuth:
|
||||||
|
type: http
|
||||||
|
name: bearerAuth
|
||||||
|
scheme: bearer
|
||||||
|
bearerFormat: JWT
|
5
src/app/core/ems/index.ts
Normal file
5
src/app/core/ems/index.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// This file is auto-generated by @hey-api/openapi-ts
|
||||||
|
export { ApiError } from './core/ApiError';
|
||||||
|
export { OpenAPI, type OpenAPIConfig } from './core/OpenAPI';
|
||||||
|
export * from './services.gen';
|
||||||
|
export * from './types.gen';
|
321
src/app/core/ems/services.gen.ts
Normal file
321
src/app/core/ems/services.gen.ts
Normal file
|
@ -0,0 +1,321 @@
|
||||||
|
// This file is auto-generated by @hey-api/openapi-ts
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import type { Observable } from 'rxjs';
|
||||||
|
import { OpenAPI } from './core/OpenAPI';
|
||||||
|
import { request as __request } from './core/request';
|
||||||
|
import type { UpdateQualificationData, UpdateQualificationResponse, DeleteQualificationByDesignationData, DeleteQualificationByDesignationResponse, FindAllResponse, CreateQualificationData, CreateQualificationResponse, FindAllEmployeesByQualificationData, FindAllEmployeesByQualificationResponse, FindByIdData, FindByIdResponse, UpdateEmployeeData, UpdateEmployeeResponse, DeleteCustomerData, DeleteCustomerResponse, PatchEmployeeData, PatchEmployeeResponse, FindAll1Response, CreateEmployeeData, CreateEmployeeResponse, FindAllQualificationOfAemployeeByIdData, FindAllQualificationOfAemployeeByIdResponse, AddQualificationToEmployeeByIdData, AddQualificationToEmployeeByIdResponse, RemoveQualificationFromEmployeeData, RemoveQualificationFromEmployeeResponse } from './types.gen';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class QualificationControllerService {
|
||||||
|
constructor(public readonly http: HttpClient) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates a qualification
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.id
|
||||||
|
* @param data.requestBody
|
||||||
|
* @returns QualificationPostDTO updated qualification
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public updateQualification(data: UpdateQualificationData): Observable<UpdateQualificationResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'PUT',
|
||||||
|
url: '/qualifications/{id}',
|
||||||
|
path: {
|
||||||
|
id: data.id
|
||||||
|
},
|
||||||
|
body: data.requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
400: 'invalid JSON posted',
|
||||||
|
401: 'not authorized',
|
||||||
|
404: 'resource not found'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deletes a qualification by id
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.id
|
||||||
|
* @returns void delete successful
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public deleteQualificationByDesignation(data: DeleteQualificationByDesignationData): Observable<DeleteQualificationByDesignationResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'DELETE',
|
||||||
|
url: '/qualifications/{id}',
|
||||||
|
path: {
|
||||||
|
id: data.id
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
401: 'not authorized',
|
||||||
|
403: 'qualification is in use',
|
||||||
|
404: 'resource not found'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delivers a list of all available qualifications
|
||||||
|
* @returns QualificationGetDTO list of qualifications
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public findAll(): Observable<FindAllResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/qualifications',
|
||||||
|
errors: {
|
||||||
|
401: 'not authorized'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a new qualification with its id and designation
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.requestBody
|
||||||
|
* @returns QualificationPostDTO created qualification
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public createQualification(data: CreateQualificationData): Observable<CreateQualificationResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/qualifications',
|
||||||
|
body: data.requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
400: 'invalid JSON posted',
|
||||||
|
401: 'not authorized'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find employees by qualification id
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.id
|
||||||
|
* @returns EmployeesForAQualificationDTO List of employees who have the desired qualification
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public findAllEmployeesByQualification(data: FindAllEmployeesByQualificationData): Observable<FindAllEmployeesByQualificationResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/qualifications/{id}/employees',
|
||||||
|
path: {
|
||||||
|
id: data.id
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
401: 'not authorized',
|
||||||
|
404: 'qualification id does not exist'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class EmployeeControllerService {
|
||||||
|
constructor(public readonly http: HttpClient) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find employee by id
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.id
|
||||||
|
* @returns EmployeeResponseDTO employee
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public findById(data: FindByIdData): Observable<FindByIdResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/employees/{id}',
|
||||||
|
path: {
|
||||||
|
id: data.id
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
401: 'not authorized',
|
||||||
|
404: 'resource not found'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates employee by id
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.id
|
||||||
|
* @param data.requestBody
|
||||||
|
* @returns EmployeeResponseDTO employee
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public updateEmployee(data: UpdateEmployeeData): Observable<UpdateEmployeeResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'PUT',
|
||||||
|
url: '/employees/{id}',
|
||||||
|
path: {
|
||||||
|
id: data.id
|
||||||
|
},
|
||||||
|
body: data.requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
401: 'not authorized',
|
||||||
|
404: 'resource not found'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deletes a employee by id
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.id
|
||||||
|
* @returns void delete successful
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public deleteCustomer(data: DeleteCustomerData): Observable<DeleteCustomerResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'DELETE',
|
||||||
|
url: '/employees/{id}',
|
||||||
|
path: {
|
||||||
|
id: data.id
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
401: 'not authorized',
|
||||||
|
404: 'resource not found'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates employee by id
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.id
|
||||||
|
* @param data.requestBody
|
||||||
|
* @returns EmployeeResponseDTO employee
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public patchEmployee(data: PatchEmployeeData): Observable<PatchEmployeeResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'PATCH',
|
||||||
|
url: '/employees/{id}',
|
||||||
|
path: {
|
||||||
|
id: data.id
|
||||||
|
},
|
||||||
|
body: data.requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
401: 'not authorized',
|
||||||
|
404: 'resource not found'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delivers a list of all employees
|
||||||
|
* @returns EmployeeResponseDTO list of employees
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public findAll1(): Observable<FindAll1Response> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/employees',
|
||||||
|
errors: {
|
||||||
|
401: 'not authorized'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a new employee
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.requestBody
|
||||||
|
* @returns EmployeeResponseDTO created employee
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public createEmployee(data: CreateEmployeeData): Observable<CreateEmployeeResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/employees',
|
||||||
|
body: data.requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
400: 'invalid JSON posted',
|
||||||
|
401: 'not authorized'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* finds all qualifications of an employee by id
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.id
|
||||||
|
* @returns EmployeeNameAndSkillDataDTO employee with a list of his qualifications
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public findAllQualificationOfAemployeeById(data: FindAllQualificationOfAemployeeByIdData): Observable<FindAllQualificationOfAemployeeByIdResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/employees/{id}/qualifications',
|
||||||
|
path: {
|
||||||
|
id: data.id
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
401: 'not authorized',
|
||||||
|
404: 'resource not found'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds a qualification to an employee by id
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.id
|
||||||
|
* @param data.requestBody
|
||||||
|
* @returns EmployeeNameAndSkillDataDTO employee with a list of his qualifications
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public addQualificationToEmployeeById(data: AddQualificationToEmployeeByIdData): Observable<AddQualificationToEmployeeByIdResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/employees/{id}/qualifications',
|
||||||
|
path: {
|
||||||
|
id: data.id
|
||||||
|
},
|
||||||
|
body: data.requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
400: 'invalid JSON posted or employee already has this qualification',
|
||||||
|
401: 'not authorized',
|
||||||
|
404: 'resource not found'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deletes a qualification of an employee by id
|
||||||
|
* @param data The data for the request.
|
||||||
|
* @param data.eid
|
||||||
|
* @param data.qid
|
||||||
|
* @returns EmployeeNameAndSkillDataDTO employee with a list of his qualifications
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public removeQualificationFromEmployee(data: RemoveQualificationFromEmployeeData): Observable<RemoveQualificationFromEmployeeResponse> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'DELETE',
|
||||||
|
url: '/employees/{eid}/qualifications/{qid}',
|
||||||
|
path: {
|
||||||
|
eid: data.eid,
|
||||||
|
qid: data.qid
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
401: 'not authorized',
|
||||||
|
404: 'resource not found'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
140
src/app/core/ems/types.gen.ts
Normal file
140
src/app/core/ems/types.gen.ts
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
// This file is auto-generated by @hey-api/openapi-ts
|
||||||
|
|
||||||
|
export type QualificationPostDTO = {
|
||||||
|
skill: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EmployeeRequestPutDTO = {
|
||||||
|
lastName?: string;
|
||||||
|
firstName?: string;
|
||||||
|
street?: string;
|
||||||
|
postcode?: string;
|
||||||
|
city?: string;
|
||||||
|
phone?: string;
|
||||||
|
skillSet?: Array<(number)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EmployeeResponseDTO = {
|
||||||
|
id?: number;
|
||||||
|
lastName: string;
|
||||||
|
firstName: string;
|
||||||
|
street: string;
|
||||||
|
postcode: string;
|
||||||
|
city: string;
|
||||||
|
phone: string;
|
||||||
|
skillSet?: Array<QualificationGetDTO>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type QualificationGetDTO = {
|
||||||
|
skill?: string;
|
||||||
|
id?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EmployeeRequestDTO = {
|
||||||
|
lastName: string;
|
||||||
|
firstName: string;
|
||||||
|
street: string;
|
||||||
|
postcode: string;
|
||||||
|
city: string;
|
||||||
|
phone: string;
|
||||||
|
skillSet?: Array<(number)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EmployeeNameAndSkillDataDTO = {
|
||||||
|
id?: number;
|
||||||
|
lastName?: string;
|
||||||
|
firstName?: string;
|
||||||
|
skillSet?: Array<QualificationGetDTO>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EmployeeNameDataDTO = {
|
||||||
|
id?: number;
|
||||||
|
lastName?: string;
|
||||||
|
firstName?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EmployeesForAQualificationDTO = {
|
||||||
|
qualification?: QualificationGetDTO;
|
||||||
|
employees?: Array<EmployeeNameDataDTO>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdateQualificationData = {
|
||||||
|
id: number;
|
||||||
|
requestBody: QualificationPostDTO;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdateQualificationResponse = (QualificationPostDTO);
|
||||||
|
|
||||||
|
export type DeleteQualificationByDesignationData = {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DeleteQualificationByDesignationResponse = (void);
|
||||||
|
|
||||||
|
export type FindAllResponse = (QualificationGetDTO);
|
||||||
|
|
||||||
|
export type CreateQualificationData = {
|
||||||
|
requestBody: QualificationPostDTO;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CreateQualificationResponse = (QualificationPostDTO);
|
||||||
|
|
||||||
|
export type FindAllEmployeesByQualificationData = {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type FindAllEmployeesByQualificationResponse = (EmployeesForAQualificationDTO);
|
||||||
|
|
||||||
|
export type FindByIdData = {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type FindByIdResponse = (EmployeeResponseDTO);
|
||||||
|
|
||||||
|
export type UpdateEmployeeData = {
|
||||||
|
id: number;
|
||||||
|
requestBody: EmployeeRequestPutDTO;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdateEmployeeResponse = (EmployeeResponseDTO);
|
||||||
|
|
||||||
|
export type DeleteCustomerData = {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DeleteCustomerResponse = (void);
|
||||||
|
|
||||||
|
export type PatchEmployeeData = {
|
||||||
|
id: number;
|
||||||
|
requestBody: EmployeeRequestPutDTO;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PatchEmployeeResponse = (EmployeeResponseDTO);
|
||||||
|
|
||||||
|
export type FindAll1Response = (Array<EmployeeResponseDTO>);
|
||||||
|
|
||||||
|
export type CreateEmployeeData = {
|
||||||
|
requestBody: EmployeeRequestDTO;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CreateEmployeeResponse = (EmployeeResponseDTO);
|
||||||
|
|
||||||
|
export type FindAllQualificationOfAemployeeByIdData = {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type FindAllQualificationOfAemployeeByIdResponse = (EmployeeNameAndSkillDataDTO);
|
||||||
|
|
||||||
|
export type AddQualificationToEmployeeByIdData = {
|
||||||
|
id: number;
|
||||||
|
requestBody: QualificationPostDTO;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AddQualificationToEmployeeByIdResponse = (EmployeeNameAndSkillDataDTO);
|
||||||
|
|
||||||
|
export type RemoveQualificationFromEmployeeData = {
|
||||||
|
eid: number;
|
||||||
|
qid: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RemoveQualificationFromEmployeeResponse = (EmployeeNameAndSkillDataDTO);
|
0
src/app/types/.gitkeep
Normal file
0
src/app/types/.gitkeep
Normal file
13
src/index.html
Normal file
13
src/index.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>A</title>
|
||||||
|
<base href="/">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<app-root></app-root>
|
||||||
|
</body>
|
||||||
|
</html>
|
7
src/main.ts
Normal file
7
src/main.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { bootstrapApplication } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
import { AppComponent } from './app/app.component';
|
||||||
|
import { appConfig } from './app/app.config';
|
||||||
|
|
||||||
|
bootstrapApplication(AppComponent, appConfig)
|
||||||
|
.catch((err) => console.error(err));
|
1
src/styles.scss
Normal file
1
src/styles.scss
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/* You can add global styles to this file, and also import other style files */
|
15
tsconfig.app.json
Normal file
15
tsconfig.app.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./out-tsc/app",
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/main.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
46
tsconfig.json
Normal file
46
tsconfig.json
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"compileOnSave": false,
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./dist/out-tsc",
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"noPropertyAccessFromIndexSignature": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"importHelpers": true,
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ES2022",
|
||||||
|
"useDefineForClassFields": false,
|
||||||
|
"lib": [
|
||||||
|
"ES2022",
|
||||||
|
"dom"
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"./*"
|
||||||
|
],
|
||||||
|
"@app/*": [
|
||||||
|
"./src/app/*"
|
||||||
|
],
|
||||||
|
"@dt/*": [
|
||||||
|
"./src/app/types/*"
|
||||||
|
],
|
||||||
|
"@core/*": [
|
||||||
|
"./src/app/core/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"enableI18nLegacyMessageIdFormat": false,
|
||||||
|
"strictInjectionParameters": true,
|
||||||
|
"strictInputAccessModifiers": true,
|
||||||
|
"strictTemplates": true
|
||||||
|
}
|
||||||
|
}
|
15
tsconfig.spec.json
Normal file
15
tsconfig.spec.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"jasmine"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.spec.ts",
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in a new issue