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

Add the possibility to draft a risk acceptance #1285

Merged
10 changes: 5 additions & 5 deletions backend/core/models.py
Original file line number Diff line number Diff line change
@@ -3415,11 +3415,11 @@ def save(self, *args, **kwargs) -> None:

class RiskAcceptance(NameDescriptionMixin, FolderMixin, PublishInRootFolderMixin):
ACCEPTANCE_STATE = [
("created", _("Created")),
("submitted", _("Submitted")),
("accepted", _("Accepted")),
("rejected", _("Rejected")),
("revoked", _("Revoked")),
("created", "Created"),
("submitted", "Submitted"),
("accepted", "Accepted"),
("rejected", "Rejected"),
("revoked", "Revoked"),
]

risk_scenarios = models.ManyToManyField(
41 changes: 27 additions & 14 deletions backend/core/views.py
Original file line number Diff line number Diff line change
@@ -1713,6 +1713,22 @@ def to_review(self, request):

return Response({"results": acceptances})

@action(detail=True, methods=["post"], name="Submit risk acceptance")
def submit(self, request, pk):
if self.get_object().approver:
self.get_object().set_state("submitted")
return Response({"results": "state updated to submitted"})
else:
return Response(
{"error": "Missing 'approver' field"}, status=status.HTTP_403_FORBIDDEN
)

# This set back risk acceptance to "Created"
@action(detail=True, methods=["post"], name="Draft risk acceptance")
def draft(self, request, pk):
self.get_object().set_state("created")
return Response({"results": "state updated back to created"})

@action(detail=True, methods=["post"], name="Accept risk acceptance")
def accept(self, request, pk):
if request.user != self.get_object().approver:
@@ -1762,23 +1778,20 @@ def waiting(self, request):
).count()
return Response({"count": acceptance_count})

def perform_create(self, serializer):
def perform_update(self, serializer):
risk_acceptance = serializer.validated_data
submitted = False

if risk_acceptance.get("approver"):
submitted = True
for scenario in risk_acceptance.get("risk_scenarios"):
if not RoleAssignment.is_access_allowed(
risk_acceptance.get("approver"),
Permission.objects.get(codename="approve_riskacceptance"),
scenario.risk_assessment.project.folder,
):
raise ValidationError(
"The approver is not allowed to approve this risk acceptance"
)
for scenario in risk_acceptance.get("risk_scenarios"):
if not RoleAssignment.is_access_allowed(
risk_acceptance.get("approver"),
Permission.objects.get(codename="approve_riskacceptance"),
scenario.risk_assessment.project.folder,
):
raise ValidationError(
"The approver is not allowed to approve this risk acceptance"
)
risk_acceptance = serializer.save()
if submitted:
risk_acceptance.set_state("submitted")


class UserFilter(df.FilterSet):
2 changes: 1 addition & 1 deletion frontend/messages/ar.json
Original file line number Diff line number Diff line change
@@ -454,7 +454,7 @@
"enterYourEmail": "أدخل عنوان بريدك الإلكتروني أدناه، وسنرسل لك تعليمات لتعيين كلمة مرور جديدة",
"send": "إرسال",
"goBackToLogin": "العودة إلى تسجيل الدخول",
"riskAcceptanceReviewMessage": "هذا القبول للمخاطر بانتظار المعالجة. تذكر مراجعته قبل الموافقة أو الرفض، لن تتمكن من العودة.",
"riskAcceptanceValidatingReviewMessage": "هذا القبول للمخاطر بانتظار المعالجة. تذكر مراجعته قبل الموافقة أو الرفض، لن تتمكن من العودة.",
"validate": "تحقق",
"reject": "رفض",
"revoke": "إلغاء",
2 changes: 1 addition & 1 deletion frontend/messages/cs.json
Original file line number Diff line number Diff line change
@@ -451,7 +451,7 @@
"enterYourEmail": "Zadejte svou e-mailovou adresu níže a zašleme vám instrukce pro nastavení nového hesla",
"send": "Odeslat",
"goBackToLogin": "Vrátit se k přihlášení",
"riskAcceptanceReviewMessage": "Toto přijetí rizika čeká na zpracování. Nezapomeňte jej před schválením nebo odmítnutím zkontrolovat, později už to nebudete moci změnit.",
"riskAcceptanceValidatingReviewMessage": "Toto přijetí rizika čeká na zpracování. Nezapomeňte jej před schválením nebo odmítnutím zkontrolovat, později už to nebudete moci změnit.",
"validate": "Ověřit",
"reject": "Odmítnout",
"revoke": "Odebrat",
2 changes: 1 addition & 1 deletion frontend/messages/de.json
Original file line number Diff line number Diff line change
@@ -453,7 +453,7 @@
"enterYourEmail": "Geben Sie unten Ihre E-Mail-Adresse ein, und wir senden Ihnen Anweisungen zum Festlegen eines neuen Passworts",
"send": "Senden",
"goBackToLogin": "Zurück zur Anmeldung",
"riskAcceptanceReviewMessage": "Diese Risikoakzeptanz wartet auf die Bearbeitung. Denken Sie daran, sie zu überprüfen, bevor Sie sie validieren oder ablehnen, Sie können nicht zurückgehen.",
"riskAcceptanceValidatingReviewMessage": "Diese Risikoakzeptanz wartet auf die Bearbeitung. Denken Sie daran, sie zu überprüfen, bevor Sie sie validieren oder ablehnen, Sie können nicht zurückgehen.",
"validate": "Validieren",
"reject": "Ablehnen",
"revoke": "Widerrufen",
6 changes: 5 additions & 1 deletion frontend/messages/en.json
Original file line number Diff line number Diff line change
@@ -146,6 +146,7 @@
"acceptedAt": "Accepted at",
"rejectedAt": "Rejected at",
"revokedAt": "Revoked at",
"created": "Created",
"submitted": "Submitted",
"rejected": "Rejected",
"revoked": "Revoked",
@@ -456,14 +457,17 @@
"enterYourEmail": "Enter your email address below, and we'll send instructions for setting a new one",
"send": "Send",
"goBackToLogin": "Go back to login",
"riskAcceptanceReviewMessage": "This risk acceptance is awaiting processing. Remember to review it before validating or rejecting it, you will not be able to go back.",
"riskAcceptanceSubmittingReviewMessage": "This will be sent to the approver for validation.",
"riskAcceptanceValidatingReviewMessage": "This risk acceptance is awaiting processing. Remember to review it before validating or rejecting it, you will not be able to go back.",
"riskAcceptanceMissingApproverMessage": "Approver required before submitting.",
"validate": "Validate",
"reject": "Reject",
"revoke": "Revoke",
"riskAcceptanceValidatedMessage": "This risk acceptance is currently validated. It can be revoked at any time, but this will be irrevocable. You will need to duplicate it with a different version if necessary.",
"confirmModalTitle": "Confirm",
"confirmModalMessage": "Are you sure? This action will permanently affect the following object",
"submit": "Submit",
"draft": "Draft",
"requirementAssessment": "Requirement assessment",
"requirementAssessments": "Requirement assessments",
"deleteModalTitle": "Delete",
2 changes: 1 addition & 1 deletion frontend/messages/es.json
Original file line number Diff line number Diff line change
@@ -453,7 +453,7 @@
"enterYourEmail": "Ingrese su dirección de correo electrónico a continuación y le enviaremos instrucciones para establecer una nueva",
"send": "Enviar",
"goBackToLogin": "Volver al inicio de sesión",
"riskAcceptanceReviewMessage": "Esta aceptación de riesgo está pendiente de procesamiento. Recuerde revisarla antes de validarla o rechazarla, no podrá volver atrás.",
"riskAcceptanceValidatingReviewMessage": "Esta aceptación de riesgo está pendiente de procesamiento. Recuerde revisarla antes de validarla o rechazarla, no podrá volver atrás.",
"validate": "Validar",
"reject": "Rechazar",
"revoke": "Revocar",
4 changes: 2 additions & 2 deletions frontend/messages/fr.json
Original file line number Diff line number Diff line change
@@ -146,6 +146,7 @@
"acceptedAt": "Accepté le",
"rejectedAt": "Rejeté le",
"revokedAt": "Révoqué le",
"created": "Créé",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add missing translations for new English messages.

The following messages are present in English but missing in German and French:

  • "created": "Created"
  • "riskAcceptanceSubmittingReviewMessage": "This will be sent to the approver for validation."
  • "riskAcceptanceMissingApproverMessage": "Approver required before submitting."

Please add the corresponding translations to maintain consistency across all language files.

Also applies to: 460-462

"submitted": "Soumis",
"rejected": "Rejeté",
"revoked": "Révoqué",
@@ -456,7 +457,7 @@
"enterYourEmail": "Entrez votre adresse e-mail ci-dessous et nous vous enverrons des instructions pour en définir un nouveau",
"send": "Envoyer",
"goBackToLogin": "Revenir à la page de connexion",
"riskAcceptanceReviewMessage": "Cette acceptation de risque est en attente de traitement. Pensez à la consulter avant de la valider ou de la rejeter, vous ne pourrez pas revenir en arrière.",
"riskAcceptanceValidatingReviewMessage": "Cette acceptation de risque est en attente de traitement. Pensez à la consulter avant de la valider ou de la rejeter, vous ne pourrez pas revenir en arrière.",
"validate": "Valider",
"reject": "Rejeter",
"revoke": "Révoquer",
@@ -473,7 +474,6 @@
"loading": "Chargement",
"open": "Ouvert",
"mitigate": "Atténué",
"accept": "Accepté",
"avoid": "Refusé",
"transfer": "Partagé",
"primary": "Primaire",
2 changes: 1 addition & 1 deletion frontend/messages/hi.json
Original file line number Diff line number Diff line change
@@ -453,7 +453,7 @@
"enterYourEmail": "नीचे अपना ईमेल पता दर्ज करें, और हम आपको नया पासवर्ड सेट करने के निर्देश भेजेंगे",
"send": "भेजें",
"goBackToLogin": "लॉगिन पर वापस जाएं",
"riskAcceptanceReviewMessage": "यह जोखिम स्वीकृति प्रसंस्करण के लिए प्रतीक्षारत है। इसे मान्य करने या अस्वीकार करने से पहले इसकी समीक्षा करना याद रखें, आप वापस नहीं जा सकेंगे।",
"riskAcceptanceValidatingReviewMessage": "यह जोखिम स्वीकृति प्रसंस्करण के लिए प्रतीक्षारत है। इसे मान्य करने या अस्वीकार करने से पहले इसकी समीक्षा करना याद रखें, आप वापस नहीं जा सकेंगे।",
"validate": "मान्य करें",
"reject": "अस्वीकार करें",
"revoke": "रद्द करें",
4 changes: 2 additions & 2 deletions frontend/messages/it.json
Original file line number Diff line number Diff line change
@@ -453,11 +453,11 @@
"enterYourEmail": "Inserisci il tuo indirizzo email per ricevere le istruzioni per impostare una nuova password",
"send": "Invia",
"goBackToLogin": "Torna al login",
"riskAcceptanceReviewMessage": "L'accettazione di questo rischio è in valutazione. Ricordati di revisionarla con attenzione prima di convalidarla o/o rifiutarla. Dopo l'accettazione o il rigiuto non sarà possibile tornare indietro.",
"riskAcceptanceValidatingReviewMessage": "L'accettazione di questo rischio è in valutazione. Ricordati di revisionarla con attenzione prima di convalidarla o/o rifiutarla. Dopo l'accettazione o il rigiuto non sarà possibile tornare indietro.",
"validate": "Convalida",
"reject": "Rifiuta",
"revoke": "Revoca",
"riskAcceptanceValidatedMessage": "L'accettazione di questo rischio è attualmente confermata. Puoi revocarla in qualsiasi momento, ma non puoi rotnare indietro. Si consiglia di duplicarla con una versione diversa se necessario.",
"riskAcceptanceValidatedMessage": "L'accettazione di questo rischio è attualmente confermata. Puoi revocarla in qualsiasi momento, ma non puoi tornare indietro. Si consiglia di duplicarla con una versione diversa se necessario.",
"confirmModalTitle": "Conferma",
"confirmModalMessage": "Sei sicuro? Questa azione modificherà in maniera permanente il seguente oggetto",
"submit": "Invia",
2 changes: 1 addition & 1 deletion frontend/messages/nl.json
Original file line number Diff line number Diff line change
@@ -453,7 +453,7 @@
"enterYourEmail": "Voer hieronder je e-mailadres in, en we sturen instructies om een nieuw wachtwoord in te stellen",
"send": "Versturen",
"goBackToLogin": "Ga terug naar inloggen",
"riskAcceptanceReviewMessage": "Deze risicoacceptatie wacht op verwerking. Vergeet niet deze te beoordelen voordat je deze valideert of afwijst, je kunt niet meer terug.",
"riskAcceptanceValidatingReviewMessage": "Deze risicoacceptatie wacht op verwerking. Vergeet niet deze te beoordelen voordat je deze valideert of afwijst, je kunt niet meer terug.",
"validate": "Valideren",
"reject": "Afwijzen",
"revoke": "Intrekken",
2 changes: 1 addition & 1 deletion frontend/messages/pl.json
Original file line number Diff line number Diff line change
@@ -453,7 +453,7 @@
"enterYourEmail": "Wpisz swój adres e-mail poniżej, a wyślemy instrukcje dotyczące ustawienia nowego hasła",
"send": "Wyślij",
"goBackToLogin": "Wróć do logowania",
"riskAcceptanceReviewMessage": "Ta akceptacja ryzyka oczekuje na przetworzenie. Pamiętaj, aby ją przejrzeć przed zatwierdzeniem lub odrzuceniem, nie będzie można wrócić.",
"riskAcceptanceValidatingReviewMessage": "Ta akceptacja ryzyka oczekuje na przetworzenie. Pamiętaj, aby ją przejrzeć przed zatwierdzeniem lub odrzuceniem, nie będzie można wrócić.",
"validate": "Zatwierdź",
"reject": "Odrzuć",
"revoke": "Cofnij",
2 changes: 1 addition & 1 deletion frontend/messages/pt.json
Original file line number Diff line number Diff line change
@@ -453,7 +453,7 @@
"enterYourEmail": "Digite seu endereço de e-mail abaixo e enviaremos instruções para definir uma nova senha",
"send": "Enviar",
"goBackToLogin": "Voltar para o login",
"riskAcceptanceReviewMessage": "Esta aceitação de risco está aguardando processamento. Lembre-se de revisá-la antes de validá-la ou rejeitá-la, pois você não poderá voltar atrás.",
"riskAcceptanceValidatingReviewMessage": "Esta aceitação de risco está aguardando processamento. Lembre-se de revisá-la antes de validá-la ou rejeitá-la, pois você não poderá voltar atrás.",
"validate": "Validar",
"reject": "Rejeitar",
"revoke": "Revogar",
2 changes: 1 addition & 1 deletion frontend/messages/ro.json
Original file line number Diff line number Diff line change
@@ -453,7 +453,7 @@
"enterYourEmail": "Introduceți adresa dvs. de e-mail mai jos și vă vom trimite instrucțiuni pentru a seta una nouă",
"send": "Trimite",
"goBackToLogin": "Înapoi la autentificare",
"riskAcceptanceReviewMessage": "Această acceptare a riscului așteaptă procesarea. Amintiți-vă să o revizuiți înainte de a o valida sau respinge, nu veți putea reveni.",
"riskAcceptanceValidatingReviewMessage": "Această acceptare a riscului așteaptă procesarea. Amintiți-vă să o revizuiți înainte de a o valida sau respinge, nu veți putea reveni.",
"validate": "Validați",
"reject": "Respingeți",
"revoke": "Revocați",
2 changes: 1 addition & 1 deletion frontend/messages/sv.json
Original file line number Diff line number Diff line change
@@ -453,7 +453,7 @@
"enterYourEmail": "Ange din e-postadress nedan, så skickar vi instruktioner för att ställa in ett nytt",
"send": "Skicka",
"goBackToLogin": "Gå tillbaka till inloggning",
"riskAcceptanceReviewMessage": "Denna riskacceptans väntar på bearbetning. Kom ihåg att granska den innan du validerar eller avvisar den; du kommer inte att kunna ångra dig.",
"riskAcceptanceValidatingReviewMessage": "Denna riskacceptans väntar på bearbetning. Kom ihåg att granska den innan du validerar eller avvisar den; du kommer inte att kunna ångra dig.",
"validate": "Validera",
"reject": "Avvisa",
"revoke": "Återkalla",
2 changes: 1 addition & 1 deletion frontend/messages/ur.json
Original file line number Diff line number Diff line change
@@ -453,7 +453,7 @@
"enterYourEmail": "نیچے اپنا ای میل پتہ درج کریں، اور ہم آپ کو نیا پاس ورڈ سیٹ کرنے کے لیے ہدایات بھیجیں گے",
"send": "بھیجیں",
"goBackToLogin": "لاگ ان پر واپس جائیں",
"riskAcceptanceReviewMessage": "یہ خطرے کی منظوری کارروائی کے لیے زیر التواء ہے۔ اسے درست کرنے یا مسترد کرنے سے پہلے اس کا جائزہ لینا یاد رکھیں، آپ واپس نہیں جا سکیں گے۔",
"riskAcceptanceValidatingReviewMessage": "یہ خطرے کی منظوری کارروائی کے لیے زیر التواء ہے۔ اسے درست کرنے یا مسترد کرنے سے پہلے اس کا جائزہ لینا یاد رکھیں، آپ واپس نہیں جا سکیں گے۔",
"validate": "درست کریں",
"reject": "مسترد کریں",
"revoke": "منسوخ کریں",
63 changes: 56 additions & 7 deletions frontend/src/lib/components/DetailView/DetailView.svelte
Original file line number Diff line number Diff line change
@@ -15,8 +15,13 @@
import { toCamelCase } from '$lib/utils/locales.js';
import * as m from '$paraglide/messages.js';
import { languageTag } from '$paraglide/runtime.js';
import type { ModalComponent, ModalSettings, ModalStore } from '@skeletonlabs/skeleton';
import { Tab, TabGroup, getModalStore } from '@skeletonlabs/skeleton';
import type {
PopupSettings,
ModalComponent,
ModalSettings,
ModalStore
} from '@skeletonlabs/skeleton';
import { popup, Tab, TabGroup, getModalStore } from '@skeletonlabs/skeleton';

import { onMount } from 'svelte';

@@ -25,6 +30,12 @@

const defaultExcludes = ['id', 'is_published', 'localization_dict'];

const popupHover: PopupSettings = {
event: 'hover',
target: 'popupHover',
placement: 'left'
};

export let data;
export let mailing = false;
export let fields: string[] = [];
@@ -169,7 +180,7 @@
$: displayEditButton = function () {
return (
canEditObject &&
!['Accepted', 'Rejected', 'Revoked'].includes(data.data.state) &&
!['Submitted', 'Accepted', 'Rejected', 'Revoked'].includes(data.data.state) &&
!data.data.urn &&
!data.data.builtin
);
@@ -188,12 +199,12 @@
</script>

<div class="flex flex-col space-y-2">
{#if data.data.state === m.submitted() && $page.data.user.id === data.data.approver.id}
{#if data.data.state === 'Submitted' && $page.data.user.id === data.data.approver.id}
<div
class="flex flex-row space-x-4 items-center bg-yellow-100 rounded-container-token shadow px-6 py-2 mb-2 justify-between"
class="flex flex-row space-x-4 items-center bg-yellow-100 rounded-container-token shadow px-6 py-2 justify-between"
>
<div class="text-yellow-900">
{m.riskAcceptanceReviewMessage()}
{m.riskAcceptanceValidatingReviewMessage()}
</div>
<div class="flex space-x-2">
<button
@@ -216,7 +227,7 @@
>
</div>
</div>
{:else if data.data.state === m.accept()}
{:else if data.data.state === 'Accepted'}
<div
class="flex flex-row items-center space-x-4 bg-green-100 rounded-container-token shadow-lg px-6 py-2 mt-2 justify-between"
>
@@ -367,7 +378,45 @@
{m.sendQuestionnaire()}
</button>
{/if}

{#if data.data.state === 'Submitted' && canEditObject}
<div class="flex flex-col space-y-2 ml-4">
<button
on:click={(_) => {
modalConfirm(data.data.id, data.data.name, '?/draft');
}}
on:keydown={(_) => modalConfirm(data.data.id, data.data.name, '?/draft')}
class="btn variant-filled-primary"
disabled={!data.data.approver}
>
<i class="fas fa-arrow-alt-circle-left mr-2" /> {m.draft()}</button
>
</div>
{/if}

{#if displayEditButton()}
{#if data.data.state === 'Created'}
<div class="flex flex-col space-y-2 ml-4">
<button
on:click={(_) => {
modalConfirm(data.data.id, data.data.name, '?/submit');
}}
on:keydown={(_) => modalConfirm(data.data.id, data.data.name, '?/submit')}
class="btn variant-filled-primary [&>*]:pointer-events-none"
disabled={!data.data.approver}
use:popup={popupHover}
>
<i class="fas fa-paper-plane mr-2" />
{m.submit()}
</button>
{#if !data.data.approver}
<div class="card variant-ghost-surface p-4 z-20" data-popup="popupHover">
<p class="font-normal">{m.riskAcceptanceMissingApproverMessage()}</p>
<div class="arrow variant-filled-surface" />
</div>
{/if}
</div>
{/if}
<div class="flex flex-col space-y-2 ml-4">
<Anchor
breadcrumbAction="push"
Original file line number Diff line number Diff line change
@@ -51,6 +51,7 @@
field="approver"
cacheLock={cacheLocks['approver']}
bind:cachedValue={formDataCache['approver']}
nullable={true}
label={m.approver()}
helpText={m.approverHelpText()}
/>
2 changes: 1 addition & 1 deletion frontend/src/lib/utils/schemas.ts
Original file line number Diff line number Diff line change
@@ -168,7 +168,7 @@ export const RiskAcceptanceSchema = z.object({
folder: z.string(),
expiry_date: z.union([z.literal('').transform(() => null), z.string().date()]).nullish(),
justification: z.string().optional().nullable(),
approver: z.string(),
approver: z.string().optional().nullable(),
risk_scenarios: z.array(z.string())
});

Loading