Skip to content

Commit

Permalink
Fix error handling on nested create modals (#1286)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohamed-Hacene authored Jan 3, 2025
2 parents 32e2f4e + b1a4df9 commit 670be9f
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 187 deletions.
31 changes: 2 additions & 29 deletions frontend/src/lib/components/DetailView/DetailView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +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,
ToastStore
} from '@skeletonlabs/skeleton';
import { Tab, TabGroup, getModalStore, getToastStore } from '@skeletonlabs/skeleton';
import type { ModalComponent, ModalSettings, ModalStore } from '@skeletonlabs/skeleton';
import { Tab, TabGroup, getModalStore } from '@skeletonlabs/skeleton';
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
const modalStore: ModalStore = getModalStore();
const toastStore: ToastStore = getToastStore();
const defaultExcludes = ['id', 'is_published', 'localization_dict'];
Expand All @@ -50,27 +44,6 @@
let tabSet = 0;
function handleFormUpdated({
form,
pageStatus,
closeModal
}: {
form: any;
pageStatus: number;
closeModal: boolean;
}) {
if (closeModal && form.valid) {
$modalStore[0] ? modalStore.close() : null;
}
if (form.message) {
const toast: { message: string; background: string } = {
message: form.message,
background: pageStatus === 200 ? 'variant-filled-success' : 'variant-filled-error'
};
toastStore.trigger(toast);
}
}
function handleKeydown(event: KeyboardEvent) {
if (event.metaKey || event.ctrlKey) return;
if (document.activeElement?.tagName !== 'BODY') return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,73 +9,26 @@
ModalComponent,
ModalSettings,
ModalStore,
PopupSettings,
ToastStore
PopupSettings
} from '@skeletonlabs/skeleton';
import { getModalStore, getToastStore, popup } from '@skeletonlabs/skeleton';
import { superForm } from 'sveltekit-superforms';
import { getModalStore, popup } from '@skeletonlabs/skeleton';
import Anchor from '$lib/components/Anchor/Anchor.svelte';
import RiskScenarioItem from '$lib/components/RiskMatrix/RiskScenarioItem.svelte';
import { safeTranslate } from '$lib/utils/i18n.js';
import * as m from '$paraglide/messages';
import { languageTag } from '$paraglide/runtime';
import Anchor from '$lib/components/Anchor/Anchor.svelte';
export let data;
const showRisks = true;
const risk_assessment = data.risk_assessment;
const modalStore: ModalStore = getModalStore();
const toastStore: ToastStore = getToastStore();
const user = $page.data.user;
const model = URL_MODEL_MAP['risk-assessments'];
const canEditObject: boolean = Object.hasOwn(user.permissions, `change_${model.name}`);
function handleFormUpdated({
form,
pageStatus,
closeModal
}: {
form: any;
pageStatus: number;
closeModal: boolean;
}) {
if (closeModal && form.valid) {
$modalStore[0] ? modalStore.close() : null;
}
if (form.message) {
const toast: { message: string; background: string } = {
message: form.message,
background: pageStatus === 200 ? 'variant-filled-success' : 'variant-filled-error'
};
toastStore.trigger(toast);
}
}
let { form: deleteForm, message: deleteMessage } = {
form: {},
message: {}
};
let { form: createForm, message: createMessage } = {
form: {},
message: {}
};
// NOTE: This is a workaround for an issue we had with getting the return value from the form actions after switching pages in route /[model=urlmodel]/ without a full page reload.
// invalidateAll() did not work.
$: {
({ form: createForm, message: createMessage } = superForm(data.scenarioCreateForm, {
onUpdated: ({ form }) =>
handleFormUpdated({ form, pageStatus: $page.status, closeModal: true })
}));
({ form: deleteForm, message: deleteMessage } = superForm(data.scenarioDeleteForm, {
onUpdated: ({ form }) =>
handleFormUpdated({ form, pageStatus: $page.status, closeModal: true })
}));
}
function modalCreateForm(): void {
const modalComponent: ModalComponent = {
ref: CreateModal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ import { setError, superValidate } from 'sveltekit-superforms';
import type { PageServerLoad } from './$types';

import { BASE_API_URL } from '$lib/utils/constants';
import { getModelInfo, urlParamModelVerboseName } from '$lib/utils/crud';
import { getModelInfo } from '$lib/utils/crud';
import { modelSchema } from '$lib/utils/schemas';
import { listViewFields } from '$lib/utils/table';
import type { StrengthOfKnowledgeEntry, urlModel } from '$lib/utils/types';
import type { StrengthOfKnowledgeEntry } from '$lib/utils/types';
import { tableSourceMapper, type TableSource } from '@skeletonlabs/skeleton';
import { fail, redirect, type Actions } from '@sveltejs/kit';
import { fail, type Actions } from '@sveltejs/kit';
import { setFlash } from 'sveltekit-flash-message/server';
import * as m from '$paraglide/messages';
import { zod } from 'sveltekit-superforms/adapters';
import { defaultWriteFormAction } from '$lib/utils/actions';
import { safeTranslate } from '$lib/utils/i18n';

export const load: PageServerLoad = async ({ params, fetch }) => {
const URLModel = 'risk-scenarios';
Expand Down Expand Up @@ -223,12 +224,15 @@ export const actions: Actions = {
const res = await event.fetch(endpoint, requestInitOptions);

if (!res.ok) {
const response = await res.json();
const response: Record<string, any> = await res.json();
console.error('server response:', response);
if (response.non_field_errors) {
setError(form, 'non_field_errors', response.non_field_errors);
}
return fail(400, { form: form });
Object.entries(response).forEach(([key, value]) => {
setError(form, key, safeTranslate(value));
});
return fail(400, { form });
}

const measure = await res.json();
Expand All @@ -252,7 +256,7 @@ export const actions: Actions = {
if (response.non_field_errors) {
setError(form, 'non_field_errors', response.non_field_errors);
}
return fail(400, { form: form });
return fail(400, { form });
}
setFlash(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,20 @@
import type { StrengthOfKnowledgeEntry } from '$lib/utils/types';
import {
getModalStore,
getToastStore,
type ModalComponent,
type ModalSettings,
type ModalStore,
type ToastStore
type ModalStore
} from '@skeletonlabs/skeleton';
import type { PageData } from './$types';
import RiskLevel from './RiskLevel.svelte';
import { browser } from '$app/environment';
import { page } from '$app/stores';
import { superForm } from 'sveltekit-superforms';
import Anchor from '$lib/components/Anchor/Anchor.svelte';
import { safeTranslate } from '$lib/utils/i18n';
import * as m from '$paraglide/messages';
import { zod } from 'sveltekit-superforms/adapters';
import Anchor from '$lib/components/Anchor/Anchor.svelte';
export let data: PageData;
Expand All @@ -43,7 +40,6 @@
.sort((a, b) => a.value - b.value);
const modalStore: ModalStore = getModalStore();
const toastStore: ToastStore = getToastStore();
function cancel(): void {
if (browser) {
Expand Down Expand Up @@ -73,43 +69,6 @@
modalStore.trigger(modal);
}
function handleFormUpdated({
form,
pageStatus,
closeModal
}: {
form: any;
pageStatus: number;
closeModal: boolean;
}) {
if (closeModal && form.valid) {
$modalStore[0] ? modalStore.close() : null;
}
if (form.message) {
const toast: { message: string; background: string } = {
message: form.message,
background: pageStatus === 200 ? 'variant-filled-success' : 'variant-filled-error'
};
toastStore.trigger(toast);
}
}
let { form: measureCreateForm, message: measureCreateMessage } = {
form: {},
message: {}
};
// NOTE: This is a workaround for an issue we had with getting the return value from the form actions after switching pages in route /[model=urlmodel]/ without a full page reload.
// invalidateAll() did not work.
$: {
({ form: measureCreateForm, message: measureCreateMessage } = superForm(
data.measureCreateForm,
{
onUpdated: ({ form }) =>
handleFormUpdated({ form, pageStatus: $page.status, closeModal: true })
}
));
}
const next = getSecureRedirect($page.url.searchParams.get('next'));
const probabilityColorMap = data.riskMatrix.probability.map(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,10 @@
Tab,
TabGroup,
getModalStore,
getToastStore,
type ModalComponent,
type ModalSettings,
type ModalStore,
type ToastStore
type ModalStore
} from '@skeletonlabs/skeleton';
import { superForm } from 'sveltekit-superforms';
import { complianceResultColorMap } from '$lib/utils/constants';
import { hideSuggestions } from '$lib/utils/stores';
Expand All @@ -46,7 +43,6 @@
import Question from '$lib/components/Forms/Question.svelte';
import List from '$lib/components/List/List.svelte';
import ConfirmModal from '$lib/components/Modals/ConfirmModal.svelte';
import { getRequirementTitle } from '$lib/utils/helpers';
import { zod } from 'sveltekit-superforms/adapters';
function cancel(): void {
Expand All @@ -56,15 +52,10 @@
if (nextValue) window.location.href = nextValue;
}
const title = getRequirementTitle(data.requirement.ref_id, data.requirement.name)
? getRequirementTitle(data.requirement.ref_id, data.requirement.name)
: getRequirementTitle(data.parent.ref_id, data.parent.name);
const complianceAssessmentURL = `/compliance-assessments/${data.requirementAssessment.compliance_assessment.id}`;
const schema = RequirementAssessmentSchema;
const modalStore: ModalStore = getModalStore();
const toastStore: ToastStore = getToastStore();
function modalMeasureCreateForm(): void {
const modalComponent: ModalComponent = {
Expand Down Expand Up @@ -105,27 +96,6 @@
modalStore.trigger(modal);
}
function handleFormUpdated({
form,
pageStatus,
closeModal
}: {
form: any;
pageStatus: number;
closeModal: boolean;
}) {
if (closeModal && form.valid) {
$modalStore[0] ? modalStore.close() : null;
}
if (form.message) {
const toast: { message: string; background: string } = {
message: form.message,
background: pageStatus === 200 ? 'variant-filled-success' : 'variant-filled-error'
};
toastStore.trigger(toast);
}
}
let createAppliedControlsLoading = false;
function modalConfirmCreateSuggestedControls(id: string, name: string, action: string): void {
Expand Down Expand Up @@ -162,34 +132,6 @@
$: if (createAppliedControlsLoading === true && form) createAppliedControlsLoading = false;
let { form: measureCreateForm, message: measureCreateMessage } = {
form: {},
message: {}
};
let { form: evidenceCreateForm, message: evidenceCreateMessage } = {
form: {},
message: {}
};
// NOTE: This is a workaround for an issue we had with getting the return value from the form actions after switching pages in route /[model=urlmodel]/ without a full page reload.
// invalidateAll() did not work.
$: {
({ form: measureCreateForm, message: measureCreateMessage } = superForm(
data.measureCreateForm,
{
onUpdated: ({ form }) =>
handleFormUpdated({ form, pageStatus: $page.status, closeModal: true })
}
));
({ form: evidenceCreateForm, message: evidenceCreateMessage } = superForm(
data.evidenceCreateForm,
{
onUpdated: ({ form }) =>
handleFormUpdated({ form, pageStatus: $page.status, closeModal: true })
}
));
}
$: mappingInference = {
sourceRequirementAssessment:
data.requirementAssessment.mapping_inference.source_requirement_assessment,
Expand Down

0 comments on commit 670be9f

Please sign in to comment.