Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ux/ebios rm improvements #1215

Merged
merged 14 commits into from
Dec 20, 2024
Merged
2 changes: 1 addition & 1 deletion backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1501,7 +1501,7 @@ def get_descendants(self) -> set[Self]:
children = self.get_children()
sub_children = set()
for child in children:
sub_children.append(child)
sub_children.add(child)
sub_children.update(child.get_descendants())
return sub_children

Expand Down
3 changes: 2 additions & 1 deletion backend/core/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,11 @@ class RiskAssessmentReadSerializer(AssessmentReadSerializer):
risk_scenarios = FieldsRelatedField(many=True)
risk_scenarios_count = serializers.IntegerField(source="risk_scenarios.count")
risk_matrix = FieldsRelatedField()
ebios_rm_study = FieldsRelatedField(["id", "name"])

class Meta:
model = RiskAssessment
exclude = ["ebios_rm_study"]
exclude = []


class AssetWriteSerializer(BaseModelSerializer):
Expand Down
29 changes: 29 additions & 0 deletions backend/ebios_rm/migrations/0009_alter_roto_activity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 5.1.4 on 2024-12-20 12:16

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("ebios_rm", "0008_remove_attackpath_ro_to_couple_strategicscenario_and_more"),
]

operations = [
migrations.AlterField(
model_name="roto",
name="activity",
field=models.PositiveSmallIntegerField(
choices=[
(0, "undefined"),
(1, "very_low"),
(2, "low"),
(3, "moderate"),
(4, "important"),
],
default=0,
validators=[django.core.validators.MaxValueValidator(4)],
verbose_name="Activity",
),
),
]
14 changes: 12 additions & 2 deletions backend/ebios_rm/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,13 @@ class Resources(models.IntegerChoices):
IMPORTANT = 3, "important"
UNLIMITED = 4, "unlimited"

class Activity(models.IntegerChoices):
UNDEFINED = 0, "undefined"
VERY_LOW = 1, "very_low"
LOW = 2, "low"
MODERATE = 3, "moderate"
IMPORTANT = 4, "important"

class Pertinence(models.IntegerChoices):
UNDEFINED = 0, "undefined"
IRRELAVANT = 1, "irrelevant"
Expand Down Expand Up @@ -306,7 +313,10 @@ class Pertinence(models.IntegerChoices):
default=Resources.UNDEFINED,
)
activity = models.PositiveSmallIntegerField(
verbose_name=_("Activity"), default=0, validators=[MaxValueValidator(4)]
verbose_name=_("Activity"),
choices=Activity.choices,
default=Activity.UNDEFINED,
validators=[MaxValueValidator(4)],
)
is_selected = models.BooleanField(verbose_name=_("Is selected"), default=False)
justification = models.TextField(verbose_name=_("Justification"), blank=True)
Expand Down Expand Up @@ -645,7 +655,7 @@ def ro_to(self):

def get_assets(self):
initial_assets = Asset.objects.filter(
feared_events__in=self.ro_to.feared_events.all(), is_selected=True
feared_events__in=self.ro_to.feared_events.filter(is_selected=True)
)
assets = set()
for asset in initial_assets:
Expand Down
1 change: 1 addition & 0 deletions backend/ebios_rm/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class RoToReadSerializer(BaseModelSerializer):

motivation = serializers.CharField(source="get_motivation_display")
resources = serializers.CharField(source="get_resources_display")
activity = serializers.CharField(source="get_activity_display")
pertinence = serializers.CharField(source="get_pertinence")

class Meta:
Expand Down
6 changes: 5 additions & 1 deletion backend/ebios_rm/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def update_workshop_step_status(self, request, pk, workshop, step):
class FearedEventViewSet(BaseModelViewSet):
model = FearedEvent

filterset_fields = ["ebios_rm_study", "ro_to_couples"]
filterset_fields = ["ebios_rm_study", "ro_to_couples", "is_selected"]

@action(detail=True, name="Get risk matrix", url_path="risk-matrix")
def risk_matrix(self, request, pk=None):
Expand Down Expand Up @@ -140,6 +140,10 @@ def motivation(self, request):
def resources(self, request):
return Response(dict(RoTo.Resources.choices))

@action(detail=False, name="Get activity choices")
def activity(self, request):
return Response(dict(RoTo.Activity.choices))


class StakeholderViewSet(BaseModelViewSet):
model = Stakeholder
Expand Down
7 changes: 6 additions & 1 deletion frontend/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1013,5 +1013,10 @@
"goBackToEbiosRmStudy": "Go back to Ebios RM study",
"addStrategicScenario": "Add strategic scenario",
"markAsDone": "Mark as done",
"markAsInProgress": "Mark as in progress"
"markAsInProgress": "Mark as in progress",
"ebiosRmRiskMatrix": "4x4 risk matrix from EBIOS-RM",
"riskAnalyses": "Risk analyses",
"client": "Client",
"partner": "Partner",
"supplier": "Supplier"
}
5 changes: 4 additions & 1 deletion frontend/messages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -1011,5 +1011,8 @@
"strategicScenario": "Scénario stratégique",
"strategicScenarios": "Scénarios stratégiques",
"goBackToEbiosRmStudy": "Retour à l'étude",
"addStrategicScenario": "Ajouter un scénario stratégique"
"addStrategicScenario": "Ajouter un scénario stratégique",
"client": "Client",
"partner": "Partenaire",
"supplier": "Fournisseur"
}
5 changes: 4 additions & 1 deletion frontend/src/lib/components/Breadcrumbs/Breadcrumbs.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

let crumbs: Array<{ label: string; href: string; icon?: string }> = [];

const disableWorkhopLink = ['workshop1', 'workshop2', 'workshop3', 'workshop4', 'workshop5']; // Disable workshops links in breadcrumb

$: {
// Remove zero-length tokens.
const tokens = $page.url.pathname.split('/').filter((t) => t !== '');
Expand All @@ -35,7 +37,8 @@
label: $page.data.label || t,
href:
Object.keys(listViewFields).includes(tokens[0]) &&
!listViewFields[tokens[0]].breadcrumb_link_disabled
!listViewFields[tokens[0]].breadcrumb_link_disabled &&
!disableWorkhopLink.includes(t) // Disable workshops links in breadcrumb
? tokenPath
: null
};
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/components/DetailView/DetailView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@
<a href={value} target="_blank" class="anchor">{value}</a>
{:else if ISO_8601_REGEX.test(value) && (key === 'created_at' || key === 'updated_at' || key === 'expiry_date' || key === 'accepted_at' || key === 'rejected_at' || key === 'revoked_at' || key === 'eta')}
{formatDateOrDateTime(value, languageTag())}
{:else if m[toCamelCase((value.str || value.name) ?? value)]}
{:else if m[toCamelCase(value.str || value.name)]}
{safeTranslate((value.str || value.name) ?? value)}
{:else}
{(value.str || value.name) ?? value}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
cacheLock={cacheLocks['risk_matrix']}
bind:cachedValue={formDataCache['risk_matrix']}
label={m.riskMatrix()}
placeholder={m.ebiosRmRiskMatrix()}
helpText={m.ebiosRmMatrixHelpText()}
/>
{:else if context === 'ebiosRmStudy'}
Expand Down
11 changes: 2 additions & 9 deletions frontend/src/lib/components/Forms/ModelForm/RoToForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,9 @@
cacheLock={cacheLocks['resources']}
bind:cachedValue={formDataCache['resources']}
/>
<!-- <Select
{form}
options={model.selectOptions['pertinence']}
field="pertinence"
label={m.pertinence()}
cacheLock={cacheLocks['pertinence']}
bind:cachedValue={formDataCache['pertinence']}
/> -->
<NumberField
<Select
{form}
options={model.selectOptions['activity']}
field="activity"
label={m.activity()}
cacheLock={cacheLocks['activity']}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/components/ModelTable/ModelTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@
on:click={(e) => e.stopPropagation()}>{val.str}</a
>
{:else if val.str}
{val.str}
{safeTranslate(val.str)}
{:else if unsafeTranslate(val.split(':')[0])}
<span class="text"
>{unsafeTranslate(val.split(':')[0] + 'Colon')}
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/lib/utils/crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,14 +645,15 @@ export const URL_MODEL_MAP: ModelMap = {
field: 'feared_events',
urlModel: 'feared-events',
endpointUrl: 'ebios-rm/feared-events',
urlParams: 'ebios_rm_study=',
urlParams: 'is_selected=true&ebios_rm_study=',
detail: true
}
],
selectFields: [
{ field: 'risk-origin' },
{ field: 'motivation', valueType: 'number' },
{ field: 'resources', valueType: 'number' }
{ field: 'resources', valueType: 'number' },
{ field: 'activity', valueType: 'number' }
]
},
stakeholders: {
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/lib/utils/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export function unsafeTranslate(key: string, params = {}, options = {}): string
if (Object.hasOwn(m, toCamelCase(key))) {
return m[toCamelCase(key)](params, options);
}
if (typeof key === 'boolean') {
return key ? '✅' : '❌';
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,20 @@
<div class="card p-4 bg-white shadow-lg">
<div class="flex flex-col space-y-4">
<div class="flex flex-row justify-between items-center w-full">
{#if ebiosRmStudy.ref_id}
<span class="badge bg-pink-200 text-pink-800 font-medium">
{m.refIdSemiColon()}
{ebiosRmStudy.ref_id}
</span>
{/if}
<a
href="/ebios-rm/{ebiosRmStudy.id}"
class="flex items-center space-x-2 text-primary-800 hover:text-primary-600"
>
<i class="fa-solid fa-arrow-left" />
<p class="">{m.goBackToEbiosRmStudy()}</p>
</a>
<div class="flex items-center space-x-2">
{#if ebiosRmStudy.ref_id}
<span class="badge bg-pink-200 text-pink-800 font-medium">
{m.refIdSemiColon()}
{ebiosRmStudy.ref_id}
</span>
{/if}
<span class="text-2xl font-bold">
{ebiosRmStudy.name} - v{ebiosRmStudy.version}
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
<div class="card p-4 bg-white shadow-lg">
<div class="flex flex-col space-y-4 items-center">
<div class="flex items-center justify-between w-full">
<a
href="/ebios-rm/{operationalScenario.ebios_rm_study.id}"
class="flex items-center space-x-2 text-primary-800 hover:text-primary-600"
>
<i class="fa-solid fa-arrow-left" />
<p class="">{m.goBackToEbiosRmStudy()}</p>
</a>
<div class="flex font-bold text-2xl space-x-2">
<span
><a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,18 @@
>
</div>
<br />
{#if risk_assessment.ebios_rm_study}
<div class="text-sm">
<span class="font-semibold" data-testid="ebios-rm-field-title">{m.ebiosRmStudy()}:</span
>
<a
href="/ebios-rm/{risk_assessment.ebios_rm_study.id}"
class="anchor"
data-testid="ebios-rm-field-value">{risk_assessment.ebios_rm_study.name}</a
>
</div>
<br />
{/if}
<div class="text-sm">
<span class="font-semibold" data-testid="description-field-title">{m.description()}:</span
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
<div class="flex flex-row space-x-1">
<p class="flex flex-col items-center">
<span class="text-xs text-gray-500">{m.riskOrigin()}</span>
<span class="font-bold">{roto.risk_origin} /</span>
<span class="font-bold">{safeTranslate(roto.risk_origin)} /</span>
</p>
<p class="flex flex-col items-center">
<span class="text-xs text-gray-500">{m.targetObjective()}</span>
Expand Down Expand Up @@ -116,7 +116,7 @@
<p>
<span class="badge bg-violet-200 text-violet-700">{m.activity()}</span>
<span>=</span>
<span class="font-bold">{roto.activity}</span>
<span class="font-bold">{safeTranslate(roto.activity)}</span>
</p>
</div>
<div
Expand Down
2 changes: 1 addition & 1 deletion frontend/tests/utils/page-detail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export class PageDetail extends BasePage {
if (this.form.fields.get(key)?.type === FormFieldType.CHECKBOX) {
await expect
.soft(this.page.getByTestId(key.replaceAll('_', '-') + '-field-value'))
.toHaveText(values[key] ? 'true' : 'false');
.toHaveText(values[key] ? '' : '');
} else if (this.form.fields.get(key)?.type === FormFieldType.DATE) {
const displayedValue = await this.page
.getByTestId(key.replaceAll('_', '-') + '-field-value')
Expand Down
Loading