From ab29baa9bc22060c796e6d40aabfb59166c47544 Mon Sep 17 00:00:00 2001 From: Mohamed-Hacene Date: Fri, 6 Dec 2024 14:58:38 +0100 Subject: [PATCH] feat: add nested risk analyses in workshop 5 --- backend/core/views.py | 1 + backend/ebios_rm/views.py | 5 + .../ebios-rm/[id=uuid]/+page.svelte | 8 +- .../risk-analyses/+page.server.ts | 113 ++++++++++++++++++ .../workshop-five/risk-analyses/+page.svelte | 63 ++++++++++ 5 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.server.ts create mode 100644 frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.svelte diff --git a/backend/core/views.py b/backend/core/views.py index 858cf7118d..a1b14eb5e6 100644 --- a/backend/core/views.py +++ b/backend/core/views.py @@ -568,6 +568,7 @@ class RiskAssessmentViewSet(BaseModelViewSet): "authors", "risk_matrix", "status", + "ebios_rm_studies" ] @action(detail=False, name="Risk assessments per status") diff --git a/backend/ebios_rm/views.py b/backend/ebios_rm/views.py index d10b4be622..4698413eef 100644 --- a/backend/ebios_rm/views.py +++ b/backend/ebios_rm/views.py @@ -31,6 +31,11 @@ class EbiosRMStudyViewSet(BaseModelViewSet): @action(detail=False, name="Get status choices") def status(self, request): return Response(dict(EbiosRMStudy.Status.choices)) + + @action(detail=True, name="Get risk matrix", url_path="risk-matrix") + def risk_matrix(self, request, pk=None): + ebios_rm_study = self.get_object() + return Response(RiskMatrixReadSerializer(ebios_rm_study.risk_matrix).data) @method_decorator(cache_page(60 * LONG_CACHE_TTL)) @action(detail=True, name="Get likelihood choices") diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.svelte index b9b5514d15..89d53a0e02 100644 --- a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.svelte +++ b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.svelte @@ -77,10 +77,10 @@ ], ws5: [ { title: safeTranslate(m.ebiosWs5_1()), status: riskAnalysisCreated ? 'done' : 'to_do', href: '#' }, - { title: safeTranslate(m.ebiosWs5_2()), status: 'done', href: '#' }, - { title: safeTranslate(m.ebiosWs5_3()), status: 'to_do', href: '#' }, - { title: safeTranslate(m.ebiosWs5_4()), status: 'to_do', href: '#' }, - { title: safeTranslate(m.ebiosWs5_5()), status: 'done', href: '#' } + { title: safeTranslate(m.ebiosWs5_2()), status: 'done', href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}` }, + { title: safeTranslate(m.ebiosWs5_3()), status: 'to_do', href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}` }, + { title: safeTranslate(m.ebiosWs5_4()), status: 'to_do', href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}` }, + { title: safeTranslate(m.ebiosWs5_5()), status: 'done', href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}` } ] }; diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.server.ts b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.server.ts new file mode 100644 index 0000000000..ad39f045a8 --- /dev/null +++ b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.server.ts @@ -0,0 +1,113 @@ +import { defaultDeleteFormAction, defaultWriteFormAction } from '$lib/utils/actions'; +import { BASE_API_URL } from '$lib/utils/constants'; +import { + getModelInfo, + urlParamModelForeignKeyFields, + urlParamModelSelectFields +} from '$lib/utils/crud'; +import { modelSchema } from '$lib/utils/schemas'; +import type { ModelInfo, urlModel } from '$lib/utils/types'; +import { type Actions } from '@sveltejs/kit'; +import { superValidate } from 'sveltekit-superforms'; +import { zod } from 'sveltekit-superforms/adapters'; +import { z } from 'zod'; +import type { PageServerLoad } from './$types'; +import { listViewFields } from '$lib/utils/table'; +import { tableSourceMapper, type TableSource } from '@skeletonlabs/skeleton'; + +export const load: PageServerLoad = async ({ params, fetch }) => { + const schema = z.object({ id: z.string().uuid() }); + const deleteForm = await superValidate(zod(schema)); + const URLModel = 'risk-assessments'; + const createSchema = modelSchema(URLModel); + const ebiosMatrixRes = await fetch(`${BASE_API_URL}/ebios-rm/studies/${params.id}/risk-matrix/`); + const risk_matrix_id = await ebiosMatrixRes.json().then((res) => res.id); + const initialData = { + ebios_rm_studies: [params.id], + risk_matrix: risk_matrix_id + }; + const createForm = await superValidate(initialData, zod(createSchema), { errors: false }); + const model: ModelInfo = getModelInfo(URLModel); + const foreignKeyFields = urlParamModelForeignKeyFields(URLModel); + const selectFields = model.selectFields; + + const foreignKeys: Record = {}; + + for (const keyField of foreignKeyFields) { + const model = getModelInfo(keyField.urlModel); + const queryParams = keyField.urlParams ? `?${keyField.urlParams}` : ''; + const url = model.endpointUrl + ? `${BASE_API_URL}/${model.endpointUrl}/${queryParams}` + : `${BASE_API_URL}/${model.urlModel}/${queryParams}`; + const response = await fetch(url); + if (response.ok) { + foreignKeys[keyField.field] = await response.json().then((data) => data.results); + } else { + console.error(`Failed to fetch data for ${keyField.field}: ${response.statusText}`); + } + } + + model['foreignKeys'] = foreignKeys; + + const selectOptions: Record = {}; + + if (selectFields) { + for (const selectField of selectFields) { + const url = `${BASE_API_URL}/${URLModel}/${ + selectField.detail ? params.id + '/' : '' + }${selectField.field}/`; + const response = await fetch(url); + if (response.ok) { + selectOptions[selectField.field] = await response.json().then((data) => + Object.entries(data).map(([key, value]) => ({ + label: value, + value: key + })) + ); + } else { + console.error(`Failed to fetch data for ${selectField.field}: ${response.statusText}`); + } + } + } + + model['selectOptions'] = selectOptions; + + const endpoint = model.endpointUrl + ? `${BASE_API_URL}/${model.endpointUrl}?ebios_rm_studies=${params.id}` + : `${BASE_API_URL}/${model.urlModel}?ebios_rm_studies=${params.id}`; + const res = await fetch(endpoint); + const data = await res.json().then((res) => res.results); + + const bodyData = tableSourceMapper(data, listViewFields[URLModel as urlModel].body); + + const headData: Record = listViewFields[URLModel as urlModel].body.reduce( + (obj, key, index) => { + obj[key] = listViewFields[URLModel as urlModel].head[index]; + return obj; + }, + {} + ); + + const table: TableSource = { + head: headData, + body: bodyData, + meta: data // metaData + }; + + return { createForm, deleteForm, model, URLModel, table }; +}; + +export const actions: Actions = { + create: async (event) => { + // const redirectToWrittenObject = Boolean(event.params.model === 'entity-assessments'); + return defaultWriteFormAction({ + event, + urlModel: 'risk-assessments', + action: 'create' + // redirectToWrittenObject: redirectToWrittenObject + }); + }, + delete: async (event) => { + return defaultDeleteFormAction({ event, urlModel: 'risk-assessments' }); + } +}; diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.svelte new file mode 100644 index 0000000000..16f92369b4 --- /dev/null +++ b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.svelte @@ -0,0 +1,63 @@ + + + +
+ + + +
+