Compare commits
166 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2cfaaa4d87 | |||
| 5850b1cfb0 | |||
| 8833d2ca6a | |||
| 1290a45fb5 | |||
| 3afbbf900d | |||
| f71419d37b | |||
| f5f673fd4e | |||
| 8ec0784490 | |||
| 13faff8e01 | |||
| 0a4f6bb0f9 | |||
| 3b4e5634b1 | |||
| 8c98e6de26 | |||
| 525d82cbda | |||
| e26aaa1420 | |||
| ec7f05d8fc | |||
| 727e95e732 | |||
| 75d3bf6ffb | |||
| 94782fc468 | |||
| 101ece44d8 | |||
| e880594a5b | |||
| c222d4cd7a | |||
| cb0fa3f728 | |||
| 4709e431b7 | |||
| bfccca72a1 | |||
| 8a3eebaab5 | |||
| 6716103d0c | |||
| ee78af1abe | |||
| 1fc726ee4b | |||
| 882f48de0b | |||
| 097a3efd4a | |||
| 934ef826c9 | |||
| bb049441b4 | |||
| 2bdbef8f8a | |||
| 20f29d88fa | |||
| 1997957069 | |||
| 116bb77e4c | |||
| a6eeea6c1f | |||
| 4a61d6a727 | |||
| 98e3d91edd | |||
| a169f6a6c1 | |||
| b14a267b5b | |||
| a43e2c806c | |||
| 10834df92b | |||
| 3d97c3360a | |||
| 76d91dd506 | |||
| 84aff2b7d7 | |||
| 2f8c10a692 | |||
| c5f74e007a | |||
| 243f693f9d | |||
| 976b4f3f47 | |||
| 1b18dae311 | |||
| 38e77b25b1 | |||
| bbc08863f0 | |||
| d58f18d206 | |||
| fd5bc54eee | |||
| cbc57d22f8 | |||
| a5cdf8867a | |||
| 45971518ee | |||
| 7db244f599 | |||
| 41e2b11da2 | |||
| 0d1b2e416e | |||
| d8eecb4dab | |||
| 3bb3b22cea | |||
| 8ffd421c1b | |||
| 6d54c7f315 | |||
| f5fb743503 | |||
| ca9022d289 | |||
| ed0e108599 | |||
| 7dc18b10cb | |||
| 171bc1676a | |||
| 1a5cd6ffe8 | |||
| 71ecfaff1f | |||
| f33aaadce7 | |||
| 591171b223 | |||
| da453d642d | |||
| e733fa21e6 | |||
| c61e49720e | |||
| d01489b1fa | |||
| 93c7498a83 | |||
| fe89cc6e0f | |||
| 1e9ca7c1a4 | |||
| 400aff6524 | |||
| 845f085a76 | |||
| 88c623edb7 | |||
| 0cc73c09aa | |||
| e8660faa06 | |||
| 4e884fdbe5 | |||
| 4c330a1138 | |||
| 65288a53a1 | |||
| 60fba0d3e9 | |||
| ada723dc48 | |||
| f07c7b74ee | |||
| f3c59c11ba | |||
| 3c4d3ad326 | |||
| 917e287784 | |||
| 611d6b9e61 | |||
| 58263cb854 | |||
| 33dcbc4413 | |||
| f3cf1a17f3 | |||
| 3466c10a88 | |||
| 4cea554116 | |||
| 332e09b283 | |||
| d3c720f995 | |||
| 453ad2af7b | |||
| 54bc17ee7d | |||
| 89b7b87b8c | |||
| 3f0a37ff19 | |||
| 954dab289a | |||
| 5affa16505 | |||
| d2b1cb999a | |||
| f1d36acff7 | |||
| 7e8a6b3c91 | |||
| b424e95e05 | |||
| 28746adfbb | |||
| 0d2f27f771 | |||
| d6410e2584 | |||
| ce1514f20a | |||
| c8ea7c4188 | |||
| 245ee2378e | |||
| afb3ac88c8 | |||
| 3a0a0055a6 | |||
| 283577df9b | |||
| 276302570f | |||
| f74c07af9a | |||
| d0eae1980a | |||
| 820ae3d374 | |||
| bf14c9a020 | |||
| a3652cc9b8 | |||
| 8f2e99195a | |||
| 2ae11e24ef | |||
| a1e8474149 | |||
| 9b329c0ac4 | |||
| 8120c92b32 | |||
| 5c261529fc | |||
| 6923b3e5ee | |||
| fc4110b11d | |||
| e078f43cc6 | |||
| 24e4c0b58e | |||
| 8d31a92692 | |||
| c619745a4a | |||
| c769115331 | |||
| 1a7da0ab9f | |||
| 78632e0e12 | |||
| 3aed8af868 | |||
| c6d1e4d7e7 | |||
| d98dc79cf8 | |||
| 9dcc09c586 | |||
| 57e7b9e999 | |||
| d97145b629 | |||
| 8ba23b6365 | |||
| 66d61e2c1f | |||
| 83f645d4c6 | |||
| 7d84e341d6 | |||
| c3ec0977c0 | |||
| d51bc47ffe | |||
| faa1d73eea | |||
| fe407d6d89 | |||
| 0759c99c1d | |||
| 77bb86a9fa | |||
| 4d7d7391c3 | |||
| c5aa3b32ef | |||
| 4ff999a74e | |||
| bdf2b2ba43 | |||
| 04dfe483e4 | |||
| 4a279738e3 | |||
| 3f65ec55fc |
@@ -1,19 +0,0 @@
|
|||||||
name: Gitea Actions Demo
|
|
||||||
run-name: ${{ gitea.actor }} ist testing out Gitea Actions
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
Explore-Gitea-Actions:
|
|
||||||
runs-on: inky
|
|
||||||
steps:
|
|
||||||
- run: echo "The job was automatically triggered by a ${{ gitea.event_name }} event."
|
|
||||||
- run: echo "This job is now running on a ${{ runner.os }} server hosted by Gitea!"
|
|
||||||
- run: echo "The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
|
|
||||||
- name: Check out repository code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- run: echo "The ${{ gitea.repository }} repository has been cloned to the runner."
|
|
||||||
- run: echo "The workflow is now ready to test your code on the runner."
|
|
||||||
- name: List files in the directory
|
|
||||||
run: |
|
|
||||||
ls ${{ gitea.workspace }}
|
|
||||||
- run: echo "The job's status is ${{ job.status }}."
|
|
||||||
+2
-6
@@ -1,6 +1,6 @@
|
|||||||
.vscode/
|
|
||||||
.idea/
|
.idea/
|
||||||
.angular/
|
.theia/
|
||||||
|
.vscode/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
bonus/
|
bonus/
|
||||||
icons/
|
icons/
|
||||||
@@ -13,8 +13,4 @@ kontor-schema/kontor_schema.egg-info
|
|||||||
kontor-gui/.pdm-python
|
kontor-gui/.pdm-python
|
||||||
kontor-gui/dist
|
kontor-gui/dist
|
||||||
fastapi/.coverage
|
fastapi/.coverage
|
||||||
kontor-api/.coverage
|
|
||||||
db-password.txt
|
db-password.txt
|
||||||
kontor-api/tests/test_main.py
|
|
||||||
kontor-api/tests/test_db.db
|
|
||||||
kontor-api/test_db.db
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
kontor_api := kontor-api
|
kontor_api := kontor-api
|
||||||
kontor_spring := kontor-spring
|
kontor_spring := kontor-spring
|
||||||
kontor_servicemix := kontor-servicemix
|
|
||||||
|
|
||||||
.PHONY: all $(kontor_spring) $(kontor_api)
|
.PHONY: all $(kontor_spring) $(kontor_api)
|
||||||
all: $(kontor_spring) $(kontor_api) $(kontor_servicemix)
|
all: $(kontor_spring) $(kontor_api)
|
||||||
|
|
||||||
$(kontor_spring) $(kontor_api) $(kontor_servicemix):
|
$(kontor_spring) $(kontor_api):
|
||||||
$(MAKE) --directory=$@ $(TARGET)
|
$(MAKE) --directory=$@ $(TARGET)
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
services:
|
|
||||||
couchdb:
|
|
||||||
image: couchdb
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
- COUCHDB_USER=admin
|
|
||||||
- COUCHDB_PASSWORD=admin
|
|
||||||
ports:
|
|
||||||
- 5984:5984
|
|
||||||
networks:
|
|
||||||
- database
|
|
||||||
- frontend
|
|
||||||
volumes:
|
|
||||||
- couchdb-data:/opt/couchdb/data
|
|
||||||
secrets:
|
|
||||||
- couchdb-password
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
couchdb-data:
|
|
||||||
secrets:
|
|
||||||
couchdb-password:
|
|
||||||
file: couchdb-password.txt
|
|
||||||
+20
-119
@@ -1,143 +1,44 @@
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
postgres:
|
mariadb:
|
||||||
image: postgres
|
image: mariadb
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_DB=kontor
|
MYSQL_ROOT_PASSWORD: kontor
|
||||||
- POSTGRES_USER=kontor
|
MYSQL_USER: kontor
|
||||||
#- POSTGRES_PASSWORD_FILE=/run/secrets/db-password
|
MYSQL_PASSWORD: kontor
|
||||||
- POSTGRES_PASSWORD=kontor
|
MYSQL_DATABASE: kontor
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "pg_isready -U kontor"]
|
|
||||||
interval: 1s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 10
|
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 3316:3306
|
||||||
networks:
|
|
||||||
- integration
|
|
||||||
- frontend
|
|
||||||
volumes:
|
|
||||||
- postgres-data:/var/lib/postgresql/data:rw
|
|
||||||
secrets:
|
|
||||||
- db-password
|
|
||||||
adminer:
|
|
||||||
image: adminer
|
|
||||||
ports:
|
|
||||||
- 8090:8080
|
|
||||||
networks:
|
networks:
|
||||||
- database
|
- database
|
||||||
- frontend
|
volumes:
|
||||||
|
- mariadb-storage:/var/lib/mysql:rw
|
||||||
kontor:
|
kontor:
|
||||||
image: kontor:0.2.0-SNAPSHOT
|
image: kontor
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- database
|
- database
|
||||||
- integration
|
|
||||||
- frontend
|
- frontend
|
||||||
ports:
|
ports:
|
||||||
- 8000:8000
|
- 8000:8000
|
||||||
volumes:
|
|
||||||
- images-data:/data/images
|
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
- mariadb
|
||||||
condition: service_healthy
|
|
||||||
kontor-api:
|
kontor-api:
|
||||||
image: kontor-api:0.2.0-SNAPSHOT
|
image: kontor-api
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://kontor-api:8500/health"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
networks:
|
networks:
|
||||||
- database
|
- database
|
||||||
- integration
|
|
||||||
- frontend
|
|
||||||
ports:
|
|
||||||
- 8500:8500
|
|
||||||
volumes:
|
|
||||||
- images-data:/data/images
|
|
||||||
depends_on:
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
kontor-fiber:
|
|
||||||
build:
|
|
||||||
context: ./kontor-fiber
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
tags:
|
|
||||||
- kontor-fiber:0.2.0-SNAPSHOT
|
|
||||||
image: kontor-fiber:0.2.0-SNAPSHOT
|
|
||||||
restart: unless-stopped
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://kontor-fiber:8600/health"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
networks:
|
|
||||||
- database
|
|
||||||
- integration
|
|
||||||
- frontend
|
|
||||||
ports:
|
|
||||||
- 8600:8600
|
|
||||||
depends_on:
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
kontor-echo:
|
|
||||||
build:
|
|
||||||
context: ./kontor-echo
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
tags:
|
|
||||||
- kontor-echo:0.2.0-SNAPSHOT
|
|
||||||
image: kontor-echo:0.2.0-SNAPSHOT
|
|
||||||
restart: unless-stopped
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://kontor-echo:8700/health"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
networks:
|
|
||||||
- database
|
|
||||||
- integration
|
|
||||||
- frontend
|
|
||||||
ports:
|
|
||||||
- 8700:8700
|
|
||||||
depends_on:
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
kontor-quarkus:
|
|
||||||
build:
|
|
||||||
context: ./kontor-quarkus
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
tags:
|
|
||||||
- kontor-quarkus:0.2.0-SNAPSHOT
|
|
||||||
image: kontor-quarkus:0.2.0-SNAPSHOT
|
|
||||||
restart: unless-stopped
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://kontor-quarkus:8800/q/health"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
networks:
|
|
||||||
- database
|
|
||||||
- integration
|
|
||||||
- frontend
|
- frontend
|
||||||
ports:
|
ports:
|
||||||
- 8800:8800
|
- 8800:8800
|
||||||
volumes:
|
|
||||||
- images-data:/data/images
|
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
- mariadb
|
||||||
condition: service_healthy
|
|
||||||
networks:
|
networks:
|
||||||
integration:
|
database:
|
||||||
name: integration
|
frontend:
|
||||||
frontend:
|
|
||||||
volumes:
|
volumes:
|
||||||
postgres-data:
|
mariadb-storage:
|
||||||
images-data:
|
|
||||||
secrets:
|
|
||||||
db-password:
|
|
||||||
file: db-password.txt
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
build/
|
||||||
|
.settings/
|
||||||
|
.gradle/
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
.vscode/
|
||||||
|
bin/
|
||||||
|
.idea/
|
||||||
|
/.eclipse-pmd
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
variables:
|
||||||
|
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- source "/home/gitlab-runner/.sdkman/bin/sdkman-init.sh"
|
||||||
|
- sdk u java 11.0.12-open
|
||||||
|
- chmod +x ./gradlew
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
- test
|
||||||
|
- analysis
|
||||||
|
- publish
|
||||||
|
|
||||||
|
Build Application:
|
||||||
|
stage: build
|
||||||
|
script: ./gradlew --build-cache compileJava
|
||||||
|
|
||||||
|
Create Documentation:
|
||||||
|
stage: build
|
||||||
|
script: ./gradlew asciidoctorPdf
|
||||||
|
|
||||||
|
Test Application:
|
||||||
|
stage: test
|
||||||
|
script: ./gradlew check
|
||||||
|
|
||||||
|
sonarqube-check:
|
||||||
|
stage: analysis
|
||||||
|
variables:
|
||||||
|
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
|
||||||
|
GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task
|
||||||
|
script: ./gradlew sonarqube
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
|
Publish Artifacts:
|
||||||
|
stage: publish
|
||||||
|
script: ./gradlew publish
|
||||||
|
|
||||||
@@ -1,36 +1,32 @@
|
|||||||
# kontor-quarkus
|
# kontor-quarkus Project
|
||||||
|
|
||||||
This project uses Quarkus, the Supersonic Subatomic Java Framework.
|
This project uses Quarkus, the Supersonic Subatomic Java Framework.
|
||||||
|
|
||||||
If you want to learn more about Quarkus, please visit its website: <https://quarkus.io/>.
|
If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ .
|
||||||
|
|
||||||
## Running the application in dev mode
|
## Running the application in dev mode
|
||||||
|
|
||||||
You can run your application in dev mode that enables live coding using:
|
You can run your application in dev mode that enables live coding using:
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
./gradlew quarkusDev
|
./gradlew quarkusDev
|
||||||
```
|
```
|
||||||
|
|
||||||
> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at <http://localhost:8080/q/dev/>.
|
> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/.
|
||||||
|
|
||||||
## Packaging and running the application
|
## Packaging and running the application
|
||||||
|
|
||||||
The application can be packaged using:
|
The application can be packaged using:
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
./gradlew build
|
./gradlew build
|
||||||
```
|
```
|
||||||
|
|
||||||
It produces the `quarkus-run.jar` file in the `build/quarkus-app/` directory.
|
It produces the `quarkus-run.jar` file in the `build/quarkus-app/` directory.
|
||||||
Be aware that it’s not an _über-jar_ as the dependencies are copied into the `build/quarkus-app/lib/` directory.
|
Be aware that it’s not an _über-jar_ as the dependencies are copied into the `build/quarkus-app/lib/` directory.
|
||||||
|
|
||||||
The application is now runnable using `java -jar build/quarkus-app/quarkus-run.jar`.
|
The application is now runnable using `java -jar build/quarkus-app/quarkus-run.jar`.
|
||||||
|
|
||||||
If you want to build an _über-jar_, execute the following command:
|
If you want to build an _über-jar_, execute the following command:
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
./gradlew build -Dquarkus.package.jar.type=uber-jar
|
./gradlew build -Dquarkus.package.type=uber-jar
|
||||||
```
|
```
|
||||||
|
|
||||||
The application, packaged as an _über-jar_, is now runnable using `java -jar build/*-runner.jar`.
|
The application, packaged as an _über-jar_, is now runnable using `java -jar build/*-runner.jar`.
|
||||||
@@ -38,31 +34,27 @@ The application, packaged as an _über-jar_, is now runnable using `java -jar bu
|
|||||||
## Creating a native executable
|
## Creating a native executable
|
||||||
|
|
||||||
You can create a native executable using:
|
You can create a native executable using:
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
./gradlew build -Dquarkus.native.enabled=true
|
./gradlew build -Dquarkus.package.type=native
|
||||||
```
|
```
|
||||||
|
|
||||||
Or, if you don't have GraalVM installed, you can run the native executable build in a container using:
|
Or, if you don't have GraalVM installed, you can run the native executable build in a container using:
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
./gradlew build -Dquarkus.native.enabled=true -Dquarkus.native.container-build=true
|
./gradlew build -Dquarkus.package.type=native -Dquarkus.native.container-build=true
|
||||||
```
|
```
|
||||||
|
|
||||||
You can then execute your native executable with: `./build/kontor-quarkus-1.0.0-SNAPSHOT-runner`
|
You can then execute your native executable with: `./build/kontor-quarkus-1.0.0-SNAPSHOT-runner`
|
||||||
|
|
||||||
If you want to learn more about building native executables, please consult <https://quarkus.io/guides/gradle-tooling>.
|
If you want to learn more about building native executables, please consult https://quarkus.io/guides/gradle-tooling.
|
||||||
|
|
||||||
## Related Guides
|
## Related Guides
|
||||||
|
|
||||||
- REST ([guide](https://quarkus.io/guides/rest)): A Jakarta REST implementation utilizing build time processing and Vert.x. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it.
|
- RESTEasy Reactive ([guide](https://quarkus.io/guides/resteasy-reactive)): A JAX-RS implementation utilizing build time processing and Vert.x. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it.
|
||||||
- REST Jackson ([guide](https://quarkus.io/guides/rest#json-serialisation)): Jackson serialization support for Quarkus REST. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it
|
|
||||||
- JDBC Driver - PostgreSQL ([guide](https://quarkus.io/guides/datasource)): Connect to the PostgreSQL database via JDBC
|
|
||||||
|
|
||||||
## Provided Code
|
## Provided Code
|
||||||
|
|
||||||
### REST
|
### RESTEasy Reactive
|
||||||
|
|
||||||
Easily start your REST Web Services
|
Easily start your Reactive RESTful Web Services
|
||||||
|
|
||||||
[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources)
|
[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources)
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'maven-publish'
|
||||||
|
id 'jacoco'
|
||||||
|
id 'jacoco-report-aggregation'
|
||||||
|
id 'pmd'
|
||||||
|
id 'checkstyle'
|
||||||
|
id 'jvm-test-suite'
|
||||||
|
id 'io.quarkus'
|
||||||
|
id "org.sonarqube" version "3.3"
|
||||||
|
alias(versionsLibs.plugins.asciidoctorConvert)
|
||||||
|
alias(versionsLibs.plugins.asciidoctorPdf)
|
||||||
|
alias(versionsLibs.plugins.asciidoctorGems)
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
ruby.gems()
|
||||||
|
maven {
|
||||||
|
url "https://nexus.thpeetz.de/nexus/content/groups/public/"
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
|
||||||
|
implementation 'io.quarkus:quarkus-resteasy-reactive'
|
||||||
|
implementation 'io.quarkus:quarkus-resteasy-reactive-jackson'
|
||||||
|
implementation 'io.quarkus:quarkus-arc'
|
||||||
|
testImplementation 'io.quarkus:quarkus-junit5'
|
||||||
|
testImplementation 'io.rest-assured:rest-assured'
|
||||||
|
testImplementation("io.quarkus:quarkus-jacoco")
|
||||||
|
}
|
||||||
|
|
||||||
|
final BUILD_DATE = new Date().format('dd.MM.yyyy').toString()
|
||||||
|
def pdfFile = layout.buildDirectory.file("docs/asciidocPdf/" + project.name + ".pdf")
|
||||||
|
def pdfArtifact = artifacts.add('archives', pdfFile.get().asFile) {
|
||||||
|
type 'pdf'
|
||||||
|
builtBy asciidoctorPdf
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(GenerateModuleMetadata).configureEach {
|
||||||
|
suppressedValidationErrors.add('enforced-platform')
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
quarkusApp(MavenPublication){
|
||||||
|
from components.java
|
||||||
|
}
|
||||||
|
docs(MavenPublication) {
|
||||||
|
groupId = group + '.docs'
|
||||||
|
artifactId = project.name
|
||||||
|
artifact pdfArtifact
|
||||||
|
}
|
||||||
|
}
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = 'nexusPeetz'
|
||||||
|
def releasesRepoUrl = "https://nexus.thpeetz.de/nexus/content/repositories/releases/"
|
||||||
|
def snapshotsRepoUrl = "https://nexus.thpeetz.de/nexus/content/repositories/snapshots/"
|
||||||
|
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
|
||||||
|
credentials(PasswordCredentials)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
|
targetCompatibility = JavaVersion.VERSION_11
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(GenerateModuleMetadata).configureEach {
|
||||||
|
suppressedValidationErrors.add('enforced-platform')
|
||||||
|
}
|
||||||
|
|
||||||
|
compileJava {
|
||||||
|
options.encoding = 'UTF-8'
|
||||||
|
options.compilerArgs << '-parameters'
|
||||||
|
}
|
||||||
|
|
||||||
|
compileTestJava {
|
||||||
|
options.encoding = 'UTF-8'
|
||||||
|
}
|
||||||
|
|
||||||
|
jacocoTestReport {
|
||||||
|
reports {
|
||||||
|
xml.required = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test.finalizedBy jacocoTestReport
|
||||||
|
|
||||||
|
|
||||||
|
pmd {
|
||||||
|
//ruleSetFiles = files("custom-pmd-ruleset.xml")
|
||||||
|
ruleSets = ["category/java/errorprone.xml", "category/java/bestpractices.xml"]
|
||||||
|
ignoreFailures = true
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(Checkstyle) {
|
||||||
|
reports {
|
||||||
|
xml.required = true
|
||||||
|
html.required = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testing {
|
||||||
|
suites {
|
||||||
|
test {
|
||||||
|
useJUnitJupiter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pmdTest.dependsOn("compileQuarkusTestGeneratedSourcesJava")
|
||||||
|
checkstyleTest.dependsOn("compileQuarkusTestGeneratedSourcesJava")
|
||||||
|
jacocoTestReport.dependsOn("compileQuarkusGeneratedSourcesJava")
|
||||||
|
pmdMain.dependsOn("compileQuarkusGeneratedSourcesJava")
|
||||||
|
|
||||||
|
sonarqube {
|
||||||
|
properties {
|
||||||
|
property "sonar.host.url", "https://sonar.thpeetz.de"
|
||||||
|
property "sonar.qualitygate.wait", true
|
||||||
|
property "sonar.sourceEncoding", "UTF-8"
|
||||||
|
property "sonar.projectKey", "kontor_kontor-quarkus_AYQek8Mxz0hBjLSV8I8O"
|
||||||
|
property "sonar.login", "5ecd90dee57806857e07443a9b0efd3cd7774a81"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.named('sonarqube').configure {
|
||||||
|
dependsOn 'test', 'pmdMain', 'checkstyleMain', 'jacocoTestReport'
|
||||||
|
}
|
||||||
|
|
||||||
|
asciidoctorPdf {
|
||||||
|
baseDirFollowsSourceFile()
|
||||||
|
|
||||||
|
asciidoctorj {
|
||||||
|
attributes 'build-gradle': file('build.gradle'),
|
||||||
|
'endpoint-url': 'https://www.thpeetz.de',
|
||||||
|
'source-highlighter': 'rouge',
|
||||||
|
'imagesdir': './images',
|
||||||
|
'toc': 'left',
|
||||||
|
'toc-title': 'Inhaltsverzeichnis',
|
||||||
|
'revdate': BUILD_DATE,
|
||||||
|
'revnumber': { project.version.toString() },
|
||||||
|
'revremark': 'Entwurf',
|
||||||
|
'chapter-label': '',
|
||||||
|
'icons': 'font',
|
||||||
|
'idprefix': 'id_',
|
||||||
|
'idseparator': '-',
|
||||||
|
'docinfo1': ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapper {
|
||||||
|
gradleVersion = "7.5"
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||||
|
<module name="Checker">
|
||||||
|
<module name="TreeWalker">
|
||||||
|
<module name="UnusedImports" />
|
||||||
|
<module name="AvoidStarImport" />
|
||||||
|
<module name="ConstantName" />
|
||||||
|
<module name="NeedBraces" />
|
||||||
|
<module name="RightCurly" />
|
||||||
|
<module name="ModifierOrder">
|
||||||
|
<property name="severity" value="warning"/>
|
||||||
|
</module>
|
||||||
|
</module>
|
||||||
|
</module>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#Gradle properties
|
||||||
|
group=de.thpeetz.kontor
|
||||||
|
version=1.0.0-SNAPSHOT
|
||||||
|
|
||||||
|
quarkusPluginId=io.quarkus
|
||||||
|
quarkusPluginVersion=2.13.2.Final
|
||||||
|
quarkusPlatformGroupId=io.quarkus.platform
|
||||||
|
quarkusPlatformArtifactId=quarkus-bom
|
||||||
|
quarkusPlatformVersion=2.13.2.Final
|
||||||
BIN
Binary file not shown.
+1
-3
@@ -1,7 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||||
networkTimeout=10000
|
|
||||||
validateDistributionUrl=true
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
Vendored
+185
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=`expr $i + 1`
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
0) set -- ;;
|
||||||
|
1) set -- "$args0" ;;
|
||||||
|
2) set -- "$args0" "$args1" ;;
|
||||||
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
||||||
+32
-22
@@ -13,8 +13,6 @@
|
|||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
@rem SPDX-License-Identifier: Apache-2.0
|
|
||||||
@rem
|
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%" == "" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@@ -28,7 +26,6 @@ if "%OS%"=="Windows_NT" setlocal
|
|||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
@rem This is normally unused
|
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@@ -43,13 +40,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@@ -57,36 +54,49 @@ goto fail
|
|||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|
||||||
set CLASSPATH=
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
@rem Execute Gradle
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
set EXIT_CODE=%ERRORLEVEL%
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
exit /b 1
|
||||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
|
||||||
exit /b %EXIT_CODE%
|
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
= Projektbeschreibung kontor-quarkus: Pflichtenheft und Projekthandbuch
|
||||||
|
:author: Thomas Peetz
|
||||||
|
:email: <thomas.peetz@thpeetz.de>
|
||||||
|
:doctype: article
|
||||||
|
:sectnums:
|
||||||
|
:sectnumlevels: 4
|
||||||
|
:toc:
|
||||||
|
:toclevels: 4
|
||||||
|
:table-caption!:
|
||||||
|
:counter: table-number: 0
|
||||||
|
|
||||||
|
//[title="Dokumenthistorie", caption="Tabelle {counter:table-number} ", id="Tabelle-{counter:table-number}", options="header"]
|
||||||
|
//[title="Dokumenthistorie", id="Table-{counter:table-number}", options="header", cols="4"]
|
||||||
|
[title="Dokumenthistorie", id="Table-{counter:table-number}", options="header"]
|
||||||
|
|===
|
||||||
|
| Version | Datum | Autor | Änderungsgrund / Bemerkungen
|
||||||
|
| 0.0.1 | 16.05.2022 | Thomas Peetz | Ersterstellung
|
||||||
|
|===
|
||||||
|
|
||||||
|
== Einführung
|
||||||
|
|
||||||
|
=== Zweck
|
||||||
|
|
||||||
|
=== Stakeholder des Systems
|
||||||
|
|
||||||
|
=== Systemumfang
|
||||||
|
|
||||||
|
==== Zielsetzung des Systems
|
||||||
|
|
||||||
|
=== Systemübersicht
|
||||||
|
|
||||||
|
==== Systemkontext
|
||||||
|
|
||||||
|
==== Systemarchitektur
|
||||||
|
|
||||||
|
==== Systemschnittstellen
|
||||||
|
|
||||||
|
===== Realisierte Schnittstellen
|
||||||
|
|
||||||
|
===== Verwendete Schnittstellen
|
||||||
|
|
||||||
|
==== Logisches Datenmodell
|
||||||
|
|
||||||
|
==== Einschränkungen
|
||||||
|
|
||||||
|
== Anforderungen der Domäne
|
||||||
|
|
||||||
|
=== Systemfunktionen
|
||||||
|
|
||||||
|
==== Anwendungsfälle
|
||||||
|
|
||||||
|
==== Akteure
|
||||||
|
|
||||||
|
==== Zielgruppen
|
||||||
|
|
||||||
|
=== Anforderungen
|
||||||
|
|
||||||
|
==== Anforderungen an externe Schnittstellen
|
||||||
|
|
||||||
|
==== Funktionale Anforderungen
|
||||||
|
|
||||||
|
==== Qualitätsanforderungen
|
||||||
|
|
||||||
|
==== Randbedingungen
|
||||||
|
|
||||||
|
==== Weitere Anforderungen
|
||||||
|
|
||||||
|
==== Wartungs- und Supportinformationen
|
||||||
|
|
||||||
|
=== Verifikation
|
||||||
|
|
||||||
|
[bibliography]
|
||||||
|
== Referenzen
|
||||||
|
|
||||||
|
[glossary]
|
||||||
|
== Glossar
|
||||||
|
|
||||||
|
== Verzeichnisse
|
||||||
|
|
||||||
|
=== Abbildungsverzeichnis
|
||||||
|
|
||||||
|
=== Tabellenverzeichnis
|
||||||
|
|
||||||
|
<<Table-1, Tabelle 1>> <<Table-1>>
|
||||||
+5
-9
@@ -14,9 +14,7 @@
|
|||||||
# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus-jvm
|
# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus-jvm
|
||||||
#
|
#
|
||||||
# If you want to include the debug port into your docker image
|
# If you want to include the debug port into your docker image
|
||||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005
|
||||||
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
|
|
||||||
# when running the container
|
|
||||||
#
|
#
|
||||||
# Then run the container using :
|
# Then run the container using :
|
||||||
#
|
#
|
||||||
@@ -26,8 +24,7 @@
|
|||||||
# This scripts computes the command line to execute your Java application, and
|
# This scripts computes the command line to execute your Java application, and
|
||||||
# includes memory/GC tuning.
|
# includes memory/GC tuning.
|
||||||
# You can configure the behavior using the following environment properties:
|
# You can configure the behavior using the following environment properties:
|
||||||
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") - Be aware that this will override
|
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
|
||||||
# the default JVM options, use `JAVA_OPTS_APPEND` to append options
|
|
||||||
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
||||||
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
||||||
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
||||||
@@ -78,7 +75,7 @@
|
|||||||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||||
#
|
#
|
||||||
###
|
###
|
||||||
FROM registry.access.redhat.com/ubi9/openjdk-21:1.21
|
FROM registry.access.redhat.com/ubi8/openjdk-11:1.14
|
||||||
|
|
||||||
ENV LANGUAGE='en_US:en'
|
ENV LANGUAGE='en_US:en'
|
||||||
|
|
||||||
@@ -91,8 +88,7 @@ COPY --chown=185 build/quarkus-app/quarkus/ /deployments/quarkus/
|
|||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
USER 185
|
USER 185
|
||||||
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
ENV AB_JOLOKIA_OFF=""
|
||||||
|
ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||||
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
||||||
|
|
||||||
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
|
|
||||||
|
|
||||||
+6
-10
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# Before building the container image run:
|
# Before building the container image run:
|
||||||
#
|
#
|
||||||
# ./gradlew build -Dquarkus.package.jar.type=legacy-jar
|
# ./gradlew build -Dquarkus.package.type=legacy-jar
|
||||||
#
|
#
|
||||||
# Then, build the image with:
|
# Then, build the image with:
|
||||||
#
|
#
|
||||||
@@ -14,9 +14,7 @@
|
|||||||
# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus-legacy-jar
|
# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus-legacy-jar
|
||||||
#
|
#
|
||||||
# If you want to include the debug port into your docker image
|
# If you want to include the debug port into your docker image
|
||||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005
|
||||||
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
|
|
||||||
# when running the container
|
|
||||||
#
|
#
|
||||||
# Then run the container using :
|
# Then run the container using :
|
||||||
#
|
#
|
||||||
@@ -26,8 +24,7 @@
|
|||||||
# This scripts computes the command line to execute your Java application, and
|
# This scripts computes the command line to execute your Java application, and
|
||||||
# includes memory/GC tuning.
|
# includes memory/GC tuning.
|
||||||
# You can configure the behavior using the following environment properties:
|
# You can configure the behavior using the following environment properties:
|
||||||
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") - Be aware that this will override
|
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
|
||||||
# the default JVM options, use `JAVA_OPTS_APPEND` to append options
|
|
||||||
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
||||||
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
||||||
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
||||||
@@ -78,7 +75,7 @@
|
|||||||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||||
#
|
#
|
||||||
###
|
###
|
||||||
FROM registry.access.redhat.com/ubi9/openjdk-21:1.21
|
FROM registry.access.redhat.com/ubi8/openjdk-11:1.14
|
||||||
|
|
||||||
ENV LANGUAGE='en_US:en'
|
ENV LANGUAGE='en_US:en'
|
||||||
|
|
||||||
@@ -88,7 +85,6 @@ COPY build/*-runner.jar /deployments/quarkus-run.jar
|
|||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
USER 185
|
USER 185
|
||||||
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
ENV AB_JOLOKIA_OFF=""
|
||||||
|
ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||||
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
||||||
|
|
||||||
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
|
|
||||||
+4
-6
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# Before building the container image run:
|
# Before building the container image run:
|
||||||
#
|
#
|
||||||
# ./gradlew build -Dquarkus.native.enabled=true
|
# ./gradlew build -Dquarkus.package.type=native
|
||||||
#
|
#
|
||||||
# Then, build the image with:
|
# Then, build the image with:
|
||||||
#
|
#
|
||||||
@@ -13,17 +13,15 @@
|
|||||||
#
|
#
|
||||||
# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus
|
# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus
|
||||||
#
|
#
|
||||||
# The ` registry.access.redhat.com/ubi9/ubi-minimal:9.5` base image is based on UBI 9.
|
|
||||||
# To use UBI 8, switch to `quay.io/ubi8/ubi-minimal:8.10`.
|
|
||||||
###
|
###
|
||||||
FROM registry.access.redhat.com/ubi9/ubi-minimal:9.5
|
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6
|
||||||
WORKDIR /work/
|
WORKDIR /work/
|
||||||
RUN chown 1001 /work \
|
RUN chown 1001 /work \
|
||||||
&& chmod "g+rwX" /work \
|
&& chmod "g+rwX" /work \
|
||||||
&& chown 1001:root /work
|
&& chown 1001:root /work
|
||||||
COPY --chown=1001:root --chmod=0755 build/*-runner /work/application
|
COPY --chown=1001:root build/*-runner /work/application
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
USER 1001
|
USER 1001
|
||||||
|
|
||||||
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
||||||
+4
-6
@@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
# Before building the container image run:
|
# Before building the container image run:
|
||||||
#
|
#
|
||||||
# ./gradlew build -Dquarkus.native.enabled=true
|
# ./gradlew build -Dquarkus.package.type=native
|
||||||
#
|
#
|
||||||
# Then, build the image with:
|
# Then, build the image with:
|
||||||
#
|
#
|
||||||
@@ -16,17 +16,15 @@
|
|||||||
#
|
#
|
||||||
# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus
|
# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus
|
||||||
#
|
#
|
||||||
# The `quay.io/quarkus/ubi9-quarkus-micro-image:2.0` base image is based on UBI 9.
|
|
||||||
# To use UBI 8, switch to `quay.io/quarkus/quarkus-micro-image:2.0`.
|
|
||||||
###
|
###
|
||||||
FROM quay.io/quarkus/ubi9-quarkus-micro-image:2.0
|
FROM quay.io/quarkus/quarkus-micro-image:1.0
|
||||||
WORKDIR /work/
|
WORKDIR /work/
|
||||||
RUN chown 1001 /work \
|
RUN chown 1001 /work \
|
||||||
&& chmod "g+rwX" /work \
|
&& chmod "g+rwX" /work \
|
||||||
&& chown 1001:root /work
|
&& chown 1001:root /work
|
||||||
COPY --chown=1001:root --chmod=0755 build/*-runner /work/application
|
COPY --chown=1001:root build/*-runner /work/application
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
USER 1001
|
USER 1001
|
||||||
|
|
||||||
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package de.thpeetz.kontor.comics;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import de.thpeetz.kontor.comics.service.ArtistService;
|
||||||
|
import de.thpeetz.kontor.comics.service.ComicsService;
|
||||||
|
import de.thpeetz.kontor.comics.service.PublisherService;
|
||||||
|
|
||||||
|
@Path("/kontor/comics")
|
||||||
|
public class ComicsResource {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
transient ComicsService comicsService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
transient ArtistService artistService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
transient PublisherService publisherService;
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.TEXT_HTML)
|
||||||
|
@Path("/")
|
||||||
|
public String showComicList() {
|
||||||
|
return comicsService.showComicList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.TEXT_HTML)
|
||||||
|
@Path("/artist")
|
||||||
|
public String showArtistList() {
|
||||||
|
return artistService.showArtistList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/artist")
|
||||||
|
public String showArtistListJson() {
|
||||||
|
return artistService.showArtistList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.TEXT_HTML)
|
||||||
|
@Path("/artist/view/{artist_id}")
|
||||||
|
public String showArtist(String artist_id) {
|
||||||
|
return artistService.showArtist(artist_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.TEXT_HTML)
|
||||||
|
@Path("/artist/create")
|
||||||
|
public String showArtistCreation() {
|
||||||
|
return artistService.showArtistCreation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Produces(MediaType.TEXT_HTML)
|
||||||
|
@Path("/artist/create")
|
||||||
|
public String validateArtistDetails() {
|
||||||
|
return artistService.validateArtistDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.TEXT_HTML)
|
||||||
|
@Path("/publisher")
|
||||||
|
public String showPublisherList() {
|
||||||
|
return publisherService.showPublisherList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.TEXT_HTML)
|
||||||
|
@Path("/publisher/view/{publisher_id}")
|
||||||
|
public String showPublisher(String publisher_id) {
|
||||||
|
return publisherService.showPublisher(publisher_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.TEXT_HTML)
|
||||||
|
@Path("/publisher/create")
|
||||||
|
public String showPublisherCreation() {
|
||||||
|
return publisherService.showPublisherCreation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Produces(MediaType.TEXT_HTML)
|
||||||
|
@Path("/publisher/create")
|
||||||
|
public String validatePublisherDetails() {
|
||||||
|
return publisherService.validatePublisherDetails();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package de.thpeetz.kontor.comics.service;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class ArtistService {
|
||||||
|
|
||||||
|
public String showArtistList() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String showArtist(String artist_id) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String showArtistCreation() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String validateArtistDetails() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package de.thpeetz.kontor.comics.service;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class ComicsService {
|
||||||
|
|
||||||
|
public String showComicList() {
|
||||||
|
return "comics";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package de.thpeetz.kontor.comics.service;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class PublisherService {
|
||||||
|
|
||||||
|
public String showPublisherList() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String showPublisher(String publisher_id) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String showPublisherCreation() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String validatePublisherDetails() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
|
|||||||
|
# Your configuration properties
|
||||||
|
quarkus.http.test-port=8083
|
||||||
|
quarkus.http.test-ssl-port=8446
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package de.thpeetz.kontor.comics;
|
||||||
|
|
||||||
|
import io.quarkus.test.junit.QuarkusIntegrationTest;
|
||||||
|
|
||||||
|
@QuarkusIntegrationTest
|
||||||
|
public class ComicsResourceIT extends ComicsResourceTest {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package de.thpeetz.kontor.comics;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static io.restassured.RestAssured.given;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
|
||||||
|
import io.quarkus.test.junit.QuarkusTest;
|
||||||
|
|
||||||
|
@QuarkusTest
|
||||||
|
class ComicsResourceTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testComicsEndpoint() {
|
||||||
|
given().when().get("/kontor/comics")
|
||||||
|
.then()
|
||||||
|
.statusCode(200)
|
||||||
|
.body(is("comics"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
dist
|
|
||||||
node_modules
|
|
||||||
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
|
|
||||||
|
|
||||||
# Compiled output
|
|
||||||
/dist
|
|
||||||
/tmp
|
|
||||||
/out-tsc
|
|
||||||
/bazel-out
|
|
||||||
|
|
||||||
# Node
|
|
||||||
/node_modules
|
|
||||||
npm-debug.log
|
|
||||||
yarn-error.log
|
|
||||||
|
|
||||||
# IDEs and editors
|
|
||||||
.idea/
|
|
||||||
.project
|
|
||||||
.classpath
|
|
||||||
.c9/
|
|
||||||
*.launch
|
|
||||||
.settings/
|
|
||||||
*.sublime-workspace
|
|
||||||
|
|
||||||
# Visual Studio Code
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
.history/*
|
|
||||||
|
|
||||||
# Miscellaneous
|
|
||||||
/.angular/cache
|
|
||||||
.sass-cache/
|
|
||||||
/connect.lock
|
|
||||||
/coverage
|
|
||||||
/libpeerconnection.log
|
|
||||||
testem.log
|
|
||||||
/typings
|
|
||||||
|
|
||||||
# System files
|
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
### STAGE 1: Build ###
|
|
||||||
FROM docker.io/node:22-alpine AS build
|
|
||||||
WORKDIR /app
|
|
||||||
COPY package.json package-lock.json ./
|
|
||||||
RUN npm install
|
|
||||||
COPY . .
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
### STAGE 2: Run ###
|
|
||||||
FROM docker.io/library/nginx:stable-alpine
|
|
||||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
|
||||||
COPY --from=build /app/dist/kontor-angular/browser /usr/share/nginx/html
|
|
||||||
EXPOSE 80
|
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
.PHONY: docker dev
|
|
||||||
|
|
||||||
docker:
|
|
||||||
docker build -t kontor-angular:0.2.0-SNAPSHOT .
|
|
||||||
|
|
||||||
dev:
|
|
||||||
ng serve
|
|
||||||
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
# KontorAngular
|
|
||||||
|
|
||||||
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.2.1.
|
|
||||||
|
|
||||||
## Development server
|
|
||||||
|
|
||||||
To start a local development server, run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ng serve
|
|
||||||
```
|
|
||||||
|
|
||||||
Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
|
|
||||||
|
|
||||||
## Code scaffolding
|
|
||||||
|
|
||||||
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ng generate component component-name
|
|
||||||
```
|
|
||||||
|
|
||||||
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ng generate --help
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building
|
|
||||||
|
|
||||||
To build the project run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ng build
|
|
||||||
```
|
|
||||||
|
|
||||||
This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
|
|
||||||
|
|
||||||
## Running unit tests
|
|
||||||
|
|
||||||
To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ng test
|
|
||||||
```
|
|
||||||
|
|
||||||
## Running end-to-end tests
|
|
||||||
|
|
||||||
For end-to-end (e2e) testing, run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ng e2e
|
|
||||||
```
|
|
||||||
|
|
||||||
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
|
||||||
|
|
||||||
## Additional Resources
|
|
||||||
|
|
||||||
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
|
||||||
"version": 1,
|
|
||||||
"newProjectRoot": "projects",
|
|
||||||
"projects": {
|
|
||||||
"kontor-angular": {
|
|
||||||
"projectType": "application",
|
|
||||||
"schematics": {},
|
|
||||||
"root": "",
|
|
||||||
"sourceRoot": "src",
|
|
||||||
"prefix": "app",
|
|
||||||
"architect": {
|
|
||||||
"build": {
|
|
||||||
"builder": "@angular/build:application",
|
|
||||||
"options": {
|
|
||||||
"browser": "src/main.ts",
|
|
||||||
"polyfills": [
|
|
||||||
"zone.js"
|
|
||||||
],
|
|
||||||
"tsConfig": "tsconfig.app.json",
|
|
||||||
"assets": [
|
|
||||||
{
|
|
||||||
"glob": "**/*",
|
|
||||||
"input": "public"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"styles": [
|
|
||||||
"src/styles.css"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"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/build:dev-server",
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"buildTarget": "kontor-angular:build:production"
|
|
||||||
},
|
|
||||||
"development": {
|
|
||||||
"buildTarget": "kontor-angular:build:development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultConfiguration": "development"
|
|
||||||
},
|
|
||||||
"extract-i18n": {
|
|
||||||
"builder": "@angular/build:extract-i18n"
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"builder": "@angular/build:karma",
|
|
||||||
"options": {
|
|
||||||
"polyfills": [
|
|
||||||
"zone.js",
|
|
||||||
"zone.js/testing"
|
|
||||||
],
|
|
||||||
"tsConfig": "tsconfig.spec.json",
|
|
||||||
"assets": [
|
|
||||||
{
|
|
||||||
"glob": "**/*",
|
|
||||||
"input": "public"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"styles": [
|
|
||||||
"src/styles.css"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cli": {
|
|
||||||
"analytics": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
server {
|
|
||||||
listen 8800;
|
|
||||||
# Root-Verzeichnis für den Server setzen (wir kopieren unsere Anwendung hierher)
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
|
|
||||||
# Definieren der Standard-Indexdatei (Angular erstellt die Datei index.html für uns und sie befindet sich im oben genannten Verzeichnis)
|
|
||||||
index index.html;
|
|
||||||
|
|
||||||
# Cache-Header für Medien-ASsets
|
|
||||||
location ~* \.(?:cur|jpe?g|gif|htc|ico|png|xml|otf|ttf|eot|woff|woff2|svg)$ {
|
|
||||||
access_log off;
|
|
||||||
add_header Pragma "must-revalidate, public";
|
|
||||||
add_header Cache-Control "must-revalidate, public";
|
|
||||||
expires max;
|
|
||||||
|
|
||||||
tcp_nodelay off;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Cache-Header für HTML, CSS und JS-Dateien
|
|
||||||
location ~* \.(?:css|js|html)$ {
|
|
||||||
access_log off;
|
|
||||||
add_header Pragma "must-revalidate, public";
|
|
||||||
add_header Cache-Control "must-revalidate, public";
|
|
||||||
expires 2d;
|
|
||||||
|
|
||||||
tcp_nodelay off;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Konfiguration für den /-Pfad
|
|
||||||
location / {
|
|
||||||
# Zunächst versuchen wir die angeforderte URI auzuliefern
|
|
||||||
# Klappt das nicht, versuchen wir es mit einem abschließenden Slash
|
|
||||||
# Klappt auch das nicht, liefern wir die index.html aus.
|
|
||||||
# Das ist nötig, damit Angular-Routen korrekt augeflöst und ausgeliefert werden
|
|
||||||
try_files $uri $uri/ /index.html;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Generated
-9970
File diff suppressed because it is too large
Load Diff
@@ -1,48 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "kontor-angular",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"scripts": {
|
|
||||||
"ng": "ng",
|
|
||||||
"start": "ng serve",
|
|
||||||
"build": "ng build",
|
|
||||||
"watch": "ng build --watch --configuration development",
|
|
||||||
"test": "ng test"
|
|
||||||
},
|
|
||||||
"prettier": {
|
|
||||||
"printWidth": 100,
|
|
||||||
"singleQuote": true,
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": "*.html",
|
|
||||||
"options": {
|
|
||||||
"parser": "angular"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"private": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@angular/common": "^20.2.0",
|
|
||||||
"@angular/compiler": "^20.2.0",
|
|
||||||
"@angular/core": "^20.2.0",
|
|
||||||
"@angular/forms": "^20.2.0",
|
|
||||||
"@angular/platform-browser": "^20.2.0",
|
|
||||||
"@angular/router": "^20.2.0",
|
|
||||||
"rxjs": "~7.8.0",
|
|
||||||
"tslib": "^2.3.0",
|
|
||||||
"zone.js": "~0.15.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@angular/build": "^20.2.1",
|
|
||||||
"@angular/cli": "^20.2.1",
|
|
||||||
"@angular/compiler-cli": "^20.2.0",
|
|
||||||
"@types/jasmine": "~5.1.0",
|
|
||||||
"jasmine-core": "~5.9.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",
|
|
||||||
"typescript": "~5.9.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 544 B |
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 634 B |
@@ -1,9 +0,0 @@
|
|||||||
h1 {
|
|
||||||
color: blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
/* max-width: 500px; */
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<div class="app">
|
|
||||||
<kontor-header />
|
|
||||||
<app-navigation/>
|
|
||||||
<main>
|
|
||||||
<router-outlet />
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<kontor-footer />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
import { RouterOutlet } from '@angular/router';
|
|
||||||
import { KontorHeaderComponent } from "./kontor/header/header.component";
|
|
||||||
import { KontorFooterComponent } from './kontor/footer/footer.component';
|
|
||||||
import { NavigationComponent } from "./kontor/navigation/navigation.component";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-root',
|
|
||||||
imports: [RouterOutlet, KontorHeaderComponent, KontorFooterComponent, NavigationComponent],
|
|
||||||
templateUrl: './app.component.html',
|
|
||||||
styleUrl: './app.component.css'
|
|
||||||
})
|
|
||||||
export class AppComponent {
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core';
|
|
||||||
import { provideRouter, withComponentInputBinding } from '@angular/router';
|
|
||||||
import { routes } from './app.routes';
|
|
||||||
import { provideHttpClient } from '@angular/common/http';
|
|
||||||
|
|
||||||
export const appConfig: ApplicationConfig = {
|
|
||||||
providers: [
|
|
||||||
provideBrowserGlobalErrorListeners(),
|
|
||||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
|
||||||
provideRouter(routes, withComponentInputBinding()),
|
|
||||||
provideHttpClient(),
|
|
||||||
]
|
|
||||||
};
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import { Routes } from '@angular/router';
|
|
||||||
import { KontorComponent } from './kontor/kontor.component';
|
|
||||||
import { Auth } from './common/auth/auth';
|
|
||||||
import { ComicSectionComponent } from './kontor/comic/comic-section/comic-section.component';
|
|
||||||
import { comicRoutes } from './kontor/comic/comic-section/comic-section.routes';
|
|
||||||
import { TyscSectionComponent } from './kontor/tysc/tysc-section/tysc-section.component';
|
|
||||||
import { tyscRoutes } from './kontor/tysc/tysc-section/tysc-section.routes';
|
|
||||||
import { MediaSectionComponent } from './kontor/media/media-section/media-section.component';
|
|
||||||
import { mediaRoutes } from './kontor/media/media-section/media-section.routes';
|
|
||||||
|
|
||||||
export const routes: Routes = [
|
|
||||||
{ path: '', component: KontorComponent, },
|
|
||||||
{ path: 'login', component: Auth, },
|
|
||||||
{
|
|
||||||
path: 'comic', component: ComicSectionComponent,
|
|
||||||
children: comicRoutes,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'tysc', component: TyscSectionComponent,
|
|
||||||
children: tyscRoutes,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'media', component: MediaSectionComponent,
|
|
||||||
children: mediaRoutes,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
import { App } from './app';
|
|
||||||
|
|
||||||
describe('App', () => {
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [App],
|
|
||||||
}).compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create the app', () => {
|
|
||||||
const fixture = TestBed.createComponent(App);
|
|
||||||
const app = fixture.componentInstance;
|
|
||||||
expect(app).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render title', () => {
|
|
||||||
const fixture = TestBed.createComponent(App);
|
|
||||||
fixture.detectChanges();
|
|
||||||
const compiled = fixture.nativeElement as HTMLElement;
|
|
||||||
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, kontor-angular');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { AuthService } from './auth-service';
|
|
||||||
|
|
||||||
describe('AuthService', () => {
|
|
||||||
let service: AuthService;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({});
|
|
||||||
service = TestBed.inject(AuthService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
|
||||||
import { inject, Injectable } from '@angular/core';
|
|
||||||
import { catchError, Observable, throwError } from 'rxjs';
|
|
||||||
|
|
||||||
|
|
||||||
interface AuthResponseData {
|
|
||||||
kind: string;
|
|
||||||
idToken: string;
|
|
||||||
email: string;
|
|
||||||
refreshToken: string;
|
|
||||||
expiresIn: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TokenData {
|
|
||||||
access_token: string;
|
|
||||||
token_type: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable({providedIn: 'root'})
|
|
||||||
export class AuthService {
|
|
||||||
private http = inject(HttpClient);
|
|
||||||
|
|
||||||
signup(email: string, password: string) {
|
|
||||||
return this.http.post<TokenData>('http://localhost:8800/signup',
|
|
||||||
{
|
|
||||||
username: email,
|
|
||||||
password: password
|
|
||||||
}
|
|
||||||
).pipe(catchError(errorRes => {
|
|
||||||
let errorMessage = 'An unknown error occurred!';
|
|
||||||
const err = Error(errorMessage);
|
|
||||||
if (!errorRes.error) {
|
|
||||||
return throwError(() => err);
|
|
||||||
}
|
|
||||||
switch(errorRes.statusText) {
|
|
||||||
case 'ERROR':
|
|
||||||
errorMessage = 'Uups...';
|
|
||||||
}
|
|
||||||
return throwError(() => Error(errorMessage));
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
login(email: string, password: string): Observable<TokenData> {
|
|
||||||
const params = new HttpParams()
|
|
||||||
.set('username', email)
|
|
||||||
.append('password', password);
|
|
||||||
return this.http.post<TokenData>('http://127.0.0.1:8800/api/login/token', params,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
button {
|
|
||||||
text-align: center;
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 10px;
|
|
||||||
margin-left: 14px;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div style="margin-top: 16px;">
|
|
||||||
@if(error) {
|
|
||||||
<div class="alert alter-danger">
|
|
||||||
<p>{{ error }}</p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@if(isLoading) {
|
|
||||||
<div style="text-align: center;">
|
|
||||||
<app-loading-spinner></app-loading-spinner>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@else {
|
|
||||||
<form (ngSubmit)="onSubmit(authForm)" #authForm="ngForm">
|
|
||||||
<div class="form-group" style="margin-bottom: 7px;">
|
|
||||||
<label for="email">E-Mail</label>
|
|
||||||
<input type="email" id="email" class="form-control" ngModel name="email" required email=""/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group" style="margin-bottom: 7px;">
|
|
||||||
<label for="password">Password</label>
|
|
||||||
<input type="password" id="password" class="form-control" ngModel name="password" required/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button class="btn btn-primary" type="submit" [disabled]="!authForm.valid">
|
|
||||||
{{ isLoginMode ? 'Login' : 'Sign Up' }}
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-primary" (click)="onSwitchMode()" type="button">
|
|
||||||
Switch to {{ isLoginMode ? 'Sign Up' : 'Login' }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { Auth } from './auth';
|
|
||||||
|
|
||||||
describe('Auth', () => {
|
|
||||||
let component: Auth;
|
|
||||||
let fixture: ComponentFixture<Auth>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [Auth]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(Auth);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
import { NgForm } from '@angular/forms';
|
|
||||||
import { AuthService, TokenData } from './auth-service';
|
|
||||||
import { LoadingSpinner } from "../../shared/loading-spinner/loading-spinner";
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-auth',
|
|
||||||
imports: [FormsModule, LoadingSpinner],
|
|
||||||
templateUrl: './auth.html',
|
|
||||||
styleUrl: './auth.css'
|
|
||||||
})
|
|
||||||
export class Auth {
|
|
||||||
isLoginMode = true;
|
|
||||||
isLoading = false;
|
|
||||||
error: string | null = null;
|
|
||||||
|
|
||||||
constructor(private authService: AuthService) {}
|
|
||||||
|
|
||||||
onSwitchMode() {
|
|
||||||
this.isLoginMode =!this.isLoginMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit(form: NgForm) {
|
|
||||||
if (!form.valid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const email = form.value.email;
|
|
||||||
const password = form.value.password;
|
|
||||||
|
|
||||||
let authObservable: Observable<TokenData>;
|
|
||||||
|
|
||||||
this.isLoading = true;
|
|
||||||
if (this.isLoginMode) {
|
|
||||||
authObservable = this.authService.login(email, password);
|
|
||||||
} else {
|
|
||||||
authObservable = this.authService.signup(email, password)
|
|
||||||
}
|
|
||||||
|
|
||||||
authObservable.subscribe({
|
|
||||||
next: token => {
|
|
||||||
console.log(token);
|
|
||||||
localStorage.setItem('userToken', JSON.stringify(token));
|
|
||||||
this.isLoading = false;
|
|
||||||
},
|
|
||||||
error: err => {
|
|
||||||
console.log(err);
|
|
||||||
this.isLoading = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
form.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
div {
|
|
||||||
border-radius: 6px;
|
|
||||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<div>
|
|
||||||
<a [routerLink]="['/', 'comic', 'artist', artist().id]" routerLinkActive="active">
|
|
||||||
<span>{{ artist().name }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComicArtistComponent } from './comic-artist.component';
|
|
||||||
|
|
||||||
describe('ComicArtistComponent', () => {
|
|
||||||
let component: ComicArtistComponent;
|
|
||||||
let fixture: ComponentFixture<ComicArtistComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [ComicArtistComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComicArtistComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { Component, input } from '@angular/core';
|
|
||||||
import { Artist } from '../comic.model';
|
|
||||||
import { RouterLink, RouterLinkActive } from '@angular/router';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-comic-artist',
|
|
||||||
imports: [RouterLink, RouterLinkActive],
|
|
||||||
templateUrl: './comic-artist.component.html',
|
|
||||||
styleUrl: './comic-artist.component.css'
|
|
||||||
})
|
|
||||||
export class ComicArtistComponent {
|
|
||||||
artist = input.required<Artist>();
|
|
||||||
}
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
ul {
|
|
||||||
list-style: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5rem;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
ul {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
<ul>
|
|
||||||
@for (artist of artists(); track artist.id) {
|
|
||||||
<li>
|
|
||||||
<app-comic-artist [artist]="artist"/>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComicArtistsListComponent } from './comic-artists-list.component';
|
|
||||||
|
|
||||||
describe('ComicArtistsListComponent', () => {
|
|
||||||
let component: ComicArtistsListComponent;
|
|
||||||
let fixture: ComponentFixture<ComicArtistsListComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [ComicArtistsListComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComicArtistsListComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
-38
@@ -1,38 +0,0 @@
|
|||||||
import { Component, DestroyRef, inject, OnInit, signal } from '@angular/core';
|
|
||||||
import { Artist } from '../comic.model';
|
|
||||||
import { ComicArtistComponent } from '../comic-artist/comic-artist.component';
|
|
||||||
import { ArtistService } from '../comic-artists/artist.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-comic-artists-list',
|
|
||||||
imports: [ComicArtistComponent],
|
|
||||||
templateUrl: './comic-artists-list.component.html',
|
|
||||||
styleUrl: './comic-artists-list.component.css'
|
|
||||||
})
|
|
||||||
export class ComicArtistsListComponent implements OnInit {
|
|
||||||
|
|
||||||
artists = signal<Artist[]>([]);
|
|
||||||
isFetching = signal(false);
|
|
||||||
error = signal('');
|
|
||||||
private artistService = inject(ArtistService);
|
|
||||||
private destroyRef = inject(DestroyRef);
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.isFetching.set(true);
|
|
||||||
const subscription = this.artistService.loadArtists().subscribe({
|
|
||||||
next: (artists) => {
|
|
||||||
this.artists.set(artists);
|
|
||||||
},
|
|
||||||
error: (error: Error) => {
|
|
||||||
this.error.set(error.message);
|
|
||||||
},
|
|
||||||
complete: () => {
|
|
||||||
this.isFetching.set(false);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
this.destroyRef.onDestroy(() => {
|
|
||||||
subscription.unsubscribe();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import { inject, Injectable, signal } from "@angular/core";
|
|
||||||
import { HttpClient } from "@angular/common/http";
|
|
||||||
import { catchError, map, throwError } from "rxjs";
|
|
||||||
import { ErrorService } from "../../../shared/error.service";
|
|
||||||
import { Artist, ArtistDetails } from "../comic.model";
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root',
|
|
||||||
})
|
|
||||||
export class ArtistService {
|
|
||||||
private errorService = inject(ErrorService);
|
|
||||||
private httpClient = inject(HttpClient);
|
|
||||||
private artists = signal<Artist[]>([]);
|
|
||||||
|
|
||||||
loadedArtists = this.artists.asReadonly();
|
|
||||||
|
|
||||||
loadArtists() {
|
|
||||||
return this.fetchArtists('http://127.0.0.1:8800/api/comics/artists', 'Someting went wrong fetching artists. Please try again later-');
|
|
||||||
}
|
|
||||||
|
|
||||||
loadArtistDetails(artistId: string | null) {
|
|
||||||
return this.fetchArtistDetails('http://127.0.0.1:8800/api/comics/artists/' + artistId, 'Someting went wrong fetching comic artists. Please try again later.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private fetchArtists(url: string, errorMessage: string) {
|
|
||||||
return this.httpClient.get<Artist[]>(url).pipe(
|
|
||||||
map((resData) => resData),
|
|
||||||
catchError((error) => {
|
|
||||||
console.log(error);
|
|
||||||
return throwError(() => new Error(errorMessage));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private fetchArtistDetails(url: string, errorMessage: string) {
|
|
||||||
return this.httpClient.get<ArtistDetails>(url).pipe(
|
|
||||||
map((resData) => {
|
|
||||||
console.log(resData);
|
|
||||||
return resData;
|
|
||||||
}),
|
|
||||||
catchError((error) => {
|
|
||||||
console.log(error);
|
|
||||||
return throwError(() => new Error(errorMessage));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
.grid-container {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
grid-gap: 20px;
|
|
||||||
}
|
|
||||||
section {
|
|
||||||
margin-left: 10px;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: darkgrey;
|
|
||||||
border-radius: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
article {
|
|
||||||
margin-left: 10px;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
<div class="grid-container">
|
|
||||||
<div>
|
|
||||||
<app-comic-artists-list />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
@if (artist()) {
|
|
||||||
<section>
|
|
||||||
<h2>{{ artist().name }}</h2>
|
|
||||||
<a href="{{ artist().weblink }}" style="background-color: green;">{{ artist().name }}</a>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
@for (work of artist().comic_works; track work.worktype.id) {
|
|
||||||
<app-comic-worktype [worktype]="work.worktype"/>
|
|
||||||
@for (comic of work.comics; track comic.id) {
|
|
||||||
<article>
|
|
||||||
<app-comic-comic [comic]="comic"/>
|
|
||||||
</article>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
@for (work of artist().issue_works; track work.worktype.id) {
|
|
||||||
<app-comic-worktype [worktype]="work.worktype"/>
|
|
||||||
@for (issue of work.issues; track issue.id) {
|
|
||||||
<article>
|
|
||||||
<app-comic-comic [comic]="issue.comic"/>
|
|
||||||
</article>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</section>
|
|
||||||
} @else {
|
|
||||||
<h2>Artist Details</h2>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComicArtistsComponent } from './comic-artists.component';
|
|
||||||
|
|
||||||
describe('ComicArtistsComponent', () => {
|
|
||||||
let component: ComicArtistsComponent;
|
|
||||||
let fixture: ComponentFixture<ComicArtistsComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [ComicArtistsComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComicArtistsComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import { Component, inject, input } from '@angular/core';
|
|
||||||
import { ComicArtistsListComponent } from '../comic-artists-list/comic-artists-list.component';
|
|
||||||
import { ActivatedRouteSnapshot, ResolveFn, RouterStateSnapshot } from '@angular/router';
|
|
||||||
import { ArtistService } from './artist.service';
|
|
||||||
import { ComicComicComponent } from "../comic-comic/comic-comic.component";
|
|
||||||
import { ComicWorktypeComponent } from "../comic-worktype/comic-worktype.component";
|
|
||||||
import { ArtistDetails } from '../comic.model';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-comic-artists',
|
|
||||||
imports: [ComicArtistsListComponent, ComicComicComponent, ComicWorktypeComponent],
|
|
||||||
templateUrl: './comic-artists.component.html',
|
|
||||||
styleUrl: './comic-artists.component.css'
|
|
||||||
})
|
|
||||||
export class ComicArtistsComponent {
|
|
||||||
artist = input.required<ArtistDetails>();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const artistResolver: ResolveFn<ArtistDetails> = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
|
|
||||||
const artistService = inject(ArtistService);
|
|
||||||
const artistId = route.paramMap.get('artistId');
|
|
||||||
const artistDetails = artistService.loadArtistDetails(artistId);
|
|
||||||
console.log(artistDetails);
|
|
||||||
return artistDetails;
|
|
||||||
};
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<div>
|
|
||||||
<a [routerLink]="['/', 'comic', 'comics', comic().id]" routerLinkActive="active">
|
|
||||||
<span>{{ comic().title }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComicComicComponent } from './comic-comic.component';
|
|
||||||
|
|
||||||
describe('ComicComicComponent', () => {
|
|
||||||
let component: ComicComicComponent;
|
|
||||||
let fixture: ComponentFixture<ComicComicComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [ComicComicComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComicComicComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { Component, input } from '@angular/core';
|
|
||||||
import { Comic } from '../comic.model';
|
|
||||||
import { RouterLink, RouterLinkActive } from '@angular/router';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-comic-comic',
|
|
||||||
imports: [RouterLink, RouterLinkActive],
|
|
||||||
templateUrl: './comic-comic.component.html',
|
|
||||||
styleUrl: './comic-comic.component.css'
|
|
||||||
})
|
|
||||||
export class ComicComicComponent {
|
|
||||||
comic = input.required<Comic>();
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
ul {
|
|
||||||
list-style: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5rem;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
ul {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
<div>
|
|
||||||
<input #searchQuery type="text" (input)="search($event.target.value)" placeholder="Search" />
|
|
||||||
</div>
|
|
||||||
<ul>
|
|
||||||
@for (comic of comics(); track comic.id) {
|
|
||||||
<li>
|
|
||||||
<app-comic-comic [comic]="comic"/>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComicComicsListComponent } from './comic-comics-list.component';
|
|
||||||
|
|
||||||
describe('ComicComicsListComponent', () => {
|
|
||||||
let component: ComicComicsListComponent;
|
|
||||||
let fixture: ComponentFixture<ComicComicsListComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [ComicComicsListComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComicComicsListComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import { Component, computed, DestroyRef, inject, OnInit, signal } from '@angular/core';
|
|
||||||
import { Comic } from '../comic.model';
|
|
||||||
import { ComicService } from '../comic-comics/comic.service';
|
|
||||||
import { ComicComicComponent } from '../comic-comic/comic-comic.component';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-comic-comics-list',
|
|
||||||
imports: [ComicComicComponent],
|
|
||||||
templateUrl: './comic-comics-list.component.html',
|
|
||||||
styleUrl: './comic-comics-list.component.css',
|
|
||||||
})
|
|
||||||
export class ComicComicsListComponent implements OnInit {
|
|
||||||
comicsFetched = signal<Comic[] | undefined>(undefined);
|
|
||||||
searchQuery = signal<string>('');
|
|
||||||
comics = computed(() => {
|
|
||||||
const sq = this.searchQuery();
|
|
||||||
return this.comicsFetched()?.filter(c => c.title.toLowerCase().includes(sq.toLowerCase()));
|
|
||||||
});
|
|
||||||
isFetching = signal(false);
|
|
||||||
error = signal('');
|
|
||||||
private comicsService = inject(ComicService);
|
|
||||||
private destroyRef = inject(DestroyRef);
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.isFetching.set(true);
|
|
||||||
const subscription = this.comicsService.loadComics().subscribe({
|
|
||||||
next: (comics) => {
|
|
||||||
this.comicsFetched.set(comics);
|
|
||||||
},
|
|
||||||
error: (error: Error) => {
|
|
||||||
this.error.set(error.message);
|
|
||||||
},
|
|
||||||
complete: () => {
|
|
||||||
this.isFetching.set(false);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
this.destroyRef.onDestroy(() => {
|
|
||||||
subscription.unsubscribe();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
search(query: string) {
|
|
||||||
this.searchQuery.set(query);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
.float-parent-element {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
.float-child-element {
|
|
||||||
float: left;
|
|
||||||
width: 50%;
|
|
||||||
border-width: 10px;
|
|
||||||
border-color: black;
|
|
||||||
}
|
|
||||||
.float-details-element {
|
|
||||||
border: 1px solid darkgreen;
|
|
||||||
background-color: lightgreen;
|
|
||||||
margin: 5px;
|
|
||||||
padding: 1rem;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.parent {
|
|
||||||
border: 1px solid black;
|
|
||||||
margin: 1rem;
|
|
||||||
padding: 2rem 2rem;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.child {
|
|
||||||
display: inline-block;
|
|
||||||
border: 1px solid red;
|
|
||||||
padding: 1rem 1rem;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
<div class="grid-container">
|
|
||||||
<div>
|
|
||||||
<app-comic-comics-list/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
@if (comic()) {
|
|
||||||
<section>
|
|
||||||
<h2>{{ comic().title }}</h2>
|
|
||||||
<a href="{{ comic().weblink }}" style="background-color: green;">{{ comic().title }}</a>
|
|
||||||
<app-comic-publisher [publisher]="comic().publisher" />
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
@for (issue of comic().issues; track issue.id) {
|
|
||||||
<app-comic-issue [issue]="issue"/>
|
|
||||||
}
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
@for (work of comic().works; track work.worktype.id) {
|
|
||||||
<app-comic-worktype [worktype]="work.worktype"/>
|
|
||||||
@for (artist of work.artists; track artist.id) {
|
|
||||||
<article>
|
|
||||||
<app-comic-artist [artist]="artist"/>
|
|
||||||
</article>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</section>
|
|
||||||
} @else {
|
|
||||||
<h2>Comic Details</h2>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComicComicsComponent } from './comic-comics.component';
|
|
||||||
|
|
||||||
describe('ComicComicsComponent', () => {
|
|
||||||
let component: ComicComicsComponent;
|
|
||||||
let fixture: ComponentFixture<ComicComicsComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [ComicComicsComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComicComicsComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
import { Component, inject, input } from '@angular/core';
|
|
||||||
import { ComicComicsListComponent } from "../comic-comics-list/comic-comics-list.component";
|
|
||||||
import { ComicDetails } from '../comic.model';
|
|
||||||
import { ActivatedRouteSnapshot, ResolveFn, RouterStateSnapshot } from '@angular/router';
|
|
||||||
import { ComicService } from './comic.service';
|
|
||||||
import { ComicWorktypeComponent } from '../comic-worktype/comic-worktype.component';
|
|
||||||
import { ComicArtistComponent } from '../comic-artist/comic-artist.component';
|
|
||||||
import { ComicIssueComponent } from '../comic-issue/comic-issue.component';
|
|
||||||
import { ComicPublisherComponent } from "../comic-publisher/comic-publisher.component";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-comic-comics',
|
|
||||||
imports: [ComicComicsListComponent, ComicWorktypeComponent, ComicArtistComponent, ComicIssueComponent, ComicPublisherComponent],
|
|
||||||
templateUrl: './comic-comics.component.html',
|
|
||||||
styleUrl: './comic-comics.component.css'
|
|
||||||
})
|
|
||||||
export class ComicComicsComponent {
|
|
||||||
comic = input.required<ComicDetails>();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const comicResolver: ResolveFn<ComicDetails> = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
|
|
||||||
const comicService = inject(ComicService);
|
|
||||||
const comicId = route.paramMap.get('comicId');
|
|
||||||
const comicDetails = comicService.loadComicDetails(comicId);
|
|
||||||
console.log(comicDetails);
|
|
||||||
return comicDetails;
|
|
||||||
};
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
import { HttpClient } from "@angular/common/http";
|
|
||||||
import { inject, Injectable, signal } from "@angular/core";
|
|
||||||
import { Comic, ComicDetails } from "../comic.model";
|
|
||||||
import { catchError, map, throwError } from "rxjs";
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class ComicService {
|
|
||||||
private httpClient = inject(HttpClient);
|
|
||||||
private comics = signal<Comic[]>([]);
|
|
||||||
|
|
||||||
loadedComics = this.comics.asReadonly();
|
|
||||||
|
|
||||||
loadComics() {
|
|
||||||
return this.fetchComics('http://127.0.0.1:8800/api/comics/comics', 'Someting went wrong fetching comics. Please try again later.');
|
|
||||||
}
|
|
||||||
|
|
||||||
loadComicDetails(comicId: string | null) {
|
|
||||||
return this.fetchComicDetails('http://127.0.0.1:8800/api/comics/comics/' + comicId, 'Someting went wrong fetching comics. Please try again later.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private fetchComicDetails(url: string, errorMessage: string) {
|
|
||||||
return this.httpClient.get<ComicDetails>(url).pipe(
|
|
||||||
map((resData) => {
|
|
||||||
console.log(resData);
|
|
||||||
return resData;
|
|
||||||
}),
|
|
||||||
catchError((error) => {
|
|
||||||
console.log(error);
|
|
||||||
return throwError(() => new Error(errorMessage));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private fetchComics(url: string, errorMessage: string) {
|
|
||||||
return this.httpClient.get<Comic[]>(url).pipe(
|
|
||||||
map((resData) => resData),
|
|
||||||
catchError((error) => {
|
|
||||||
console.log(error);
|
|
||||||
return throwError(() => new Error(errorMessage));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<div>
|
|
||||||
<a [routerLink]="['/', 'comic', 'issue', issue().id]" routerLinkActive="active">
|
|
||||||
<span>{{ issue().issue_number }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComicIssueComponent } from './comic-issue.component';
|
|
||||||
|
|
||||||
describe('ComicIssueComponent', () => {
|
|
||||||
let component: ComicIssueComponent;
|
|
||||||
let fixture: ComponentFixture<ComicIssueComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [ComicIssueComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComicIssueComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { Component, input } from '@angular/core';
|
|
||||||
import { Issue } from '../comic.model';
|
|
||||||
import { RouterLink, RouterLinkActive } from '@angular/router';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-comic-issue',
|
|
||||||
imports: [RouterLink, RouterLinkActive],
|
|
||||||
templateUrl: './comic-issue.component.html',
|
|
||||||
styleUrl: './comic-issue.component.css'
|
|
||||||
})
|
|
||||||
export class ComicIssueComponent {
|
|
||||||
issue = input.required<Issue>();
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<div class="subnav">
|
|
||||||
<a routerLink="/comic/comics" routerLinkActive="active">Comics</a>
|
|
||||||
<a routerLink="/comic/publisher" routerLinkActive="active">Publisher</a>
|
|
||||||
<a routerLink="/comic/artist" routerLinkActive="active">Artists</a>
|
|
||||||
</div>
|
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComicNavigationComponent } from './comic-navigation.component';
|
|
||||||
|
|
||||||
describe('ComicNavigationComponent', () => {
|
|
||||||
let component: ComicNavigationComponent;
|
|
||||||
let fixture: ComponentFixture<ComicNavigationComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [ComicNavigationComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComicNavigationComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
import { RouterLink, RouterLinkActive } from '@angular/router';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-comic-navigation',
|
|
||||||
imports: [RouterLink, RouterLinkActive],
|
|
||||||
templateUrl: './comic-navigation.component.html',
|
|
||||||
styleUrl: './comic-navigation.component.css'
|
|
||||||
})
|
|
||||||
export class ComicNavigationComponent {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<div>
|
|
||||||
<a [routerLink]="['/', 'comic', 'publisher', publisher().id]" routerLinkActive="active">
|
|
||||||
<span>{{ publisher().name }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComicPublisherComponent } from './comic-publisher.component';
|
|
||||||
|
|
||||||
describe('ComicPublisherComponent', () => {
|
|
||||||
let component: ComicPublisherComponent;
|
|
||||||
let fixture: ComponentFixture<ComicPublisherComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [ComicPublisherComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComicPublisherComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { Component, input } from '@angular/core';
|
|
||||||
import { Publisher } from '../comic.model';
|
|
||||||
import { RouterLink, RouterLinkActive } from '@angular/router';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-comic-publisher',
|
|
||||||
imports: [RouterLink, RouterLinkActive],
|
|
||||||
templateUrl: './comic-publisher.component.html',
|
|
||||||
styleUrl: './comic-publisher.component.css'
|
|
||||||
})
|
|
||||||
export class ComicPublisherComponent {
|
|
||||||
publisher = input.required<Publisher>();
|
|
||||||
}
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
ul {
|
|
||||||
list-style: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5rem;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
ul {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
<ul>
|
|
||||||
@for (publisher of publishers(); track publisher.id) {
|
|
||||||
<li>
|
|
||||||
<app-comic-publisher [publisher]="publisher" />
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComicPublishersListComponent } from './comic-publishers-list.component';
|
|
||||||
|
|
||||||
describe('ComicPublishersListComponent', () => {
|
|
||||||
let component: ComicPublishersListComponent;
|
|
||||||
let fixture: ComponentFixture<ComicPublishersListComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [ComicPublishersListComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComicPublishersListComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
-37
@@ -1,37 +0,0 @@
|
|||||||
import { Component, DestroyRef, inject, OnInit, signal } from '@angular/core';
|
|
||||||
import { Publisher } from '../comic.model';
|
|
||||||
import { PublisherService } from '../comic-publishers/publisher.service';
|
|
||||||
import { ComicPublisherComponent } from "../comic-publisher/comic-publisher.component";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-comic-publishers-list',
|
|
||||||
imports: [ComicPublisherComponent],
|
|
||||||
templateUrl: './comic-publishers-list.component.html',
|
|
||||||
styleUrl: './comic-publishers-list.component.css'
|
|
||||||
})
|
|
||||||
export class ComicPublishersListComponent implements OnInit {
|
|
||||||
publishers = signal<Publisher[]>([]);
|
|
||||||
isFetching = signal(false);
|
|
||||||
error = signal('');
|
|
||||||
private publisherService = inject(PublisherService);
|
|
||||||
private destroyRef = inject(DestroyRef);
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.isFetching.set(true);
|
|
||||||
const subscription = this.publisherService.loadPublishers().subscribe({
|
|
||||||
next: (publishers) => {
|
|
||||||
this.publishers.set(publishers);
|
|
||||||
},
|
|
||||||
error: (error: Error) => {
|
|
||||||
this.error.set(error.message);
|
|
||||||
},
|
|
||||||
complete: () => {
|
|
||||||
this.isFetching.set(false);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
this.destroyRef.onDestroy(() => {
|
|
||||||
subscription.unsubscribe();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
<div class="grid-container">
|
|
||||||
<div>
|
|
||||||
<app-comic-publishers-list />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
@if (publisher()) {
|
|
||||||
<section>
|
|
||||||
<h2>{{ publisher().name }}</h2>
|
|
||||||
@if (publisher().parent_publisher) {
|
|
||||||
<app-comic-publisher [publisher]="publisher().parent_publisher" />
|
|
||||||
}
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
@for (imprint of publisher().imprints; track imprint.id) {
|
|
||||||
<article>
|
|
||||||
<app-comic-publisher [publisher]="imprint" />
|
|
||||||
</article>
|
|
||||||
}
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
@for (comic of publisher().comics; track comic.id) {
|
|
||||||
<article>
|
|
||||||
<app-comic-comic [comic]="comic" />
|
|
||||||
</article>
|
|
||||||
}
|
|
||||||
</section>
|
|
||||||
} @else {
|
|
||||||
<h2>Publisher Details</h2>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComicPublishersComponent } from './comic-publishers.component';
|
|
||||||
|
|
||||||
describe('ComicPublishersComponent', () => {
|
|
||||||
let component: ComicPublishersComponent;
|
|
||||||
let fixture: ComponentFixture<ComicPublishersComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [ComicPublishersComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComicPublishersComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import { Component, inject, input } from '@angular/core';
|
|
||||||
import { Publisher, PublisherDetails } from '../comic.model';
|
|
||||||
import { ComicPublishersListComponent } from '../comic-publishers-list/comic-publishers-list.component';
|
|
||||||
import { ActivatedRouteSnapshot, ResolveFn, RouterStateSnapshot } from '@angular/router';
|
|
||||||
import { PublisherService } from './publisher.service';
|
|
||||||
import { ComicPublisherComponent } from "../comic-publisher/comic-publisher.component";
|
|
||||||
import { ComicComicComponent } from "../comic-comic/comic-comic.component";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-comic-publishers',
|
|
||||||
imports: [ComicPublishersListComponent, ComicPublisherComponent, ComicComicComponent],
|
|
||||||
templateUrl: './comic-publishers.component.html',
|
|
||||||
styleUrl: './comic-publishers.component.css'
|
|
||||||
})
|
|
||||||
export class ComicPublishersComponent {
|
|
||||||
publisher = input.required<PublisherDetails>();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const publisherResolver: ResolveFn<PublisherDetails> = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
|
|
||||||
const publisherService = inject(PublisherService);
|
|
||||||
const publisherId = route.paramMap.get('publisherId');
|
|
||||||
const publisherDetails = publisherService.loadPublisherDetails(publisherId);
|
|
||||||
console.log(publisherDetails);
|
|
||||||
return publisherDetails;
|
|
||||||
};
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user