Skip to content

Commit

Permalink
feat: add a progress field on applied controls (#1443)
Browse files Browse the repository at this point in the history
* Add a progress field on applied controls

* changed save model function & regionalize

* inverse colors and add a validator on the progress field model
  • Loading branch information
melinoix authored Jan 30, 2025
1 parent d37a5c1 commit b3c334d
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 3 deletions.
29 changes: 29 additions & 0 deletions backend/core/migrations/0050_appliedcontrol_progress_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 5.1.5 on 2025-01-30 11:40

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


class Migration(migrations.Migration):
dependencies = [
("core", "0049_complianceassessment_show_documentation_score_and_more"),
]

operations = [
migrations.AddField(
model_name="appliedcontrol",
name="progress_field",
field=models.IntegerField(
default=0,
validators=[
django.core.validators.MinValueValidator(
0, message="Progress cannot be less than 0"
),
django.core.validators.MaxValueValidator(
100, message="Progress cannot be more than 100"
),
],
verbose_name="Progress Field",
),
),
]
13 changes: 12 additions & 1 deletion backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from django.contrib.auth import get_user_model
from django.core import serializers
from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, RegexValidator
from django.core.validators import MaxValueValidator, RegexValidator, MinValueValidator
from django.db import models, transaction
from django.db.models import Q
from django.forms.models import model_to_dict
Expand Down Expand Up @@ -1854,6 +1854,15 @@ class Status(models.TextChoices):
verbose_name=_("Cost"),
)

progress_field = models.IntegerField(
default=0,
verbose_name=_("Progress Field"),
validators=[
MinValueValidator(0, message="Progress cannot be less than 0"),
MaxValueValidator(100, message="Progress cannot be more than 100"),
],
)

fields_to_check = ["name"]

class Meta:
Expand All @@ -1865,6 +1874,8 @@ def save(self, *args, **kwargs):
self.category = self.reference_control.category
if self.reference_control and self.csf_function is None:
self.csf_function = self.reference_control.csf_function
if self.status == "active":
self.progress_field = 100
super(AppliedControl, self).save(*args, **kwargs)

@property
Expand Down
2 changes: 2 additions & 0 deletions backend/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,7 @@ class AppliedControlViewSet(BaseModelViewSet):
"risk_scenarios_e",
"requirement_assessments",
"evidences",
"progress_field",
]
search_fields = ["name", "description", "risk_scenarios", "requirement_assessments"]

Expand Down Expand Up @@ -1408,6 +1409,7 @@ def duplicate(self, request, pk):
link=applied_control.link,
effort=applied_control.effort,
cost=applied_control.cost,
progress_field=applied_control.progress_field,
)
duplicate_applied_control.owner.set(applied_control.owner.all())
if data["duplicate_evidences"]:
Expand Down
1 change: 1 addition & 0 deletions frontend/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,7 @@
"greenZoneRadius": "Green zone radius",
"yellowZoneRadius": "Yellow zone radius",
"redZoneRadius": "Red zone radius",
"progressField": "Progress",
"recap": "Recap",
"sectionMoved": "Section moved here"
}
1 change: 1 addition & 0 deletions frontend/messages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,7 @@
"greenZoneRadius": "Rayon de la zone verte",
"yellowZoneRadius": "Rayon de la zone jaune",
"redZoneRadius": "Rayon de la zone rouge",
"progressField": "Progrès",
"recap": "Recap",
"sectionMoved": "Section déplacée ici"
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import Checkbox from '$lib/components/Forms/Checkbox.svelte';
import TextField from '$lib/components/Forms/TextField.svelte';
import NumberField from '$lib/components/Forms/NumberField.svelte';
import Score from '$lib/components/Forms/Score.svelte';
import { getOptions } from '$lib/utils/crud';
import type { SuperValidated } from 'sveltekit-superforms';
import type { ModelInfo, CacheLock } from '$lib/utils/types';
Expand Down Expand Up @@ -139,6 +140,14 @@
cacheLock={cacheLocks['cost']}
bind:cachedValue={formDataCache['cost']}
/>
<Score
{form}
label={m.progress()}
field="progress_field"
fullDonut
min_score={0}
max_score={100}
/>
{/if}

{#if duplicate}
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/lib/utils/crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ export const URL_MODEL_MAP: ModelMap = {
{ field: 'eta', type: 'date' },
{ field: 'owner' },
{ field: 'expiry_date', type: 'date' },
{ field: 'link' }
{ field: 'link' },
{ field: 'progress_field' }
],
foreignKeyFields: [
{ field: 'reference_control', urlModel: 'reference-controls' },
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/lib/utils/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ export const AppliedControlSchema = z.object({
cost: z.number().multipleOf(0.000001).optional().nullable(),
folder: z.string(),
reference_control: z.string().optional().nullable(),
owner: z.string().uuid().optional().array().optional()
owner: z.string().uuid().optional().array().optional(),
progress_field: z.number().optional().default(0)
});

export const AppliedControlDuplicateSchema = z.object({
Expand Down

0 comments on commit b3c334d

Please sign in to comment.