From ff936a860e6735db857728202e37bc540dcbb71a Mon Sep 17 00:00:00 2001 From: redouan Date: Thu, 26 Sep 2024 18:43:05 +0200 Subject: [PATCH 1/7] #4694 feature (What-new-and-correction): Implemented 'What's New' Section and Profile Updates --- .../components/welcome/welcome.component.html | 39 ++ .../components/welcome/welcome.component.scss | 354 ++++++++++++------ .../components/welcome/welcome.component.ts | 25 +- .../draggable-window.component.scss | 2 +- .../dialogs/whats-new/whats-new.component.ts | 11 +- front/src/app/services/whats-new.service.ts | 2 +- front/src/assets/config.json | 12 +- front/src/assets/i18n/en.json | 2 +- 8 files changed, 315 insertions(+), 132 deletions(-) diff --git a/front/src/app/components/welcome/welcome.component.html b/front/src/app/components/welcome/welcome.component.html index cb111546..f30dfad2 100755 --- a/front/src/app/components/welcome/welcome.component.html +++ b/front/src/app/components/welcome/welcome.component.html @@ -31,6 +31,45 @@

+ +
+
What's New
+
{{ date }}
+
+ +
+ +
+ + +
+
NEW FEATURES
+
+
+
    +
  • + :  + {{ feature.text }} +
  • +
+
+ + +
+
BUG FIXES
+
+
+
    +
  • + {{ bugfix.text }} +
  • +
+
+
+
+
+
Explore More
+
diff --git a/front/src/app/components/welcome/welcome.component.scss b/front/src/app/components/welcome/welcome.component.scss index 9808d532..7b860b1a 100755 --- a/front/src/app/components/welcome/welcome.component.scss +++ b/front/src/app/components/welcome/welcome.component.scss @@ -9,18 +9,18 @@ // First level container .container { width: 100%; - height: 100%; + height: 180%; display: flex; justify-content: center; align-items: center; @include for-phone-only { - height: 180vh; + height: 260vh; margin-bottom: 0; } @include for-tablet-portrait-only { - height: 120vh; + height: 190vh; } // Main container for the welcome page @@ -59,139 +59,132 @@ margin-top: 10px; } } - // Container for the welcome buttons and new testcase - .welcome_buttons { - display: flex; - flex-direction: row; - width: 100%; - height: 100%; - margin-top: 30px; - max-width: 75vw; - column-gap: 20px; - @include for-phone-only { - flex-direction: column; - } +// Container for the welcome buttons and new testcase +.welcome_buttons { + display: flex; + flex-direction: row; + width: 97.5%; + height: 100%; + margin-top: 30px; + max-width: 75vw; + column-gap: 20px; - @include for-tablet-portrait-only { - flex-direction: column; - } - - - .welcome_container { - flex-direction: column; - position: relative; - box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12); - padding: 15px; - border-top-left-radius: 7px; - border-top-right-radius: 7px; - width: 100%; + @include for-phone-only { + flex-direction: column; + } - @include for-phone-only { - margin-top: 30px; - } - - @include for-tablet-portrait-only { - margin: 40px 0 0 0; - } + @include for-tablet-portrait-only { + flex-direction: column; + } - @include for-desktop-up { - margin: 10px 0 0 0; - height: 300px; - } + .welcome_container { + flex-direction: column; + position: relative; + box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12); + padding: 15px; + border-top-left-radius: 7px; + border-top-right-radius: 7px; + width: 100%; + min-height: 300px; // Altura mínima para un tamaño uniforme - } + @include for-phone-only { + margin-top: 30px; + } - .welcome_container_header { - position: absolute; - align-items: center; - justify-content: center; - align-self: center; - max-width: 140px; - height: 30px; - transform: translateY(-100%); - border-top-left-radius: 7px; - border-top-right-radius: 7px; - } + @include for-tablet-portrait-only { + margin: 40px 0 0 0; + } + @include for-desktop-up { + margin: 10px 0 0 0; + } + } - .welcome_container_info { - flex-direction: row; - justify-content: space-between; - text-align: left; - padding-left: 20px; - margin: 20px 0 20px 10px; - @include for-tablet-portrait-only { - - - } - } + .welcome_container_header { + position: absolute; + align-items: center; + justify-content: center; + align-self: center; + max-width: 140px; + height: 30px; + transform: translateY(-100%); + border-top-left-radius: 7px; + border-top-right-radius: 7px; + } - .welcome_container_info div { - align-items: left; - text-align: left; - } + .welcome_container_info { + flex-direction: column; // Cambia a columna para un mejor control + justify-content: space-between; + text-align: left; + padding-left: 20px; + margin: 20px 0 20px 10px; - .welcome_container_info div a h3 { - margin-left: 30px; - } + div { + align-items: left; + text-align: left; + flex: 1; // Permite que cada div tome el mismo espacio + } + } - // Each div the button description - div { - display: flex; - flex-direction: column; - box-sizing: border-box; - width: 90%; - height: 100%; - background-color: $pure-white; - color: $primary-color; - // Container for the upper image of the button - div { - width: 100%; - // Image itself - i { - width: 100px; - height: 100px; - background-image: url(^assets/internal/COM_WELCOME_LOGO.svg); - background-repeat: no-repeat; - background-position: center; - background-size: contain; - @include for-phone-landscape-up { - width: 100px; - height: 100px; - } - } - } - .welcome_container_i { - align-items: center; - } - // Header and footer text of the button - a { - text-decoration: none; - display: inline-block; - h2, - h3 { - cursor: pointer; - color: $blue; - font-weight: normal; - } - } + + div { + display: flex; + flex-direction: column; + box-sizing: border-box; + width: 90%; + height: 100%; + background-color: $pure-white; + color: $primary-color; + + div { + width: 100%; + i { + width: 100px; + height: 100px; + background-image: url(^assets/internal/COM_WELCOME_LOGO.svg); + background-repeat: no-repeat; + background-position: center; + background-size: contain; @include for-phone-landscape-up { - width: 30%; + width: 100px; + height: 100px; } } } - // Container with the buttons to manage testcase creation and tutorial + + .welcome_container_i { + align-items: center; + } + + a { + text-decoration: none; + display: inline-block; + + h2, + h3 { + cursor: pointer; + color: $blue; + font-weight: normal; + } + } + + @include for-phone-landscape-up { + width: 30%; + } + } +} + .create_testcase { display: flex; flex-direction: row; - width: 100%; + width: 98.5%; height: 100%; margin-top: 30px; align-self: center; justify-content: space-between; color: #1a1a1a; - // Each button + div { display: flex; align-items: center; @@ -203,34 +196,37 @@ font-size: 18px; border-top-right-radius: 8px; height: 40px; - width: 45%; + flex-grow: 1; /* Agregado para que crezcan equitativamente */ + margin: 0 5px; /* Espaciado entre botones */ box-shadow: 0 1px 3px 0 #e5b355; - @include for-phone-only { + + @include for-phone-only { width: 100%; margin-bottom: 30px; } } - - @include for-phone-only { + + @include for-phone-only { flex-direction: column; } - + @include for-tablet-portrait-only { flex-direction: row; margin-top: 60px; } - } + // Upper image with cometa's log container .welcome_logo { width: 60%; display: flex; justify-content: center; margin-bottom: 30px; + margin-top: -150px; // Logo itself i { width: 60vw; - height: 40vh; + height: 25vh; background-image: url(^assets/internal/COM_WELCOME_LOGO.svg); background-repeat: no-repeat; background-position: center; @@ -238,12 +234,126 @@ @include for-phone-only { width: 60vw; height: 25vh; + margin-top: -200px; } - @include for-phone-landscape-up { + @include for-tablet-portrait-only { width: 30vw; height: 15vh; + margin-top: 200px; } } } } -} \ No newline at end of file +} + +.welcome_container_info { + min-height: 100px; +} + +.whats-new-title { + margin: 0; + padding: 12px 15px; + box-sizing: border-box; + position: relative; + display: flex; + flex-wrap: wrap; + flex-direction: row; + line-height: 20px; + align-items: flex-start; + width: 100%; + margin-top: 50px; + .title { + text-transform: uppercase; + color: $blue; + width: 100%; + font: inherit; + font-family: 'CorpoS', sans-serif; + font-weight: bold; + font-size: 14pt; + } + .date { + width: 100%; + font-size: 9pt; + font-weight: bold; + color: rgba(black, 0.75); + } +} + +.what-new-content { + width: 100%; +} + +:host { + display: block; + position: relative; +} + +:host::ng-deep icon { + background-repeat: no-repeat; + display: inline-block; + fill: currentColor; + height: 24px; + width: 24px; + font-family: 'Material Icons'; + font-weight: normal; + font-style: normal; + font-size: 24px; + display: inline-block; + line-height: 10px; + text-transform: none; + letter-spacing: normal; + word-wrap: normal; + white-space: nowrap; + direction: ltr; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + -moz-osx-font-smoothing: grayscale; + font-feature-settings: 'liga'; + position: relative; + top: 7px; + color: $blue; +} + +.body { + padding: 15px; + box-sizing: border-box; + max-height: 300px; + overflow-y: auto; + padding-right: 15px; + .header { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 15px; + .title { + flex: initial; + text-transform: uppercase; + color: $blue; + font-weight: bold; + } + .bar { + flex: 1; + height: 1px; + margin-left: 10px; + background-color: rgba($blue, 0.75); + } + } + ul { + display: block; + padding-left: 20px; + li { + list-style-type: none; + margin: 10px 0; + line-height: 25px; + strong { + color: $blue; + } + &:before { + content: '• '; + color: $blue; + } + } + } +} + + diff --git a/front/src/app/components/welcome/welcome.component.ts b/front/src/app/components/welcome/welcome.component.ts index 9589254f..e8c983c7 100755 --- a/front/src/app/components/welcome/welcome.component.ts +++ b/front/src/app/components/welcome/welcome.component.ts @@ -13,7 +13,7 @@ import { Component, ChangeDetectionStrategy, - HostListener, + HostListener } from '@angular/core'; import { Select } from '@ngxs/store'; import { CustomSelectors } from '@others/custom-selectors'; @@ -25,6 +25,11 @@ import { UserState } from '@store/user.state'; import { map, Observable } from 'rxjs'; import { LetDirective } from '../../directives/ng-let.directive'; import { NgIf, AsyncPipe } from '@angular/common'; +import { WhatsNewService } from '@services/whats-new.service'; +import { CommonModule } from '@angular/common'; +import { ViewSelectSnapshot } from '@ngxs-labs/select-snapshot'; +import { ConfigState } from '@store/config.state'; +import { MatDialogModule } from '@angular/material/dialog'; @Component({ selector: 'cometa-welcome', @@ -32,14 +37,15 @@ import { NgIf, AsyncPipe } from '@angular/common'; styleUrls: ['./welcome.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, - imports: [NgIf, LetDirective, AsyncPipe], + imports: [NgIf, LetDirective, AsyncPipe, CommonModule, MatDialogModule], }) export class WelcomeComponent { constructor( private _tours: Tours, public _sharedActions: SharedActionsService, private _tourService: TourService, - private _joyRide: JoyrideService + private _joyRide: JoyrideService, + private whatsNewService: WhatsNewService ) { // Get the tours data from the current user this.tours$ = this.settings$.pipe( @@ -68,6 +74,19 @@ export class WelcomeComponent { ); } + /** Get formatted date from last changelog item, can be null */ + @ViewSelectSnapshot(ConfigState.getLastChangelogDate) date: string | null; + + changes: LogChange[] = []; + features: LogChange[] = []; + bugfixes: LogChange[] = []; + + ngOnInit(){ + this.changes = this.whatsNewService.collectAllChanges(); + this.features = this.changes.filter(change => change.type === 'feature'); + this.bugfixes = this.changes.filter(change => change.type === 'bugfix'); + } + // Gets the name of the current user @Select(UserState.GetUserName) userName$: Observable< ReturnType diff --git a/front/src/app/dialogs/draggable-window/draggable-window.component.scss b/front/src/app/dialogs/draggable-window/draggable-window.component.scss index 245f2e41..72279272 100644 --- a/front/src/app/dialogs/draggable-window/draggable-window.component.scss +++ b/front/src/app/dialogs/draggable-window/draggable-window.component.scss @@ -4,7 +4,7 @@ .handle { position: absolute; - top: 10px; + top: 4px; right: 15px; color: #ccc; cursor: move; diff --git a/front/src/app/dialogs/whats-new/whats-new.component.ts b/front/src/app/dialogs/whats-new/whats-new.component.ts index 2b70d77d..22e55646 100644 --- a/front/src/app/dialogs/whats-new/whats-new.component.ts +++ b/front/src/app/dialogs/whats-new/whats-new.component.ts @@ -45,13 +45,18 @@ export class WhatsNewDialog { @Inject(MAT_DIALOG_DATA) private data: LogChange[], private _sanitizer: DomSanitizer ) { - // Filter changes to show on dialog - this.changes = classifyByProperty(this.data, 'type'); + if (Array.isArray(this.data)) { + this.changes = classifyByProperty(this.data, 'type'); + } else { + console.error('Expected array, but got:', this.data); + this.changes = { feature: [], bugfix: [] }; + } + const randPoster = Math.floor(Math.random() * 3) + 1; - // Sanitize poster url this.poster = this._sanitizer.bypassSecurityTrustUrl( `assets/img/poster_${randPoster}.svg` ); + } poster: SafeUrl; diff --git a/front/src/app/services/whats-new.service.ts b/front/src/app/services/whats-new.service.ts index c8736d82..b821f89c 100644 --- a/front/src/app/services/whats-new.service.ts +++ b/front/src/app/services/whats-new.service.ts @@ -109,7 +109,7 @@ export class WhatsNewService { // Open What's New Dialog this._dialog .open(WhatsNewDialog, { - data: changes, + data: changes || [], disableClose: true, autoFocus: false, closeOnNavigation: false, diff --git a/front/src/assets/config.json b/front/src/assets/config.json index e978f559..c58e93f9 100755 --- a/front/src/assets/config.json +++ b/front/src/assets/config.json @@ -1,5 +1,5 @@ { - "version": "3.0.0", + "version": "3.0.1", "language": "en", "appTitle": "co.meta", "scenario": "dev", @@ -232,6 +232,16 @@ "{Code is Poetry}" ], "changelog": [ + { + "version": "3.0.1", + "date": "2024-09-26", + "features": [ + { + "title": "#4694 Implemented 'What's New' Section and Profile Updates", + "description": "Added a 'What's New' section in the Home tab, updated Profile with new changes, corrected typos, and adjusted the draggable icon for alignment." + } + ] + }, { "version": "3.0.0", "date": "2024-09-21", diff --git a/front/src/assets/i18n/en.json b/front/src/assets/i18n/en.json index a59c4c6d..ec608541 100755 --- a/front/src/assets/i18n/en.json +++ b/front/src/assets/i18n/en.json @@ -80,7 +80,7 @@ }, "user": { "tour_description": "In co.meta you can learn about features interactive using the virtual tour guide. The virtual tour guide will show you around and explain step by step the how's and where's. Move your mouse over the tour buttons to see a short description.", - "webhooks_desc": "Integrating co.meta with your preferred tools empowers you to optimize your development process. By seamlessly connecting Co.Meta, you can accelerate project completion, implement continuous testing practices, and effectively share quality updates with your entire department." + "webhooks_desc": "Integrating co.meta with your preferred tools empowers you to optimize your development process. By seamlessly connecting co.meta, you can accelerate project completion, implement continuous testing practices, and effectively share quality updates with your entire department." }, "connected": "Connected", "not_connected": "Not connected", From ff54cf5c630502f437d563c0152ca28e10e52573 Mon Sep 17 00:00:00 2001 From: redouan Date: Wed, 9 Oct 2024 10:58:17 +0200 Subject: [PATCH 2/7] #4694 (change-short): Replace letetr D to O --- .../edit-feature/edit-feature.component.ts | 6 +-- front/src/app/others/enums.ts | 37 ++++++++++--------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/front/src/app/dialogs/edit-feature/edit-feature.component.ts b/front/src/app/dialogs/edit-feature/edit-feature.component.ts index d46032e2..3f167517 100755 --- a/front/src/app/dialogs/edit-feature/edit-feature.component.ts +++ b/front/src/app/dialogs/edit-feature/edit-feature.component.ts @@ -461,8 +461,8 @@ export class EditFeature implements OnInit, OnDestroy { this.editVariables(); } break; - case KEY_CODES.D: - // Depends on other featre + case KEY_CODES.O: + // Depends on other feature this.toggleDependsOnOthers(KeyPressed); break; case KEY_CODES.M: @@ -512,7 +512,7 @@ export class EditFeature implements OnInit, OnDestroy { toggleDependsOnOthers(KeyPressed) { let checkboxValue = this.featureForm.get('send_mail').value; let dependsOnOthers = this.featureForm.get('depends_on_others').value; - if(KeyPressed === KEY_CODES.D) { + if(KeyPressed === KEY_CODES.O) { dependsOnOthers = this.featureForm.get('depends_on_others').value; this.featureForm.get('depends_on_others').setValue(!dependsOnOthers); } diff --git a/front/src/app/others/enums.ts b/front/src/app/others/enums.ts index e944f42f..970248bb 100644 --- a/front/src/app/others/enums.ts +++ b/front/src/app/others/enums.ts @@ -1,26 +1,27 @@ export enum KEY_CODES { - RIGHT_ARROW = 39, - LEFT_ARROW = 37, - SPACE = 32, - ESCAPE = 27, + A = 65, + ARROW_DOWN = 40, + ARROW_UP = 38, + B = 66, C = 67, - PLUS = 187, + CTRL = 17, + D = 68, E = 69, + ESCAPE = 27, + F = 70, + G = 71, + H = 72, L = 76, + M = 77, + N = 78, + O = 79, P = 80, - S = 83, + PLUS = 187, R = 82, - N = 78, - V = 86, - D = 68, - M = 77, - F = 70, - H = 72, - A = 65, + RIGHT_ARROW = 39, + S = 83, + SPACE = 32, T = 84, - B = 66, - G = 71, - CTRL = 17, - ARROW_DOWN = 40, - ARROW_UP = 38 + V = 86, + LEFT_ARROW = 37 } From 047cdd4314eced9fb200d634cea4902e73e4657e Mon Sep 17 00:00:00 2001 From: redouan Date: Wed, 9 Oct 2024 11:37:13 +0200 Subject: [PATCH 3/7] #4694 (change-short): Replace letetr D to O --- front/src/assets/config.json | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/front/src/assets/config.json b/front/src/assets/config.json index e978f559..b215eaa6 100755 --- a/front/src/assets/config.json +++ b/front/src/assets/config.json @@ -1,5 +1,5 @@ { - "version": "3.0.0", + "version": "3.0.2", "language": "en", "appTitle": "co.meta", "scenario": "dev", @@ -232,6 +232,26 @@ "{Code is Poetry}" ], "changelog": [ + { + "version": "3.0.2", + "date": "2024-10-09", + "features": [ + { + "title": "#4694 - Updated Keyboard Shortcut", + "description": "The keyboard shortcut for the feature that was previously triggered by pressing 'D' is now updated to 'O'." + } + ] + }, + { + "version": "3.0.1", + "date": "2024-09-26", + "features": [ + { + "title": "#4694 Implemented 'What's New' Section and Profile Updates", + "description": "Added a 'What's New' section in the Home tab, updated Profile with new changes, corrected typos, and adjusted the draggable icon for alignment." + } + ] + }, { "version": "3.0.0", "date": "2024-09-21", From 45b0a5525b6cf784a2ee3002e24bc1df47504112 Mon Sep 17 00:00:00 2001 From: redouan Date: Thu, 10 Oct 2024 14:40:41 +0200 Subject: [PATCH 4/7] #4694 fix (Dissbale-shortcuts): Dissable shortcuts when select mat-form-fields --- .../dialogs/edit-feature/edit-feature.component.html | 12 +++++++++--- .../dialogs/edit-feature/edit-feature.component.ts | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/front/src/app/dialogs/edit-feature/edit-feature.component.html b/front/src/app/dialogs/edit-feature/edit-feature.component.html index 25927fd2..e6cea42e 100755 --- a/front/src/app/dialogs/edit-feature/edit-feature.component.html +++ b/front/src/app/dialogs/edit-feature/edit-feature.component.html @@ -33,7 +33,9 @@

Clone feature

+ formControlName="department_name" + (focus)="onInputFocus()" + (blur)="onInputBlur()"> @@ -45,7 +47,9 @@

Clone feature

Application + formControlName="app_name" + (focus)="onInputFocus()" + (blur)="onInputBlur()"> @@ -57,7 +61,9 @@

Clone feature

Environment + formControlName="environment_name" + (focus)="onInputFocus()" + (blur)="onInputBlur()"> diff --git a/front/src/app/dialogs/edit-feature/edit-feature.component.ts b/front/src/app/dialogs/edit-feature/edit-feature.component.ts index 3f167517..f812ffb0 100755 --- a/front/src/app/dialogs/edit-feature/edit-feature.component.ts +++ b/front/src/app/dialogs/edit-feature/edit-feature.component.ts @@ -461,7 +461,7 @@ export class EditFeature implements OnInit, OnDestroy { this.editVariables(); } break; - case KEY_CODES.O: + case KEY_CODES.D: // Depends on other feature this.toggleDependsOnOthers(KeyPressed); break; @@ -512,7 +512,7 @@ export class EditFeature implements OnInit, OnDestroy { toggleDependsOnOthers(KeyPressed) { let checkboxValue = this.featureForm.get('send_mail').value; let dependsOnOthers = this.featureForm.get('depends_on_others').value; - if(KeyPressed === KEY_CODES.O) { + if(KeyPressed === KEY_CODES.D) { dependsOnOthers = this.featureForm.get('depends_on_others').value; this.featureForm.get('depends_on_others').setValue(!dependsOnOthers); } From b6f1e73fed58525651e37b4dcaa3d9d33e828be2 Mon Sep 17 00:00:00 2001 From: Anand Kushwaha Date: Wed, 16 Oct 2024 13:24:21 +0200 Subject: [PATCH 5/7] Update README.md --- README.md | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 1bf30f93..81cca80c 100644 --- a/README.md +++ b/README.md @@ -39,22 +39,24 @@ Here is what you need to be able to run Cometa. Co.Meta needs to be able to fetch software from the internet. For example python libraries, pre-built containers with virtual browser. When installing Co.meta in a corporate environment, make sure to whitelist the following domains on the Secure Proxy: + +* **List of FQDNs (Full Qualified Domain Names) to clear proxy** + | **Domain** | **Reason** | + |--------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| + | git.amvara.de | Configure GitLab-runner to provide updates to Cometa. The server should have access to the Amvara GitLab. | + | d.amvara.de | Set up Discord notifications for monitoring Cometa servers (storage, errors, feature executions, etc.) and sending notifications to the Amvara team. | + | github.com
raw.githubusercontent.com
media.githubusercontent.com
avatars.githubusercontent.com
gist.githubusercontent.com | Cometa downloads dependencies from GitHub repositories, as it is built on open-source libraries. | + | docs.docker.com
download.docker.com
store.docker.com | These URLs are used to download and update Docker and Docker Compose installers when updates are required. | + | hub.docker.com | Cometa runs on Docker containers and downloads necessary images from Docker Hub, such as Python, Apache, Node.js, etc. | + | registry.npmjs.org
www.npmjs.com
deb.nodesource.com | Cometa runs a container called `cometa_socket`, which uses Node.js and npm. | + | repo.maven.apache.org | Cometa runs a container called `cometa_selenoid`, which downloads JAR libraries from Maven. | + | pypi.org | The Cometa components `cometa_behave`, `cometa_django`, and `cometa_scheduler` rely on Python libraries and download dependencies from this URL. | + | kubernetes-charts.storage.googleapis.com | Proxy clearance for accessing Kubernetes charts. | + | deb.debian.org
security.debian.org (http and https) | Most of the containers running within cometa uses debian based container, so Debian official repositories are needed for downloading and updating dependencies. | + | deb.debian.org (http and https) | Debian backports repository for newer packages available for stable releases. | + | deb-multimedia.org (http and https) | Debian multimedia repository for additional multimedia-related packages. | + | deb.debian.org (http and https) | Debian "non-free" and "contrib" repositories for software outside of Debian's strict free software guidelines. | - * https://*.amvara.de - * https://github.com - * https://*.githubusercontent.com - * https://*.docker.com - * https://*.docker.io - * https://registry.npmjs.org - * https://www.npmjs.com - * https://repo.maven.apache.org - * https://kubernetes-charts.storage.googleapis.com - * https://plugins.gradle.org:443 - * https://registry.yarnpkg.com - * https://deb.nodesource.com - * https://mod-auth-openidc.org - * https://pypi.org - * http://*.debian.org and https://*.debian.org

For corporate environments using a Secure Proxy the Proxy usage needs to be configured: From 0c6e01eed1ed48ca614fe5f2f8767b1e4cf4616d Mon Sep 17 00:00:00 2001 From: Anand Kushwaha Date: Wed, 16 Oct 2024 15:12:59 +0200 Subject: [PATCH 6/7] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 81cca80c..28a34567 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,7 @@ Here is what you need to be able to run Cometa. | pypi.org | The Cometa components `cometa_behave`, `cometa_django`, and `cometa_scheduler` rely on Python libraries and download dependencies from this URL. | | kubernetes-charts.storage.googleapis.com | Proxy clearance for accessing Kubernetes charts. | | deb.debian.org
security.debian.org (http and https) | Most of the containers running within cometa uses debian based container, so Debian official repositories are needed for downloading and updating dependencies. | - | deb.debian.org (http and https) | Debian backports repository for newer packages available for stable releases. | - | deb-multimedia.org (http and https) | Debian multimedia repository for additional multimedia-related packages. | - | deb.debian.org (http and https) | Debian "non-free" and "contrib" repositories for software outside of Debian's strict free software guidelines. | + | deb-multimedia.org (http and https) | Debian multimedia repository for additional multimedia-related packages. |

From b11f009bc4bc7a20d6d255e86f5b2e0b9d52b488 Mon Sep 17 00:00:00 2001 From: anandkushwaha064 Date: Wed, 13 Nov 2024 21:05:13 +0530 Subject: [PATCH 7/7] #4938 Adding option to send email on error after X times only --- backend/src/backend/generatePDF.py | 45 +++++++++++++++++-- backend/src/backend/models.py | 4 ++ .../edit-feature/edit-feature.component.html | 23 ++++++++++ .../edit-feature/edit-feature.component.scss | 6 ++- .../edit-feature/edit-feature.component.ts | 4 ++ front/src/assets/config.json | 12 ++++- front/src/assets/i18n/en.json | 1 + front/src/assets/i18n/es.json | 1 + 8 files changed, 90 insertions(+), 6 deletions(-) diff --git a/backend/src/backend/generatePDF.py b/backend/src/backend/generatePDF.py index c422316c..09a531b9 100644 --- a/backend/src/backend/generatePDF.py +++ b/backend/src/backend/generatePDF.py @@ -173,17 +173,54 @@ def get(self, request): response['Content-Length'] = len(PDFContent) return response else: + self.send_mail() + + # Finish + return HttpResponse("200") + + """ + This function handles the logic of sending the mail + """ + def send_mail(self): + feature = Feature.objects.get(feature_id=self.feature_id) + should_send_the_email = True + + # if feature is set to check for notification on error + if feature.check_maximum_notification_on_error: + logger.debug("Checking for maximum emails on error") + # Check if current feature_result is failed + # Check if number of sent notifications are less then maximum number set to send the notification + if self.feature_result.success and not feature.send_mail_on_error: + should_send_the_email = True + feature.number_notification_sent = 0 + + elif self.feature_result.success: + should_send_the_email = False + feature.number_notification_sent = 0 + + # Send email and increase number_notification_sent count by 1 + elif feature.number_notification_sent < feature.maximum_notification_on_error: + feature.number_notification_sent = feature.number_notification_sent + 1 + should_send_the_email = True + + elif feature.number_notification_sent >= feature.maximum_notification_on_error: + should_send_the_email = False + # In check_maximum_notification_on_error set number_notification_sent to 0 so that user can get the notification when new error is there + else: + feature.number_notification_sent = 0 + + feature.save() + + if should_send_the_email: # Build the subject and the emailbody. self.subject = self.BuildEmailSubject() self.emailbody = self.BuildEmailBody() # Send the email. self.SendEmail() - - - # Finish - return HttpResponse("200") + else: + logger.info("Skip sending email ") """ This function starts a logger to output information into syslog. It uses python default logger object. """ diff --git a/backend/src/backend/models.py b/backend/src/backend/models.py index 3c917262..8eb50f4f 100755 --- a/backend/src/backend/models.py +++ b/backend/src/backend/models.py @@ -17,6 +17,7 @@ from django.dispatch import receiver from django_cryptography.fields import encrypt from crontab import CronSlices +from django.core.validators import MinValueValidator, MaxValueValidator # GLOBAL VARIABLES @@ -778,6 +779,9 @@ class Feature(models.Model): created_by = models.ForeignKey(OIDCAccount, on_delete=models.SET_NULL, null=True, default=None, related_name="created_by") send_mail = models.BooleanField(default=False) send_mail_on_error = models.BooleanField(default=False) + check_maximum_notification_on_error = models.BooleanField(default=False) + maximum_notification_on_error = models.IntegerField(default=0,validators=[MinValueValidator(0)]) + number_notification_sent = models.IntegerField(default=0,validators=[MinValueValidator(0)]) attach_pdf_report_to_email = models.BooleanField(verbose_name="Enable or disable the option to attach PDFs to emails.", help_text="If true, a test result PDF will be attached to the email; otherwise, the email will be sent without the PDF. This is useful when sending emails with a customized template.", default=True) do_not_use_default_template = models.BooleanField(verbose_name="Do not use Default e-Mail Template", help_text="If true, then the alternative template will be used, which can be used for creating customized e-Mails, e.g. only containing screenshot", default=False) email_address = ArrayField(models.CharField(max_length=250), null=True, blank=True, default=list) diff --git a/front/src/app/dialogs/edit-feature/edit-feature.component.html b/front/src/app/dialogs/edit-feature/edit-feature.component.html index e6cea42e..147013a7 100755 --- a/front/src/app/dialogs/edit-feature/edit-feature.component.html +++ b/front/src/app/dialogs/edit-feature/edit-feature.component.html @@ -276,6 +276,20 @@

Clone feature

(blur)="onInputBlur()" > + + Maximum notifications on errors + + + +
When to send email: Clone feature

>On error + + Set maximum notifications on errors Clone feature mat-icon-button> help_outline + diff --git a/front/src/app/dialogs/edit-feature/edit-feature.component.scss b/front/src/app/dialogs/edit-feature/edit-feature.component.scss index 21bba533..78bb8fc3 100755 --- a/front/src/app/dialogs/edit-feature/edit-feature.component.scss +++ b/front/src/app/dialogs/edit-feature/edit-feature.component.scss @@ -43,7 +43,11 @@ } .default_template { - margin-left: 5%; + margin-left: 2%; +} + +.maximum-notifications-check { + margin-left: 3%; } .report_to_email { diff --git a/front/src/app/dialogs/edit-feature/edit-feature.component.ts b/front/src/app/dialogs/edit-feature/edit-feature.component.ts index f812ffb0..0343ec7a 100755 --- a/front/src/app/dialogs/edit-feature/edit-feature.component.ts +++ b/front/src/app/dialogs/edit-feature/edit-feature.component.ts @@ -250,6 +250,8 @@ export class EditFeature implements OnInit, OnDestroy { generate_dataset: [false], need_help: [false], send_mail_on_error: [false], + check_maximum_notification_on_error: [false], + maximum_notification_on_error: ['3'], attach_pdf_report_to_email: [true], do_not_use_default_template: [false], continue_on_failure: [true], @@ -635,6 +637,8 @@ export class EditFeature implements OnInit, OnDestroy { 'email_subject', 'email_body', 'send_mail_on_error', + 'maximum_notification_on_error', + 'check_maximum_notification_on_error', 'attach_pdf_report_to_email', 'do_not_use_default_template', ]; diff --git a/front/src/assets/config.json b/front/src/assets/config.json index b215eaa6..2c9ae385 100755 --- a/front/src/assets/config.json +++ b/front/src/assets/config.json @@ -1,5 +1,5 @@ { - "version": "3.0.2", + "version": "3.0.3", "language": "en", "appTitle": "co.meta", "scenario": "dev", @@ -232,6 +232,16 @@ "{Code is Poetry}" ], "changelog": [ + { + "version": "3.0.3", + "date": "2024-11-13", + "features": [ + { + "title": "#4938 - Email report enhancement", + "description": "Email reporting enhanced to set the number of consecutive failure emails you want to receive. This option helps to avoid continuous failure notifications, so the user is not bombarded with excessive emails." + } + ] + }, { "version": "3.0.2", "date": "2024-10-09", diff --git a/front/src/assets/i18n/en.json b/front/src/assets/i18n/en.json index ec608541..cd842f34 100755 --- a/front/src/assets/i18n/en.json +++ b/front/src/assets/i18n/en.json @@ -40,6 +40,7 @@ "explanation": "Enabling this option allows other users to help you on this feature", "edit_variable": "In this section, we can add or edit variables among other functionalities", "default_template": "If Checked, then please provide your custom email template, which can be used for creating customized e-Mails, e.g. only containing screenshot. The default is false - to not change the actual behavior customers are using", + "maximum_notification_on_error": "If checked, please set the number of consecutive failure emails you want to receive. This option helps to avoid continuous failure notifications, so the user is not bombarded with excessive emails.", "attach_pdf": "If Checked, PDF test result will be attached within the email, Other wise email without PDF will be sent. Useful when sending email with customized template" }, "step-definition": { diff --git a/front/src/assets/i18n/es.json b/front/src/assets/i18n/es.json index 4fc1275b..93ced20e 100755 --- a/front/src/assets/i18n/es.json +++ b/front/src/assets/i18n/es.json @@ -157,6 +157,7 @@ "explanation": "Habilitar esta opción permite que otros usuarios te ayuden en esta característica", "edit_variable": "En esta sección, podemos agregar o editar variables entre otras funcionalidades", "default_template": "Si está marcado, proporcione su plantilla de correo electrónico personalizada, que se puede usar para crear correos electrónicos personalizados, por ejemplo, solo con capturas de pantalla. El valor predeterminado es falso: para no cambiar el comportamiento actual que usan los clientes.", + "maximum_notification_on_error":"Si está marcado, proporcione la cantidad de correos electrónicos de fallos consecutivos que desea recibir. Esta opción es útil para evitar notificaciones continuas de fallos, de modo que el usuario no sea bombardeado con correos electrónicos excesivos.", "attach_pdf": "Si está marcado, se adjuntará el resultado de la prueba en PDF en el correo electrónico. De lo contrario, se enviará el correo electrónico sin PDF. Útil cuando se envía correo electrónico con plantilla personalizada." }, "step-definition": {