From f40952120195e20c7d6c9de3f5d79faa1f3d1d1d Mon Sep 17 00:00:00 2001
From: Luka Pajukanta
Date: Fri, 2 Oct 2026 14:47:16 +0300
Subject: [PATCH 1/7] Move annotation extraction config from universe
annotations to form fields
Fields now declare propagateToAnnotation / propagateDimensionOn{Create,Edit}
in the form editor. UniverseAnnotation.form_fields is migrated onto the
fields and removed. Part of #990.
Co-Authored-By: Claude Sonnet 5.5
---
kompassi-v2-frontend/src/__generated__/gql.ts | 12 +-
.../src/__generated__/graphql.ts | 13 +-
.../program-annotations/actions.ts | 6 -
.../[eventSlug]/program-annotations/page.tsx | 17 +--
.../edit/[language]/fields/page.tsx | 18 +++
.../src/components/forms/EditFieldModal.tsx | 8 ++
.../src/components/forms/FormEditor.tsx | 9 ++
.../components/forms/FormEditorWrapper.tsx | 7 +
.../src/components/forms/editFieldForm.ts | 135 ++++++++++++++----
.../src/components/forms/models.ts | 4 +
kompassi-v2-frontend/src/translations/en.tsx | 31 ++--
kompassi-v2-frontend/src/translations/fi.tsx | 32 +++--
kompassi-v2-frontend/src/translations/sv.tsx | 31 ++--
kompassi/core/pseudonymization.py | 1 -
kompassi/dimensions/graphql/annotation.py | 1 +
.../mutations/put_universe_annotation.py | 16 +--
.../graphql/universe_annotation_limited.py | 4 -
...opagate_annotation_form_fields_to_forms.py | 70 +++++++++
.../dimensions/models/universe_annotation.py | 4 -
kompassi/forms/models/field.py | 58 ++++++++
kompassi/forms/tests.py | 24 ++++
kompassi/forms/utils/extract_annotations.py | 94 ++++++------
kompassi/program_v2/tests.py | 13 +-
23 files changed, 438 insertions(+), 170 deletions(-)
create mode 100644 kompassi/dimensions/migrations/0020_propagate_annotation_form_fields_to_forms.py
diff --git a/kompassi-v2-frontend/src/__generated__/gql.ts b/kompassi-v2-frontend/src/__generated__/gql.ts
index a302cf2b4..535dc5ae8 100644
--- a/kompassi-v2-frontend/src/__generated__/gql.ts
+++ b/kompassi-v2-frontend/src/__generated__/gql.ts
@@ -87,7 +87,7 @@ type Documents = {
"\n fragment ProgramAdmin on FullProgramType {\n slug\n title\n scheduleItems {\n startTime\n }\n cachedDimensions\n }\n": typeof types.ProgramAdminFragmentDoc,
"\n query ProgramAdminList(\n $eventSlug: String!\n $locale: String\n $filters: [DimensionFilterInput!]\n ) {\n event(slug: $eventSlug) {\n slug\n name\n program {\n scheduleItemsExcelExportLink\n dimensions(publicOnly: false) {\n slug\n title(lang: $locale)\n isTechnical\n isMultiValue\n isKeyDimension\n isListFilter\n\n values(lang: $locale) {\n slug\n title(lang: $locale)\n color\n }\n }\n\n programs(filters: $filters, publicOnly: false) {\n ...ProgramAdmin\n }\n }\n }\n }\n": typeof types.ProgramAdminListDocument,
"\n mutation PutEventAnnotation($input: PutUniverseAnnotationInput!) {\n putUniverseAnnotation(input: $input) {\n universeAnnotation {\n annotation {\n slug\n }\n }\n }\n }\n": typeof types.PutEventAnnotationDocument,
- "\n fragment ProgramAdminEventAnnotation on LimitedUniverseAnnotationType {\n annotation {\n slug\n title(lang: $locale)\n description(lang: $locale)\n type\n isComputed\n isPublic\n isShownInDetail\n isInternal\n isApplicableToProgramItems\n isApplicableToScheduleItems\n }\n isActive\n formFields\n }\n": typeof types.ProgramAdminEventAnnotationFragmentDoc,
+ "\n fragment ProgramAdminEventAnnotation on LimitedUniverseAnnotationType {\n annotation {\n slug\n title(lang: $locale)\n description(lang: $locale)\n type\n isComputed\n isPublic\n isShownInDetail\n isInternal\n isApplicableToProgramItems\n isApplicableToScheduleItems\n }\n isActive\n }\n": typeof types.ProgramAdminEventAnnotationFragmentDoc,
"\n query ProgramAdminEventAnnotations($eventSlug: String!, $locale: String) {\n event(slug: $eventSlug) {\n name\n slug\n timezone\n\n program {\n eventAnnotations {\n ...ProgramAdminEventAnnotation\n }\n }\n }\n }\n": typeof types.ProgramAdminEventAnnotationsDocument,
"\n mutation PutProgramDimension($input: PutDimensionInput!) {\n putDimension(input: $input) {\n dimension {\n slug\n }\n }\n }\n": typeof types.PutProgramDimensionDocument,
"\n mutation DeleteProgramDimension($input: DeleteDimensionInput!) {\n deleteDimension(input: $input) {\n slug\n }\n }\n": typeof types.DeleteProgramDimensionDocument,
@@ -100,7 +100,7 @@ type Documents = {
"\n mutation DeleteProgramFormLanguage($input: DeleteSurveyLanguageInput!) {\n deleteSurveyLanguage(input: $input) {\n language\n }\n }\n": typeof types.DeleteProgramFormLanguageDocument,
"\n mutation UpdateFormFieldsMutation($input: UpdateFormFieldsInput!) {\n updateFormFields(input: $input) {\n survey {\n slug\n }\n }\n }\n": typeof types.UpdateFormFieldsMutationDocument,
"\n mutation PromoteProgramFormFieldToDimension(\n $input: PromoteFieldToDimensionInput!\n ) {\n promoteFieldToDimension(input: $input) {\n survey {\n slug\n }\n }\n }\n": typeof types.PromoteProgramFormFieldToDimensionDocument,
- "\n query EditProgramFormFieldsPage(\n $eventSlug: String!\n $surveySlug: String!\n $language: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n forms {\n survey(slug: $surveySlug, app: PROGRAM) {\n ...EditSurveyFieldsPage\n }\n }\n }\n }\n": typeof types.EditProgramFormFieldsPageDocument,
+ "\n query EditProgramFormFieldsPage(\n $eventSlug: String!\n $surveySlug: String!\n $language: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n program {\n eventAnnotations {\n isActive\n annotation {\n slug\n title(lang: $locale)\n isApplicableToProgramItems\n isApplicableToInvolvements\n }\n }\n }\n\n forms {\n survey(slug: $surveySlug, app: PROGRAM) {\n ...EditSurveyFieldsPage\n }\n }\n }\n }\n": typeof types.EditProgramFormFieldsPageDocument,
"\n fragment EditProgramFormLanguage on FullSurveyType {\n slug\n title(lang: $locale)\n canRemove\n canGrantAccess\n purpose\n\n form(lang: $language) {\n title\n language\n description\n thankYouMessage\n fields\n canRemove\n }\n\n languages {\n language\n }\n }\n": typeof types.EditProgramFormLanguageFragmentDoc,
"\n query EditProgramFormLanguagePage(\n $eventSlug: String!\n $surveySlug: String!\n $language: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n forms {\n survey(slug: $surveySlug, app: PROGRAM) {\n ...EditProgramFormLanguage\n }\n }\n }\n }\n": typeof types.EditProgramFormLanguagePageDocument,
"\n mutation CreateProgramFormLanguage($input: CreateSurveyLanguageInput!) {\n createSurveyLanguage(input: $input) {\n form {\n language\n }\n }\n }\n": typeof types.CreateProgramFormLanguageDocument,
@@ -336,7 +336,7 @@ const documents: Documents = {
"\n fragment ProgramAdmin on FullProgramType {\n slug\n title\n scheduleItems {\n startTime\n }\n cachedDimensions\n }\n": types.ProgramAdminFragmentDoc,
"\n query ProgramAdminList(\n $eventSlug: String!\n $locale: String\n $filters: [DimensionFilterInput!]\n ) {\n event(slug: $eventSlug) {\n slug\n name\n program {\n scheduleItemsExcelExportLink\n dimensions(publicOnly: false) {\n slug\n title(lang: $locale)\n isTechnical\n isMultiValue\n isKeyDimension\n isListFilter\n\n values(lang: $locale) {\n slug\n title(lang: $locale)\n color\n }\n }\n\n programs(filters: $filters, publicOnly: false) {\n ...ProgramAdmin\n }\n }\n }\n }\n": types.ProgramAdminListDocument,
"\n mutation PutEventAnnotation($input: PutUniverseAnnotationInput!) {\n putUniverseAnnotation(input: $input) {\n universeAnnotation {\n annotation {\n slug\n }\n }\n }\n }\n": types.PutEventAnnotationDocument,
- "\n fragment ProgramAdminEventAnnotation on LimitedUniverseAnnotationType {\n annotation {\n slug\n title(lang: $locale)\n description(lang: $locale)\n type\n isComputed\n isPublic\n isShownInDetail\n isInternal\n isApplicableToProgramItems\n isApplicableToScheduleItems\n }\n isActive\n formFields\n }\n": types.ProgramAdminEventAnnotationFragmentDoc,
+ "\n fragment ProgramAdminEventAnnotation on LimitedUniverseAnnotationType {\n annotation {\n slug\n title(lang: $locale)\n description(lang: $locale)\n type\n isComputed\n isPublic\n isShownInDetail\n isInternal\n isApplicableToProgramItems\n isApplicableToScheduleItems\n }\n isActive\n }\n": types.ProgramAdminEventAnnotationFragmentDoc,
"\n query ProgramAdminEventAnnotations($eventSlug: String!, $locale: String) {\n event(slug: $eventSlug) {\n name\n slug\n timezone\n\n program {\n eventAnnotations {\n ...ProgramAdminEventAnnotation\n }\n }\n }\n }\n": types.ProgramAdminEventAnnotationsDocument,
"\n mutation PutProgramDimension($input: PutDimensionInput!) {\n putDimension(input: $input) {\n dimension {\n slug\n }\n }\n }\n": types.PutProgramDimensionDocument,
"\n mutation DeleteProgramDimension($input: DeleteDimensionInput!) {\n deleteDimension(input: $input) {\n slug\n }\n }\n": types.DeleteProgramDimensionDocument,
@@ -349,7 +349,7 @@ const documents: Documents = {
"\n mutation DeleteProgramFormLanguage($input: DeleteSurveyLanguageInput!) {\n deleteSurveyLanguage(input: $input) {\n language\n }\n }\n": types.DeleteProgramFormLanguageDocument,
"\n mutation UpdateFormFieldsMutation($input: UpdateFormFieldsInput!) {\n updateFormFields(input: $input) {\n survey {\n slug\n }\n }\n }\n": types.UpdateFormFieldsMutationDocument,
"\n mutation PromoteProgramFormFieldToDimension(\n $input: PromoteFieldToDimensionInput!\n ) {\n promoteFieldToDimension(input: $input) {\n survey {\n slug\n }\n }\n }\n": types.PromoteProgramFormFieldToDimensionDocument,
- "\n query EditProgramFormFieldsPage(\n $eventSlug: String!\n $surveySlug: String!\n $language: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n forms {\n survey(slug: $surveySlug, app: PROGRAM) {\n ...EditSurveyFieldsPage\n }\n }\n }\n }\n": types.EditProgramFormFieldsPageDocument,
+ "\n query EditProgramFormFieldsPage(\n $eventSlug: String!\n $surveySlug: String!\n $language: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n program {\n eventAnnotations {\n isActive\n annotation {\n slug\n title(lang: $locale)\n isApplicableToProgramItems\n isApplicableToInvolvements\n }\n }\n }\n\n forms {\n survey(slug: $surveySlug, app: PROGRAM) {\n ...EditSurveyFieldsPage\n }\n }\n }\n }\n": types.EditProgramFormFieldsPageDocument,
"\n fragment EditProgramFormLanguage on FullSurveyType {\n slug\n title(lang: $locale)\n canRemove\n canGrantAccess\n purpose\n\n form(lang: $language) {\n title\n language\n description\n thankYouMessage\n fields\n canRemove\n }\n\n languages {\n language\n }\n }\n": types.EditProgramFormLanguageFragmentDoc,
"\n query EditProgramFormLanguagePage(\n $eventSlug: String!\n $surveySlug: String!\n $language: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n forms {\n survey(slug: $surveySlug, app: PROGRAM) {\n ...EditProgramFormLanguage\n }\n }\n }\n }\n": types.EditProgramFormLanguagePageDocument,
"\n mutation CreateProgramFormLanguage($input: CreateSurveyLanguageInput!) {\n createSurveyLanguage(input: $input) {\n form {\n language\n }\n }\n }\n": types.CreateProgramFormLanguageDocument,
@@ -821,7 +821,7 @@ export function graphql(source: "\n mutation PutEventAnnotation($input: PutUniv
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
-export function graphql(source: "\n fragment ProgramAdminEventAnnotation on LimitedUniverseAnnotationType {\n annotation {\n slug\n title(lang: $locale)\n description(lang: $locale)\n type\n isComputed\n isPublic\n isShownInDetail\n isInternal\n isApplicableToProgramItems\n isApplicableToScheduleItems\n }\n isActive\n formFields\n }\n"): (typeof documents)["\n fragment ProgramAdminEventAnnotation on LimitedUniverseAnnotationType {\n annotation {\n slug\n title(lang: $locale)\n description(lang: $locale)\n type\n isComputed\n isPublic\n isShownInDetail\n isInternal\n isApplicableToProgramItems\n isApplicableToScheduleItems\n }\n isActive\n formFields\n }\n"];
+export function graphql(source: "\n fragment ProgramAdminEventAnnotation on LimitedUniverseAnnotationType {\n annotation {\n slug\n title(lang: $locale)\n description(lang: $locale)\n type\n isComputed\n isPublic\n isShownInDetail\n isInternal\n isApplicableToProgramItems\n isApplicableToScheduleItems\n }\n isActive\n }\n"): (typeof documents)["\n fragment ProgramAdminEventAnnotation on LimitedUniverseAnnotationType {\n annotation {\n slug\n title(lang: $locale)\n description(lang: $locale)\n type\n isComputed\n isPublic\n isShownInDetail\n isInternal\n isApplicableToProgramItems\n isApplicableToScheduleItems\n }\n isActive\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
@@ -873,7 +873,7 @@ export function graphql(source: "\n mutation PromoteProgramFormFieldToDimension
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
-export function graphql(source: "\n query EditProgramFormFieldsPage(\n $eventSlug: String!\n $surveySlug: String!\n $language: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n forms {\n survey(slug: $surveySlug, app: PROGRAM) {\n ...EditSurveyFieldsPage\n }\n }\n }\n }\n"): (typeof documents)["\n query EditProgramFormFieldsPage(\n $eventSlug: String!\n $surveySlug: String!\n $language: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n forms {\n survey(slug: $surveySlug, app: PROGRAM) {\n ...EditSurveyFieldsPage\n }\n }\n }\n }\n"];
+export function graphql(source: "\n query EditProgramFormFieldsPage(\n $eventSlug: String!\n $surveySlug: String!\n $language: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n program {\n eventAnnotations {\n isActive\n annotation {\n slug\n title(lang: $locale)\n isApplicableToProgramItems\n isApplicableToInvolvements\n }\n }\n }\n\n forms {\n survey(slug: $surveySlug, app: PROGRAM) {\n ...EditSurveyFieldsPage\n }\n }\n }\n }\n"): (typeof documents)["\n query EditProgramFormFieldsPage(\n $eventSlug: String!\n $surveySlug: String!\n $language: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n program {\n eventAnnotations {\n isActive\n annotation {\n slug\n title(lang: $locale)\n isApplicableToProgramItems\n isApplicableToInvolvements\n }\n }\n }\n\n forms {\n survey(slug: $surveySlug, app: PROGRAM) {\n ...EditSurveyFieldsPage\n }\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
diff --git a/kompassi-v2-frontend/src/__generated__/graphql.ts b/kompassi-v2-frontend/src/__generated__/graphql.ts
index c874bdccc..fffb9d70e 100644
--- a/kompassi-v2-frontend/src/__generated__/graphql.ts
+++ b/kompassi-v2-frontend/src/__generated__/graphql.ts
@@ -450,7 +450,6 @@ export enum PutUniverseAnnotationAction {
export type PutUniverseAnnotationInput = {
action?: PutUniverseAnnotationAction | null | undefined;
annotationSlug: string;
- formFields: Array;
isActive: boolean;
scopeSlug: string;
universeSlug: string;
@@ -1130,7 +1129,7 @@ export type PutEventAnnotationMutationVariables = Exact<{
export type PutEventAnnotationMutation = { putUniverseAnnotation: { universeAnnotation: { annotation: { slug: string } } | null } | null };
-export type ProgramAdminEventAnnotationFragment = { isActive: boolean, formFields: unknown, annotation: { slug: string, title: string, description: string, type: AnnotationDataType, isComputed: boolean, isPublic: boolean, isShownInDetail: boolean, isInternal: boolean, isApplicableToProgramItems: boolean, isApplicableToScheduleItems: boolean } };
+export type ProgramAdminEventAnnotationFragment = { isActive: boolean, annotation: { slug: string, title: string, description: string, type: AnnotationDataType, isComputed: boolean, isPublic: boolean, isShownInDetail: boolean, isInternal: boolean, isApplicableToProgramItems: boolean, isApplicableToScheduleItems: boolean } };
export type ProgramAdminEventAnnotationsQueryVariables = Exact<{
eventSlug: string;
@@ -1138,7 +1137,7 @@ export type ProgramAdminEventAnnotationsQueryVariables = Exact<{
}>;
-export type ProgramAdminEventAnnotationsQuery = { event: { name: string, slug: string, timezone: string, program: { eventAnnotations: Array<{ isActive: boolean, formFields: unknown, annotation: { slug: string, title: string, description: string, type: AnnotationDataType, isComputed: boolean, isPublic: boolean, isShownInDetail: boolean, isInternal: boolean, isApplicableToProgramItems: boolean, isApplicableToScheduleItems: boolean } }> } | null } | null };
+export type ProgramAdminEventAnnotationsQuery = { event: { name: string, slug: string, timezone: string, program: { eventAnnotations: Array<{ isActive: boolean, annotation: { slug: string, title: string, description: string, type: AnnotationDataType, isComputed: boolean, isPublic: boolean, isShownInDetail: boolean, isInternal: boolean, isApplicableToProgramItems: boolean, isApplicableToScheduleItems: boolean } }> } | null } | null };
export type PutProgramDimensionMutationVariables = Exact<{
input: PutDimensionInput;
@@ -1228,7 +1227,7 @@ export type EditProgramFormFieldsPageQueryVariables = Exact<{
}>;
-export type EditProgramFormFieldsPageQuery = { event: { name: string, slug: string, forms: { survey: { slug: string, title: string | null, canRemove: boolean, canGrantAccess: boolean, purpose: SurveyPurpose, dimensions: Array<{ slug: string, canRemove: boolean, canAddValues: boolean, title: string | null, isPublic: boolean, isKeyDimension: boolean, isMultiValue: boolean, isListFilter: boolean, isShownInDetail: boolean, isNegativeSelection: boolean, isTechnical: boolean, valueOrdering: DimensionsDimensionValueOrderingChoices, titleFi: string, titleEn: string, titleSv: string, values: Array<{ slug: string, color: string, isTechnical: boolean, isSubjectLocked: boolean, canRemove: boolean, title: string | null, titleFi: string, titleEn: string, titleSv: string }> }>, form: { title: string, language: FormsFormLanguageChoices, fields: unknown, canRemove: boolean } | null, languages: Array<{ language: FormsFormLanguageChoices }> } | null } | null } | null };
+export type EditProgramFormFieldsPageQuery = { event: { name: string, slug: string, program: { eventAnnotations: Array<{ isActive: boolean, annotation: { slug: string, title: string, isApplicableToProgramItems: boolean, isApplicableToInvolvements: boolean } }> } | null, forms: { survey: { slug: string, title: string | null, canRemove: boolean, canGrantAccess: boolean, purpose: SurveyPurpose, dimensions: Array<{ slug: string, canRemove: boolean, canAddValues: boolean, title: string | null, isPublic: boolean, isKeyDimension: boolean, isMultiValue: boolean, isListFilter: boolean, isShownInDetail: boolean, isNegativeSelection: boolean, isTechnical: boolean, valueOrdering: DimensionsDimensionValueOrderingChoices, titleFi: string, titleEn: string, titleSv: string, values: Array<{ slug: string, color: string, isTechnical: boolean, isSubjectLocked: boolean, canRemove: boolean, title: string | null, titleFi: string, titleEn: string, titleSv: string }> }>, form: { title: string, language: FormsFormLanguageChoices, fields: unknown, canRemove: boolean } | null, languages: Array<{ language: FormsFormLanguageChoices }> } | null } | null } | null };
export type EditProgramFormLanguageFragment = { slug: string, title: string | null, canRemove: boolean, canGrantAccess: boolean, purpose: SurveyPurpose, form: { title: string, language: FormsFormLanguageChoices, description: string, thankYouMessage: string, fields: unknown, canRemove: boolean } | null, languages: Array<{ language: FormsFormLanguageChoices }> };
@@ -2161,7 +2160,7 @@ export const ProgramAdminDetailHostFragmentDoc = {"kind":"Document","definitions
export const ProgramAdminDetailInvitationFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProgramAdminDetailInvitation"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedInvitationType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"cachedDimensions"}}]}}]} as unknown as DocumentNode;
export const ProgramAdminDetailScheduleItemFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProgramAdminDetailScheduleItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedScheduleItemType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"subtitle"}},{"kind":"Field","name":{"kind":"Name","value":"location"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"startTime"}},{"kind":"Field","name":{"kind":"Name","value":"durationMinutes"}},{"kind":"Field","name":{"kind":"Name","value":"room"}},{"kind":"Field","name":{"kind":"Name","value":"freeformLocation"}},{"kind":"Field","name":{"kind":"Name","value":"isPublic"}}]}}]} as unknown as DocumentNode;
export const ProgramAdminFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProgramAdmin"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullProgramType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"scheduleItems"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"startTime"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cachedDimensions"}}]}}]} as unknown as DocumentNode;
-export const ProgramAdminEventAnnotationFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProgramAdminEventAnnotation"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUniverseAnnotationType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"description"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"isComputed"}},{"kind":"Field","name":{"kind":"Name","value":"isPublic"}},{"kind":"Field","name":{"kind":"Name","value":"isShownInDetail"}},{"kind":"Field","name":{"kind":"Name","value":"isInternal"}},{"kind":"Field","name":{"kind":"Name","value":"isApplicableToProgramItems"}},{"kind":"Field","name":{"kind":"Name","value":"isApplicableToScheduleItems"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"formFields"}}]}}]} as unknown as DocumentNode;
+export const ProgramAdminEventAnnotationFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProgramAdminEventAnnotation"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUniverseAnnotationType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"description"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"isComputed"}},{"kind":"Field","name":{"kind":"Name","value":"isPublic"}},{"kind":"Field","name":{"kind":"Name","value":"isShownInDetail"}},{"kind":"Field","name":{"kind":"Name","value":"isInternal"}},{"kind":"Field","name":{"kind":"Name","value":"isApplicableToProgramItems"}},{"kind":"Field","name":{"kind":"Name","value":"isApplicableToScheduleItems"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}}]}}]} as unknown as DocumentNode;
export const EditProgramFormLanguageFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"EditProgramFormLanguage"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullSurveyType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}},{"kind":"Field","name":{"kind":"Name","value":"canGrantAccess"}},{"kind":"Field","name":{"kind":"Name","value":"purpose"}},{"kind":"Field","name":{"kind":"Name","value":"form"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"language"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"thankYouMessage"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}}]}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode;
export const EditProgramFormFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"EditProgramForm"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullSurveyType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"activeFrom"}},{"kind":"Field","name":{"kind":"Name","value":"activeUntil"}},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}},{"kind":"Field","name":{"kind":"Name","value":"canGrantAccess"}},{"kind":"Field","name":{"kind":"Name","value":"purpose"}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}}]}}]}}]} as unknown as DocumentNode;
export const ProgramFormResponseEditFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProgramFormResponseEdit"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullResponseType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"revisionCreatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"originalCreatedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fullName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"values"}},{"kind":"Field","name":{"kind":"Name","value":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"survey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"profileFieldSelector"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullProfileFieldSelector"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullProfileFieldSelector"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProfileFieldSelectorType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"nick"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"phoneNumber"}},{"kind":"Field","name":{"kind":"Name","value":"discordHandle"}}]}}]} as unknown as DocumentNode;
@@ -2271,7 +2270,7 @@ export const ProgramAdminDetailScheduleDocument = {"kind":"Document","definition
export const CreateProgramDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateProgram"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateProgramInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createProgram"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"program"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]} as unknown as DocumentNode;
export const ProgramAdminListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProgramAdminList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"DimensionFilterInput"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"program"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"scheduleItemsExcelExportLink"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"publicOnly"},"value":{"kind":"BooleanValue","value":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"isTechnical"}},{"kind":"Field","name":{"kind":"Name","value":"isMultiValue"}},{"kind":"Field","name":{"kind":"Name","value":"isKeyDimension"}},{"kind":"Field","name":{"kind":"Name","value":"isListFilter"}},{"kind":"Field","name":{"kind":"Name","value":"values"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"programs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}},{"kind":"Argument","name":{"kind":"Name","value":"publicOnly"},"value":{"kind":"BooleanValue","value":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProgramAdmin"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProgramAdmin"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullProgramType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"scheduleItems"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"startTime"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cachedDimensions"}}]}}]} as unknown as DocumentNode;
export const PutEventAnnotationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"PutEventAnnotation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"PutUniverseAnnotationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"putUniverseAnnotation"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universeAnnotation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]}}]} as unknown as DocumentNode;
-export const ProgramAdminEventAnnotationsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProgramAdminEventAnnotations"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"program"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"eventAnnotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProgramAdminEventAnnotation"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProgramAdminEventAnnotation"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUniverseAnnotationType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"description"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"isComputed"}},{"kind":"Field","name":{"kind":"Name","value":"isPublic"}},{"kind":"Field","name":{"kind":"Name","value":"isShownInDetail"}},{"kind":"Field","name":{"kind":"Name","value":"isInternal"}},{"kind":"Field","name":{"kind":"Name","value":"isApplicableToProgramItems"}},{"kind":"Field","name":{"kind":"Name","value":"isApplicableToScheduleItems"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"formFields"}}]}}]} as unknown as DocumentNode;
+export const ProgramAdminEventAnnotationsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProgramAdminEventAnnotations"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"program"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"eventAnnotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProgramAdminEventAnnotation"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProgramAdminEventAnnotation"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUniverseAnnotationType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"description"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"isComputed"}},{"kind":"Field","name":{"kind":"Name","value":"isPublic"}},{"kind":"Field","name":{"kind":"Name","value":"isShownInDetail"}},{"kind":"Field","name":{"kind":"Name","value":"isInternal"}},{"kind":"Field","name":{"kind":"Name","value":"isApplicableToProgramItems"}},{"kind":"Field","name":{"kind":"Name","value":"isApplicableToScheduleItems"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}}]}}]} as unknown as DocumentNode;
export const PutProgramDimensionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"PutProgramDimension"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"PutDimensionInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"putDimension"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimension"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]} as unknown as DocumentNode;
export const DeleteProgramDimensionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteProgramDimension"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"DeleteDimensionInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteDimension"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]} as unknown as DocumentNode;
export const PutProgramDimensionValueDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"PutProgramDimensionValue"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"PutDimensionValueInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"putDimensionValue"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"value"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]} as unknown as DocumentNode;
@@ -2283,7 +2282,7 @@ export const UpdateProgramFormLanguageDocument = {"kind":"Document","definitions
export const DeleteProgramFormLanguageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteProgramFormLanguage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"DeleteSurveyLanguageInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteSurveyLanguage"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode;
export const UpdateFormFieldsMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateFormFieldsMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateFormFieldsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateFormFields"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"survey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]} as unknown as DocumentNode;
export const PromoteProgramFormFieldToDimensionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"PromoteProgramFormFieldToDimension"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"PromoteFieldToDimensionInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"promoteFieldToDimension"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"survey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]} as unknown as DocumentNode;
-export const EditProgramFormFieldsPageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"EditProgramFormFieldsPage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"surveySlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"language"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"survey"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"surveySlug"}}},{"kind":"Argument","name":{"kind":"Name","value":"app"},"value":{"kind":"EnumValue","value":"PROGRAM"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"EditSurveyFieldsPage"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionEditorValue"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"isTechnical"}},{"kind":"Field","name":{"kind":"Name","value":"isSubjectLocked"}},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"titleFi"}},{"kind":"Field","name":{"kind":"Name","value":"titleEn"}},{"kind":"Field","name":{"kind":"Name","value":"titleSv"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionEditor"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}},{"kind":"Field","name":{"kind":"Name","value":"canAddValues"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"isPublic"}},{"kind":"Field","name":{"kind":"Name","value":"isKeyDimension"}},{"kind":"Field","name":{"kind":"Name","value":"isMultiValue"}},{"kind":"Field","name":{"kind":"Name","value":"isListFilter"}},{"kind":"Field","name":{"kind":"Name","value":"isShownInDetail"}},{"kind":"Field","name":{"kind":"Name","value":"isNegativeSelection"}},{"kind":"Field","name":{"kind":"Name","value":"isTechnical"}},{"kind":"Field","name":{"kind":"Name","value":"valueOrdering"}},{"kind":"Field","name":{"kind":"Name","value":"titleFi"}},{"kind":"Field","name":{"kind":"Name","value":"titleEn"}},{"kind":"Field","name":{"kind":"Name","value":"titleSv"}},{"kind":"Field","name":{"kind":"Name","value":"values"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionEditorValue"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"EditSurveyFieldsPage"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullSurveyType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}},{"kind":"Field","name":{"kind":"Name","value":"canGrantAccess"}},{"kind":"Field","name":{"kind":"Name","value":"purpose"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionEditor"}}]}},{"kind":"Field","name":{"kind":"Name","value":"form"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"language"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"fields"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"enrich"},"value":{"kind":"BooleanValue","value":false}}]},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}}]}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode;
+export const EditProgramFormFieldsPageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"EditProgramFormFieldsPage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"surveySlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"language"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"program"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"eventAnnotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"annotation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"isApplicableToProgramItems"}},{"kind":"Field","name":{"kind":"Name","value":"isApplicableToInvolvements"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"survey"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"surveySlug"}}},{"kind":"Argument","name":{"kind":"Name","value":"app"},"value":{"kind":"EnumValue","value":"PROGRAM"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"EditSurveyFieldsPage"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionEditorValue"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"isTechnical"}},{"kind":"Field","name":{"kind":"Name","value":"isSubjectLocked"}},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"titleFi"}},{"kind":"Field","name":{"kind":"Name","value":"titleEn"}},{"kind":"Field","name":{"kind":"Name","value":"titleSv"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionEditor"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}},{"kind":"Field","name":{"kind":"Name","value":"canAddValues"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"isPublic"}},{"kind":"Field","name":{"kind":"Name","value":"isKeyDimension"}},{"kind":"Field","name":{"kind":"Name","value":"isMultiValue"}},{"kind":"Field","name":{"kind":"Name","value":"isListFilter"}},{"kind":"Field","name":{"kind":"Name","value":"isShownInDetail"}},{"kind":"Field","name":{"kind":"Name","value":"isNegativeSelection"}},{"kind":"Field","name":{"kind":"Name","value":"isTechnical"}},{"kind":"Field","name":{"kind":"Name","value":"valueOrdering"}},{"kind":"Field","name":{"kind":"Name","value":"titleFi"}},{"kind":"Field","name":{"kind":"Name","value":"titleEn"}},{"kind":"Field","name":{"kind":"Name","value":"titleSv"}},{"kind":"Field","name":{"kind":"Name","value":"values"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionEditorValue"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"EditSurveyFieldsPage"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullSurveyType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}},{"kind":"Field","name":{"kind":"Name","value":"canGrantAccess"}},{"kind":"Field","name":{"kind":"Name","value":"purpose"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionEditor"}}]}},{"kind":"Field","name":{"kind":"Name","value":"form"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"language"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"fields"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"enrich"},"value":{"kind":"BooleanValue","value":false}}]},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}}]}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode;
export const EditProgramFormLanguagePageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"EditProgramFormLanguagePage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"surveySlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"language"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"survey"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"surveySlug"}}},{"kind":"Argument","name":{"kind":"Name","value":"app"},"value":{"kind":"EnumValue","value":"PROGRAM"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"EditProgramFormLanguage"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"EditProgramFormLanguage"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullSurveyType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}},{"kind":"Field","name":{"kind":"Name","value":"canGrantAccess"}},{"kind":"Field","name":{"kind":"Name","value":"purpose"}},{"kind":"Field","name":{"kind":"Name","value":"form"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"language"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"thankYouMessage"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"canRemove"}}]}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode;
export const CreateProgramFormLanguageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateProgramFormLanguage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateSurveyLanguageInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSurveyLanguage"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]}}]} as unknown as DocumentNode;
export const UpdateProgramFormMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateProgramFormMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateSurveyInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateProgramForm"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"survey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]} as unknown as DocumentNode;
diff --git a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-annotations/actions.ts b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-annotations/actions.ts
index 38eb44eee..84dad84d2 100644
--- a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-annotations/actions.ts
+++ b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-annotations/actions.ts
@@ -34,17 +34,11 @@ export async function putEventAnnotation(
? true
: decodeBoolean((formData.get("isActive") as string | null) || "false");
- const formFields = ((formData.get("formFields") as string | null) || "")
- .split("\n")
- .map((field) => field.trim())
- .filter(Boolean);
-
const input = {
scopeSlug: eventSlug,
universeSlug,
annotationSlug,
isActive,
- formFields,
action,
};
diff --git a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-annotations/page.tsx b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-annotations/page.tsx
index 40b142b7b..07eb5f0a3 100644
--- a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-annotations/page.tsx
+++ b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-annotations/page.tsx
@@ -40,7 +40,6 @@ graphql(`
isApplicableToScheduleItems
}
isActive
- formFields
}
`);
@@ -167,7 +166,6 @@ export default async function ProgramAdminAnnotationsPage(props: Props) {
className: "col-6 py-3",
getCellContents: (row) => {
const slug = mangleAnnotationSlug(row.annotation.slug);
- const formFields = row.formFields as string[];
const fields: Field[] = [
{
slug: "isActive",
@@ -175,17 +173,8 @@ export default async function ProgramAdminAnnotationsPage(props: Props) {
title: t.attributes.isActive.checkboxLabel(row.annotation.slug),
readOnly: row.annotation.slug.startsWith("internal:"),
},
- {
- slug: "formFields",
- type: "MultiLineText",
- rows: 5,
- title: t.attributes.formFields.title,
- },
];
- const values = {
- ...row,
- formFields: formFields.join("\n") || "",
- };
+ const values = row;
return (
-
- {t.attributes.formFields.title}:{" "}
- {t.attributes.formFields.description}
-
{t.eventAnnotationsAdmin.actions.saveWithoutRefresh.title}:{" "}
{t.eventAnnotationsAdmin.actions.saveWithoutRefresh.description}
diff --git a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-forms/[surveySlug]/edit/[language]/fields/page.tsx b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-forms/[surveySlug]/edit/[language]/fields/page.tsx
index f0b646fb9..e030c1a4a 100644
--- a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-forms/[surveySlug]/edit/[language]/fields/page.tsx
+++ b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-forms/[surveySlug]/edit/[language]/fields/page.tsx
@@ -22,6 +22,18 @@ const query = graphql(`
name
slug
+ program {
+ eventAnnotations {
+ isActive
+ annotation {
+ slug
+ title(lang: $locale)
+ isApplicableToProgramItems
+ isApplicableToInvolvements
+ }
+ }
+ }
+
forms {
survey(slug: $surveySlug, app: PROGRAM) {
...EditSurveyFieldsPage
@@ -107,6 +119,10 @@ export default async function EditProgramFormFieldsPage(props: Props) {
validateFields(form.fields);
+ const annotations = (data.event.program?.eventAnnotations ?? [])
+ .filter(({ isActive }) => isActive)
+ .map(({ annotation }) => annotation);
+
return (
{
const t = messages.FormEditor.editFieldModal;
const fields = getFieldEditorFields(
fieldToEdit.type,
messages.FormEditor.editFieldForm,
dimensions,
+ annotations,
+ formContext,
);
const handleSubmit = useCallback(
diff --git a/kompassi-v2-frontend/src/components/forms/FormEditor.tsx b/kompassi-v2-frontend/src/components/forms/FormEditor.tsx
index 5e33975ac..6c452bcba 100644
--- a/kompassi-v2-frontend/src/components/forms/FormEditor.tsx
+++ b/kompassi-v2-frontend/src/components/forms/FormEditor.tsx
@@ -3,6 +3,7 @@
import React from "react";
import AddFieldDropdown from "./AddFieldDropdown";
+import type { AnnotationOption, FormEditorContext } from "./editFieldForm";
import EditFieldModal from "./EditFieldModal";
import FormEditorControls from "./FormEditorControls";
import { addField, removeField, replaceField } from "./formEditorLogic";
@@ -25,6 +26,10 @@ interface Props {
SchemaForm: Translations["SchemaForm"];
};
dimensions: DimensionValueSelectFragment[];
+ /// Annotations that fields may pass their values forward to.
+ annotations?: AnnotationOption[];
+ /// Where responses end up; survey responses have nothing to pass values forward to.
+ formContext?: FormEditorContext;
}
/// The end user facing SchemaForm operates on enriched fields
@@ -81,6 +86,8 @@ export default function FormEditor(props: Props) {
onPromoteFieldToDimension: onPromoteFieldToDimension,
messages,
dimensions,
+ annotations = [],
+ formContext = "survey",
} = props;
const t = messages.FormEditor;
@@ -196,6 +203,8 @@ export default function FormEditor(props: Props) {
}}
onClose={() => setEditFieldModalOpen(false)}
dimensions={dimensions}
+ annotations={annotations}
+ formContext={formContext}
messages={messages}
/>
)}
diff --git a/kompassi-v2-frontend/src/components/forms/FormEditorWrapper.tsx b/kompassi-v2-frontend/src/components/forms/FormEditorWrapper.tsx
index e7ce4f398..4fba404bc 100644
--- a/kompassi-v2-frontend/src/components/forms/FormEditorWrapper.tsx
+++ b/kompassi-v2-frontend/src/components/forms/FormEditorWrapper.tsx
@@ -2,6 +2,7 @@
import { useCallback, useState } from "react";
import FormEditor from "./FormEditor";
+import type { AnnotationOption, FormEditorContext } from "./editFieldForm";
import { Field } from "./models";
import { DimensionValueSelectFragment } from "@/__generated__/graphql";
import type { Translations } from "@/translations/en";
@@ -9,6 +10,8 @@ import type { Translations } from "@/translations/en";
interface Props {
initialFields: Field[];
dimensions: DimensionValueSelectFragment[];
+ annotations?: AnnotationOption[];
+ formContext?: FormEditorContext;
messages: {
FormEditor: Translations["FormEditor"];
SchemaForm: Translations["SchemaForm"];
@@ -25,6 +28,8 @@ export default function FormEditorWrapper({
onChange,
onPromoteFieldToDimension: onPromoteFieldToDimension,
dimensions,
+ annotations,
+ formContext,
}: Props) {
const [fields, setFields] = useState(initialFields);
@@ -40,6 +45,8 @@ export default function FormEditorWrapper({
return (
+ formContext === "involvement"
+ ? annotation.isApplicableToInvolvements
+ : annotation.isApplicableToProgramItems,
+ );
+ propagationFields.push(
+ {
+ type: "SingleSelect",
+ slug: "propagateToAnnotation",
+ required: false,
+ presentation: "dropdown",
+ choices: [
+ { slug: "", title: t.propagateToAnnotation.none },
+ ...applicable.map(({ slug, title }) => ({ slug, title })),
+ ],
+ title: t.propagateToAnnotation.title,
+ helpText: t.propagateToAnnotation.helpText,
+ },
+ {
+ type: "SingleCheckbox",
+ slug: "propagateToAnnotationOnEdit",
+ required: false,
+ ...t.propagateToAnnotationOnEdit,
+ },
+ );
+ }
+ }
+
const choicesField: Field = {
type: "MultiLineText",
slug: "choices",
@@ -89,33 +165,38 @@ export function getFieldEditorFields(
// ...t.encryptTo,
// };
- switch (fieldType) {
- case "SingleSelect":
- case "MultiSelect":
- return editableFieldFields.concat([choicesField]); // , encryptTo]);
- case "DimensionSingleSelect":
- case "DimensionMultiSelect":
- case "DimensionSingleCheckbox":
- return editableFieldFields.concat([dimensionField]); // , encryptTo]);
- case "RadioMatrix":
- return editableFieldFields.concat([
- questionsField,
- choicesField,
- // encryptTo,
- ]);
- case "MultiLineText":
- case "MarkdownText":
- return editableFieldFields.concat([maxLengthField]);
- case "Divider":
- case "Spacer":
- return [slugField];
- case "StaticText":
- return baseFieldEditorFields;
- default:
- // TODO implement encryption
- return editableFieldFields;
- // default:
- // return baseFieldEditorFields.concat([encryptTo]);
+ const fields = getTypeSpecificFields();
+ return fields.concat(propagationFields);
+
+ function getTypeSpecificFields(): Field[] {
+ switch (fieldType) {
+ case "SingleSelect":
+ case "MultiSelect":
+ return editableFieldFields.concat([choicesField]); // , encryptTo]);
+ case "DimensionSingleSelect":
+ case "DimensionMultiSelect":
+ case "DimensionSingleCheckbox":
+ return editableFieldFields.concat([dimensionField]); // , encryptTo]);
+ case "RadioMatrix":
+ return editableFieldFields.concat([
+ questionsField,
+ choicesField,
+ // encryptTo,
+ ]);
+ case "MultiLineText":
+ case "MarkdownText":
+ return editableFieldFields.concat([maxLengthField]);
+ case "Divider":
+ case "Spacer":
+ return [slugField];
+ case "StaticText":
+ return baseFieldEditorFields;
+ default:
+ // TODO implement encryption
+ return editableFieldFields;
+ // default:
+ // return baseFieldEditorFields.concat([encryptTo]);
+ }
}
}
diff --git a/kompassi-v2-frontend/src/components/forms/models.ts b/kompassi-v2-frontend/src/components/forms/models.ts
index 3a8674d32..b16806598 100644
--- a/kompassi-v2-frontend/src/components/forms/models.ts
+++ b/kompassi-v2-frontend/src/components/forms/models.ts
@@ -74,6 +74,10 @@ interface BaseField {
isKeyField?: boolean;
htmlType?: HtmlType;
encryptTo?: string[];
+ propagateDimensionOnCreate?: boolean;
+ propagateDimensionOnEdit?: boolean;
+ propagateToAnnotation?: string;
+ propagateToAnnotationOnEdit?: boolean;
}
export interface Divider extends BaseField {
diff --git a/kompassi-v2-frontend/src/translations/en.tsx b/kompassi-v2-frontend/src/translations/en.tsx
index bc0c4cdc7..82ff91ef1 100644
--- a/kompassi-v2-frontend/src/translations/en.tsx
+++ b/kompassi-v2-frontend/src/translations/en.tsx
@@ -257,6 +257,27 @@ const translations = {
title: "Key field",
helpText: "Key fields are shown in the response list.",
},
+ propagateDimensionOnCreate: {
+ title: "Pass value forward on create",
+ helpText:
+ "When the response is created, set the corresponding dimension of the target object (eg. the program item or the involvement) to this value.",
+ },
+ propagateDimensionOnEdit: {
+ title: "Pass value forward on edit",
+ helpText:
+ "When the response is edited, update the corresponding dimension of the target object.",
+ },
+ propagateToAnnotation: {
+ title: "Pass value forward to annotation",
+ helpText:
+ "Set this annotation of the target object (eg. the program item or the involvement) to the value of this field.",
+ none: "(do not pass forward)",
+ },
+ propagateToAnnotationOnEdit: {
+ title: "Also pass forward on edit",
+ helpText:
+ "Update the annotation also when the response is edited, not just when it is created.",
+ },
choices: {
title: "Choices",
helpText:
@@ -2501,16 +2522,6 @@ const translations = {
isShownInDetail: {
title: "Shown in program guide",
},
- formFields: {
- title: "Program form fields",
- description: (
- <>
- Slugs of program form fields values for this annotation will be
- extracted from. One per line, in order: the first field that has a
- nonempty value of an appropriate type will be used.
- >
- ),
- },
properties: {
title: "Properties",
},
diff --git a/kompassi-v2-frontend/src/translations/fi.tsx b/kompassi-v2-frontend/src/translations/fi.tsx
index 09335735a..2292f91aa 100644
--- a/kompassi-v2-frontend/src/translations/fi.tsx
+++ b/kompassi-v2-frontend/src/translations/fi.tsx
@@ -263,6 +263,27 @@ const translations: Translations = {
title: "Avainkenttä",
helpText: "Avainkentät näytetään vastauslistassa.",
},
+ propagateDimensionOnCreate: {
+ title: "Välitä arvo eteenpäin luotaessa",
+ helpText:
+ "Kun vastaus luodaan, aseta kohdeobjektin (esim. ohjelmanumeron tai osallisuuden) vastaava ulottuvuus tähän arvoon.",
+ },
+ propagateDimensionOnEdit: {
+ title: "Välitä arvo eteenpäin muokattaessa",
+ helpText:
+ "Kun vastausta muokataan, päivitä kohdeobjektin vastaava ulottuvuus.",
+ },
+ propagateToAnnotation: {
+ title: "Välitä arvo lisätietoon",
+ helpText:
+ "Aseta kohdeobjektin (esim. ohjelmanumeron tai osallisuuden) tämä lisätieto tämän kentän arvoon.",
+ none: "(ei välitetä eteenpäin)",
+ },
+ propagateToAnnotationOnEdit: {
+ title: "Välitä myös muokattaessa",
+ helpText:
+ "Päivitä lisätieto myös kun vastausta muokataan, ei vain kun se luodaan.",
+ },
choices: {
title: "Vaihtoehdot",
helpText:
@@ -2439,17 +2460,6 @@ const translations: Translations = {
isInternal: {
title: "Sisäinen",
},
- formFields: {
- title: "Lähdekentät ohjelmalomakkeilla",
- description: (
- <>
- Niiden lomakekenttien tekniset nimet, joista tämän lisätiedon arvoja
- yritetään kaivella. Yksi per rivi, järjestys merkitsee: lisätiedon
- arvon määrittelee ensimmäinen näistä kentistä jolla on
- oikeantyyppinen, epätyhjä arvo.
- >
- ),
- },
properties: {
title: "Ominaisuudet",
},
diff --git a/kompassi-v2-frontend/src/translations/sv.tsx b/kompassi-v2-frontend/src/translations/sv.tsx
index 44e7905d8..003c94ff0 100644
--- a/kompassi-v2-frontend/src/translations/sv.tsx
+++ b/kompassi-v2-frontend/src/translations/sv.tsx
@@ -253,6 +253,27 @@ const translations: Translations = {
title: "Nyckelfält",
helpText: "Nyckelfält visas i svarslistan.",
},
+ propagateDimensionOnCreate: {
+ title: "Skicka värdet vidare vid skapande",
+ helpText:
+ "När svaret skapas, sätt motsvarande dimension hos målobjektet (t.ex. programpunkten eller delaktigheten) till detta värde.",
+ },
+ propagateDimensionOnEdit: {
+ title: "Skicka värdet vidare vid redigering",
+ helpText:
+ "När svaret redigeras, uppdatera motsvarande dimension hos målobjektet.",
+ },
+ propagateToAnnotation: {
+ title: "Skicka värdet vidare till anteckning",
+ helpText:
+ "Sätt denna anteckning hos målobjektet (t.ex. programpunkten eller delaktigheten) till fältets värde.",
+ none: "(skicka inte vidare)",
+ },
+ propagateToAnnotationOnEdit: {
+ title: "Skicka vidare även vid redigering",
+ helpText:
+ "Uppdatera anteckningen även när svaret redigeras, inte bara när det skapas.",
+ },
choices: {
title: "Val",
helpText:
@@ -2443,16 +2464,6 @@ const translations: Translations = {
},
isInternal: { title: "Intern" },
isShownInDetail: { title: "Visas i programguiden" },
- formFields: {
- title: "Programformulärsfält",
- description: (
- <>
- Tekniska namn på programformulärsfält vars värden extraheras för
- denna anteckning. Ett per rad, i ordning: det första fältet med ett
- icke-tomt värde av lämplig typ används.
- >
- ),
- },
properties: { title: "Egenskaper" },
actions: { title: "Funktioner" },
},
diff --git a/kompassi/core/pseudonymization.py b/kompassi/core/pseudonymization.py
index edefd02e6..4aee0370f 100644
--- a/kompassi/core/pseudonymization.py
+++ b/kompassi/core/pseudonymization.py
@@ -315,7 +315,6 @@ def pseudonymize_responses(model: type[models.Model]) -> str:
"programme.Role": "perks",
"programme.SpecialReservation": "code",
"programme.Tag": "v2_dimensions",
- "dimensions.UniverseAnnotation": "form_fields",
"involvement.InvolvementToGroupMapping": "required_dimensions",
"involvement.InvolvementToBadgeMapping": "required_dimensions annotations",
"badges.SurveyToBadgeMapping": "required_dimensions annotations",
diff --git a/kompassi/dimensions/graphql/annotation.py b/kompassi/dimensions/graphql/annotation.py
index a927180b9..08d618c65 100644
--- a/kompassi/dimensions/graphql/annotation.py
+++ b/kompassi/dimensions/graphql/annotation.py
@@ -28,3 +28,4 @@ class Meta:
is_computed = graphene.NonNull(graphene.Boolean)
is_applicable_to_program_items = graphene.NonNull(graphene.Boolean)
is_applicable_to_schedule_items = graphene.NonNull(graphene.Boolean)
+ is_applicable_to_involvements = graphene.NonNull(graphene.Boolean)
diff --git a/kompassi/dimensions/graphql/mutations/put_universe_annotation.py b/kompassi/dimensions/graphql/mutations/put_universe_annotation.py
index 18ce49235..4367173c0 100644
--- a/kompassi/dimensions/graphql/mutations/put_universe_annotation.py
+++ b/kompassi/dimensions/graphql/mutations/put_universe_annotation.py
@@ -1,7 +1,6 @@
from enum import Enum
import graphene
-import pydantic
from django.db import transaction
from django.http import HttpRequest
@@ -13,10 +12,6 @@
from ...tasks import universe_annotation_refresh_values
from ..universe_annotation_limited import LimitedUniverseAnnotationType
-# too strict, users will be confounded
-# ListOfSlugsAdapter = pydantic.TypeAdapter(list[Slug])
-ListOfSlugsAdapter = pydantic.TypeAdapter(list[str])
-
class PutUniverseAnnotationAction(Enum):
SAVE_WITHOUT_REFRESH = "SAVE_WITHOUT_REFRESH"
@@ -31,10 +26,6 @@ class PutUniverseAnnotationInput(graphene.InputObjectType):
universe_slug = graphene.String(required=True)
annotation_slug = graphene.String(required=True)
is_active = graphene.Boolean(required=True)
- form_fields = graphene.InputField(
- graphene.List(graphene.NonNull(graphene.String)),
- required=True,
- )
action = graphene.InputField(PutUniverseAnnotationActionType)
@@ -68,8 +59,6 @@ def mutate(
if annotation.is_internal and not input.is_active:
raise ValueError("Internal annotations cannot be deactivated.")
- form_fields = ListOfSlugsAdapter.validate_python(input.form_fields)
-
if input.action:
action = PutUniverseAnnotationAction(input.action)
else:
@@ -82,10 +71,7 @@ def mutate(
).update_or_create(
universe=universe,
annotation=annotation,
- defaults=dict(
- is_active=input.is_active,
- form_fields=form_fields,
- ),
+ defaults=dict(is_active=input.is_active),
)
match action:
diff --git a/kompassi/dimensions/graphql/universe_annotation_limited.py b/kompassi/dimensions/graphql/universe_annotation_limited.py
index 28297371b..948ca4d6f 100644
--- a/kompassi/dimensions/graphql/universe_annotation_limited.py
+++ b/kompassi/dimensions/graphql/universe_annotation_limited.py
@@ -1,4 +1,3 @@
-from graphene.types.generic import GenericScalar
from graphene_django import DjangoObjectType
from ..models.universe_annotation import UniverseAnnotation
@@ -10,7 +9,4 @@ class Meta:
fields = (
"annotation",
"is_active",
- "form_fields",
)
-
- form_fields = GenericScalar()
diff --git a/kompassi/dimensions/migrations/0020_propagate_annotation_form_fields_to_forms.py b/kompassi/dimensions/migrations/0020_propagate_annotation_form_fields_to_forms.py
new file mode 100644
index 000000000..bc681dde6
--- /dev/null
+++ b/kompassi/dimensions/migrations/0020_propagate_annotation_form_fields_to_forms.py
@@ -0,0 +1,70 @@
+import logging
+
+from django.db import migrations
+
+logger = logging.getLogger(__name__)
+
+# keep in sync with FieldType.can_propagate_to_annotation (frozen here so the migration stays stable)
+PROPAGATABLE_TYPES = {
+ "SingleLineText",
+ "MultiLineText",
+ "MarkdownText",
+ "SingleCheckbox",
+ "NumberField",
+ "DecimalField",
+ "DateField",
+ "TimeField",
+ "DateTimeField",
+}
+
+
+def propagate_form_fields_to_forms(apps, schema_editor):
+ UniverseAnnotation = apps.get_model("dimensions", "UniverseAnnotation")
+ Form = apps.get_model("forms", "Form")
+
+ for universe_annotation in UniverseAnnotation.objects.exclude(form_fields=[]).select_related("annotation"):
+ annotation_slug = universe_annotation.annotation.slug
+ wanted_slugs = universe_annotation.form_fields
+
+ for form in Form.objects.filter(survey__universe_id=universe_annotation.universe_id):
+ changed = False
+ for field_list in (form.fields, form.cached_enriched_fields):
+ claimed = False
+ # first wanted slug that exists in this form wins, as in the old extractor
+ for wanted_slug in wanted_slugs:
+ for field in field_list:
+ if field.get("slug") != wanted_slug:
+ continue
+ if field.get("type") not in PROPAGATABLE_TYPES:
+ logger.warning(
+ "Form %s: field %s of type %s cannot propagate to annotation %s",
+ form.id,
+ wanted_slug,
+ field.get("type"),
+ annotation_slug,
+ )
+ continue
+ if claimed:
+ logger.warning(
+ "Form %s: field %s also fed annotation %s; only the first is kept",
+ form.id,
+ wanted_slug,
+ annotation_slug,
+ )
+ continue
+ field["propagateToAnnotation"] = annotation_slug
+ claimed = changed = True
+ if changed:
+ form.save(update_fields=["fields", "cached_enriched_fields"])
+
+
+class Migration(migrations.Migration):
+ dependencies = [ # noqa: RUF012
+ ("dimensions", "0019_rename_universe_app_name_to_app"),
+ ("forms", "0058_survey_retention_period"),
+ ]
+
+ operations = [ # noqa: RUF012
+ migrations.RunPython(propagate_form_fields_to_forms, migrations.RunPython.noop),
+ migrations.RemoveField(model_name="universeannotation", name="form_fields"),
+ ]
diff --git a/kompassi/dimensions/models/universe_annotation.py b/kompassi/dimensions/models/universe_annotation.py
index 2d48b5c56..ae6dd6bce 100644
--- a/kompassi/dimensions/models/universe_annotation.py
+++ b/kompassi/dimensions/models/universe_annotation.py
@@ -26,10 +26,6 @@ class UniverseAnnotation(models.Model):
)
is_active = models.BooleanField(default=True)
- form_fields = models.JSONField(
- default=list,
- help_text="Slugs of form fields to extract values from.",
- )
class Meta:
unique_together = ("universe", "annotation")
diff --git a/kompassi/forms/models/field.py b/kompassi/forms/models/field.py
index 4cfe1021e..d59a9592d 100644
--- a/kompassi/forms/models/field.py
+++ b/kompassi/forms/models/field.py
@@ -49,6 +49,24 @@ def are_attachments_allowed(self) -> bool:
"""
return self == FieldType.FILE_UPLOAD
+ @property
+ def can_propagate_to_annotation(self) -> bool:
+ """
+ Returns True iff the value of this field is a scalar string, number, date or boolean
+ and can thus be passed forward to an annotation.
+ """
+ return self in (
+ FieldType.SINGLE_LINE_TEXT,
+ FieldType.MULTI_LINE_TEXT,
+ FieldType.MARKDOWN_TEXT,
+ FieldType.SINGLE_CHECKBOX,
+ FieldType.NUMBER_FIELD,
+ FieldType.DECIMAL_FIELD,
+ FieldType.DATE_FIELD,
+ FieldType.TIME_FIELD,
+ FieldType.DATE_TIME_FIELD,
+ )
+
@property
def is_dimension_field(self) -> bool:
"""
@@ -169,6 +187,46 @@ class Field(pydantic.BaseModel, populate_by_name=True):
repr=False,
)
+ propagate_dimension_on_create: bool | None = pydantic.Field(
+ default=None,
+ validation_alias="propagateDimensionOnCreate",
+ serialization_alias="propagateDimensionOnCreate",
+ repr=False,
+ )
+ propagate_dimension_on_edit: bool | None = pydantic.Field(
+ default=None,
+ validation_alias="propagateDimensionOnEdit",
+ serialization_alias="propagateDimensionOnEdit",
+ repr=False,
+ )
+ propagate_to_annotation: str | None = pydantic.Field(
+ default=None,
+ validation_alias="propagateToAnnotation",
+ serialization_alias="propagateToAnnotation",
+ repr=False,
+ )
+ propagate_to_annotation_on_edit: bool | None = pydantic.Field(
+ default=None,
+ validation_alias="propagateToAnnotationOnEdit",
+ serialization_alias="propagateToAnnotationOnEdit",
+ repr=False,
+ )
+
+ @pydantic.model_validator(mode="after")
+ def validate_propagation(self) -> Field:
+ wants_dimension = self.propagate_dimension_on_create or self.propagate_dimension_on_edit
+ if wants_dimension and not self.type.is_dimension_field:
+ raise ValueError(f"Field {self.slug}: only Dimension* fields can propagate dimension values")
+
+ wants_annotation = self.propagate_to_annotation or self.propagate_to_annotation_on_edit
+ if wants_annotation and not self.type.can_propagate_to_annotation:
+ raise ValueError(f"Field {self.slug}: {self.type} fields cannot propagate to an annotation")
+
+ if self.propagate_to_annotation_on_edit and not self.propagate_to_annotation:
+ raise ValueError(f"Field {self.slug}: propagateToAnnotationOnEdit requires propagateToAnnotation")
+
+ return self
+
@classmethod
def from_dimension(
cls,
diff --git a/kompassi/forms/tests.py b/kompassi/forms/tests.py
index 01eddae6e..9eb758fbf 100644
--- a/kompassi/forms/tests.py
+++ b/kompassi/forms/tests.py
@@ -1,6 +1,7 @@
from datetime import datetime, timedelta
from types import SimpleNamespace
+import pydantic
import pytest
import yaml
from django.contrib.auth import get_user_model
@@ -2060,3 +2061,26 @@ def test_grantee_can_manage_dimensions_only_in_the_granted_surveys_universe():
assert survey_a.universe.can_dimensions_be_created_by(_cached_request(grantee.user))
assert not survey_b.universe.can_dimensions_be_created_by(_cached_request(grantee.user))
+
+
+def test_field_propagation_config_is_validated():
+ ok = Field.model_validate(
+ dict(
+ slug="max",
+ type="NumberField",
+ propagateToAnnotation="konsti:maxAttendance",
+ propagateToAnnotationOnEdit=True,
+ )
+ )
+ assert ok.propagate_to_annotation == "konsti:maxAttendance"
+
+ Field.model_validate(dict(slug="d", type="DimensionSingleSelect", dimension="d", propagateDimensionOnCreate=True))
+
+ with pytest.raises(pydantic.ValidationError):
+ Field.model_validate(dict(slug="d", type="DimensionSingleSelect", dimension="d", propagateToAnnotation="x:y"))
+
+ with pytest.raises(pydantic.ValidationError):
+ Field.model_validate(dict(slug="s", type="SingleSelect", propagateDimensionOnCreate=True))
+
+ with pytest.raises(pydantic.ValidationError):
+ Field.model_validate(dict(slug="n", type="NumberField", propagateToAnnotationOnEdit=True))
diff --git a/kompassi/forms/utils/extract_annotations.py b/kompassi/forms/utils/extract_annotations.py
index 7d7bbdef7..63318ccbe 100644
--- a/kompassi/forms/utils/extract_annotations.py
+++ b/kompassi/forms/utils/extract_annotations.py
@@ -1,7 +1,6 @@
import logging
from collections.abc import Iterable
-from kompassi.dimensions.models.annotation import Annotation
from kompassi.dimensions.models.cached_annotations import CachedAnnotations
from kompassi.dimensions.models.universe_annotation import UniverseAnnotation
@@ -13,53 +12,62 @@
def extract_annotations_from_responses(
responses: Iterable[Response],
universe_annotations: Iterable[UniverseAnnotation],
+ *,
+ on_edit: bool = False,
) -> CachedAnnotations:
- schema: list[Annotation] = []
- field_mapping: dict[str, list[str]] = {}
- interesting_fields: set[str] = set()
-
- for ea in universe_annotations:
- schema.append(ea.annotation)
- field_mapping[ea.annotation.slug] = ea.form_fields
- interesting_fields.update(ea.form_fields)
+ """
+ Collects annotation values from fields that declare `propagate_to_annotation`.
+ Annotations not active in the given universe annotations are ignored.
+ When several fields target the same annotation, the first field with a usable value wins.
+ """
+ schema = {ua.annotation.slug: ua.annotation for ua in universe_annotations}
result: CachedAnnotations = {}
for response in responses:
fields = response.form.validated_fields
- values, warnings = response.get_processed_form_data(fields=fields, field_slugs=interesting_fields)
- form_fields_by_slug = {field.slug: field for field in fields}
-
- for annotation in schema:
- for form_field_slug in field_mapping[annotation.slug]:
- form_field = form_fields_by_slug.get(form_field_slug)
- if form_field is None:
- # this form does not have this field
- continue
-
- value = values.get(form_field_slug)
- if value is None:
- # no value for this field in this response
- continue
-
- if field_warnings := warnings.get(form_field_slug):
- logger.info(
- "Cowardly refusing to look for value for annotation in a field with warnings: %s",
- dict(
- response=response.id,
- annotation_slug=annotation.slug,
- form_field_slug=form_field_slug,
- field_warnings=field_warnings,
- ),
- )
- continue
-
- value = annotation.type.conform_value(value)
- if value is None:
- # value did not conform to the data type of the annotation
- continue
-
- result[annotation.slug] = value
- break
+ propagating_fields = [
+ field
+ for field in fields
+ if field.propagate_to_annotation in schema and (not on_edit or field.propagate_to_annotation_on_edit)
+ ]
+ if not propagating_fields:
+ continue
+
+ values, warnings = response.get_processed_form_data(
+ fields=fields,
+ field_slugs={field.slug for field in propagating_fields},
+ )
+
+ response_result: CachedAnnotations = {}
+ for field in propagating_fields:
+ annotation = schema[str(field.propagate_to_annotation)]
+
+ if annotation.slug in response_result:
+ continue
+
+ value = values.get(field.slug)
+ if value is None:
+ continue
+
+ if field_warnings := warnings.get(field.slug):
+ logger.info(
+ "Cowardly refusing to look for value for annotation in a field with warnings: %s",
+ dict(
+ response=response.id,
+ annotation_slug=annotation.slug,
+ form_field_slug=field.slug,
+ field_warnings=field_warnings,
+ ),
+ )
+ continue
+
+ value = annotation.type.conform_value(value)
+ if value is None:
+ continue
+
+ response_result[annotation.slug] = value
+
+ result.update(response_result)
return result
diff --git a/kompassi/program_v2/tests.py b/kompassi/program_v2/tests.py
index 3a98eb094..eb6c42105 100644
--- a/kompassi/program_v2/tests.py
+++ b/kompassi/program_v2/tests.py
@@ -213,6 +213,7 @@ def test_extract_annotations():
title="Max participants",
type="NumberField",
required=False,
+ propagateToAnnotation="konsti:maxAttendance",
),
],
)
@@ -238,12 +239,14 @@ def test_extract_annotations():
title="Max participants",
type="NumberField",
required=False,
+ propagateToAnnotation="konsti:maxAttendance",
),
dict(
slug="is_revolving_door",
title="Is revolving door",
type="SingleCheckbox",
required=False,
+ propagateToAnnotation="ropecon:isRevolvingDoor",
),
],
)
@@ -269,11 +272,6 @@ def test_extract_annotations():
annotation=Annotation.objects.get(slug="konsti:maxAttendance"),
defaults=dict(
is_active=True,
- form_fields=[
- "this_field_does_not_exist",
- "max_participants",
- "also_this_field_does_not_exist",
- ],
),
)
assert not created
@@ -283,11 +281,6 @@ def test_extract_annotations():
annotation=Annotation.objects.get(slug="ropecon:isRevolvingDoor"),
defaults=dict(
is_active=True,
- form_fields=[
- "this_field_does_not_exist",
- "is_revolving_door",
- "also_this_field_does_not_exist",
- ],
),
)
assert not created
From ed2af9171bafd57555836aa61466bf6dc8e383d4 Mon Sep 17 00:00:00 2001
From: Luka Pajukanta
Date: Fri, 2 Oct 2026 16:32:11 +0300
Subject: [PATCH 2/7] Address review: normalize on-edit flag, honor is_active
and on_edit in extraction
Co-Authored-By: Claude Sonnet 5.5
---
.../src/components/forms/editFieldForm.ts | 8 ++++++++
kompassi/forms/utils/extract_annotations.py | 2 +-
kompassi/program_v2/workflows/program_host_invitation.py | 1 +
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/kompassi-v2-frontend/src/components/forms/editFieldForm.ts b/kompassi-v2-frontend/src/components/forms/editFieldForm.ts
index 7bdbc12b9..34d426ae3 100644
--- a/kompassi-v2-frontend/src/components/forms/editFieldForm.ts
+++ b/kompassi-v2-frontend/src/components/forms/editFieldForm.ts
@@ -247,6 +247,14 @@ export function formDataToField(
encryptTo: ((formData.get("encryptTo") as string) || "").split("\n"),
};
+ // the backend rejects "on edit" without an annotation to pass forward to
+ if (
+ "propagateToAnnotationOnEdit" in values &&
+ !values.propagateToAnnotation
+ ) {
+ values.propagateToAnnotationOnEdit = false;
+ }
+
switch (initialValues.type) {
case "SingleSelect":
case "MultiSelect":
diff --git a/kompassi/forms/utils/extract_annotations.py b/kompassi/forms/utils/extract_annotations.py
index 63318ccbe..2829a9c8d 100644
--- a/kompassi/forms/utils/extract_annotations.py
+++ b/kompassi/forms/utils/extract_annotations.py
@@ -20,7 +20,7 @@ def extract_annotations_from_responses(
Annotations not active in the given universe annotations are ignored.
When several fields target the same annotation, the first field with a usable value wins.
"""
- schema = {ua.annotation.slug: ua.annotation for ua in universe_annotations}
+ schema = {ua.annotation.slug: ua.annotation for ua in universe_annotations if ua.is_active}
result: CachedAnnotations = {}
diff --git a/kompassi/program_v2/workflows/program_host_invitation.py b/kompassi/program_v2/workflows/program_host_invitation.py
index 19869000f..27562820c 100644
--- a/kompassi/program_v2/workflows/program_host_invitation.py
+++ b/kompassi/program_v2/workflows/program_host_invitation.py
@@ -68,6 +68,7 @@ def handle_new_response_phase2(
extract_annotations_from_responses(
program.responses.all(),
program.universe.active_universe_annotations.all(),
+ on_edit=old_version is not None,
)
)
program.refresh_dependents()
From d1c4e88696ad4fe61d2a77161a5676cc11198738 Mon Sep 17 00:00:00 2001
From: Luka Pajukanta
Date: Fri, 2 Oct 2026 16:58:55 +0300
Subject: [PATCH 3/7] Address review: keep edit propagation in migration,
filter annotations by universe
Co-Authored-By: Claude Sonnet 5.5
---
...opagate_annotation_form_fields_to_forms.py | 2 +
kompassi/forms/tests.py | 39 +++++++++++++++++++
kompassi/forms/utils/extract_annotations.py | 26 ++++++++++++-
3 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/kompassi/dimensions/migrations/0020_propagate_annotation_form_fields_to_forms.py b/kompassi/dimensions/migrations/0020_propagate_annotation_form_fields_to_forms.py
index bc681dde6..e6d4ab368 100644
--- a/kompassi/dimensions/migrations/0020_propagate_annotation_form_fields_to_forms.py
+++ b/kompassi/dimensions/migrations/0020_propagate_annotation_form_fields_to_forms.py
@@ -53,6 +53,8 @@ def propagate_form_fields_to_forms(apps, schema_editor):
)
continue
field["propagateToAnnotation"] = annotation_slug
+ # the old extractor also ran after edits
+ field["propagateToAnnotationOnEdit"] = True
claimed = changed = True
if changed:
form.save(update_fields=["fields", "cached_enriched_fields"])
diff --git a/kompassi/forms/tests.py b/kompassi/forms/tests.py
index 9eb758fbf..cafb2e840 100644
--- a/kompassi/forms/tests.py
+++ b/kompassi/forms/tests.py
@@ -2084,3 +2084,42 @@ def test_field_propagation_config_is_validated():
with pytest.raises(pydantic.ValidationError):
Field.model_validate(dict(slug="n", type="NumberField", propagateToAnnotationOnEdit=True))
+
+
+@pytest.mark.django_db
+def test_extract_annotations_ignores_annotations_not_applicable_to_the_universe():
+ from kompassi.dimensions.models.annotation import Annotation
+ from kompassi.dimensions.models.enums import AnnotationAppliesTo, AnnotationDataType
+ from kompassi.dimensions.models.universe_annotation import UniverseAnnotation
+ from kompassi.program_v2.models.meta import ProgramV2EventMeta
+
+ from .utils.extract_annotations import extract_annotations_from_responses
+
+ meta, _ = ProgramV2EventMeta.get_or_create_dummy()
+ event = meta.event
+
+ survey = Survey(event=event, slug="offer", app=DimensionApp.PROGRAM, purpose=SurveyPurpose.DEFAULT)
+ survey.with_mandatory_fields().save()
+ form = Form.objects.create(
+ event=event,
+ survey=survey,
+ language="en",
+ fields=[
+ dict(slug="a", type="SingleLineText", propagateToAnnotation="test:programNote"),
+ dict(slug="b", type="SingleLineText", propagateToAnnotation="test:hostNote"),
+ ],
+ )
+ response = Response.objects.create(form=form, form_data={"a": "x", "b": "y"})
+
+ universe_annotations = [
+ UniverseAnnotation.objects.create(
+ universe=meta.universe,
+ annotation=Annotation.objects.create(slug=slug, type=AnnotationDataType.STRING, applies_to=applies_to),
+ )
+ for slug, applies_to in (
+ ("test:programNote", AnnotationAppliesTo.PROGRAM_ITEM),
+ ("test:hostNote", AnnotationAppliesTo.INVOLVEMENT),
+ )
+ ]
+
+ assert extract_annotations_from_responses([response], universe_annotations) == {"test:programNote": "x"}
diff --git a/kompassi/forms/utils/extract_annotations.py b/kompassi/forms/utils/extract_annotations.py
index 2829a9c8d..881fe6206 100644
--- a/kompassi/forms/utils/extract_annotations.py
+++ b/kompassi/forms/utils/extract_annotations.py
@@ -1,7 +1,10 @@
import logging
from collections.abc import Iterable
+from kompassi.dimensions.models.annotation import Annotation
from kompassi.dimensions.models.cached_annotations import CachedAnnotations
+from kompassi.dimensions.models.enums import DimensionApp
+from kompassi.dimensions.models.universe import Universe
from kompassi.dimensions.models.universe_annotation import UniverseAnnotation
from ..models.response import Response
@@ -17,10 +20,19 @@ def extract_annotations_from_responses(
) -> CachedAnnotations:
"""
Collects annotation values from fields that declare `propagate_to_annotation`.
- Annotations not active in the given universe annotations are ignored.
+ Annotations not active in the given universe annotations are ignored, as are annotations
+ that do not apply to the kind of object the universe holds (every annotation is
+ activated in every universe, so eg. an involvement-only annotation could otherwise
+ end up on a program item).
When several fields target the same annotation, the first field with a usable value wins.
"""
- schema = {ua.annotation.slug: ua.annotation for ua in universe_annotations if ua.is_active}
+ active = [ua for ua in universe_annotations if ua.is_active]
+ universe_apps = dict(Universe.objects.filter(id__in={ua.universe_id for ua in active}).values_list("id", "app"))
+ schema = {
+ ua.annotation.slug: ua.annotation
+ for ua in active
+ if _is_applicable_in_universe(ua.annotation, universe_apps[ua.universe_id])
+ }
result: CachedAnnotations = {}
@@ -71,3 +83,13 @@ def extract_annotations_from_responses(
result.update(response_result)
return result
+
+
+def _is_applicable_in_universe(annotation: Annotation, app: DimensionApp) -> bool:
+ match app:
+ case DimensionApp.PROGRAM:
+ return annotation.is_applicable_to_program_items
+ case DimensionApp.INVOLVEMENT:
+ return annotation.is_applicable_to_involvements
+ case _:
+ return True
From 19fcaeacedcf7209392284a28b73d830bb0fbeff Mon Sep 17 00:00:00 2001
From: Luka Pajukanta
Date: Fri, 2 Oct 2026 17:18:15 +0300
Subject: [PATCH 4/7] Address review: legacy-compatible annotation context for
INVITE forms
Co-Authored-By: Claude Sonnet 5.5
---
.../[surveySlug]/edit/[language]/fields/page.tsx | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-forms/[surveySlug]/edit/[language]/fields/page.tsx b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-forms/[surveySlug]/edit/[language]/fields/page.tsx
index e030c1a4a..ad22e1a3f 100644
--- a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-forms/[surveySlug]/edit/[language]/fields/page.tsx
+++ b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/program-forms/[surveySlug]/edit/[language]/fields/page.tsx
@@ -134,7 +134,11 @@ export default async function EditProgramFormFieldsPage(props: Props) {
initialFields={form.fields}
dimensions={dimensions}
annotations={annotations}
- formContext={survey.purpose === "DEFAULT" ? "program" : "involvement"}
+ formContext={
+ survey.purpose === "DEFAULT" || survey.purpose === "INVITE"
+ ? "program"
+ : "involvement"
+ }
messages={{
FormEditor: translations.FormEditor,
SchemaForm: translations.SchemaForm,
From c1b22db95caec11036a80bc06262e9219d76d671 Mon Sep 17 00:00:00 2001
From: Luka Pajukanta
Date: Fri, 2 Oct 2026 20:49:55 +0300
Subject: [PATCH 5/7] Use dimensio for dimension in Finnish translations
Co-Authored-By: Claude Sonnet 5.5
---
kompassi-v2-frontend/src/translations/fi.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kompassi-v2-frontend/src/translations/fi.tsx b/kompassi-v2-frontend/src/translations/fi.tsx
index 2292f91aa..08af7e8dc 100644
--- a/kompassi-v2-frontend/src/translations/fi.tsx
+++ b/kompassi-v2-frontend/src/translations/fi.tsx
@@ -266,12 +266,12 @@ const translations: Translations = {
propagateDimensionOnCreate: {
title: "Välitä arvo eteenpäin luotaessa",
helpText:
- "Kun vastaus luodaan, aseta kohdeobjektin (esim. ohjelmanumeron tai osallisuuden) vastaava ulottuvuus tähän arvoon.",
+ "Kun vastaus luodaan, aseta kohdeobjektin (esim. ohjelmanumeron tai osallisuuden) vastaava dimensio tähän arvoon.",
},
propagateDimensionOnEdit: {
title: "Välitä arvo eteenpäin muokattaessa",
helpText:
- "Kun vastausta muokataan, päivitä kohdeobjektin vastaava ulottuvuus.",
+ "Kun vastausta muokataan, päivitä kohdeobjektin vastaava dimensio.",
},
propagateToAnnotation: {
title: "Välitä arvo lisätietoon",
From a5b6b0961df899f23a7dfcbf544f12cb92fe972b Mon Sep 17 00:00:00 2001
From: Luka Pajukanta
Date: Fri, 2 Oct 2026 20:54:31 +0300
Subject: [PATCH 6/7] Specialize propagation help texts by form context
Co-Authored-By: Claude Sonnet 5.5
---
.../src/components/forms/editFieldForm.ts | 8 ++++---
kompassi-v2-frontend/src/translations/en.tsx | 24 ++++++++++++++-----
kompassi-v2-frontend/src/translations/fi.tsx | 22 ++++++++++++-----
kompassi-v2-frontend/src/translations/sv.tsx | 23 +++++++++++++-----
4 files changed, 56 insertions(+), 21 deletions(-)
diff --git a/kompassi-v2-frontend/src/components/forms/editFieldForm.ts b/kompassi-v2-frontend/src/components/forms/editFieldForm.ts
index 34d426ae3..bf00c1978 100644
--- a/kompassi-v2-frontend/src/components/forms/editFieldForm.ts
+++ b/kompassi-v2-frontend/src/components/forms/editFieldForm.ts
@@ -86,13 +86,15 @@ export function getFieldEditorFields(
type: "SingleCheckbox",
slug: "propagateDimensionOnCreate",
required: false,
- ...t.propagateDimensionOnCreate,
+ title: t.propagateDimensionOnCreate.title,
+ helpText: t.propagateDimensionOnCreate.helpText[formContext],
},
{
type: "SingleCheckbox",
slug: "propagateDimensionOnEdit",
required: false,
- ...t.propagateDimensionOnEdit,
+ title: t.propagateDimensionOnEdit.title,
+ helpText: t.propagateDimensionOnEdit.helpText[formContext],
},
);
} else if (annotationPropagatingTypes.includes(fieldType)) {
@@ -112,7 +114,7 @@ export function getFieldEditorFields(
...applicable.map(({ slug, title }) => ({ slug, title })),
],
title: t.propagateToAnnotation.title,
- helpText: t.propagateToAnnotation.helpText,
+ helpText: t.propagateToAnnotation.helpText[formContext],
},
{
type: "SingleCheckbox",
diff --git a/kompassi-v2-frontend/src/translations/en.tsx b/kompassi-v2-frontend/src/translations/en.tsx
index 82ff91ef1..68ef95872 100644
--- a/kompassi-v2-frontend/src/translations/en.tsx
+++ b/kompassi-v2-frontend/src/translations/en.tsx
@@ -259,18 +259,30 @@ const translations = {
},
propagateDimensionOnCreate: {
title: "Pass value forward on create",
- helpText:
- "When the response is created, set the corresponding dimension of the target object (eg. the program item or the involvement) to this value.",
+ helpText: {
+ program:
+ "When the response is created, set the corresponding dimension of the program item to this value.",
+ involvement:
+ "When the response is created, set the corresponding dimension of the involvement to this value.",
+ },
},
propagateDimensionOnEdit: {
title: "Pass value forward on edit",
- helpText:
- "When the response is edited, update the corresponding dimension of the target object.",
+ helpText: {
+ program:
+ "When the response is edited, update the corresponding dimension of the program item.",
+ involvement:
+ "When the response is edited, update the corresponding dimension of the involvement.",
+ },
},
propagateToAnnotation: {
title: "Pass value forward to annotation",
- helpText:
- "Set this annotation of the target object (eg. the program item or the involvement) to the value of this field.",
+ helpText: {
+ program:
+ "Set this annotation of the program item to the value of this field.",
+ involvement:
+ "Set this annotation of the involvement to the value of this field.",
+ },
none: "(do not pass forward)",
},
propagateToAnnotationOnEdit: {
diff --git a/kompassi-v2-frontend/src/translations/fi.tsx b/kompassi-v2-frontend/src/translations/fi.tsx
index 08af7e8dc..89afb0f50 100644
--- a/kompassi-v2-frontend/src/translations/fi.tsx
+++ b/kompassi-v2-frontend/src/translations/fi.tsx
@@ -265,18 +265,28 @@ const translations: Translations = {
},
propagateDimensionOnCreate: {
title: "Välitä arvo eteenpäin luotaessa",
- helpText:
- "Kun vastaus luodaan, aseta kohdeobjektin (esim. ohjelmanumeron tai osallisuuden) vastaava dimensio tähän arvoon.",
+ helpText: {
+ program:
+ "Kun vastaus luodaan, aseta ohjelmanumeron vastaava dimensio tähän arvoon.",
+ involvement:
+ "Kun vastaus luodaan, aseta osallisuuden vastaava dimensio tähän arvoon.",
+ },
},
propagateDimensionOnEdit: {
title: "Välitä arvo eteenpäin muokattaessa",
- helpText:
- "Kun vastausta muokataan, päivitä kohdeobjektin vastaava dimensio.",
+ helpText: {
+ program:
+ "Kun vastausta muokataan, päivitä ohjelmanumeron vastaava dimensio.",
+ involvement:
+ "Kun vastausta muokataan, päivitä osallisuuden vastaava dimensio.",
+ },
},
propagateToAnnotation: {
title: "Välitä arvo lisätietoon",
- helpText:
- "Aseta kohdeobjektin (esim. ohjelmanumeron tai osallisuuden) tämä lisätieto tämän kentän arvoon.",
+ helpText: {
+ program: "Aseta ohjelmanumeron tämä lisätieto tämän kentän arvoon.",
+ involvement: "Aseta osallisuuden tämä lisätieto tämän kentän arvoon.",
+ },
none: "(ei välitetä eteenpäin)",
},
propagateToAnnotationOnEdit: {
diff --git a/kompassi-v2-frontend/src/translations/sv.tsx b/kompassi-v2-frontend/src/translations/sv.tsx
index 003c94ff0..4b89d620a 100644
--- a/kompassi-v2-frontend/src/translations/sv.tsx
+++ b/kompassi-v2-frontend/src/translations/sv.tsx
@@ -255,18 +255,29 @@ const translations: Translations = {
},
propagateDimensionOnCreate: {
title: "Skicka värdet vidare vid skapande",
- helpText:
- "När svaret skapas, sätt motsvarande dimension hos målobjektet (t.ex. programpunkten eller delaktigheten) till detta värde.",
+ helpText: {
+ program:
+ "När svaret skapas, sätt programpunktens motsvarande dimension till detta värde.",
+ involvement:
+ "När svaret skapas, sätt delaktighetens motsvarande dimension till detta värde.",
+ },
},
propagateDimensionOnEdit: {
title: "Skicka värdet vidare vid redigering",
- helpText:
- "När svaret redigeras, uppdatera motsvarande dimension hos målobjektet.",
+ helpText: {
+ program:
+ "När svaret redigeras, uppdatera programpunktens motsvarande dimension.",
+ involvement:
+ "När svaret redigeras, uppdatera delaktighetens motsvarande dimension.",
+ },
},
propagateToAnnotation: {
title: "Skicka värdet vidare till anteckning",
- helpText:
- "Sätt denna anteckning hos målobjektet (t.ex. programpunkten eller delaktigheten) till fältets värde.",
+ helpText: {
+ program: "Sätt programpunktens denna anteckning till fältets värde.",
+ involvement:
+ "Sätt delaktighetens denna anteckning till fältets värde.",
+ },
none: "(skicka inte vidare)",
},
propagateToAnnotationOnEdit: {
From f58c3f8669e06253456c71b6450edbaece21d1c4 Mon Sep 17 00:00:00 2001
From: Luka Pajukanta
Date: Fri, 2 Oct 2026 20:57:17 +0300
Subject: [PATCH 7/7] chore: translation fix
---
kompassi-v2-frontend/src/translations/fi.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kompassi-v2-frontend/src/translations/fi.tsx b/kompassi-v2-frontend/src/translations/fi.tsx
index 89afb0f50..e44d187dc 100644
--- a/kompassi-v2-frontend/src/translations/fi.tsx
+++ b/kompassi-v2-frontend/src/translations/fi.tsx
@@ -306,7 +306,7 @@ const translations: Translations = {
},
dimension: {
title: "Dimensio",
- helpText: "Mistä dimensiosta tämä kenttä saa vastauksensa?",
+ helpText: "Mistä dimensiosta tämä kenttä saa vastausvaihtoehtonsa?",
},
maxLength: {
title: "Enimmäispituus",