From 7461df3180919d932567309d7362bf2e59ace32d Mon Sep 17 00:00:00 2001 From: Clara Llorente Date: Mon, 20 Nov 2023 13:54:38 +0100 Subject: [PATCH 01/41] feat: create settings and tags component --- AMW_angular/io/src/app/app-routing.module.ts | 11 ++++++++- AMW_angular/io/src/app/app.module.ts | 2 ++ .../app/settings/settings-routing.module.ts | 20 ++++++++++++++++ .../src/app/settings/settings.component.html | 1 + .../src/app/settings/settings.component.scss | 0 .../app/settings/settings.component.spec.ts | 23 +++++++++++++++++++ .../io/src/app/settings/settings.component.ts | 14 +++++++++++ .../io/src/app/settings/settings.module.ts | 16 +++++++++++++ .../src/app/settings/tags/tags.component.html | 1 + .../src/app/settings/tags/tags.component.scss | 0 .../app/settings/tags/tags.component.spec.ts | 23 +++++++++++++++++++ .../src/app/settings/tags/tags.component.ts | 10 ++++++++ 12 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 AMW_angular/io/src/app/settings/settings-routing.module.ts create mode 100644 AMW_angular/io/src/app/settings/settings.component.html create mode 100644 AMW_angular/io/src/app/settings/settings.component.scss create mode 100644 AMW_angular/io/src/app/settings/settings.component.spec.ts create mode 100644 AMW_angular/io/src/app/settings/settings.component.ts create mode 100644 AMW_angular/io/src/app/settings/settings.module.ts create mode 100644 AMW_angular/io/src/app/settings/tags/tags.component.html create mode 100644 AMW_angular/io/src/app/settings/tags/tags.component.scss create mode 100644 AMW_angular/io/src/app/settings/tags/tags.component.spec.ts create mode 100644 AMW_angular/io/src/app/settings/tags/tags.component.ts diff --git a/AMW_angular/io/src/app/app-routing.module.ts b/AMW_angular/io/src/app/app-routing.module.ts index 58a65407a..5713c5e30 100644 --- a/AMW_angular/io/src/app/app-routing.module.ts +++ b/AMW_angular/io/src/app/app-routing.module.ts @@ -1,10 +1,19 @@ import { Routes, RouterModule } from '@angular/router'; import { NgModule } from '@angular/core'; import { DeploymentsComponent } from './deployments/deployments.component'; +import {TagsComponent} from "./settings/tags/tags.component"; +import {SettingsComponent} from "./settings/settings.component"; export const routes: Routes = [ // default route only, the rest is done in module routing - { path: '', component: DeploymentsComponent } + { path: '', component: DeploymentsComponent }, + { + path: 'settings', + component: SettingsComponent, + children: [ + { path: 'tags', component: TagsComponent }, + ], + }, ]; @NgModule({ diff --git a/AMW_angular/io/src/app/app.module.ts b/AMW_angular/io/src/app/app.module.ts index 99676cadf..ec72ad0dd 100644 --- a/AMW_angular/io/src/app/app.module.ts +++ b/AMW_angular/io/src/app/app.module.ts @@ -26,6 +26,7 @@ import { DeploymentsModule } from './deployments/deployments.module'; import { NavigationStoreService } from './navigation/navigation-store.service'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { CodemirrorModule } from '@ctrl/ngx-codemirror'; +import {SettingsModule} from "./settings/settings.module"; // Application wide providers const APP_PROVIDERS = [NavigationStoreService]; @@ -50,6 +51,7 @@ const APP_PROVIDERS = [NavigationStoreService]; NavigationModule, NgbModule, CodemirrorModule, + SettingsModule, ], providers: [APP_PROVIDERS], bootstrap: [AppComponent], diff --git a/AMW_angular/io/src/app/settings/settings-routing.module.ts b/AMW_angular/io/src/app/settings/settings-routing.module.ts new file mode 100644 index 000000000..71b16e522 --- /dev/null +++ b/AMW_angular/io/src/app/settings/settings-routing.module.ts @@ -0,0 +1,20 @@ +import { RouterModule } from '@angular/router'; +import { NgModule } from '@angular/core'; +import {TagsComponent} from "./tags/tags.component"; +import {SettingsComponent} from "./settings.component"; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { + path: 'settings', + component: SettingsComponent, + children: [ + { path: '', component: TagsComponent }, + ], + }, + ]), + ], + exports: [RouterModule], +}) +export class SettingsRoutingModule {} diff --git a/AMW_angular/io/src/app/settings/settings.component.html b/AMW_angular/io/src/app/settings/settings.component.html new file mode 100644 index 000000000..0680b43f9 --- /dev/null +++ b/AMW_angular/io/src/app/settings/settings.component.html @@ -0,0 +1 @@ + diff --git a/AMW_angular/io/src/app/settings/settings.component.scss b/AMW_angular/io/src/app/settings/settings.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/AMW_angular/io/src/app/settings/settings.component.spec.ts b/AMW_angular/io/src/app/settings/settings.component.spec.ts new file mode 100644 index 000000000..8e5829222 --- /dev/null +++ b/AMW_angular/io/src/app/settings/settings.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SettingsComponent } from './settings.component'; + +describe('SettingsComponent', () => { + let component: SettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SettingsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(SettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/AMW_angular/io/src/app/settings/settings.component.ts b/AMW_angular/io/src/app/settings/settings.component.ts new file mode 100644 index 000000000..a48f4eb00 --- /dev/null +++ b/AMW_angular/io/src/app/settings/settings.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import {NavigationStoreService} from "../navigation/navigation-store.service"; + +@Component({ + selector: 'app-settings', + templateUrl: './settings.component.html', + styleUrl: './settings.component.scss' +}) +export class SettingsComponent { + constructor(public navigationStore: NavigationStoreService) { + this.navigationStore.setPageTitle('Settings'); + this.navigationStore.setCurrent('Settings'); + } +} diff --git a/AMW_angular/io/src/app/settings/settings.module.ts b/AMW_angular/io/src/app/settings/settings.module.ts new file mode 100644 index 000000000..c76dc8c35 --- /dev/null +++ b/AMW_angular/io/src/app/settings/settings.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import {TagsComponent} from "./tags/tags.component"; +import {SettingsRoutingModule} from "./settings-routing.module"; +import {SettingsComponent} from "./settings.component"; + + + +@NgModule({ + declarations: [SettingsComponent, TagsComponent], + imports: [ + CommonModule, + SettingsRoutingModule + ] +}) +export class SettingsModule { } diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.html b/AMW_angular/io/src/app/settings/tags/tags.component.html new file mode 100644 index 000000000..1951e16ee --- /dev/null +++ b/AMW_angular/io/src/app/settings/tags/tags.component.html @@ -0,0 +1 @@ +

tags works!

diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.scss b/AMW_angular/io/src/app/settings/tags/tags.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.spec.ts b/AMW_angular/io/src/app/settings/tags/tags.component.spec.ts new file mode 100644 index 000000000..352c6ff81 --- /dev/null +++ b/AMW_angular/io/src/app/settings/tags/tags.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TagsComponent } from './tags.component'; + +describe('TagsComponent', () => { + let component: TagsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [TagsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TagsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.ts b/AMW_angular/io/src/app/settings/tags/tags.component.ts new file mode 100644 index 000000000..df24d0806 --- /dev/null +++ b/AMW_angular/io/src/app/settings/tags/tags.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'amw-tags', + templateUrl: './tags.component.html', + styleUrl: './tags.component.scss' +}) +export class TagsComponent { + +} From e0e0f575a142dea606dec37650d5ab36100d3786 Mon Sep 17 00:00:00 2001 From: Clara Llorente Date: Tue, 21 Nov 2023 15:03:51 +0100 Subject: [PATCH 02/41] feat: build tags input field, list and delete tags --- AMW_angular/io/angular.json | 3 ++- .../io/src/app/settings/settings.module.ts | 11 +++++--- .../src/app/settings/tags/tags.component.html | 26 ++++++++++++++++++- .../src/app/settings/tags/tags.component.scss | 12 +++++++++ .../src/app/settings/tags/tags.component.ts | 17 +++++++++++- 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/AMW_angular/io/angular.json b/AMW_angular/io/angular.json index c0e424c99..3a1ed4f18 100644 --- a/AMW_angular/io/angular.json +++ b/AMW_angular/io/angular.json @@ -32,7 +32,8 @@ } ], "styles": [ - "src/styles.scss" + "src/styles.scss", + "./node_modules/bootstrap-icons/font/bootstrap-icons.scss" ], "scripts": [ "node_modules/codemirror/lib/codemirror.js", diff --git a/AMW_angular/io/src/app/settings/settings.module.ts b/AMW_angular/io/src/app/settings/settings.module.ts index c76dc8c35..36e4a6462 100644 --- a/AMW_angular/io/src/app/settings/settings.module.ts +++ b/AMW_angular/io/src/app/settings/settings.module.ts @@ -3,14 +3,17 @@ import { CommonModule } from '@angular/common'; import {TagsComponent} from "./tags/tags.component"; import {SettingsRoutingModule} from "./settings-routing.module"; import {SettingsComponent} from "./settings.component"; +import {FormsModule, ReactiveFormsModule} from "@angular/forms"; @NgModule({ declarations: [SettingsComponent, TagsComponent], - imports: [ - CommonModule, - SettingsRoutingModule - ] + imports: [ + CommonModule, + SettingsRoutingModule, + ReactiveFormsModule, + FormsModule + ] }) export class SettingsModule { } diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.html b/AMW_angular/io/src/app/settings/tags/tags.component.html index 1951e16ee..a1956352e 100644 --- a/AMW_angular/io/src/app/settings/tags/tags.component.html +++ b/AMW_angular/io/src/app/settings/tags/tags.component.html @@ -1 +1,25 @@ -

tags works!

+
+ + + + + + + + + + @for (tag of tags; track tag) { + + + + + } +
Tags +
+ + +
+
NameDelete
{{ tag.name }}
+
+ + diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.scss b/AMW_angular/io/src/app/settings/tags/tags.component.scss index e69de29bb..41be3aa36 100644 --- a/AMW_angular/io/src/app/settings/tags/tags.component.scss +++ b/AMW_angular/io/src/app/settings/tags/tags.component.scss @@ -0,0 +1,12 @@ +.table-bordered td, .table-bordered th { + border: 1px solid #dee2e6; +} + +.table-bordered td { + padding: 10px; +} + +.input-group { + width: fit-content; +} + diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.ts b/AMW_angular/io/src/app/settings/tags/tags.component.ts index df24d0806..fc75da5b2 100644 --- a/AMW_angular/io/src/app/settings/tags/tags.component.ts +++ b/AMW_angular/io/src/app/settings/tags/tags.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import {Component} from '@angular/core'; @Component({ selector: 'amw-tags', @@ -6,5 +6,20 @@ import { Component } from '@angular/core'; styleUrl: './tags.component.scss' }) export class TagsComponent { + tagName: string = ''; + tags: { id: number, name: string }[] = []; + private tagId = 0; + addTag(): void { + if (this.tagName.trim().length > 0) { + console.log('Tag added:', this.tagName); + this.tags.push({ id: this.tagId++, name: this.tagName.trim() }); + console.log(this.tags); + this.tagName = ''; + } + } + + deleteTag(index: number): void { + this.tags.splice(index, 1); + } } From 38daa5f276249e8fbd2329ae743bffcda32f7c64 Mon Sep 17 00:00:00 2001 From: Clara Llorente Date: Tue, 21 Nov 2023 15:12:02 +0100 Subject: [PATCH 03/41] feat: build tags input field, list and delete tags --- AMW_angular/io/src/app/settings/tags/tags.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.ts b/AMW_angular/io/src/app/settings/tags/tags.component.ts index fc75da5b2..a9e59417c 100644 --- a/AMW_angular/io/src/app/settings/tags/tags.component.ts +++ b/AMW_angular/io/src/app/settings/tags/tags.component.ts @@ -19,7 +19,7 @@ export class TagsComponent { } } - deleteTag(index: number): void { - this.tags.splice(index, 1); + deleteTag(tagId: number): void { + this.tags = this.tags.filter(tag => tag.id !== tagId) } } From d83b9bea423af251d6cb32af0d2b2de320ff6778 Mon Sep 17 00:00:00 2001 From: Clara Llorente Date: Wed, 22 Nov 2023 17:39:05 +0100 Subject: [PATCH 04/41] feat: build TagsRest to get all tags and cypress test --- .../src/app/settings/tags/tags.component.html | 4 +- .../src/app/settings/tags/tags.component.ts | 19 +- AMW_e2e/.gitignore | 4 +- AMW_e2e/cypress/e2e/tags-rest.cy.js | 15 + AMW_e2e/cypress/support/e2e.js | 8 +- AMW_e2e/package-lock.json | 347 +++--------------- AMW_e2e/package.json | 4 +- .../itc/mobiliar/rest/RESTApplication.java | 2 + .../mobi/itc/mobiliar/rest/tags/TagsRest.java | 30 ++ 9 files changed, 128 insertions(+), 305 deletions(-) create mode 100644 AMW_e2e/cypress/e2e/tags-rest.cy.js create mode 100644 AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.html b/AMW_angular/io/src/app/settings/tags/tags.component.html index a1956352e..96bab3633 100644 --- a/AMW_angular/io/src/app/settings/tags/tags.component.html +++ b/AMW_angular/io/src/app/settings/tags/tags.component.html @@ -15,8 +15,8 @@ @for (tag of tags; track tag) { - {{ tag.name }} - + {{ tag.name }} + } diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.ts b/AMW_angular/io/src/app/settings/tags/tags.component.ts index a9e59417c..13cec62d2 100644 --- a/AMW_angular/io/src/app/settings/tags/tags.component.ts +++ b/AMW_angular/io/src/app/settings/tags/tags.component.ts @@ -1,25 +1,32 @@ -import {Component} from '@angular/core'; +import { Component } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; + +type Tag = { id: number; name: string }; @Component({ selector: 'amw-tags', templateUrl: './tags.component.html', - styleUrl: './tags.component.scss' + styleUrl: './tags.component.scss', }) export class TagsComponent { tagName: string = ''; - tags: { id: number, name: string }[] = []; + tags: Tag[] = []; private tagId = 0; + constructor(private http: HttpClient) { + http.get('AMW_rest/resources/settings/tags').subscribe((data) => { + this.tags = data; + }); + } + addTag(): void { if (this.tagName.trim().length > 0) { - console.log('Tag added:', this.tagName); this.tags.push({ id: this.tagId++, name: this.tagName.trim() }); - console.log(this.tags); this.tagName = ''; } } deleteTag(tagId: number): void { - this.tags = this.tags.filter(tag => tag.id !== tagId) + this.tags = this.tags.filter((tag) => tag.id !== tagId); } } diff --git a/AMW_e2e/.gitignore b/AMW_e2e/.gitignore index b512c09d4..aa6ba5993 100644 --- a/AMW_e2e/.gitignore +++ b/AMW_e2e/.gitignore @@ -1 +1,3 @@ -node_modules \ No newline at end of file +node_modules +/cypress/downloads/ +/cypress/screenshots/ diff --git a/AMW_e2e/cypress/e2e/tags-rest.cy.js b/AMW_e2e/cypress/e2e/tags-rest.cy.js new file mode 100644 index 000000000..a84c64e7c --- /dev/null +++ b/AMW_e2e/cypress/e2e/tags-rest.cy.js @@ -0,0 +1,15 @@ +describe("tags-rest integration test", () => { + it("should get all tags", () => { + cy.request("http://admin:admin@localhost:8080/AMW_rest/resources/settings/tags") + .then((response) => { + const body = response.body; + expect(body.length).to.equals(0) +/* expect(body[0]).to.eql({ + "id": 551, + "name": "a", + "tagType": "GLOBAL"*/ + /* })*/ + } + ); + }); +}) \ No newline at end of file diff --git a/AMW_e2e/cypress/support/e2e.js b/AMW_e2e/cypress/support/e2e.js index 0e7290a13..d4e2ab65d 100644 --- a/AMW_e2e/cypress/support/e2e.js +++ b/AMW_e2e/cypress/support/e2e.js @@ -17,4 +17,10 @@ import './commands' // Alternatively you can use CommonJS syntax: -// require('./commands') \ No newline at end of file +// require('./commands') + +Cypress.on('uncaught:exception', (err, runnable) => { + // returning false here prevents Cypress from + // failing the test + return false +}) \ No newline at end of file diff --git a/AMW_e2e/package-lock.json b/AMW_e2e/package-lock.json index 07b976237..e88ad8d6d 100644 --- a/AMW_e2e/package-lock.json +++ b/AMW_e2e/package-lock.json @@ -8,12 +8,9 @@ "name": "amw_e2e", "version": "1.0.0", "license": "ISC", - "dependencies": { - "wait-on": "^7.1.0" - }, "devDependencies": { "cypress": "^13.5.0", - "start-server-and-test": "^2.0.2" + "wait-on": "^7.1.0" } }, "node_modules/@colors/colors": { @@ -77,12 +74,14 @@ "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "dev": true }, "node_modules/@hapi/topo": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dev": true, "dependencies": { "@hapi/hoek": "^9.0.0" } @@ -91,6 +90,7 @@ "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "dev": true, "dependencies": { "@hapi/hoek": "^9.0.0" } @@ -98,12 +98,14 @@ "node_modules/@sideway/formula": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "dev": true }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true }, "node_modules/@types/node": { "version": "18.18.9", @@ -217,12 +219,6 @@ } ] }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true - }, "node_modules/asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -259,7 +255,8 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "node_modules/at-least-node": { "version": "1.0.0", @@ -289,6 +286,7 @@ "version": "0.27.2", "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dev": true, "dependencies": { "follow-redirects": "^1.14.9", "form-data": "^4.0.0" @@ -298,6 +296,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -558,6 +557,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -720,16 +720,11 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, "engines": { "node": ">=0.4.0" } }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -777,21 +772,6 @@ "node": ">=0.8.0" } }, - "node_modules/event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", - "dev": true, - "dependencies": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, "node_modules/eventemitter2": { "version": "6.4.7", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", @@ -896,6 +876,7 @@ "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "dev": true, "funding": [ { "type": "individual", @@ -934,12 +915,6 @@ "node": ">= 0.12" } }, - "node_modules/from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", - "dev": true - }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -1297,6 +1272,7 @@ "version": "17.11.0", "resolved": "https://registry.npmjs.org/joi/-/joi-17.11.0.tgz", "integrity": "sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==", + "dev": true, "dependencies": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", @@ -1389,7 +1365,8 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/lodash.once": { "version": "4.1.1", @@ -1474,12 +1451,6 @@ "node": ">=10" } }, - "node_modules/map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", - "dev": true - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -1490,6 +1461,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -1498,6 +1470,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -1530,6 +1503,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1624,15 +1598,6 @@ "node": ">=8" } }, - "node_modules/pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "dev": true, - "dependencies": { - "through": "~2.3" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -1681,21 +1646,6 @@ "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", "dev": true }, - "node_modules/ps-tree": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", - "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", - "dev": true, - "dependencies": { - "event-stream": "=3.3.4" - }, - "bin": { - "ps-tree": "bin/ps-tree.js" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -1795,6 +1745,7 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, "dependencies": { "tslib": "^2.1.0" } @@ -1910,18 +1861,6 @@ "node": ">=8" } }, - "node_modules/split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", - "dev": true, - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, "node_modules/sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", @@ -1947,83 +1886,6 @@ "node": ">=0.10.0" } }, - "node_modules/start-server-and-test": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.0.2.tgz", - "integrity": "sha512-4sGS2QmETUwqeBUqtTLP7OqXp3PdDnevaWlPlrFQgn8+7uCgVg4Do7/H/ZhAAVyvnL3DqKyANhnLgcgxrjhrMA==", - "dev": true, - "dependencies": { - "arg": "^5.0.2", - "bluebird": "3.7.2", - "check-more-types": "2.24.0", - "debug": "4.3.4", - "execa": "5.1.1", - "lazy-ass": "1.6.0", - "ps-tree": "1.2.0", - "wait-on": "7.1.0" - }, - "bin": { - "server-test": "src/bin/start.js", - "start-server-and-test": "src/bin/start.js", - "start-test": "src/bin/start.js" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/start-server-and-test/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/start-server-and-test/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/start-server-and-test/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", - "dev": true, - "dependencies": { - "duplexer": "~0.1.1" - } - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -2125,7 +1987,8 @@ "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true }, "node_modules/tunnel-agent": { "version": "0.6.0", @@ -2218,6 +2081,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.1.0.tgz", "integrity": "sha512-U7TF/OYYzAg+OoiT/B8opvN48UHt0QYMi4aD3PjRFpybQ+o6czQF8Ig3SKCCMJdxpBrCalIJ4O00FBof27Fu9Q==", + "dev": true, "dependencies": { "axios": "^0.27.2", "joi": "^17.11.0", @@ -2345,12 +2209,14 @@ "@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "dev": true }, "@hapi/topo": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dev": true, "requires": { "@hapi/hoek": "^9.0.0" } @@ -2359,6 +2225,7 @@ "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "dev": true, "requires": { "@hapi/hoek": "^9.0.0" } @@ -2366,12 +2233,14 @@ "@sideway/formula": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "dev": true }, "@sideway/pinpoint": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true }, "@types/node": { "version": "18.18.9", @@ -2450,12 +2319,6 @@ "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", "dev": true }, - "arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true - }, "asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -2486,7 +2349,8 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "at-least-node": { "version": "1.0.0", @@ -2510,6 +2374,7 @@ "version": "0.27.2", "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dev": true, "requires": { "follow-redirects": "^1.14.9", "form-data": "^4.0.0" @@ -2519,6 +2384,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -2702,6 +2568,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -2830,12 +2697,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, "ecc-jsbn": { @@ -2879,21 +2741,6 @@ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, - "event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", - "dev": true, - "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, "eventemitter2": { "version": "6.4.7", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", @@ -2971,7 +2818,8 @@ "follow-redirects": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "dev": true }, "forever-agent": { "version": "0.6.1", @@ -2990,12 +2838,6 @@ "mime-types": "^2.1.12" } }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", - "dev": true - }, "fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -3249,6 +3091,7 @@ "version": "17.11.0", "resolved": "https://registry.npmjs.org/joi/-/joi-17.11.0.tgz", "integrity": "sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==", + "dev": true, "requires": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", @@ -3322,7 +3165,8 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "lodash.once": { "version": "4.1.1", @@ -3385,12 +3229,6 @@ "yallist": "^4.0.0" } }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", - "dev": true - }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -3400,12 +3238,14 @@ "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, "requires": { "mime-db": "1.52.0" } @@ -3428,7 +3268,8 @@ "minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true }, "ms": { "version": "2.1.2", @@ -3496,15 +3337,6 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "dev": true, - "requires": { - "through": "~2.3" - } - }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -3541,15 +3373,6 @@ "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", "dev": true }, - "ps-tree": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", - "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", - "dev": true, - "requires": { - "event-stream": "=3.3.4" - } - }, "psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -3631,6 +3454,7 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, "requires": { "tslib": "^2.1.0" } @@ -3711,15 +3535,6 @@ "is-fullwidth-code-point": "^3.0.0" } }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", - "dev": true, - "requires": { - "through": "2" - } - }, "sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", @@ -3737,62 +3552,6 @@ "tweetnacl": "~0.14.0" } }, - "start-server-and-test": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.0.2.tgz", - "integrity": "sha512-4sGS2QmETUwqeBUqtTLP7OqXp3PdDnevaWlPlrFQgn8+7uCgVg4Do7/H/ZhAAVyvnL3DqKyANhnLgcgxrjhrMA==", - "dev": true, - "requires": { - "arg": "^5.0.2", - "bluebird": "3.7.2", - "check-more-types": "2.24.0", - "debug": "4.3.4", - "execa": "5.1.1", - "lazy-ass": "1.6.0", - "ps-tree": "1.2.0", - "wait-on": "7.1.0" - }, - "dependencies": { - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - } - } - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", - "dev": true, - "requires": { - "duplexer": "~0.1.1" - } - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -3872,7 +3631,8 @@ "tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true }, "tunnel-agent": { "version": "0.6.0", @@ -3944,6 +3704,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.1.0.tgz", "integrity": "sha512-U7TF/OYYzAg+OoiT/B8opvN48UHt0QYMi4aD3PjRFpybQ+o6czQF8Ig3SKCCMJdxpBrCalIJ4O00FBof27Fu9Q==", + "dev": true, "requires": { "axios": "^0.27.2", "joi": "^17.11.0", diff --git a/AMW_e2e/package.json b/AMW_e2e/package.json index 587727411..6994abdcf 100644 --- a/AMW_e2e/package.json +++ b/AMW_e2e/package.json @@ -9,8 +9,8 @@ "test": "cypress run", "test:ci": "npm start & wait-on http://admin:admin@127.0.0.1:8080/AMW_web && cypress run", "docker:build": "cd ./../ && mvn clean install -DskipTests && ./AMW_docker/build.sh && cd ./AMW_e2e", - "docker:start": "docker-compose -f ./../AMW_docker/docker-compose/docker-compose.yml up -d", - "docker:stop": "docker-compose -f ./../AMW_docker/docker-compose/docker-compose.yml down" + "docker:start": "docker compose -f ./../AMW_docker/docker-compose/docker-compose.yml up -d", + "docker:stop": "docker compose -f ./../AMW_docker/docker-compose/docker-compose.yml down" }, "author": "", "license": "ISC", diff --git a/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/RESTApplication.java b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/RESTApplication.java index 128b2cfba..d986ae2a8 100644 --- a/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/RESTApplication.java +++ b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/RESTApplication.java @@ -31,6 +31,7 @@ import ch.mobi.itc.mobiliar.rest.resources.*; import ch.mobi.itc.mobiliar.rest.releases.ReleasesRest; import ch.mobi.itc.mobiliar.rest.settings.SettingsRest; +import ch.mobi.itc.mobiliar.rest.tags.TagsRest; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @@ -81,5 +82,6 @@ private void addRestResourceClasses(Set> resources) { resources.add(SettingsRest.class); resources.add(TestGenerationRest.class); resources.add(ObjectMapperConfig.class); + resources.add(TagsRest.class); } } diff --git a/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java new file mode 100644 index 000000000..f76fd0020 --- /dev/null +++ b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java @@ -0,0 +1,30 @@ +package ch.mobi.itc.mobiliar.rest.tags; + +import ch.puzzle.itc.mobiliar.business.property.control.PropertyTagEditingService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; + +import javax.ejb.Stateless; +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import static javax.ws.rs.core.Response.Status.OK; + +@Stateless +@Path("/settings/tags") +@Api(value = "/settings/tags") +public class TagsRest { + + @Inject + PropertyTagEditingService propertyTagEditingService; + @GET + @Produces({MediaType.APPLICATION_JSON}) + @ApiOperation(value = "Gets all tags") + public Response getAllTags() { + return Response.status(OK).entity(propertyTagEditingService.loadAllGlobalPropertyTagEntities(false)).build(); + } +} From 292b7ff2c53dd17e30118bb1229f7f6783c72768 Mon Sep 17 00:00:00 2001 From: Max Burri Date: Wed, 22 Nov 2023 20:27:30 +0100 Subject: [PATCH 05/41] fix: import HttpClientTestingModule to fix the test --- AMW_angular/io/src/app/settings/tags/tags.component.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.spec.ts b/AMW_angular/io/src/app/settings/tags/tags.component.spec.ts index 352c6ff81..de4f8072d 100644 --- a/AMW_angular/io/src/app/settings/tags/tags.component.spec.ts +++ b/AMW_angular/io/src/app/settings/tags/tags.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { TagsComponent } from './tags.component'; +import {HttpClientTestingModule} from "@angular/common/http/testing"; describe('TagsComponent', () => { let component: TagsComponent; @@ -8,7 +9,8 @@ describe('TagsComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [TagsComponent] + declarations: [TagsComponent], + imports: [HttpClientTestingModule] }) .compileComponents(); From 42df83066254298747334a6190e8a566143e1768 Mon Sep 17 00:00:00 2001 From: Max Burri Date: Wed, 22 Nov 2023 20:28:37 +0100 Subject: [PATCH 06/41] chore: reformat code with prettier --- .../io/src/app/settings/tags/tags.component.spec.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.spec.ts b/AMW_angular/io/src/app/settings/tags/tags.component.spec.ts index de4f8072d..3e635c5e7 100644 --- a/AMW_angular/io/src/app/settings/tags/tags.component.spec.ts +++ b/AMW_angular/io/src/app/settings/tags/tags.component.spec.ts @@ -1,7 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { TagsComponent } from './tags.component'; -import {HttpClientTestingModule} from "@angular/common/http/testing"; +import { HttpClientTestingModule } from '@angular/common/http/testing'; describe('TagsComponent', () => { let component: TagsComponent; @@ -10,9 +10,8 @@ describe('TagsComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [TagsComponent], - imports: [HttpClientTestingModule] - }) - .compileComponents(); + imports: [HttpClientTestingModule], + }).compileComponents(); fixture = TestBed.createComponent(TagsComponent); component = fixture.componentInstance; From 421c637065e6c065cca06852d19e378550425d05 Mon Sep 17 00:00:00 2001 From: Clara Llorente Date: Thu, 23 Nov 2023 10:41:19 +0100 Subject: [PATCH 07/41] fix: docker-compose --- AMW_e2e/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AMW_e2e/package.json b/AMW_e2e/package.json index 6994abdcf..587727411 100644 --- a/AMW_e2e/package.json +++ b/AMW_e2e/package.json @@ -9,8 +9,8 @@ "test": "cypress run", "test:ci": "npm start & wait-on http://admin:admin@127.0.0.1:8080/AMW_web && cypress run", "docker:build": "cd ./../ && mvn clean install -DskipTests && ./AMW_docker/build.sh && cd ./AMW_e2e", - "docker:start": "docker compose -f ./../AMW_docker/docker-compose/docker-compose.yml up -d", - "docker:stop": "docker compose -f ./../AMW_docker/docker-compose/docker-compose.yml down" + "docker:start": "docker-compose -f ./../AMW_docker/docker-compose/docker-compose.yml up -d", + "docker:stop": "docker-compose -f ./../AMW_docker/docker-compose/docker-compose.yml down" }, "author": "", "license": "ISC", From c574cf00d0a36c33174f25737298c7fd8d679973 Mon Sep 17 00:00:00 2001 From: Clara Llorente Date: Thu, 23 Nov 2023 16:47:10 +0100 Subject: [PATCH 08/41] feat: add post endpoint to TagsRest --- .../src/app/settings/tags/tags.component.ts | 5 ++-- .../mobi/itc/mobiliar/rest/dtos/TagDTO.java | 13 ++++++++++ .../mobi/itc/mobiliar/rest/tags/TagsRest.java | 24 ++++++++++++++++--- 3 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/dtos/TagDTO.java diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.ts b/AMW_angular/io/src/app/settings/tags/tags.component.ts index 13cec62d2..8ef2d6f00 100644 --- a/AMW_angular/io/src/app/settings/tags/tags.component.ts +++ b/AMW_angular/io/src/app/settings/tags/tags.component.ts @@ -21,8 +21,9 @@ export class TagsComponent { addTag(): void { if (this.tagName.trim().length > 0) { - this.tags.push({ id: this.tagId++, name: this.tagName.trim() }); - this.tagName = ''; + this.http.post('AMW_rest/resources/settings/tags', { name: this.tagName }).subscribe((newTag) => { + this.tags.push(newTag); + }); } } diff --git a/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/dtos/TagDTO.java b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/dtos/TagDTO.java new file mode 100644 index 000000000..a28e95021 --- /dev/null +++ b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/dtos/TagDTO.java @@ -0,0 +1,13 @@ +package ch.mobi.itc.mobiliar.rest.dtos; + +public class TagDTO { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java index f76fd0020..0003e1992 100644 --- a/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java +++ b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java @@ -1,18 +1,21 @@ package ch.mobi.itc.mobiliar.rest.tags; +import ch.mobi.itc.mobiliar.rest.dtos.TagDTO; +import ch.puzzle.itc.mobiliar.business.property.boundary.PropertyTagEditor; import ch.puzzle.itc.mobiliar.business.property.control.PropertyTagEditingService; +import ch.puzzle.itc.mobiliar.business.property.entity.PropertyTagEntity; +import ch.puzzle.itc.mobiliar.business.property.entity.PropertyTagType; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import javax.ejb.Stateless; import javax.inject.Inject; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; +import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import static javax.ws.rs.core.Response.Status.OK; +import static javax.ws.rs.core.Response.Status.CREATED; @Stateless @Path("/settings/tags") @@ -21,10 +24,25 @@ public class TagsRest { @Inject PropertyTagEditingService propertyTagEditingService; + @GET @Produces({MediaType.APPLICATION_JSON}) @ApiOperation(value = "Gets all tags") public Response getAllTags() { return Response.status(OK).entity(propertyTagEditingService.loadAllGlobalPropertyTagEntities(false)).build(); } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Adds one tag") + public Response addOneTag(TagDTO tagDTO) { + String tagName = tagDTO.getName(); + PropertyTagEntity newTag = new PropertyTagEntity(); + newTag.setName(tagName); + newTag.setTagType(PropertyTagType.GLOBAL); + propertyTagEditingService.addPropertyTag(newTag); + return Response.status(CREATED).build(); + + } + } From d3653176b5ae00cafa6f88a965585f6ef0a8f59c Mon Sep 17 00:00:00 2001 From: Clara Llorente Date: Thu, 23 Nov 2023 16:48:50 +0100 Subject: [PATCH 09/41] refactor: unused imports --- .../src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java index 0003e1992..a0b9c12fa 100644 --- a/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java +++ b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java @@ -1,7 +1,6 @@ package ch.mobi.itc.mobiliar.rest.tags; import ch.mobi.itc.mobiliar.rest.dtos.TagDTO; -import ch.puzzle.itc.mobiliar.business.property.boundary.PropertyTagEditor; import ch.puzzle.itc.mobiliar.business.property.control.PropertyTagEditingService; import ch.puzzle.itc.mobiliar.business.property.entity.PropertyTagEntity; import ch.puzzle.itc.mobiliar.business.property.entity.PropertyTagType; @@ -14,8 +13,8 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import static javax.ws.rs.core.Response.Status.OK; import static javax.ws.rs.core.Response.Status.CREATED; +import static javax.ws.rs.core.Response.Status.OK; @Stateless @Path("/settings/tags") From c0483d4fadf667b667eb2e2f2a8e5b34f913b5fa Mon Sep 17 00:00:00 2001 From: Clara Llorente Date: Wed, 29 Nov 2023 07:46:03 +0100 Subject: [PATCH 10/41] feat: add delete endpoint to TagsRest --- .../mobi/itc/mobiliar/rest/tags/TagsRest.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java index a0b9c12fa..87a9b70d5 100644 --- a/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java +++ b/AMW_rest/src/main/java/ch/mobi/itc/mobiliar/rest/tags/TagsRest.java @@ -13,8 +13,9 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import static javax.ws.rs.core.Response.Status.CREATED; -import static javax.ws.rs.core.Response.Status.OK; +import java.util.List; + +import static javax.ws.rs.core.Response.Status.*; @Stateless @Path("/settings/tags") @@ -41,7 +42,21 @@ public Response addOneTag(TagDTO tagDTO) { newTag.setTagType(PropertyTagType.GLOBAL); propertyTagEditingService.addPropertyTag(newTag); return Response.status(CREATED).build(); + } + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Deletes one tag") + public Response deleteOneTag(TagDTO tagDTO) { + String tagName = tagDTO.getName(); + List propertyTags= propertyTagEditingService.loadAllGlobalPropertyTagEntities(false); + for (PropertyTagEntity tag : propertyTags) { + if (tag.getName().equals(tagName)) { + propertyTagEditingService.deletePropertyTagById(tag.getId()); + return Response.status(OK).build(); + } + } + return Response.status(NOT_FOUND).entity("Tag not found").build(); } } From 04108d730d308f5c0552817c884cd9352b59e74b Mon Sep 17 00:00:00 2001 From: Clara Llorente Date: Wed, 29 Nov 2023 16:22:31 +0100 Subject: [PATCH 11/41] feat: refactor delete endpoint and create toast style for error --- .../app/deployments/deployments.component.ts | 174 +++++++----------- .../src/app/settings/tags/tags.component.ts | 19 +- .../elements/toast/toast.component.scss | 59 +++++- .../shared/elements/toast/toast.component.ts | 34 +++- .../control/PropertyImportService.java | 14 -- .../control/PropertyTagEditingService.java | 13 +- .../mobi/itc/mobiliar/rest/tags/TagsRest.java | 24 +-- 7 files changed, 170 insertions(+), 167 deletions(-) diff --git a/AMW_angular/io/src/app/deployments/deployments.component.ts b/AMW_angular/io/src/app/deployments/deployments.component.ts index a58fafac6..581dc7df5 100644 --- a/AMW_angular/io/src/app/deployments/deployments.component.ts +++ b/AMW_angular/io/src/app/deployments/deployments.component.ts @@ -91,7 +91,7 @@ export class DeploymentsComponent implements OnInit { private deploymentService: DeploymentService, private resourceService: ResourceService, public navigationStore: NavigationStoreService, - private modalService: NgbModal + private modalService: NgbModal, ) { this.navigationStore.setVisible(false); } @@ -107,9 +107,7 @@ export class DeploymentsComponent implements OnInit { } } else { if (sessionStorage.getItem('deploymentFilters')) { - this.paramFilters = JSON.parse( - sessionStorage.getItem('deploymentFilters') - ); + this.paramFilters = JSON.parse(sessionStorage.getItem('deploymentFilters')); } } this.initTypeAndOptions(); @@ -122,12 +120,9 @@ export class DeploymentsComponent implements OnInit { const newFilter: DeploymentFilter = {} as DeploymentFilter; newFilter.name = this.selectedFilterType.name; newFilter.comp = this.defaultComparator; - newFilter.val = - this.selectedFilterType.type === 'booleanType' ? 'true' : ''; + newFilter.val = this.selectedFilterType.type === 'booleanType' ? 'true' : ''; newFilter.type = this.selectedFilterType.type; - newFilter.compOptions = this.comparatorOptionsForType( - this.selectedFilterType.type - ); + newFilter.compOptions = this.comparatorOptionsForType(this.selectedFilterType.type); this.setValueOptionsForFilter(newFilter); this.filters.push(newFilter); this.offset = 0; @@ -173,7 +168,7 @@ export class DeploymentsComponent implements OnInit { this.filtersForBackend.push({ name: filter.name, comp: filter.comp, - val: filter.val.toEpoch().toString() + val: filter.val.toEpoch().toString(), } as DeploymentFilter); } else { this.filtersForBackend.push({ @@ -222,22 +217,28 @@ export class DeploymentsComponent implements OnInit { selected: true, }); const firstDeployment = this.deployments[indexOfFirstSelectedElem]; - this.resourceService - .canCreateShakedownTest(firstDeployment.appServerId) - .subscribe( - /* happy path */ (r) => (this.hasPermissionShakedownTest = r), - /* error path */ (e) => (this.errorMessage = e), - /* onComplete */ () => { - const modalRef = this.modalService.open(DeploymentsEditModalComponent); - modalRef.componentInstance.deployments = this.getSelectedDeployments(); - modalRef.componentInstance.hasPermissionShakedownTest = this.hasPermissionShakedownTest; - - modalRef.componentInstance.doConfirmDeployment.subscribe((deployment: Deployment) => this.confirmDeployment(deployment)) - modalRef.componentInstance.doRejectDeployment.subscribe((deployment: Deployment) => this.rejectDeployment(deployment)) - modalRef.componentInstance.doCancelDeployment.subscribe((deployment: Deployment) => this.cancelDeployment(deployment)) - modalRef.componentInstance.doEditDeploymentDate.subscribe((deployment: Deployment) => this.changeDeploymentDate(deployment)) - } - ); + this.resourceService.canCreateShakedownTest(firstDeployment.appServerId).subscribe( + /* happy path */ (r) => (this.hasPermissionShakedownTest = r), + /* error path */ (e) => (this.errorMessage = e), + /* onComplete */ () => { + const modalRef = this.modalService.open(DeploymentsEditModalComponent); + modalRef.componentInstance.deployments = this.getSelectedDeployments(); + modalRef.componentInstance.hasPermissionShakedownTest = this.hasPermissionShakedownTest; + + modalRef.componentInstance.doConfirmDeployment.subscribe((deployment: Deployment) => + this.confirmDeployment(deployment), + ); + modalRef.componentInstance.doRejectDeployment.subscribe((deployment: Deployment) => + this.rejectDeployment(deployment), + ); + modalRef.componentInstance.doCancelDeployment.subscribe((deployment: Deployment) => + this.cancelDeployment(deployment), + ); + modalRef.componentInstance.doEditDeploymentDate.subscribe((deployment: Deployment) => + this.changeDeploymentDate(deployment), + ); + }, + ); } confirmDeployment(deployment: Deployment) { @@ -246,11 +247,8 @@ export class DeploymentsComponent implements OnInit { deployment.state = this.reMapState(deployment.state); this.deploymentService.confirmDeployment(deployment).subscribe( /* happy path */ (r) => r, - /* error path */ (e) => - (this.errorMessage = this.errorMessage - ? this.errorMessage + '
' + e - : e), - /* onComplete */ () => this.reloadDeployment(deployment.id) + /* error path */ (e) => (this.errorMessage = this.errorMessage ? this.errorMessage + '
' + e : e), + /* onComplete */ () => this.reloadDeployment(deployment.id), ); } } @@ -259,11 +257,8 @@ export class DeploymentsComponent implements OnInit { if (deployment) { this.deploymentService.rejectDeployment(deployment.id).subscribe( /* happy path */ (r) => r, - /* error path */ (e) => - (this.errorMessage = this.errorMessage - ? this.errorMessage + '
' + e - : e), - /* onComplete */ () => this.reloadDeployment(deployment.id) + /* error path */ (e) => (this.errorMessage = this.errorMessage ? this.errorMessage + '
' + e : e), + /* onComplete */ () => this.reloadDeployment(deployment.id), ); } } @@ -272,31 +267,25 @@ export class DeploymentsComponent implements OnInit { if (deployment) { this.deploymentService.cancelDeployment(deployment.id).subscribe( /* happy path */ (r) => r, - /* error path */ (e) => - (this.errorMessage = this.errorMessage - ? this.errorMessage + '
' + e - : e), - /* onComplete */ () => this.reloadDeployment(deployment.id) + /* error path */ (e) => (this.errorMessage = this.errorMessage ? this.errorMessage + '
' + e : e), + /* onComplete */ () => this.reloadDeployment(deployment.id), ); } } exportCSV() { this.isLoading = true; - this.errorMessage = - 'Generating your CSV.
Please hold on, depending on the requested data this may take a while'; - this.getFilteredDeploymentsForCsvExport( - JSON.stringify(this.filtersForBackend) - ); + this.errorMessage = 'Generating your CSV.
Please hold on, depending on the requested data this may take a while'; + this.getFilteredDeploymentsForCsvExport(JSON.stringify(this.filtersForBackend)); } async copyURL() { const url: string = decodeURIComponent(window.location.href); try { await navigator.clipboard.writeText(url); - this.toast.display('URL copied to clipboard'); + this.toast.display('URL copied to clipboard.'); } catch (err) { - this.toast.display('Failed to copy URL. Please try again.'); + this.toast.display('Failed to copy URL. Please try again.', 'error'); } } @@ -326,39 +315,33 @@ export class DeploymentsComponent implements OnInit { this.deploymentService.getWithActions(deploymentId).subscribe( /* happy path */ (r) => (reloadedDeployment = r), /* error path */ (e) => (this.errorMessage = e), - /* on complete */ () => this.updateDeploymentsList(reloadedDeployment) + /* on complete */ () => this.updateDeploymentsList(reloadedDeployment), ); } getSelectedDeployments(): Deployment[] { - return this.deployments.filter( - (deployment) => deployment.selected === true - ); + return this.deployments.filter((deployment) => deployment.selected === true); } autoRefresh() { if (this.refreshInterval > 0 && !this.timerSubscription) { - this.timerSubscription = timer(this.refreshInterval * 1000).subscribe( - () => { - this.getFilteredDeployments(JSON.stringify(this.filtersForBackend)); - this.timerSubscription = null; - } - ); + this.timerSubscription = timer(this.refreshInterval * 1000).subscribe(() => { + this.getFilteredDeployments(JSON.stringify(this.filtersForBackend)); + this.timerSubscription = null; + }); } } private canFilterBeAdded(): boolean { return ( - this.selectedFilterType.name !== - 'Latest deployment job for App Server and Env' || + this.selectedFilterType.name !== 'Latest deployment job for App Server and Env' || _.findIndex(this.filters, { name: this.selectedFilterType.name }) === -1 ); } private pushDownload(prefix: string) { this.isLoading = false; - const docName: string = - prefix + '_' + datefns.format(new Date(), 'yyyy-MM-dd_HHmm').toString() + '.csv'; + const docName: string = prefix + '_' + datefns.format(new Date(), 'yyyy-MM-dd_HHmm').toString() + '.csv'; const blob = new Blob([this.csvDocument], { type: 'text/csv' }); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); @@ -373,32 +356,19 @@ export class DeploymentsComponent implements OnInit { } private setDeploymentDate(deployment: Deployment, deploymentDate: number) { - this.deploymentService - .setDeploymentDate(deployment.id, deploymentDate) - .subscribe( - /* happy path */ (r) => r, - /* error path */ (e) => - (this.errorMessage = this.errorMessage - ? this.errorMessage + '
' + e - : e), - /* on complete */ () => this.reloadDeployment(deployment.id) - ); + this.deploymentService.setDeploymentDate(deployment.id, deploymentDate).subscribe( + /* happy path */ (r) => r, + /* error path */ (e) => (this.errorMessage = this.errorMessage ? this.errorMessage + '
' + e : e), + /* on complete */ () => this.reloadDeployment(deployment.id), + ); } private updateDeploymentsList(deployment: Deployment) { - this.deployments.splice( - _.findIndex(this.deployments, { id: deployment.id }), - 1, - deployment - ); + this.deployments.splice(_.findIndex(this.deployments, { id: deployment.id }), 1, deployment); } private comparatorOptionsForType(filterType: string) { - if ( - filterType === 'booleanType' || - filterType === 'StringType' || - filterType === 'ENUM_TYPE' - ) { + if (filterType === 'booleanType' || filterType === 'StringType' || filterType === 'ENUM_TYPE') { return [{ name: 'eq', displayName: 'is' }]; } else { return this.comparatorOptions; @@ -408,10 +378,7 @@ export class DeploymentsComponent implements OnInit { private setValueOptionsForFilter(filter: DeploymentFilter) { if (!this.filterValueOptions[filter.name]) { if (filter.type === 'booleanType') { - filter.valOptions = this.filterValueOptions[filter.name] = [ - 'true', - 'false', - ]; + filter.valOptions = this.filterValueOptions[filter.name] = ['true', 'false']; } else { this.getAndSetFilterOptionValues(filter); } @@ -452,7 +419,7 @@ export class DeploymentsComponent implements OnInit { this.deploymentService.getAllDeploymentFilterTypes().subscribe( /* happy path */ (r) => (this.filterTypes = _.sortBy(r, 'name')), /* error path */ (e) => (this.errorMessage = e), - /* onComplete */ () => this.getAllComparatorOptions() + /* onComplete */ () => this.getAllComparatorOptions(), ); } @@ -463,7 +430,7 @@ export class DeploymentsComponent implements OnInit { /* onComplete */ () => { this.populateMap(); this.enhanceParamFilter(); - } + }, ); } @@ -471,21 +438,14 @@ export class DeploymentsComponent implements OnInit { this.deploymentService.getFilterOptionValues(filter.name).subscribe( /* happy path */ (r) => (this.filterValueOptions[filter.name] = r), /* error path */ (e) => (this.errorMessage = e), - /* onComplete */ () => - (filter.valOptions = this.filterValueOptions[filter.name]) + /* onComplete */ () => (filter.valOptions = this.filterValueOptions[filter.name]), ); } private getFilteredDeployments(filterString: string) { this.isLoading = true; this.deploymentService - .getFilteredDeployments( - filterString, - this.sortCol, - this.sortDirection, - this.offset, - this.maxResults - ) + .getFilteredDeployments(filterString, this.sortCol, this.sortDirection, this.offset, this.maxResults) .subscribe( /* happy path */ (r) => { this.deployments = r.deployments; @@ -501,28 +461,22 @@ export class DeploymentsComponent implements OnInit { this.isLoading = false; this.mapStates(); this.autoRefresh(); - } + }, ); } private getFilteredDeploymentsForCsvExport(filterString: string) { - this.deploymentService - .getFilteredDeploymentsForCsvExport( - filterString, - this.sortCol, - this.sortDirection - ) - .subscribe( - /* happy path */ (r) => (this.csvDocument = r), - /* error path */ (e) => (this.errorMessage = e), - /* onComplete */ () => this.pushDownload('deployments') - ); + this.deploymentService.getFilteredDeploymentsForCsvExport(filterString, this.sortCol, this.sortDirection).subscribe( + /* happy path */ (r) => (this.csvDocument = r), + /* error path */ (e) => (this.errorMessage = e), + /* onComplete */ () => this.pushDownload('deployments'), + ); } private canRequestDeployments() { this.deploymentService.canRequestDeployments().subscribe( /* happy path */ (r) => (this.hasPermissionToRequestDeployments = r), - /* error path */ (e) => (this.errorMessage = e) + /* error path */ (e) => (this.errorMessage = e), ); } diff --git a/AMW_angular/io/src/app/settings/tags/tags.component.ts b/AMW_angular/io/src/app/settings/tags/tags.component.ts index 8ef2d6f00..a872d426c 100644 --- a/AMW_angular/io/src/app/settings/tags/tags.component.ts +++ b/AMW_angular/io/src/app/settings/tags/tags.component.ts @@ -14,20 +14,29 @@ export class TagsComponent { private tagId = 0; constructor(private http: HttpClient) { - http.get('AMW_rest/resources/settings/tags').subscribe((data) => { - this.tags = data; + http.get('AMW_rest/resources/settings/tags').subscribe({ + next: (data) => { + this.tags = data; + }, }); } addTag(): void { if (this.tagName.trim().length > 0) { - this.http.post('AMW_rest/resources/settings/tags', { name: this.tagName }).subscribe((newTag) => { - this.tags.push(newTag); + this.http.post('AMW_rest/resources/settings/tags', { name: this.tagName }).subscribe({ + next: (newTag) => { + this.tags.push(newTag); + }, + error: (error) => console.log(error), }); } } deleteTag(tagId: number): void { - this.tags = this.tags.filter((tag) => tag.id !== tagId); + this.http.delete(`AMW_rest/resources/settings/tags/${tagId}`).subscribe({ + next: (response) => { + this.tags = this.tags.filter((tag) => tag.id !== tagId); + }, + }); } } diff --git a/AMW_angular/io/src/app/shared/elements/toast/toast.component.scss b/AMW_angular/io/src/app/shared/elements/toast/toast.component.scss index 11cb1e874..bb97839cf 100644 --- a/AMW_angular/io/src/app/shared/elements/toast/toast.component.scss +++ b/AMW_angular/io/src/app/shared/elements/toast/toast.component.scss @@ -10,7 +10,6 @@ } .toast-image { - background-color: #05366E; background-image: url('/assets/images/toast_alert.png'); width: 50px; border-radius: 8px; @@ -18,9 +17,24 @@ border-bottom-right-radius: 0; } +.image-success { + background-color: midnightblue; +} + +.image-error { + background-color: darkred; +} + .toast-body { - color: #127e94; - padding-top: 0; + padding-top: 0; +} + +.body-success { + color: steelblue; +} + +.body-error { + color: darkred; } .toast-list { @@ -33,17 +47,44 @@ justify-content: space-between; padding-top: 0.5rem; padding-bottom: 0; - color: #127e94; border-bottom: 0; } +.header-success { + color: steelblue; +} + +.header-error { + color: darkred; +} + .close { - font-size: 0.8rem; - line-height: 1; - color: #127e94; + font-size: 24px; + line-height: 16px; + color: steelblue; + background-color: transparent; border-radius: 50%; - border: 1px solid #127e94; + border: 2px solid steelblue; width: 16px; height: 16px; - text-align: center; + display: flex; + align-items: center; + justify-content: center; + padding: 0; +} + +.close-success { + color: steelblue; + border: 2px solid steelblue; +} + +.close-error { + color: darkred; + border: 2px solid darkred; } + + + + + + diff --git a/AMW_angular/io/src/app/shared/elements/toast/toast.component.ts b/AMW_angular/io/src/app/shared/elements/toast/toast.component.ts index f182355a1..1975a99d0 100644 --- a/AMW_angular/io/src/app/shared/elements/toast/toast.component.ts +++ b/AMW_angular/io/src/app/shared/elements/toast/toast.component.ts @@ -1,19 +1,31 @@ -import {Component, Input} from '@angular/core'; +import { Component, Input } from '@angular/core'; +type SuccessOrError = 'success' | 'error'; @Component({ selector: 'app-toast', template: `