diff --git a/backend/core/helpers.py b/backend/core/helpers.py index 6a8b6988a..a01f0521e 100644 --- a/backend/core/helpers.py +++ b/backend/core/helpers.py @@ -803,6 +803,7 @@ def compile_risk_assessment_for_composer(user, risk_assessment_list: list): v = {"value": count, "itemStyle": {"color": STATUS_COLOR_MAP[st[0]]}} values.append(v) labels.append(st[1]) + local_lables = [camel_case(str(l)) for l in labels] risk_assessment_objects = list() @@ -843,6 +844,6 @@ def compile_risk_assessment_for_composer(user, risk_assessment_list: list): "untreated_h_vh": untreated_h_vh, "accepted": accepted, }, - "security_measure_status": {"labels": labels, "values": values}, + "security_measure_status": {"localLables":local_lables, "labels": labels, "values": values}, "colors": get_risk_color_ordered_list(user, risk_assessment_list), } diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 4682636e1..e5ec8a27e 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -35,7 +35,7 @@ "governance": "Governance", "risk": "Risk", "compliance": "Compliance", - "organization": "Organisation", + "organization": "Organization", "extra": "Extra", "analytics": "Analytics", "calendar": "Calendar", @@ -224,6 +224,7 @@ "infosFound": "info{s} found", "remediationPlan": "Remediation plan", "treatmentPlan": "Treatment plan", + "plan": "Plan", "asPDF": "as PDF", "asCSV": "as CSV", "draft": "Draft", @@ -338,5 +339,31 @@ "dependencies": "Dependencies", "copyright": "Copyright", "uploadYourLibrary": "Upload your own library", - "libraryFileInYaml": "Library file in YAML format" + "libraryFileInYaml": "Library file in YAML format", + "scope": "Scope", + "auditor": "Auditor", + "lastUpdate": "Last update", + "riskScenarioAssetHelpText": "Assets impacted by this risk scenario", + "riskScenarioMeasureHelpText": "The existing security measures to manage this risk", + "currentAssessment": "Current assessment", + "targetAssessment": "Target assessment", + "currentRiskLevel": "Current risk level", + "residualRiskLevel": "Residual risk level", + "currentRiskLevelHelpText": "The risk level given the current measures", + "residualRiskLevelHelpText": "The risk level when all the extra measures are done", + "yourSelection": "Your selection", + "composerHint": "Hint: you can bookmark this page for future usage", + "composerTitle": "Here is the overview for the selected risk assessment", + "composerTitlePlural": "Here is the overview for the {number} selected risk assessments", + "statusOfAssociatedMeasures": "Status of associated measures", + "forTheSelectedScope": "For the selected scope, you have", + "untreatedRiskScenarios": "{count} untreated risk scenario{s}", + "acceptedRiskScenarios": "{count} accepted risk scenario{s}", + "reviewNeeded": "Review needed", + "ok": "Ok", + "inconsistenciesFoundComposer": "Found {count} inconsistenc{plural}. For more details, check", + "current": "Current", + "residual": "Residual", + "jumpToRiskAssessment": "Jump to risk assessment", + "additionalMeasures": "Additional measures" } diff --git a/frontend/messages/fr.json b/frontend/messages/fr.json index cc88900ff..90bfcf18b 100644 --- a/frontend/messages/fr.json +++ b/frontend/messages/fr.json @@ -151,7 +151,7 @@ "statistics": "Statistiques", "myProjects": "Mes projets", "scenarios": "Scénarios", - "assignedProjects": "Assigné à {number} project{s}", + "assignedProjects": "Assigné à {number} projet{s}", "currentRiskLevelPerScenario": "Niveau de risque courant par scénario de risque", "residualRiskLevelPerScenario": "Niveau de risque résiduel par scénario de risque", "securityMeasuresStatus": "Statut des mesures de sécurité", @@ -224,6 +224,7 @@ "infosFound": "info{s} trouvée{s}", "remediationPlan": "Plan de remédiation", "treatmentPlan": "Plan de traitement", + "plan": "Plan", "asPDF": "en PDF", "asCSV": "en CSV", "draft": "Brouillon", @@ -338,5 +339,31 @@ "dependencies": "Dépendances", "copyright": "Droits d'auteur", "uploadYourLibrary": "Téléchargez votre propre bibliothèque", - "libraryFileInYaml": "Fichier de librairie en format YAML" + "libraryFileInYaml": "Fichier de librairie en format YAML", + "scope": "Périmètre", + "auditor": "Auditeur", + "lastUpdate": "Dernière mise à jour", + "riskScenarioAssetHelpText": "Biens sensibles impactés par ce scénario de risque", + "riskScenarioMeasureHelpText": "Les mesures de sécurité existantes pour gérer ce risque", + "currentAssessment": "Évaluation actuelle", + "targetAssessment": "Évaluation cible", + "currentRiskLevel": "Niveau de risque courrant", + "residualRiskLevel": "Niveau de risque résiduel", + "currentRiskLevelHelpText": "Le niveau de risque compte tenu des mesures actuelles", + "residualRiskLevelHelpText": "Le niveau de risque lorsque toutes les mesures supplémentaires sont prises", + "yourSelection": "Votre sélection", + "composerHint": "Astuce : vous pouvez ajouter cette page à vos favoris pour une utilisation future", + "composerTitle": "Voici l’aperçu de l’évaluation de risque sélectionnée", + "composerTitlePlural": "Voici l'aperçu des {number} évaluations de risques sélectionnées", + "statusOfAssociatedMeasures": "Statut des mesures associées", + "forTheSelectedScope": "Pour le périmètre sélectionné, vous avez", + "untreatedRiskScenarios": "{count} scénario{s} de risque non traité{s}", + "acceptedRiskScenarios": "{count} scénario{s} de risque accepté{s}", + "reviewNeeded": "Révision nécessaire", + "ok": "Ok", + "inconsistenciesFoundComposer": "Il y a {count} incohérence{s}. Pour plus de détail, vérifiez", + "current": "Courrant", + "residual": "Résiduel", + "jumpToRiskAssessment": "Passer à l'évaluation des risques", + "additionalMeasures": "Mesures supplémentaires" } diff --git a/frontend/src/lib/components/Breadcrumbs/Breadcrumbs.svelte b/frontend/src/lib/components/Breadcrumbs/Breadcrumbs.svelte index fadc08ae0..a8bab7086 100644 --- a/frontend/src/lib/components/Breadcrumbs/Breadcrumbs.svelte +++ b/frontend/src/lib/components/Breadcrumbs/Breadcrumbs.svelte @@ -29,15 +29,17 @@ crumbs = tokens.map((t) => { tokenPath += '/' + t; if (t === $breadcrumbObject.id) { - if ($breadcrumbObject.name) title = $breadcrumbObject.name; - else title = $breadcrumbObject.email; + if ($breadcrumbObject.name) t = $breadcrumbObject.name; + else t = $breadcrumbObject.email; } else if (t === 'folders') { t = 'domains'; } - t = t.replace(/-/g, ' '); - t = capitalizeSecondWord(t); + else{ + t = t.replace(/-/g, ' '); + t = capitalizeSecondWord(t); + } return { - label: $page.data.label || title || t, + label: $page.data.label || t, href: Object.keys(listViewFields).includes(tokens[0]) ? tokenPath : null }; }); diff --git a/frontend/src/lib/utils/locales.ts b/frontend/src/lib/utils/locales.ts index 339c5d845..35fc9d758 100644 --- a/frontend/src/lib/utils/locales.ts +++ b/frontend/src/lib/utils/locales.ts @@ -256,7 +256,9 @@ export function localItems(languageTag: string): LocalItems { lossOfAccountabilityText: m.lossOfAccountabilityText({ languageTag: languageTag }), lossOfAccountabilityChoice1: m.lossOfAccountabilityChoice1({ languageTag: languageTag }), lossOfAccountabilityChoice2: m.lossOfAccountabilityChoice2({ languageTag: languageTag }), - lossOfAccountabilityChoice3: m.lossOfAccountabilityChoice3({ languageTag: languageTag }) + lossOfAccountabilityChoice3: m.lossOfAccountabilityChoice3({ languageTag: languageTag }), + composer: m.composer({ languageTag: languageTag }), + plan: m.plan({ languageTag: languageTag }), }; return LOCAL_ITEMS; } diff --git a/frontend/src/routes/(app)/analytics/composer/+page.svelte b/frontend/src/routes/(app)/analytics/composer/+page.svelte index cb3c19395..16bf41172 100644 --- a/frontend/src/routes/(app)/analytics/composer/+page.svelte +++ b/frontend/src/routes/(app)/analytics/composer/+page.svelte @@ -1,36 +1,47 @@
-
Your selection
+
{m.yourSelection()}
- Hint: you can bookmark this page for future usage + {m.composerHint()}
- Here is the overview for the {data.risk_assessment_objects.length <= 1 - ? 'selected risk_assessment' - : `${data.risk_assessment_objects.length} selected risk assessments`}: + {data.risk_assessment_objects.length <= 1 + ? m.composerTitle() + : m.composerTitlePlural({ number: data.risk_assessment_objects.length})}:
-
Current risk level per risk scenario
+
{m.currentRiskLevelPerScenario()}
object.color)} /> @@ -38,7 +49,7 @@
-
Status of associated measures
+
{m.statusOfAssociatedMeasures()}
-
Residual risk level per risk scenario
+
{m.residualRiskLevelPerScenario()}
 For the selected scope, you have:{m.forTheSelectedScope()}:
  • - {data.counters.untreated} untreated risk scenario{data.counters.untreated > 1 - ? 's' - : ''} + {m.untreatedRiskScenarios({ + count: data.counters.untreated, + s: data.counters.untreated > 1 ? 's' : '' + })}
      {#each data.riskscenarios.untreated as scenario}
    • {scenario.name}
    • @@ -79,8 +91,10 @@
  • - and - {data.counters.accepted} risk scenario{data.counters.accepted > 1 ? 's' : ''} accepted + {m.acceptedRiskScenarios({ + count: data.counters.accepted, + s: data.counters.accepted > 1 ? 's' : '' + })}
      {#each data.riskscenarios.accepted as scenario}
    • {scenario.name}
    • @@ -116,9 +130,9 @@
      {#if item.risk_assessment.quality_check.count > 0} - Review needed + {m.reviewNeeded()} {:else} - Ok + {m.ok()} {/if}
@@ -127,23 +141,23 @@
{#if item.risk_assessment.quality_check.count > 0}➡️ Found - {item.risk_assessment.quality_check.count} inconsistenc{item - .risk_assessment.quality_check.count > 1 - ? 'es' - : 'y'} that you need to check (use + >{m.inconsistenciesFoundComposer({ + count: item.risk_assessment.quality_check.count, + s: item.risk_assessment.quality_check.count > 1 ? 's' : '', + plural: item.risk_assessment.quality_check.count > 1 ? 'ies' : 'y' + })} x-rays for more information). + >. {/if}
- + + {#each item.synth_table as lvl} @@ -159,7 +173,7 @@ Jump to full risk risk_assessment {m.jumpToRiskAssessment()} diff --git a/frontend/src/routes/(app)/risk-assessments/[id=uuid]/plan/+page.server.ts b/frontend/src/routes/(app)/risk-assessments/[id=uuid]/plan/+page.server.ts index ac6a98ab6..fb1b469bd 100644 --- a/frontend/src/routes/(app)/risk-assessments/[id=uuid]/plan/+page.server.ts +++ b/frontend/src/routes/(app)/risk-assessments/[id=uuid]/plan/+page.server.ts @@ -1,5 +1,4 @@ import { BASE_API_URL } from '$lib/utils/constants'; -import type { UUID } from 'crypto'; import type { PageServerLoad } from './$types'; @@ -9,11 +8,12 @@ export const load = (async ({ fetch, params }) => { const res = await fetch(endpoint); const risk_assessment = await res.json(); - const folder = await fetch(`${BASE_API_URL}/folders/${risk_assessment.project.id.folder}/`).then( + const project = await fetch(`${BASE_API_URL}/projects/${risk_assessment.project.id}/`).then( + (res) => res.json() + ); + const folder = await fetch(`${BASE_API_URL}/folders/${project.folder.id}/`).then( (res) => res.json() ); - risk_assessment.folder = folder; - return { URLModel, risk_assessment }; }) satisfies PageServerLoad; diff --git a/frontend/src/routes/(app)/risk-assessments/[id=uuid]/plan/+page.svelte b/frontend/src/routes/(app)/risk-assessments/[id=uuid]/plan/+page.svelte index a09f84752..96711969b 100644 --- a/frontend/src/routes/(app)/risk-assessments/[id=uuid]/plan/+page.svelte +++ b/frontend/src/routes/(app)/risk-assessments/[id=uuid]/plan/+page.svelte @@ -1,5 +1,6 @@ -

Associated risk scenarios:

+

{m.associatedRiskScenarios()}:

- CurrentResidual{m.current()}{m.residual()}
@@ -69,27 +75,27 @@ {#if scenario.existing_measures} - + - + {/if} {#if scenario.security_measures.length > 0} - + - - - - - - - - + + + + + + + + {#each scenario.security_measures as measure, index} 0)} {/if} diff --git a/frontend/src/routes/(app)/risk-scenarios/[id=uuid]/edit/+page.svelte b/frontend/src/routes/(app)/risk-scenarios/[id=uuid]/edit/+page.svelte index e46972915..1d26cf69c 100644 --- a/frontend/src/routes/(app)/risk-scenarios/[id=uuid]/edit/+page.svelte +++ b/frontend/src/routes/(app)/risk-scenarios/[id=uuid]/edit/+page.svelte @@ -125,10 +125,10 @@ >
-

Scope

+

{m.scope()}

-

Project

+

{m.project()}

{data.scenario.project.str} @@ -137,10 +137,10 @@ {form} options={getOptions({ objects: data.foreignKeys['risk_assessment'] })} field="risk_assessment" - label="RiskAssessment" + label={m.riskAssessment()} /> -

Auditor

+

{m.auditor()}

{#if data.scenario.auditor} {data.scenario.auditor.str} -

Version

+

{m.version()}

{data.scenario.version}

-

Status

+

{m.status()}

-

Last update

+

{m.lastUpdate()}

{new Date(data.scenario.updated_at).toLocaleString()}

@@ -166,7 +166,7 @@ {form} options={data.treatmentChoices} field="treatment" - label="Treatment status" + label={m.treatmentStatus()} />
@@ -179,10 +179,10 @@ multiple options={getOptions({ objects: data.foreignKeys['threats'] })} field="threats" - label="Threats" + label={m.threats()} /> - -
Existing measures: {m.existingMeasures()}:
lorem ipsum {scenario.existing_measures}
Additional measures: {m.additionalMeasures()}:
#NameDescriptionTypeSecurity functionETAEffortLinkStatus{m.name()}{m.description()}{m.type()}{m.securityFunction()}{m.eta()}{m.effort()}{m.link()}{m.status()}
- No associated measure + {m.noSecurityMeasureYet()}