diff --git a/security-c4po-angular/angular.json b/security-c4po-angular/angular.json index c78969b..9155bfb 100644 --- a/security-c4po-angular/angular.json +++ b/security-c4po-angular/angular.json @@ -29,7 +29,9 @@ ], "styles": [ "src/assets/@theme/styles/styles.scss", - "node_modules/@fortawesome/fontawesome-free/css/all.css" + "node_modules/@fortawesome/fontawesome-free/css/all.css", + "node_modules/@glidejs/glide/src/assets/sass/glide.core.scss", + "node_modules/@glidejs/glide/src/assets/sass/glide.theme.scss" ], "scripts": [ "node_modules/@fortawesome/fontawesome-free/js/all.js" diff --git a/security-c4po-angular/package-lock.json b/security-c4po-angular/package-lock.json index 2598d99..28b2120 100644 --- a/security-c4po-angular/package-lock.json +++ b/security-c4po-angular/package-lock.json @@ -472,11 +472,11 @@ } }, "@angular/animations": { - "version": "12.2.17", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-12.2.17.tgz", - "integrity": "sha512-WVUcvKvr6wr9Nf3I2ksu5bFJ5xHhby4UEBTvOAdLpDqic+dzqtzVwAktDRprBSdxKQk1OlTw6jD4MsVEDKnZTg==", + "version": "11.2.14", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-11.2.14.tgz", + "integrity": "sha512-Heq/nNrCmb3jbkusu+BQszOecfFI/31Oxxj+CDQkqqYpBcswk6bOJLoEE472o+vmgxaXbgeflU9qbIiCQhpMFA==", "requires": { - "tslib": "^2.2.0" + "tslib": "^2.0.0" } }, "@angular/cdk": { @@ -2433,6 +2433,11 @@ } } }, + "@glidejs/glide": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@glidejs/glide/-/glide-3.6.0.tgz", + "integrity": "sha512-47Aa+JmYjY4xTFpTtYCwrqirmI1arnp1UZETwtWpbTPisXUAuxrdJxKJLH8KHFWMsSrLi9+AcfyfzDIuO75rEA==" + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -11802,6 +11807,14 @@ "resolved": "https://registry.npmjs.org/ng-mocks/-/ng-mocks-13.5.2.tgz", "integrity": "sha512-mn9qkef166cKmg5k1/jY4AlXEGEPx/cdWXKDdSrs/Fett+nLEAx70uD1LJrpQ35PY6k0v6AUd4fbZX5OaoFNRg==" }, + "ngx-glide": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/ngx-glide/-/ngx-glide-12.1.1.tgz", + "integrity": "sha512-nbc5lRm22WRJ7Kb6bXFJ1E+2S/HIKy157ML6ZXlo2CYwJ1mt+LvvWCGiQP2mQ9CIKufbE4fcZqn1QZWkDxnkGQ==", + "requires": { + "tslib": "^2.1.0" + } + }, "ngx-moment": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ngx-moment/-/ngx-moment-5.0.0.tgz", diff --git a/security-c4po-angular/package.json b/security-c4po-angular/package.json index 01b9aed..f77026e 100644 --- a/security-c4po-angular/package.json +++ b/security-c4po-angular/package.json @@ -11,7 +11,7 @@ }, "private": true, "dependencies": { - "@angular/animations": "^12.2.16", + "@angular/animations": "^11.2.14", "@angular/cdk": "^12.2.7", "@angular/common": "^12.2.16", "@angular/compiler": "~12.2.16", @@ -27,6 +27,7 @@ "@fortawesome/fontawesome-svg-core": "^6.3.0", "@fortawesome/free-regular-svg-icons": "^6.3.0", "@fortawesome/free-solid-svg-icons": "^6.3.0", + "@glidejs/glide": "^3.6.0", "@nebular/eva-icons": "^8.0.0", "@nebular/theme": "^8.0.0", "@ngneat/until-destroy": "~8.0.4", @@ -44,6 +45,7 @@ "moment": "^2.29.1", "moment-timezone": "latest", "ng-mocks": "^13.4.2", + "ngx-glide": "^12.0.0", "ngx-moment": "^5.0.0", "ngx-take-until-destroy": "^5.4.0", "ngx-translate-testing": "^5.2.0", diff --git a/security-c4po-angular/src/app/header/header.component.html b/security-c4po-angular/src/app/header/header.component.html index 12b61a6..508a40c 100644 --- a/security-c4po-angular/src/app/header/header.component.html +++ b/security-c4po-angular/src/app/header/header.component.html @@ -14,7 +14,7 @@ - + diff --git a/security-c4po-angular/src/app/header/header.component.ts b/security-c4po-angular/src/app/header/header.component.ts index 73aad41..a2e92ab 100644 --- a/security-c4po-angular/src/app/header/header.component.ts +++ b/security-c4po-angular/src/app/header/header.component.ts @@ -16,6 +16,7 @@ import {environment} from '../../environments/environment'; import {Router} from '@angular/router'; import {DialogService} from '@shared/services/dialog-service/dialog.service'; import {ProfileSettingsComponent} from '@shared/modules/profile-settings/profile-settings.component'; +import {TutorialDialogComponent} from '@shared/modules/tutorial-dialog/tutorial-dialog.component'; @Component({ selector: 'app-header', @@ -128,8 +129,20 @@ export class HeaderComponent implements OnInit { window.open(url, '_blank'); } - onClickShowInfo(): void { + onClickShowTutorial(): void { console.info('To be implemented..'); + + this.dialogService.openCustomDialog( + TutorialDialogComponent, + {} + ).onClose.pipe( + filter((confirm) => !!confirm), + untilDestroyed(this) + ).subscribe({ + next: () => { + console.info('New Settings confirmed'); + } + }); } onClickSwitchTheme(): void { diff --git a/security-c4po-angular/src/app/header/header.module.ts b/security-c4po-angular/src/app/header/header.module.ts index e38e908..7dcd031 100644 --- a/security-c4po-angular/src/app/header/header.module.ts +++ b/security-c4po-angular/src/app/header/header.module.ts @@ -13,6 +13,7 @@ import {FontAwesomeModule} from '@fortawesome/angular-fontawesome'; import {FlexLayoutModule} from '@angular/flex-layout'; import {TranslateModule} from '@ngx-translate/core'; import {ProfileSettingsModule} from '@shared/modules/profile-settings/profile-settings.module'; +import {TutorialDialogModule} from '@shared/modules/tutorial-dialog/tutorial-dialog.module'; @NgModule({ declarations: [ @@ -33,6 +34,7 @@ import {ProfileSettingsModule} from '@shared/modules/profile-settings/profile-se NbUserModule, NbContextMenuModule, ProfileSettingsModule, + TutorialDialogModule ], providers: [ ] diff --git a/security-c4po-angular/src/assets/@theme/styles/styles.scss b/security-c4po-angular/src/assets/@theme/styles/styles.scss index 741f677..1a5e3f5 100644 --- a/security-c4po-angular/src/assets/@theme/styles/styles.scss +++ b/security-c4po-angular/src/assets/@theme/styles/styles.scss @@ -9,6 +9,10 @@ @import './overrides'; @import './variables'; +// loading glide +@import "~@glidejs/glide/src/assets/sass/glide.core"; +@import "~@glidejs/glide/src/assets/sass/glide.theme"; + * { font-family: Roboto, "Helvetica Neue", sans-serif; } diff --git a/security-c4po-angular/src/assets/i18n/de-DE.json b/security-c4po-angular/src/assets/i18n/de-DE.json index 4f8a183..755378c 100644 --- a/security-c4po-angular/src/assets/i18n/de-DE.json +++ b/security-c4po-angular/src/assets/i18n/de-DE.json @@ -20,6 +20,7 @@ "action.complete": "Fertig", "action.disable": "Deaktivieren", "action.enable": "Aktivieren", + "action.close": "Schließen", "action.yes": "Ja", "action.no": "Nein", "username": "Nutzername", @@ -87,6 +88,23 @@ } } }, + "tutorial": { + "header": "Erste Schritte mit C4PO", + "carousel": { + "project_overview": "Die Projektübersicht gibt Ihnen einen Überblick über alle Ihre aktuellen Projekte.\nHier können Sie neue erstellen, bestehende bearbeiten oder löschen oder nach einem bestimmten Projekt filtern.\nSehen Sie den aktuellen Stand Ihrer Projekte sowie den Fortschritt zusammen mit einigen zusätzlichen Informationen wie Name, Kunde, Tester und wann es erstellt wurde.", + "project_overview_filtered": "Das Filtern in der Projektübersicht kann Ihnen helfen, das/die gesuchte(n) Projekt(e) zu finden.\nGeben Sie bestimmte Schlüsselwörter wie den Titel eines Projekts oder einen speziellen Status wie „Benötigt weitere Informationen“ ein oder suchen Sie nach einem wichtigen Kunden.", + "create_edit_project": "Erstellen Sie ein neues oder ein bestehendes Projekt, geben Sie ihm einen Titel und einen Kundennamen, weisen Sie einen Tester zu und schreiben Sie eine Zusammenfassung für den Pentest (nur im Bearbeitungsmodus verfügbar).\nDarüber hinaus können Sie auch einen bestimmten Status für das Projekt auswählen, um anzuzeigen, ob der Pentest derzeit „in Arbeit“ ist oder darauf wartet, dass der Kunde den Bericht überprüft.", + "userprofile": "Ändern Sie Ihre Einstellungen.\nEgal, ob Sie nur die Sprache der Anwendung auswählen oder Ihr Passwort ändern.", + "category&objective_overview": "Sehen Sie sich hier jedes Ziel jeder Kategorie an.\nDerselbe Inhalt ist auch im OWASP Web Testing Guide enthalten.\nSie können sich einen guten Überblick über alle Ziele verschaffen, die in einer bestimmten Kategorie enthalten sind, sehen, wie viele Ergebnisse und Kommentare hinzugefügt wurden, und sogar bestimmte Ziele deaktivieren, was zur Folge hat, dass sie nicht in den Bericht aufgenommen werden.", + "objective_info": "Lesen Sie die wichtigsten Informationen zum gewählten Ziel.\nZu diesen Informationen gehört, was am Ziel zu tun ist, welche Probleme am häufigsten auftreten und wie Sie sie ausnutzen können.", + "objective_finding_overview": "Sehen Sie sich alle Funde an, die sich auf das ausgewählte Ziel beziehen.\nSie können den Titel, den Schweregrad, einen Teil der Beschreibung und die Auswirkung des Befundes sehen.\nDarüber hinaus können Sie einen bestimmten Befund auch bearbeiten oder sogar löschen.", + "create_edit_finding": "Bearbeiten oder erstellen Sie neue Funde für das Ziel.\nDokumentieren Sie hier den Titel, die Beschreibung, die betroffenen Anwendungsteile, die betroffenen URLs oder APIs und eine Schweregradbewertung zusammen mit Reproduktionsschritten und einem Abhilfevorschlag.\nSie können Befunde erst erstellen, wenn Sie den Timer gestartet haben, damit Ihre Arbeit nachverfolgt wird.", + "objective_comment_overview": "Sehen Sie sich alle Kommentare an, die sich auf das ausgewählte Ziel beziehen.\nSie können den Titel und einen Teil der Beschreibung des Kommentars sehen.\nDarüber hinaus können Sie einen bestimmten Kommentar auch bearbeiten oder sogar löschen.", + "create_edit_comment": "Bearbeiten oder erstellen Sie neue Kommentare für das Ziel.\nDokumentieren Sie hier den Titel und eine Beschreibung.\nSie können Kommentare erst erstellen, wenn Sie den Timer gestartet haben, damit Ihre Arbeit nachverfolgt wird.", + "generate_report": "Generieren und exportieren Sie Ihren Bericht. Sie können den Namen und die Version Ihres Projekts sowie einige Statistiken darüber sehen, wie viele Ihrer Ziele abgeschlossen, in Bearbeitung, pausiert, nicht gestartet oder deaktiviert sind.\nNur Ihre abgeschlossenen Ziele werden in den Abschlussbericht aufgenommen.\nStellen Sie vor dem Exportieren sicher, dass Sie die richtige Sprache für Ihren Bericht auswählen.", + "report": "Laden Sie Ihren generierten Bericht als PDF herunter und senden Sie ihn direkt an den Kunden.\nDer Bericht enthält alle Informationen, die Sie in der C4PO-Anwendung eingegeben haben.\nDer Bericht besteht aus einem Deckblatt, einem Inhaltsverzeichnis, dem Stand der Vertraulichkeit, einer Zusammenfassung, technischen Details zu den Ergebnissen sowie Kommentaren und Anhängen." + } + }, "state": { "new": "Neu", "needs_more_info": "Benötigt mehr Informationen", @@ -203,7 +221,7 @@ "title.label": "Fundtitel", "description.label": "Beschreibung des Funds", "impact.label": "Auswirkung auf Anwendung", - "affectedUrls.label": "Betroffene URL's", + "affectedUrls.label": "Betroffene URL's / API's", "reproduction.label": "Reproduktionsschritte", "mitigation.label": "Minderungsvorschlag", "no.findings": "Keine Funde verfügbar", diff --git a/security-c4po-angular/src/assets/i18n/en-US.json b/security-c4po-angular/src/assets/i18n/en-US.json index e818f97..4441554 100644 --- a/security-c4po-angular/src/assets/i18n/en-US.json +++ b/security-c4po-angular/src/assets/i18n/en-US.json @@ -20,6 +20,7 @@ "action.complete": "Complete", "action.disable": "Deactivate", "action.enable": "Activate", + "action.close": "Close", "action.yes": "Yes", "action.no": "No", "username": "Username", @@ -87,6 +88,23 @@ } } }, + "tutorial": { + "header": "Getting started with C4PO", + "carousel": { + "project_overview": "The Project Overview gives you a rundown of all your current projects. \nYou can create new ones, edit or delete existing ones or filter for an specific project here. \nLook up the current state of your projects as well as the progress together with some additional information like name, client, tester and when it was created.", + "project_overview_filtered": "Filtering through the Project Overview can help you to find the project(s) you are looking for. \nEnter specific keywords like the title of a project, a special state like 'Needs More Info or look for an important client.", + "create_edit_project": "Create a new project or an existing one and give it a title, client name, assign a tester and write a summary for the pentest (only available in edit mode). \nIn addition to that you can also select a specific state for the project to show if the pentest is currently 'work in progress' or waits for the customer to review the report.", + "userprofile": "Change your settings. \nWeather it's just selecting the language of the application or changing your password.", + "category&objective_overview": "View every objective of every category here. \nThe same content is also included in the OWASP Web Testing Guide. \nYou can get a good overview of all the objectives that are included in a specific category, see how many findings and comments have been added and even deactivate specific ones that you will result in them not being included in the report.", + "objective_info": "Read the most important information in regards to the selected objective. \nThis information includes what has to be done in the objective and what are the most common issue as well as how you could exploit them.", + "objective_finding_overview": "See all the findings that relate to the selected objective. \nYou can see the title, severity, part of the description and impact of the finding. \nIn addition you can also edit or even delete a specific finding.", + "create_edit_finding": "Edit or create new findings for the objective. \nDocument the title, description, the impacted application parts, affected URL's or API's and a severity rating together with reproduction steps and a mitigation suggestion here. \nYou can only create findings once you have started the timer so that your work will be tracked.", + "objective_comment_overview": "See all the comments that relate to the selected objective. \nYou can see the title and part of the description of the comment. \nIn addition you can also edit or even delete a specific comment.", + "create_edit_comment": "Edit or create new comments for the objective. \nDocument the title and a description here. \nYou can only create comments once you have started the timer so that your work will be tracked.", + "generate_report": "Generate and export your report. You can see your project name and version as well as some statistics about how many of your objectives are completed, in progress, paused, not started or disabled. \nOnly your completed objectives will be included in the final report. \nBefore exporting make sure you select the correct language of you report.", + "report": "Download your generated report as an pdf and send it directly to the customer. \nThe report includes all the information you have entered in the C4PO application. \nThe report consists of a Cover, Table of Contents, State of Confidentiality, Executive Summary, Technical Details for Findings and Comments and Appendencies." + } + }, "state": { "new": "New", "needs_more_info": "Needs More Info", @@ -203,7 +221,7 @@ "title.label": "Finding Title", "description.label": "Description of Finding", "impact.label": "Impacted Applicationparts", - "affectedUrls.label": "Affected URL's", + "affectedUrls.label": "Affected URL's / API's", "reproduction.label": "Reproductionsteps", "mitigation.label": "Suggest Mitigation", "no.findings": "No findings available", diff --git a/security-c4po-angular/src/assets/images/icons/url-broken.svg b/security-c4po-angular/src/assets/images/icons/url-broken.svg new file mode 100644 index 0000000..61d18b6 --- /dev/null +++ b/security-c4po-angular/src/assets/images/icons/url-broken.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/security-c4po-angular/src/assets/images/tutorial/IMAGE_404.png b/security-c4po-angular/src/assets/images/tutorial/IMAGE_404.png new file mode 100644 index 0000000..27e7a18 Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/IMAGE_404.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/10_Objective_Comment_Overview.png b/security-c4po-angular/src/assets/images/tutorial/views/10_Objective_Comment_Overview.png new file mode 100644 index 0000000..aae6992 Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/10_Objective_Comment_Overview.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/11_Create_Edit_Comment.png b/security-c4po-angular/src/assets/images/tutorial/views/11_Create_Edit_Comment.png new file mode 100644 index 0000000..5149149 Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/11_Create_Edit_Comment.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/12_Generate_Report.png b/security-c4po-angular/src/assets/images/tutorial/views/12_Generate_Report.png new file mode 100644 index 0000000..d752069 Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/12_Generate_Report.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/13_Report.png b/security-c4po-angular/src/assets/images/tutorial/views/13_Report.png new file mode 100644 index 0000000..a619048 Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/13_Report.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/1_Project_Overview.png b/security-c4po-angular/src/assets/images/tutorial/views/1_Project_Overview.png new file mode 100644 index 0000000..d6efe95 Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/1_Project_Overview.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/2_Project_Overview_Filter.png b/security-c4po-angular/src/assets/images/tutorial/views/2_Project_Overview_Filter.png new file mode 100644 index 0000000..c665637 Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/2_Project_Overview_Filter.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/3_Create_Edit_Project.png b/security-c4po-angular/src/assets/images/tutorial/views/3_Create_Edit_Project.png new file mode 100644 index 0000000..e98c0ab Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/3_Create_Edit_Project.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/4_Create_Edit_Projectstates.png b/security-c4po-angular/src/assets/images/tutorial/views/4_Create_Edit_Projectstates.png new file mode 100644 index 0000000..8f36cef Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/4_Create_Edit_Projectstates.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/5_Userprofile.png b/security-c4po-angular/src/assets/images/tutorial/views/5_Userprofile.png new file mode 100644 index 0000000..41db7c2 Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/5_Userprofile.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/6_Category_&_Objective_Overview.png b/security-c4po-angular/src/assets/images/tutorial/views/6_Category_&_Objective_Overview.png new file mode 100644 index 0000000..91da0fc Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/6_Category_&_Objective_Overview.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/7_Objective_Info.png b/security-c4po-angular/src/assets/images/tutorial/views/7_Objective_Info.png new file mode 100644 index 0000000..124237c Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/7_Objective_Info.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/8_Objective_Finding_Overview.png b/security-c4po-angular/src/assets/images/tutorial/views/8_Objective_Finding_Overview.png new file mode 100644 index 0000000..9259965 Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/8_Objective_Finding_Overview.png differ diff --git a/security-c4po-angular/src/assets/images/tutorial/views/9_Create_Edit_Finding.png b/security-c4po-angular/src/assets/images/tutorial/views/9_Create_Edit_Finding.png new file mode 100644 index 0000000..ebbb5aa Binary files /dev/null and b/security-c4po-angular/src/assets/images/tutorial/views/9_Create_Edit_Finding.png differ diff --git a/security-c4po-angular/src/shared/modules/profile-settings/profile-settings.component.html b/security-c4po-angular/src/shared/modules/profile-settings/profile-settings.component.html index 4d4a254..e2ee25b 100644 --- a/security-c4po-angular/src/shared/modules/profile-settings/profile-settings.component.html +++ b/security-c4po-angular/src/shared/modules/profile-settings/profile-settings.component.html @@ -135,7 +135,7 @@ diff --git a/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-content.ts b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-content.ts new file mode 100644 index 0000000..5c250bb --- /dev/null +++ b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-content.ts @@ -0,0 +1,55 @@ +export class ImageSliderContent { + source: string; + translationText: string; +} + +export const CONTENT_IMAGES: ImageSliderContent[] = [ + { + source: '../../../assets/images/tutorial/views/1_Project_Overview.png', + translationText: 'tutorial.carousel.project_overview' + }, + { + source: '../../../assets/images/tutorial/views/2_Project_Overview_Filter.png', + translationText: 'tutorial.carousel.project_overview_filtered' + }, + { + source: '../../../assets/images/tutorial/views/4_Create_Edit_Projectstates.png', + translationText: 'tutorial.carousel.create_edit_project' + }, + { + source: '../../../assets/images/tutorial/views/5_Userprofile.png', + translationText: 'tutorial.carousel.userprofile' + }, + { + source: '../../../assets/images/tutorial/views/6_Category_&_Objective_Overview.png', + translationText: 'tutorial.carousel.category&objective_overview' + }, + { + source: '../../../assets/images/tutorial/views/7_Objective_Info.png', + translationText: 'tutorial.carousel.objective_info' + }, + { + source: '../../../assets/images/tutorial/views/8_Objective_Finding_Overview.png', + translationText: 'tutorial.carousel.objective_finding_overview' + }, + { + source: '../../../assets/images/tutorial/views/9_Create_Edit_Finding.png', + translationText: 'tutorial.carousel.create_edit_finding' + }, + { + source: '../../../assets/images/tutorial/views/10_Objective_Comment_Overview.png', + translationText: 'tutorial.carousel.objective_comment_overview' + }, + { + source: '../../../assets/images/tutorial/views/11_Create_Edit_Comment.png', + translationText: 'tutorial.carousel.create_edit_comment' + }, + { + source: '../../../assets/images/tutorial/views/12_Generate_Report.png', + translationText: 'tutorial.carousel.generate_report' + }, + { + source: '../../../assets/images/tutorial/views/13_Report.png', + translationText: 'tutorial.carousel.report' + }, +]; diff --git a/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.html b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.html new file mode 100644 index 0000000..4390faf --- /dev/null +++ b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.html @@ -0,0 +1,56 @@ + + + + + {{ 'tutorial.header' | translate }} + + +
+
+
+ + + +
+ +
+
+ +
+ +
+
+
+
+ {{image.translationText | translate}} +
+
+ tutorial-img +
+
+
+
+ +
+
+
+
+
+ + + +
diff --git a/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.scss b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.scss new file mode 100644 index 0000000..127a8a3 --- /dev/null +++ b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.scss @@ -0,0 +1,83 @@ +@import "../../../assets/@theme/styles/_dialog.scss"; +@import '../../../assets/@theme/styles/themes'; + +$control-button-margin: 1.5rem; +$control-button-size: 3.5rem; + +.profile-setting-dialog { + width: 65.25rem !important; + height: 58rem; + + .dialog-header { + height: 8vh; + + .header-text { + font-size: 1.5rem; + padding-left: 1rem; + } + } + + .dialog-body { + //overflow: hidden!important; + + .info-slideshow { + max-width: 100%; + max-height: 100%; + + .image-text { + font-size: 1.2rem; + padding-top: 1.25rem; + // padding-bottom: 2.25rem; + max-width: 80%; + text-align: center; + // Allows \n in translation file for line breaks + white-space: pre-line; + } + + .image { + img { + max-width: 100%; + } + } + + .default-image { + background-image: url("../../../assets/images/tutorial/IMAGE_404.png"); + background-position: center; + background-repeat: no-repeat; + background-size: cover; + + /*min-width: 100%; + min-height: 100vh;*/ + + position: inherit; + top: 0; + bottom: 0; + right: 0; + left: 0; + } + + .left-arrow, + .right-arrow { + display: block; + top: calc(55% - (#{$control-button-size} / 2)); + position: absolute; + font-size: 2rem; + color: nb-theme(color-basic-transparent-focus); + cursor: pointer; + z-index: 1000; + + &:hover { + color: nb-theme(color-info-default); + } + } + + .left-arrow { + left: $control-button-margin; + } + + .right-arrow { + right: $control-button-margin; + } + } + } +} diff --git a/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.spec.ts b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.spec.ts new file mode 100644 index 0000000..8b5ccd5 --- /dev/null +++ b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.spec.ts @@ -0,0 +1,61 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TutorialDialogComponent } from './tutorial-dialog.component'; +import {NgxGlideModule} from 'ngx-glide'; +import {DialogService} from '@shared/services/dialog-service/dialog.service'; +import {DialogServiceMock} from '@shared/services/dialog-service/dialog.service.mock'; +import {NbDialogRef, NbFormFieldModule} from '@nebular/theme'; +import {createSpyObj} from '@shared/modules/project-dialog/project-dialog.component.spec'; +import {ReactiveFormsModule} from '@angular/forms'; +import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; +import {ThemeModule} from '@assets/@theme/theme.module'; +import {TranslateLoader, TranslateModule} from '@ngx-translate/core'; +import {HttpLoaderFactory} from '../../../app/common-app.module'; +import {HttpClient, HttpClientModule} from '@angular/common/http'; +import {HttpClientTestingModule} from '@angular/common/http/testing'; + +describe('TutorialDialogComponent', () => { + let component: TutorialDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + const dialogSpy = createSpyObj('NbDialogRef', ['close']); + + await TestBed.configureTestingModule({ + declarations: [ + TutorialDialogComponent + ], + imports: [ + NgxGlideModule, + NbFormFieldModule, + ReactiveFormsModule, + BrowserAnimationsModule, + ThemeModule.forRoot(), + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: HttpLoaderFactory, + deps: [HttpClient] + } + }), + HttpClientModule, + HttpClientTestingModule + ], + providers: [ + {provide: DialogService, useClass: DialogServiceMock}, + {provide: NbDialogRef, useValue: dialogSpy} + ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(TutorialDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.ts b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.ts new file mode 100644 index 0000000..a0dc704 --- /dev/null +++ b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.component.ts @@ -0,0 +1,27 @@ +import {Component, OnInit} from '@angular/core'; +import {NbDialogRef} from '@nebular/theme'; +import * as FA from '@fortawesome/free-solid-svg-icons'; +import {CONTENT_IMAGES, ImageSliderContent} from '@shared/modules/tutorial-dialog/tutorial-content'; + +@Component({ + selector: 'app-tutorial-dialog', + templateUrl: './tutorial-dialog.component.html', + styleUrls: ['./tutorial-dialog.component.scss'] +}) +export class TutorialDialogComponent implements OnInit { + // HTML only + readonly fa = FA; + readonly FALLBACK_IMAGE = '../../../assets/images/tutorial/IMAGE_404.png'; + + images: Array = CONTENT_IMAGES; + + constructor(protected dialogRef: NbDialogRef) { } + + ngOnInit(): void { + } + + onClickCancel(): void { + this.dialogRef.close(); + } + +} diff --git a/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.module.ts b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.module.ts new file mode 100644 index 0000000..5e98bb6 --- /dev/null +++ b/security-c4po-angular/src/shared/modules/tutorial-dialog/tutorial-dialog.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import {TutorialDialogComponent} from '@shared/modules/tutorial-dialog/tutorial-dialog.component'; +import {NbButtonModule, NbCardModule} from '@nebular/theme'; +import {FontAwesomeModule} from '@fortawesome/angular-fontawesome'; +import {TranslateModule} from '@ngx-translate/core'; +import {FlexModule} from '@angular/flex-layout'; +import {NgxGlideModule} from 'ngx-glide'; + +@NgModule({ + declarations: [ + TutorialDialogComponent + ], + imports: [ + CommonModule, + NbCardModule, + FontAwesomeModule, + TranslateModule, + NbButtonModule, + FlexModule, + NgxGlideModule + ], + exports: [ + TutorialDialogComponent + ] +}) +export class TutorialDialogModule { } diff --git a/security-c4po-angular/src/shared/pipes/date-time-format.pipe.spec.ts b/security-c4po-angular/src/shared/pipes/date-time-format.pipe.spec.ts index 6c5b875..03869d0 100644 --- a/security-c4po-angular/src/shared/pipes/date-time-format.pipe.spec.ts +++ b/security-c4po-angular/src/shared/pipes/date-time-format.pipe.spec.ts @@ -7,7 +7,7 @@ import {UserService} from '@shared/services/user-service/user.service'; import {inject, TestBed} from '@angular/core/testing'; import {HttpClient} from '@angular/common/http'; import {HttpLoaderFactory} from '../../app/common-app.module'; -import {TranslateLoader, TranslateModule} from '@ngx-translate/core'; +import {TranslateLoader, TranslateModule, TranslateService} from '@ngx-translate/core'; import {HttpClientTestingModule} from '@angular/common/http/testing'; import {KeycloakService} from 'keycloak-angular'; @@ -21,7 +21,6 @@ const DESIRED_STORE_STATE_SESSION: SessionStateModel = { describe('DateTimeFormatPipe', () => { let pipe: DateTimeFormatPipe; - let store: Store; // tslint:disable-next-line:prefer-const let dateAndNumberFormat: NumberAndDateFormatSystem; @@ -43,18 +42,14 @@ describe('DateTimeFormatPipe', () => { ], providers: [ {provide: UserService}, - {provide: KeycloakService} + {provide: KeycloakService}, + {provide: TranslateService} ] }).compileComponents(); }); - beforeEach(inject([Store], (inStore: Store) => { - store = inStore; - store.reset({ - ...store.snapshot(), - [SESSION_STATE_NAME]: DESIRED_STORE_STATE_SESSION - }); - pipe = new DateTimeFormatPipe(inStore); + beforeEach(inject([Store], (translateService: TranslateService) => { + pipe = new DateTimeFormatPipe(translateService); }) ); diff --git a/security-c4po-angular/src/shared/pipes/date-time-format.pipe.ts b/security-c4po-angular/src/shared/pipes/date-time-format.pipe.ts index 405496e..446b994 100644 --- a/security-c4po-angular/src/shared/pipes/date-time-format.pipe.ts +++ b/security-c4po-angular/src/shared/pipes/date-time-format.pipe.ts @@ -1,6 +1,5 @@ import {Pipe, PipeTransform} from '@angular/core'; import {formatDate} from '@angular/common'; -import {Store} from '@ngxs/store'; import {CustomPipe} from '@shared/models/custom-pipe.mode'; import {TranslateService} from '@ngx-translate/core'; @@ -10,7 +9,7 @@ import {TranslateService} from '@ngx-translate/core'; }) export class DateTimeFormatPipe implements PipeTransform { - constructor(private store: Store, private translateService: TranslateService) { + constructor(private translateService: TranslateService) { } /** diff --git a/security-c4po-reporting/security-c4po-reporting.postman_collection.json b/security-c4po-reporting/security-c4po-reporting.postman_collection.json index 63cf8d2..7c17f18 100644 --- a/security-c4po-reporting/security-c4po-reporting.postman_collection.json +++ b/security-c4po-reporting/security-c4po-reporting.postman_collection.json @@ -124,7 +124,7 @@ } ], "url": { - "raw": "http://localhost:8444/reports/575dd9d4-cb3c-4df3-981e-8a18bf8dc1d2/pdf", + "raw": "http://localhost:8444/reports/575dd9d4-cb3c-4df3-981e-8a18bf8dc1d2/pdf/en-US", "protocol": "http", "host": [ "localhost" @@ -133,61 +133,8 @@ "path": [ "reports", "575dd9d4-cb3c-4df3-981e-8a18bf8dc1d2", - "pdf" - ] - } - }, - "response": [] - }, - { - "name": "getReportCSVforProjectById", - "request": { - "method": "GET", - "header": [ - { - "key": "Content-Type", - "value": "text/html", - "type": "text" - } - ], - "url": { - "raw": "http://localhost:8444/reports/195809ed-9722-4ad5-a84b-0099a9a01652/csv", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8444", - "path": [ - "reports", - "195809ed-9722-4ad5-a84b-0099a9a01652", - "csv" - ] - } - }, - "response": [] - }, - { - "name": "getReportHTMLforProjectById", - "request": { - "method": "GET", - "header": [ - { - "key": "Content-Type", - "value": "text/csv", - "type": "text" - } - ], - "url": { - "raw": "http://localhost:8444/reports/195809ed-9722-4ad5-a84b-0099a9a01652/html", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8444", - "path": [ - "reports", - "195809ed-9722-4ad5-a84b-0099a9a01652", - "html" + "pdf", + "en-US" ] } },