Skip to content

Commit 29ae1e5

Browse files
committed
Improve UX of project creation modal
* Replaces the separate "General" and "Identity" tabs with a non-tabbed view. "Identity" is now a collapsible section that is explicitly marked as optional. * Makes the modal a proper form, such that it supports confirmation by pressing enter etc. * Adds proper input validation to prevent invalid configurations from being submitted, e.g. missing classifier, collection project enabled but no collection logic selected, etc. * Prevents the modal from closing when project creation fails. Lets users refine their inputs and retry. * Waits for the creation request to complete before closing the modal. * Redirects directly to the created project instead of back to the project list. Signed-off-by: nscuro <nscuro@protonmail.com>
1 parent 1cce817 commit 29ae1e5

17 files changed

Lines changed: 442 additions & 300 deletions

File tree

src/App.vue

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,25 @@ export default {
7373
}
7474
7575
this.axios.interceptors.response.use(null, (error) => {
76+
if (!error.response) {
77+
this.$toastr.e(
78+
this.$t('condition.unsuccessful_action'),
79+
this.$t('condition.http_request_error'),
80+
);
81+
return Promise.reject(error);
82+
}
83+
const contentType =
84+
(error.response.headers && error.response.headers['content-type']) ||
85+
'';
7686
// On error status codes (4xx - 5xx), display a toast with either:
7787
// * The problem title and detail in case of an RFC 9457 response
7888
// * the HTTP status code and text
7989
if (error.response.status >= 400 && error.response.status < 500) {
80-
if (
81-
error.response.headers['content-type'] === 'application/problem+json'
82-
) {
90+
if (contentType.includes('application/problem+json')) {
8391
this.$toastr.w(error.response.data.detail, error.response.data.title);
8492
} else if (
8593
error.response.status === 400 &&
86-
error.response.headers['content-type'] === 'application/json' &&
94+
contentType.includes('application/json') &&
8795
error.response.data &&
8896
Array.isArray(error.response.data) &&
8997
error.response.data[0].hasOwnProperty('invalidValue')
@@ -102,9 +110,7 @@ export default {
102110
);
103111
}
104112
} else {
105-
if (
106-
error.response.headers['content-type'] === 'application/problem+json'
107-
) {
113+
if (contentType.includes('application/problem+json')) {
108114
this.$toastr.w(error.response.data.detail, error.response.data.title);
109115
} else {
110116
this.$toastr.e(

src/i18n/locales/de.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@
583583
"identifier": "Kennung",
584584
"identifier_type": "Kennungstyp",
585585
"identity": "Identität",
586+
"identity_fields_set": null,
586587
"in_triage": "In Triage",
587588
"inactive": "Inaktiv",
588589
"inactive_active_children": "Das Projekt kann nicht auf inaktiv gesetzt werden, wenn es aktive untergeordnete Projekte hat",
@@ -601,6 +602,7 @@
601602
"internal": "Intern",
602603
"inventory": "Inventar",
603604
"inventory_with_vulnerabilities": "Inventarisierung mit Schwachstellen",
605+
"is_latest_tooltip": null,
604606
"item": "Element",
605607
"justification": "Begründung",
606608
"justification_tooltip": "Die Begründung, warum der Auswirkungsanalysestatus „Nicht betroffen“ lautete",
@@ -667,6 +669,7 @@
667669
"only_outdated_tooltip": "Nur Abhängigkeiten anzeigen, für die neuere stabile Versionen verfügbar sind",
668670
"operational_risk": "Betriebsrisiko",
669671
"operator": "Operator",
672+
"optional": null,
670673
"osi_approved": "OSI-Zulassung",
671674
"outdated_only": "Nur veraltet",
672675
"overview": "Überblick",
@@ -909,6 +912,8 @@
909912
"rejected": "Abgelehnt",
910913
"remove_component": "Komponente entfernen",
911914
"reported_by": "Berichtet von",
915+
"required_classifier": null,
916+
"required_collection_logic": null,
912917
"required_component_identifier": "Eine Komponentenkennung ist erforderlich",
913918
"required_component_name": "Der Komponentenname ist erforderlich",
914919
"required_component_version": "Die Komponentenversion ist erforderlich",

src/i18n/locales/en.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@
583583
"identifier": "Identifier",
584584
"identifier_type": "Identifier Type",
585585
"identity": "Identity",
586+
"identity_fields_set": "{count} field(s) set",
586587
"in_triage": "In Triage",
587588
"inactive": "Inactive",
588589
"inactive_active_children": "The project cannot be set to inactive if it has active children",
@@ -601,6 +602,7 @@
601602
"internal": "Internal",
602603
"inventory": "Inventory",
603604
"inventory_with_vulnerabilities": "Inventory with Vulnerabilities",
605+
"is_latest_tooltip": "Marks this version as the latest release of the project",
604606
"item": "Item",
605607
"justification": "Justification",
606608
"justification_tooltip": "The rationale of why the impact analysis state was asserted to be \"Not Affected\"",
@@ -667,6 +669,7 @@
667669
"only_outdated_tooltip": "Only show dependencies that have newer stable versions available",
668670
"operational_risk": "Operational Risk",
669671
"operator": "Operator",
672+
"optional": "optional",
670673
"osi_approved": "OSI Approved",
671674
"outdated_only": "Outdated only",
672675
"overview": "Overview",
@@ -909,6 +912,8 @@
909912
"rejected": "Rejected",
910913
"remove_component": "Remove Component",
911914
"reported_by": "Reported By",
915+
"required_classifier": "A classifier is required",
916+
"required_collection_logic": "A collection logic is required",
912917
"required_component_identifier": "A component identifier is required",
913918
"required_component_name": "The component name is required",
914919
"required_component_version": "The component version is required",

src/i18n/locales/es.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@
583583
"identifier": "Identificador",
584584
"identifier_type": "Tipo de identificador",
585585
"identity": "Identidad",
586+
"identity_fields_set": null,
586587
"in_triage": "En triaje",
587588
"inactive": "Inactivo",
588589
"inactive_active_children": "El proyecto no se puede configurar como inactivo si tiene hijos activos",
@@ -601,6 +602,7 @@
601602
"internal": "Interno",
602603
"inventory": "Inventario",
603604
"inventory_with_vulnerabilities": "Inventario con vulnerabilidades",
605+
"is_latest_tooltip": null,
604606
"item": "Elemento",
605607
"justification": "Justificación",
606608
"justification_tooltip": "El motivo por el que se afirmó que el estado del análisis de impacto era \"No afectado\"",
@@ -667,6 +669,7 @@
667669
"only_outdated_tooltip": "Mostrar solo las dependencias que tengan versiones estables más nuevas disponibles",
668670
"operational_risk": "Riesgo operacional",
669671
"operator": "Operador",
672+
"optional": null,
670673
"osi_approved": "Aprobado por OSI",
671674
"outdated_only": "Sólo anticuado",
672675
"overview": "Descripción general",
@@ -909,6 +912,8 @@
909912
"rejected": "Rechazado",
910913
"remove_component": "Quitar componente",
911914
"reported_by": "Reportado por",
915+
"required_classifier": null,
916+
"required_collection_logic": null,
912917
"required_component_identifier": "Se requiere un identificador de componente",
913918
"required_component_name": "El nombre del componente es obligatorio.",
914919
"required_component_version": "La versión del componente es obligatoria.",

src/i18n/locales/fr.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@
583583
"identifier": "Identifiant",
584584
"identifier_type": "Type d'identifiant",
585585
"identity": "Identité",
586+
"identity_fields_set": null,
586587
"in_triage": "Au tri",
587588
"inactive": "Inactif",
588589
"inactive_active_children": "Le projet ne peut pas être défini comme inactif s'il a des enfants actifs",
@@ -601,6 +602,7 @@
601602
"internal": "Interne",
602603
"inventory": "Inventaire",
603604
"inventory_with_vulnerabilities": "Inventaire avec vulnérabilités",
605+
"is_latest_tooltip": null,
604606
"item": "Élément",
605607
"justification": "Justification",
606608
"justification_tooltip": "La raison pour laquelle l'état de l'analyse d'impact a été déclaré « Non affecté »",
@@ -667,6 +669,7 @@
667669
"only_outdated_tooltip": "Afficher uniquement les dépendances pour lesquelles des versions stables plus récentes sont disponibles",
668670
"operational_risk": "Risque opérationnel",
669671
"operator": "Opérateur",
672+
"optional": null,
670673
"osi_approved": "Approuvée par l'OSI",
671674
"outdated_only": "Obsolète seulement",
672675
"overview": "Aperçu",
@@ -909,6 +912,8 @@
909912
"rejected": "Rejetée",
910913
"remove_component": "Supprimer un composant",
911914
"reported_by": "Rapporté par",
915+
"required_classifier": null,
916+
"required_collection_logic": null,
912917
"required_component_identifier": "Un identifiant de composant est requis",
913918
"required_component_name": "Le nom du composant est obligatoire",
914919
"required_component_version": "La version du composant est requise",

src/i18n/locales/hi.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@
583583
"identifier": "पहचानकर्ता",
584584
"identifier_type": "पहचानकर्ता प्रकार",
585585
"identity": "पहचान",
586+
"identity_fields_set": null,
586587
"in_triage": "ट्राइएज में",
587588
"inactive": "निष्क्रिय",
588589
"inactive_active_children": "यदि प्रोजेक्ट में सक्रिय बच्चे हैं तो उसे निष्क्रिय नहीं किया जा सकता",
@@ -601,6 +602,7 @@
601602
"internal": "आंतरिक",
602603
"inventory": "भंडार",
603604
"inventory_with_vulnerabilities": "कमज़ोरियों वाली सूची",
605+
"is_latest_tooltip": null,
604606
"item": "वस्तु",
605607
"justification": "औचित्य",
606608
"justification_tooltip": "प्रभाव विश्लेषण स्थिति को \"प्रभावित नहीं\" क्यों कहा गया, इसका औचित्य",
@@ -667,6 +669,7 @@
667669
"only_outdated_tooltip": "केवल उन निर्भरताओं को दिखाएं जिनके नए स्थिर संस्करण उपलब्ध हैं",
668670
"operational_risk": "परिचालनात्मक जोखिम",
669671
"operator": "ऑपरेटर",
672+
"optional": null,
670673
"osi_approved": "ओएसआई स्वीकृत",
671674
"outdated_only": "केवल पुराना",
672675
"overview": "अवलोकन",
@@ -909,6 +912,8 @@
909912
"rejected": "अस्वीकार कर दिया",
910913
"remove_component": "घटक हटाएँ",
911914
"reported_by": "के द्वारा रिपोर्ट किया गया",
915+
"required_classifier": null,
916+
"required_collection_logic": null,
912917
"required_component_identifier": "घटक पहचानकर्ता आवश्यक है",
913918
"required_component_name": "घटक का नाम आवश्यक है",
914919
"required_component_version": "घटक संस्करण आवश्यक है",

src/i18n/locales/it.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@
583583
"identifier": "Identificatore",
584584
"identifier_type": "Tipo di identificatore",
585585
"identity": "Identità",
586+
"identity_fields_set": null,
586587
"in_triage": "Nel triage",
587588
"inactive": "Inattivo",
588589
"inactive_active_children": "Il progetto non può essere impostato su inattivo se ha figli attivi",
@@ -601,6 +602,7 @@
601602
"internal": "Interno",
602603
"inventory": "Inventario",
603604
"inventory_with_vulnerabilities": "Inventario con vulnerabilità",
605+
"is_latest_tooltip": null,
604606
"item": "Elemento",
605607
"justification": "Giustificazione",
606608
"justification_tooltip": "La motivazione per cui lo stato dell'analisi d'impatto è stato dichiarato \"Non interessato\"",
@@ -667,6 +669,7 @@
667669
"only_outdated_tooltip": "Mostra solo le dipendenze per cui sono disponibili versioni stabili più recenti",
668670
"operational_risk": "Rischio operativo",
669671
"operator": "Operatore",
672+
"optional": null,
670673
"osi_approved": "Approvato dall'OSI",
671674
"outdated_only": "Solo obsoleto",
672675
"overview": "Panoramica",
@@ -909,6 +912,8 @@
909912
"rejected": "Respinto",
910913
"remove_component": "Rimuovi componente",
911914
"reported_by": "Segnalato da",
915+
"required_classifier": null,
916+
"required_collection_logic": null,
912917
"required_component_identifier": "È obbligatorio un identificatore del componente",
913918
"required_component_name": "Il nome del componente è obbligatorio",
914919
"required_component_version": "La versione del componente è obbligatoria",

src/i18n/locales/ja.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@
583583
"identifier": "識別子",
584584
"identifier_type": "識別子の種類",
585585
"identity": "身元",
586+
"identity_fields_set": null,
586587
"in_triage": "トリアージ中",
587588
"inactive": "非活性",
588589
"inactive_active_children": "アクティブな子プロジェクトがある場合、プロジェクトを非アクティブに設定することはできません。",
@@ -601,6 +602,7 @@
601602
"internal": "内部",
602603
"inventory": "インベントリ",
603604
"inventory_with_vulnerabilities": "脆弱性のあるインベントリ",
605+
"is_latest_tooltip": null,
604606
"item": "アイテム",
605607
"justification": "正当化",
606608
"justification_tooltip": "影響分析の状態が「影響を受けない」と主張された理由",
@@ -667,6 +669,7 @@
667669
"only_outdated_tooltip": "新しい安定バージョンが利用可能な依存関係のみを表示する",
668670
"operational_risk": "運用リスク",
669671
"operator": "オペレーター",
672+
"optional": null,
670673
"osi_approved": "OSI承認",
671674
"outdated_only": "古いもののみ",
672675
"overview": "概要",
@@ -909,6 +912,8 @@
909912
"rejected": "拒否",
910913
"remove_component": "コンポーネントを削除",
911914
"reported_by": "報告者",
915+
"required_classifier": null,
916+
"required_collection_logic": null,
912917
"required_component_identifier": "コンポーネント識別子が必要です",
913918
"required_component_name": "コンポーネント名は必須です",
914919
"required_component_version": "コンポーネントのバージョンが必要です",

src/i18n/locales/pl.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@
583583
"identifier": "Identyfikator",
584584
"identifier_type": "Typ identyfikatora",
585585
"identity": "Tożsamość",
586+
"identity_fields_set": null,
586587
"in_triage": "W segregacji",
587588
"inactive": "Nieaktywny",
588589
"inactive_active_children": "Projektu nie można ustawić jako nieaktywnego, jeśli ma aktywne elementy podrzędne",
@@ -601,6 +602,7 @@
601602
"internal": "Wewnętrzny",
602603
"inventory": "Spis",
603604
"inventory_with_vulnerabilities": "Inwentarz z lukami w zabezpieczeniach",
605+
"is_latest_tooltip": null,
604606
"item": "Pozycja",
605607
"justification": "Uzasadnienie",
606608
"justification_tooltip": "Uzasadnienie, dla którego stwierdzono, że stan analizy wpływu to „Nie ma wpływu”",
@@ -667,6 +669,7 @@
667669
"only_outdated_tooltip": "Pokazuj tylko zależności, dla których dostępne są nowsze stabilne wersje",
668670
"operational_risk": "Ryzyko operacyjne",
669671
"operator": "Operator",
672+
"optional": null,
670673
"osi_approved": "Zatwierdzone przez OSI",
671674
"outdated_only": "Tylko nieaktualne",
672675
"overview": "Przegląd",
@@ -909,6 +912,8 @@
909912
"rejected": "Odrzucony",
910913
"remove_component": "Usuń komponent",
911914
"reported_by": "Zgłoszone przez",
915+
"required_classifier": null,
916+
"required_collection_logic": null,
912917
"required_component_identifier": "Wymagany jest identyfikator komponentu",
913918
"required_component_name": "Nazwa komponentu jest wymagana",
914919
"required_component_version": "Wymagana jest wersja komponentu",

src/i18n/locales/pt-BR.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@
583583
"identifier": "Identificador",
584584
"identifier_type": "Tipo de identificador",
585585
"identity": "Identidade",
586+
"identity_fields_set": null,
586587
"in_triage": "Em triagem",
587588
"inactive": "Inativo",
588589
"inactive_active_children": "O projeto não pode ser definido como inativo se tiver filhos ativos",
@@ -601,6 +602,7 @@
601602
"internal": "interno",
602603
"inventory": "Inventário",
603604
"inventory_with_vulnerabilities": "Inventário com vulnerabilidades",
605+
"is_latest_tooltip": null,
604606
"item": "Item",
605607
"justification": "Justificação",
606608
"justification_tooltip": "A justificativa pela qual o estado da análise de impacto foi declarado como \"Não afetado\"",
@@ -667,6 +669,7 @@
667669
"only_outdated_tooltip": "Mostrar apenas dependências que tenham versões estáveis mais recentes disponíveis",
668670
"operational_risk": "Risco operacional",
669671
"operator": "Operador",
672+
"optional": null,
670673
"osi_approved": "Aprovado pelo OSI",
671674
"outdated_only": "Apenas desatualizado",
672675
"overview": "Visão geral",
@@ -909,6 +912,8 @@
909912
"rejected": "Rejeitado",
910913
"remove_component": "Remover componente",
911914
"reported_by": "Reportado por",
915+
"required_classifier": null,
916+
"required_collection_logic": null,
912917
"required_component_identifier": "Um identificador de componente é obrigatório",
913918
"required_component_name": "O nome do componente é obrigatório",
914919
"required_component_version": "A versão do componente é obrigatória",

0 commit comments

Comments
 (0)