From 969307f50e5c3361ea0e21a8c8f550085684de6b Mon Sep 17 00:00:00 2001 From: Santtu Pajukanta Date: Sat, 27 Jan 2024 16:30:47 +0200 Subject: [PATCH 1/8] feat(forms): create dimension --- .../mutations/create_survey_dimension.py | 38 ++++ backend/forms/models/dimension.py | 24 ++- backend/forms/tests.py | 42 ++++- backend/graphql_api/schema.py | 4 +- frontend/package-lock.json | 177 +++++++++++++++++- frontend/package.json | 1 + frontend/src/__generated__/gql.ts | 24 ++- frontend/src/__generated__/graphql.ts | 43 ++++- frontend/src/app/[locale]/default.tsx | 3 + .../dimensions/@modal/(.)new/page.tsx | 34 ++++ .../dimensions/@modal/default.tsx | 3 + .../dimensions/EditDimensionForm.tsx | 53 ++++++ .../surveys/[surveySlug]/dimensions/TODO.md | 21 +++ .../[surveySlug]/dimensions/actions.ts | 108 +++++++++++ .../[surveySlug]/dimensions/layout.tsx | 13 ++ .../[surveySlug]/dimensions/new/page.tsx | 119 ++++++++++++ .../surveys/[surveySlug]/dimensions/page.tsx | 162 ++++++++++++---- frontend/src/app/[locale]/layout.tsx | 7 +- .../src/components/InterceptingRouteModal.tsx | 49 +++++ .../components/SchemaForm/SchemaFormField.tsx | 7 +- frontend/src/components/SchemaForm/index.tsx | 5 +- frontend/src/components/helpers/Heading.tsx | 17 ++ frontend/src/translations/en.tsx | 39 ++++ frontend/src/translations/fi.tsx | 37 ++++ 24 files changed, 966 insertions(+), 64 deletions(-) create mode 100644 backend/forms/graphql/mutations/create_survey_dimension.py create mode 100644 frontend/src/app/[locale]/default.tsx create mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/(.)new/page.tsx create mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/default.tsx create mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/EditDimensionForm.tsx create mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/TODO.md create mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts create mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx create mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/new/page.tsx create mode 100644 frontend/src/components/InterceptingRouteModal.tsx create mode 100644 frontend/src/components/helpers/Heading.tsx diff --git a/backend/forms/graphql/mutations/create_survey_dimension.py b/backend/forms/graphql/mutations/create_survey_dimension.py new file mode 100644 index 000000000..602dc3517 --- /dev/null +++ b/backend/forms/graphql/mutations/create_survey_dimension.py @@ -0,0 +1,38 @@ +import graphene +from graphene.types.generic import GenericScalar + +from access.cbac import graphql_check_access + +from ...models.dimension import DimensionDTO +from ...models.survey import Survey +from ..dimension import SurveyDimensionType + + +class CreateSurveyDimensionInput(graphene.InputObjectType): + event_slug = graphene.String(required=True) + survey_slug = graphene.String(required=True) + form_data = GenericScalar(required=True) + + +class CreateSurveyDimension(graphene.Mutation): + class Arguments: + input = CreateSurveyDimensionInput(required=True) + + dimension = graphene.Field(SurveyDimensionType) + + @staticmethod + def mutate( + root, + info, + input: CreateSurveyDimensionInput, + ): + survey = Survey.objects.get(event__slug=input.event_slug, slug=input.survey_slug) + + # TODO bastardization of graphql_check_access, rethink + graphql_check_access(survey, info, "dimensions", "mutation") + + form_data: dict[str, str] = input.form_data # type: ignore + print(form_data) + dimension = DimensionDTO.from_form_data(form_data).save(survey) + + return CreateSurveyDimension(dimension=dimension) # type: ignore diff --git a/backend/forms/models/dimension.py b/backend/forms/models/dimension.py index 30c61c73c..a5f32459e 100644 --- a/backend/forms/models/dimension.py +++ b/backend/forms/models/dimension.py @@ -122,11 +122,13 @@ class DimensionDTO(pydantic.BaseModel): Helper to load dimensions from YAML. """ + model_config = pydantic.ConfigDict(populate_by_name=True) + slug: str title: dict[str, str] - choices: list[DimensionValueDTO] - is_key_dimension: bool = False - is_multi_value: bool = False + choices: list[DimensionValueDTO] = pydantic.Field(default_factory=list) + is_key_dimension: bool = pydantic.Field(default=False, alias="isKeyDimension") + is_multi_value: bool = pydantic.Field(default=False, alias="isMultiValue") def save(self, survey: Survey, order: int = 0): # TODO change to get_or_create when form editor is implemented @@ -151,6 +153,8 @@ def save(self, survey: Survey, order: int = 0): for choice in self.choices: choice.save(dimension) + return dimension + @classmethod def save_many(cls, survey: Survey, dimensions: list[DimensionDTO]): order = 0 @@ -158,6 +162,20 @@ def save_many(cls, survey: Survey, dimensions: list[DimensionDTO]): order += 10 dimension.save(survey, order) + @classmethod + def from_form_data(cls, form_data: dict[str, str]) -> DimensionDTO: + """ + Used by dimension editor to create and edit dimensions. + The localized title field is presented as field per language. + """ + title = {key.removeprefix("title."): value for key, value in form_data.items() if key.startswith("title.")} + data: dict[str, str | dict[str, str]] = { + key: value for key, value in form_data.items() if not key.startswith("title.") + } + data["title"] = title + + return cls.model_validate(data) + class ResponseDimensionValue(models.Model): response = models.ForeignKey( diff --git a/backend/forms/tests.py b/backend/forms/tests.py index 1d2295f25..1f2042486 100644 --- a/backend/forms/tests.py +++ b/backend/forms/tests.py @@ -7,6 +7,7 @@ from core.models import Event from .excel_export import get_header_cells, get_response_cells +from .graphql.mutations.create_survey_dimension import CreateSurveyDimension from .graphql.mutations.update_response_dimensions import UpdateResponseDimensions from .models.dimension import Dimension, DimensionValue from .models.field import Choice, Field, FieldType @@ -17,6 +18,10 @@ from .utils.s3_presign import BUCKET_NAME, S3_ENDPOINT_URL from .utils.summarize_responses import MatrixFieldSummary, SelectFieldSummary, TextFieldSummary, summarize_responses +# pass this as the info param to mutations to appease the graphql_check_access decorator +# (remember to also mock.patch graphql_check_access) +MOCK_INFO = SimpleNamespace(context=SimpleNamespace(user=None)) + def test_process_form_data(): fields = [ @@ -668,7 +673,7 @@ def test_lift_and_set_dimensions(_patched_graphql_check_access): # as a value type to fail, so we have to use SimpleNamespace instead UpdateResponseDimensions.mutate( None, - SimpleNamespace(context=SimpleNamespace(user=None)), + MOCK_INFO, SimpleNamespace( event_slug=event.slug, survey_slug=survey.slug, @@ -689,3 +694,38 @@ def test_lift_and_set_dimensions(_patched_graphql_check_access): "test-dimension": ["test-dimension-value-2"], "test-dimension2": ["test-dimension2-value-1", "test-dimension2-value-2"], } + + +@pytest.mark.django_db +@mock.patch("forms.graphql.mutations.create_survey_dimension.graphql_check_access", autospec=True) +def test_create_survey_dimension(_patched_graphql_check_access): + form_data = { + "slug": "test-dimension", + "title.en": "Test dimension", + "title.sv": "Testdimension", + "isKeyDimension": "on", + } + + event, _created = Event.get_or_create_dummy() + + survey = Survey.objects.create( + event=event, + slug="test-survey", + ) + + CreateSurveyDimension.mutate( + None, + MOCK_INFO, + SimpleNamespace( + event_slug=event.slug, + survey_slug=survey.slug, + form_data=form_data, + ), # type: ignore + ) + + dimension = Dimension.objects.get(survey=survey, slug="test-dimension") + + assert dimension.slug == "test-dimension" + assert dimension.title == {"en": "Test dimension", "sv": "Testdimension"} + assert dimension.is_key_dimension is True + assert dimension.is_multi_value is False diff --git a/backend/graphql_api/schema.py b/backend/graphql_api/schema.py index 13eadd46c..fc396cd76 100644 --- a/backend/graphql_api/schema.py +++ b/backend/graphql_api/schema.py @@ -6,6 +6,7 @@ from core.graphql.event import FullEventType from core.graphql.profile import ProfileType from core.models import Event, Person +from forms.graphql.mutations.create_survey_dimension import CreateSurveyDimension from forms.graphql.mutations.create_survey_response import CreateSurveyResponse from forms.graphql.mutations.init_file_upload import InitFileUpload from forms.graphql.mutations.update_response_dimensions import UpdateResponseDimensions @@ -59,9 +60,10 @@ def resolve_profile(root, info): class Mutation(graphene.ObjectType): + create_survey_dimension = CreateSurveyDimension.Field() create_survey_response = CreateSurveyResponse.Field() - update_response_dimensions = UpdateResponseDimensions.Field() init_file_upload = InitFileUpload.Field() + update_response_dimensions = UpdateResponseDimensions.Field() schema = graphene.Schema(query=Query, mutation=Mutation) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index d185cea3b..add0bc967 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -17,6 +17,7 @@ "next-auth": "^4.24.5", "next-intl": "^3.0.0-rc.4", "react": "^18.2.0", + "react-bootstrap": "^2.10.0", "react-dom": "^18.2.0" }, "devDependencies": { @@ -3013,18 +3014,70 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, + "node_modules/@react-aria/ssr": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.1.tgz", + "integrity": "sha512-NqzkLFP8ZVI4GSorS0AYljC13QW2sc8bDqJOkBvkAt3M8gbcAXJWVRGtZBCRscki9RZF+rNlnPdg0G0jYkhJcg==", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, "node_modules/@repeaterjs/repeater": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.5.tgz", "integrity": "sha512-l3YHBLAol6d/IKnB9LhpD0cEZWAoe3eFKUyTYWmFmCO2Q/WOckxLQAUyMZWwZV2M/m3+4vgRoaolFqaII82/TA==", "dev": true }, + "node_modules/@restart/hooks": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.15.tgz", + "integrity": "sha512-cZFXYTxbpzYcieq/mBwSyXgqnGMHoBVh3J7MU0CCoIB4NRZxV9/TuwTBAaLMqpNhC3zTPMCgkQ5Ey07L02Xmcw==", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@restart/ui": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", + "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@popperjs/core": "^2.11.6", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.4.9", + "@types/warning": "^3.0.0", + "dequal": "^2.0.3", + "dom-helpers": "^5.2.0", + "uncontrollable": "^8.0.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + } + }, + "node_modules/@restart/ui/node_modules/uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "peerDependencies": { + "react": ">=16.14.0" + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.1.tgz", @@ -3093,14 +3146,12 @@ "node_modules/@types/prop-types": { "version": "15.7.11", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", - "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", - "devOptional": true + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { "version": "18.2.47", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.47.tgz", "integrity": "sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ==", - "devOptional": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3116,11 +3167,23 @@ "@types/react": "*" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/scheduler": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "devOptional": true + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "node_modules/@types/warning": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" }, "node_modules/@types/ws": { "version": "8.5.10", @@ -4110,6 +4173,11 @@ "node": ">= 6" } }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -4403,8 +4471,7 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -4528,7 +4595,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, "engines": { "node": ">=6" } @@ -4587,6 +4653,15 @@ "node": ">=6.0.0" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", @@ -6077,7 +6152,6 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, "dependencies": { "loose-envify": "^1.0.0" } @@ -7768,6 +7842,18 @@ "react-is": "^16.13.1" } }, + "node_modules/prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "dependencies": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, "node_modules/punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -7823,6 +7909,35 @@ "node": ">=0.10.0" } }, + "node_modules/react-bootstrap": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.0.tgz", + "integrity": "sha512-87gRP69VAfeU2yKgp8RI3HvzhPNrnYIV2QNranYXataz3ef+k7OhvKGGdxQLQfUsQ2RTmlY66tn4pdFrZ94hNg==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.6.6", + "@types/react-transition-group": "^4.4.6", + "classnames": "^2.3.2", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.8.1", + "prop-types-extra": "^1.1.0", + "react-transition-group": "^4.4.5", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "@types/react": ">=16.14.8", + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -7840,6 +7955,26 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -8919,6 +9054,20 @@ "node": ">=0.10.0" } }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -9062,6 +9211,14 @@ "node": ">=12" } }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 6cfaf1301..4c869d154 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -23,6 +23,7 @@ "next-auth": "^4.24.5", "next-intl": "^3.0.0-rc.4", "react": "^18.2.0", + "react-bootstrap": "^2.10.0", "react-dom": "^18.2.0" }, "license": "MIT", diff --git a/frontend/src/__generated__/gql.ts b/frontend/src/__generated__/gql.ts index 3b778980a..fbc4ad620 100644 --- a/frontend/src/__generated__/gql.ts +++ b/frontend/src/__generated__/gql.ts @@ -17,7 +17,11 @@ const documents = { "\n query NewProgramFormSelectionQuery($eventSlug: String!, $locale: String) {\n event(slug: $eventSlug) {\n name\n slug\n\n program {\n skipOfferFormSelection\n\n offerForms {\n slug\n shortDescription(lang: $locale)\n form(lang: $locale) {\n title\n slug\n }\n }\n }\n }\n }\n": types.NewProgramFormSelectionQueryDocument, "\n mutation CreateSurveyResponse($input: CreateSurveyResponseInput!) {\n createSurveyResponse(input: $input) {\n response {\n id\n }\n }\n }\n": types.CreateSurveyResponseDocument, "\n mutation InitFileUploadMutation($input: InitFileUploadInput!) {\n initFileUpload(input: $input) {\n uploadUrl\n fileUrl\n }\n }\n": types.InitFileUploadMutationDocument, - "\n query DimensionsList(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n dimensions {\n slug\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n values {\n slug\n color\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n }\n }\n }\n }\n }\n }\n": types.DimensionsListDocument, + "\n mutation CreateSurveyDimension($input: CreateSurveyDimensionInput!) {\n createSurveyDimension(input: $input) {\n dimension {\n slug\n }\n }\n }\n": types.CreateSurveyDimensionDocument, + "\n query NewDimensionPage(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n }\n }\n }\n }\n": types.NewDimensionPageDocument, + "\n fragment ValueFields on SurveyDimensionValueType {\n slug\n color\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n }\n": types.ValueFieldsFragmentDoc, + "\n fragment DimensionRowGroup on SurveyDimensionType {\n slug\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n values {\n ...ValueFields\n }\n }\n": types.DimensionRowGroupFragmentDoc, + "\n query DimensionsList(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n dimensions {\n ...DimensionRowGroup\n }\n }\n }\n }\n }\n": types.DimensionsListDocument, "\n query SurveyPageQuery(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n\n forms {\n survey(slug: $surveySlug) {\n loginRequired\n anonymity\n maxResponsesPerUser\n countResponsesByCurrentUser\n\n form(lang: $locale) {\n title\n description\n fields\n layout\n }\n }\n }\n }\n }\n": types.SurveyPageQueryDocument, "\n mutation UpdateResponseDimensions($input: UpdateResponseDimensionsInput!) {\n updateResponseDimensions(input: $input) {\n response {\n id\n }\n }\n }\n": types.UpdateResponseDimensionsDocument, "\n query SurveyResponseDetail(\n $eventSlug: String!\n $surveySlug: String!\n $responseId: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n slug\n anonymity\n dimensions {\n title(lang: $locale)\n slug\n isMultiValue\n values {\n title(lang: $locale)\n slug\n color\n }\n }\n response(id: $responseId) {\n id\n createdAt\n createdBy {\n displayName\n email\n }\n language\n values\n form {\n fields\n layout\n }\n cachedDimensions\n }\n }\n }\n }\n }\n": types.SurveyResponseDetailDocument, @@ -65,7 +69,23 @@ export function graphql(source: "\n mutation InitFileUploadMutation($input: Ini /** * 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 DimensionsList(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n dimensions {\n slug\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n values {\n slug\n color\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query DimensionsList(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n dimensions {\n slug\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n values {\n slug\n color\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n }\n }\n }\n }\n }\n }\n"]; +export function graphql(source: "\n mutation CreateSurveyDimension($input: CreateSurveyDimensionInput!) {\n createSurveyDimension(input: $input) {\n dimension {\n slug\n }\n }\n }\n"): (typeof documents)["\n mutation CreateSurveyDimension($input: CreateSurveyDimensionInput!) {\n createSurveyDimension(input: $input) {\n dimension {\n slug\n }\n }\n }\n"]; +/** + * 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 NewDimensionPage(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n }\n }\n }\n }\n"): (typeof documents)["\n query NewDimensionPage(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n }\n }\n }\n }\n"]; +/** + * 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 ValueFields on SurveyDimensionValueType {\n slug\n color\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n }\n"): (typeof documents)["\n fragment ValueFields on SurveyDimensionValueType {\n slug\n color\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n }\n"]; +/** + * 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 DimensionRowGroup on SurveyDimensionType {\n slug\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n values {\n ...ValueFields\n }\n }\n"): (typeof documents)["\n fragment DimensionRowGroup on SurveyDimensionType {\n slug\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n values {\n ...ValueFields\n }\n }\n"]; +/** + * 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 DimensionsList(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n dimensions {\n ...DimensionRowGroup\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query DimensionsList(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n dimensions {\n ...DimensionRowGroup\n }\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/frontend/src/__generated__/graphql.ts b/frontend/src/__generated__/graphql.ts index c27d53bd7..f09809103 100644 --- a/frontend/src/__generated__/graphql.ts +++ b/frontend/src/__generated__/graphql.ts @@ -40,6 +40,17 @@ export type Scalars = { UUID: { input: string; output: string; } }; +export type CreateSurveyDimension = { + __typename?: 'CreateSurveyDimension'; + dimension?: Maybe; +}; + +export type CreateSurveyDimensionInput = { + eventSlug: Scalars['String']['input']; + formData: Scalars['GenericScalar']['input']; + surveySlug: Scalars['String']['input']; +}; + export type CreateSurveyResponse = { __typename?: 'CreateSurveyResponse'; response?: Maybe; @@ -279,12 +290,18 @@ export type LimitedUserType = { export type Mutation = { __typename?: 'Mutation'; + createSurveyDimension?: Maybe; createSurveyResponse?: Maybe; initFileUpload?: Maybe; updateResponseDimensions?: Maybe; }; +export type MutationCreateSurveyDimensionArgs = { + input: CreateSurveyDimensionInput; +}; + + export type MutationCreateSurveyResponseArgs = { input: CreateSurveyResponseInput; }; @@ -547,6 +564,26 @@ export type InitFileUploadMutationMutationVariables = Exact<{ export type InitFileUploadMutationMutation = { __typename?: 'Mutation', initFileUpload?: { __typename?: 'InitFileUploadResponse', uploadUrl?: string | null, fileUrl?: string | null } | null }; +export type CreateSurveyDimensionMutationVariables = Exact<{ + input: CreateSurveyDimensionInput; +}>; + + +export type CreateSurveyDimensionMutation = { __typename?: 'Mutation', createSurveyDimension?: { __typename?: 'CreateSurveyDimension', dimension?: { __typename?: 'SurveyDimensionType', slug: string } | null } | null }; + +export type NewDimensionPageQueryVariables = Exact<{ + eventSlug: Scalars['String']['input']; + surveySlug: Scalars['String']['input']; + locale: Scalars['String']['input']; +}>; + + +export type NewDimensionPageQuery = { __typename?: 'Query', event?: { __typename?: 'FullEventType', name: string, forms?: { __typename?: 'FormsEventMetaType', survey?: { __typename?: 'SurveyType', title?: string | null } | null } | null } | null }; + +export type ValueFieldsFragment = { __typename?: 'SurveyDimensionValueType', slug: string, color: string, titleFi?: string | null, titleEn?: string | null }; + +export type DimensionRowGroupFragment = { __typename?: 'SurveyDimensionType', slug: string, titleFi?: string | null, titleEn?: string | null, values: Array<{ __typename?: 'SurveyDimensionValueType', slug: string, color: string, titleFi?: string | null, titleEn?: string | null }> }; + export type DimensionsListQueryVariables = Exact<{ eventSlug: Scalars['String']['input']; surveySlug: Scalars['String']['input']; @@ -637,6 +674,8 @@ export type OwnFormResponsesQueryVariables = Exact<{ [key: string]: never; }>; export type OwnFormResponsesQuery = { __typename?: 'Query', profile?: { __typename?: 'ProfileType', forms: { __typename?: 'FormsProfileMetaType', responses: Array<{ __typename?: 'FullResponseType', id: string, createdAt: string, form: { __typename?: 'FormType', slug: string, title: string, event: { __typename?: 'LimitedEventType', slug: string, name: string } } }> } } | null }; +export const ValueFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ValueFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]}]}}]} as unknown as DocumentNode; +export const DimensionRowGroupFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionRowGroup"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]},{"kind":"Field","name":{"kind":"Name","value":"values"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ValueFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ValueFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]}]}}]} as unknown as DocumentNode; export const SurveyResponseFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SurveyResponse"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedResponseType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"displayName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"values"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyFieldsOnly"},"value":{"kind":"BooleanValue","value":true}}]},{"kind":"Field","name":{"kind":"Name","value":"cachedDimensions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyDimensionsOnly"},"value":{"kind":"BooleanValue","value":true}}]}]}}]} as unknown as DocumentNode; export const SurveyFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Survey"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyType"}},"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":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"activeFrom"}},{"kind":"Field","name":{"kind":"Name","value":"activeUntil"}},{"kind":"Field","name":{"kind":"Name","value":"countResponses"}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode; export const OwnResponseFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OwnResponse"},"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":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; @@ -644,7 +683,9 @@ export const NewProgramQueryDocument = {"kind":"Document","definitions":[{"kind" export const NewProgramFormSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NewProgramFormSelectionQuery"},"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":"program"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"skipOfferFormSelection"}},{"kind":"Field","name":{"kind":"Name","value":"offerForms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"shortDescription"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"form"},"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":"title"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const CreateSurveyResponseDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSurveyResponse"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateSurveyResponseInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSurveyResponse"},"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":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; export const InitFileUploadMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InitFileUploadMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"InitFileUploadInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"initFileUpload"},"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":"uploadUrl"}},{"kind":"Field","name":{"kind":"Name","value":"fileUrl"}}]}}]}}]} as unknown as DocumentNode; -export const DimensionsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"DimensionsList"},"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":"locale"}},"type":{"kind":"NonNullType","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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"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":"dimensions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]},{"kind":"Field","name":{"kind":"Name","value":"values"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const CreateSurveyDimensionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSurveyDimension"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateSurveyDimensionInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSurveyDimension"},"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 NewDimensionPageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NewDimensionPage"},"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":"locale"}},"type":{"kind":"NonNullType","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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const DimensionsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"DimensionsList"},"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":"locale"}},"type":{"kind":"NonNullType","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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"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":"dimensions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionRowGroup"}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ValueFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionRowGroup"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]},{"kind":"Field","name":{"kind":"Name","value":"values"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ValueFields"}}]}}]}}]} as unknown as DocumentNode; export const SurveyPageQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SurveyPageQuery"},"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":"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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"loginRequired"}},{"kind":"Field","name":{"kind":"Name","value":"anonymity"}},{"kind":"Field","name":{"kind":"Name","value":"maxResponsesPerUser"}},{"kind":"Field","name":{"kind":"Name","value":"countResponsesByCurrentUser"}},{"kind":"Field","name":{"kind":"Name","value":"form"},"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":"title"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const UpdateResponseDimensionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateResponseDimensions"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateResponseDimensionsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateResponseDimensions"},"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":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; export const SurveyResponseDetailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SurveyResponseDetail"},"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":"responseId"}},"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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"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":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"anonymity"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"selectionSet":{"kind":"SelectionSet","selections":[{"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":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"isMultiValue"}},{"kind":"Field","name":{"kind":"Name","value":"values"},"selectionSet":{"kind":"SelectionSet","selections":[{"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":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"response"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"responseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"values"}},{"kind":"Field","name":{"kind":"Name","value":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cachedDimensions"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; diff --git a/frontend/src/app/[locale]/default.tsx b/frontend/src/app/[locale]/default.tsx new file mode 100644 index 000000000..0038780e6 --- /dev/null +++ b/frontend/src/app/[locale]/default.tsx @@ -0,0 +1,3 @@ +export function Default() { + return null; +} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/(.)new/page.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/(.)new/page.tsx new file mode 100644 index 000000000..f66f7ac9e --- /dev/null +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/(.)new/page.tsx @@ -0,0 +1,34 @@ +import { createDimension } from "../../actions"; +import EditDimensionForm from "../../EditDimensionForm"; +import InterceptingRouteModal from "@/components/InterceptingRouteModal"; +import { getTranslations } from "@/translations"; + +interface Props { + params: { + locale: string; + eventSlug: string; + surveySlug: string; + }; +} + +export default function NewDimensionModal({ params }: Props) { + const { eventSlug, surveySlug, locale } = params; + const translations = getTranslations(locale); + const t = translations.Survey.editDimensionModal; + + return ( + + + + ); +} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/default.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/default.tsx new file mode 100644 index 000000000..6ddf1b76f --- /dev/null +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/default.tsx @@ -0,0 +1,3 @@ +export default function Default() { + return null; +} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/EditDimensionForm.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/EditDimensionForm.tsx new file mode 100644 index 000000000..c2e4508f2 --- /dev/null +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/EditDimensionForm.tsx @@ -0,0 +1,53 @@ +import { HeadingLevel } from "@/components/helpers/Heading"; +import { SchemaForm } from "@/components/SchemaForm"; +import { Field, Layout } from "@/components/SchemaForm/models"; +import { supportedLanguages } from "@/translations"; +import type { Translations } from "@/translations/en"; + +interface Props { + headingLevel: HeadingLevel; + messages: { + SchemaForm: Translations["SchemaForm"]; + Survey: Translations["Survey"]; + }; +} + +export default function EditDimensionForm({ messages, headingLevel }: Props) { + const t = messages.Survey.editDimensionModal; + const fields: Field[] = [ + { + type: "SingleLineText", + slug: "slug", + required: true, + ...t.attributes.slug, + }, + { + type: "SingleCheckbox", + slug: "isKeyDimension", + title: t.attributes.isKeyDimension.title, + helpText: t.attributes.isKeyDimension.helpText, + }, + { + type: "StaticText", + slug: "localizedTitleHeader", + ...t.attributes.localizedTitleHeader, + }, + ...supportedLanguages.map( + (locale) => + ({ + type: "SingleLineText", + slug: `title.${locale}`, + title: t.attributes.title[locale], + }) as Field, + ), + ]; + + return ( + + ); +} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/TODO.md b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/TODO.md new file mode 100644 index 000000000..eb42ff9c0 --- /dev/null +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/TODO.md @@ -0,0 +1,21 @@ +# Intercepting routes may be too heavy machinery for the dimension editor + +The new dimension / edit dimension modal was written using an intercepting route. This allows both opening it as a modal on top of the dimensions view and navigating to it as a stand-alone view. + +While a fun exercise in intercepting routes, this may not be very useful or necessary for the actual use case. + +## On a hard reload, can we open the dimensions page and then the modal on top of it + +…without resorting to some `?intent=createValue(dimensionSlug)` that redirects to the intercepting route? + +For example: The user navigates to `/event/hitpoint2024/surveys/larp-survey/dimensions/new`. Instead of opening the form as a standalone page, could we make it open the dimensions view and then the modal on top of it, so that the Next.js recommended way of closing the modal with `router.back()` would work. + +## Check if the @modal can be pushed to root layout + +If we settle on using intercepting routes, there are still things we could do + +It's a bit unwieldy to have to create the layout containing a `@modal` slot, with its own `default.tsx`, in every page that happens to use modals via intercepting routes. See if it would be possible to move the `@modal` slot to the root layout. + +## See also + +- [Next.js documentation: Intercepting routes](https://nextjs.org/docs/app/building-your-application/routing/intercepting-routes) diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts new file mode 100644 index 000000000..55ceb2416 --- /dev/null +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts @@ -0,0 +1,108 @@ +"use server"; + +import { redirect } from "next/navigation"; +import { graphql } from "@/__generated__"; +import { getClient } from "@/apolloClient"; + +const createDimensionMutation = graphql(` + mutation CreateSurveyDimension($input: CreateSurveyDimensionInput!) { + createSurveyDimension(input: $input) { + dimension { + slug + } + } + } +`); + +export async function createDimension( + eventSlug: string, + surveySlug: string, + formData: FormData, +) { + await getClient().mutate({ + mutation: createDimensionMutation, + variables: { + input: { + eventSlug, + surveySlug, + formData: Object.fromEntries(formData), + }, + }, + }); + redirect(`/events/${eventSlug}/surveys/${surveySlug}/dimensions`); +} + +export async function updateDimension( + eventSlug: string, + surveySlug: string, + dimensionSlug: string, + formData: FormData, +) { + // TODO stubb + console.log( + "updateDimension", + eventSlug, + surveySlug, + dimensionSlug, + formData, + ); +} + +export async function deleteDimension( + eventSlug: string, + surveySlug: string, + dimensionSlug: string, +) { + // TODO stubb + console.log("deleteDimension", eventSlug, surveySlug, dimensionSlug); +} + +export async function createDimensionValue( + eventSlug: string, + surveySlug: string, + dimensionSlug: string, + formData: FormData, +) { + // TODO stubb + console.log( + "createDimensionValue", + eventSlug, + surveySlug, + dimensionSlug, + formData, + ); +} + +export async function updateDimensionValue( + eventSlug: string, + surveySlug: string, + dimensionSlug: string, + valueSlug: string, + formData: FormData, +) { + // TODO stubb + console.log( + "updateDimensionValue", + eventSlug, + surveySlug, + dimensionSlug, + valueSlug, + formData, + ); +} + +export async function deleteDimensionValue( + eventSlug: string, + surveySlug: string, + dimensionSlug: string, + valueSlug: string, +) { + // TODO stubb + console.log( + "deleteDimensionValue", + eventSlug, + surveySlug, + dimensionSlug, + valueSlug, + ); +} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx new file mode 100644 index 000000000..2649934c5 --- /dev/null +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx @@ -0,0 +1,13 @@ +interface Props { + children: React.ReactNode; + modal?: React.ReactNode; +} + +export default function Layout({ children, modal }: Props) { + return ( + <> + {children} + {modal} + + ); +} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/new/page.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/new/page.tsx new file mode 100644 index 000000000..1f03eaf17 --- /dev/null +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/new/page.tsx @@ -0,0 +1,119 @@ +import Link from "next/link"; +import { notFound } from "next/navigation"; +import { createDimension } from "../actions"; +import EditDimensionForm from "../EditDimensionForm"; +import { graphql } from "@/__generated__"; +import { getClient } from "@/apolloClient"; +import { auth } from "@/auth"; +import SubmitButton from "@/components/SchemaForm/SubmitButton"; +import SignInRequired from "@/components/SignInRequired"; +import ViewContainer from "@/components/ViewContainer"; +import ViewHeading from "@/components/ViewHeading"; +import getPageTitle from "@/helpers/getPageTitle"; +import { getTranslations } from "@/translations"; + +const query = graphql(` + query NewDimensionPage( + $eventSlug: String! + $surveySlug: String! + $locale: String! + ) { + event(slug: $eventSlug) { + name + forms { + survey(slug: $surveySlug) { + title(lang: $locale) + } + } + } + } +`); + +interface Props { + params: { + locale: string; + eventSlug: string; + surveySlug: string; + }; +} + +export async function generateMetadata({ params }: Props) { + const { locale, eventSlug, surveySlug } = params; + const translations = getTranslations(locale); + + // TODO encap + const session = await auth(); + if (!session) { + return translations.SignInRequired.metadata; + } + + const t = translations.Survey; + + const { data } = await getClient().query({ + query, + variables: { locale, eventSlug, surveySlug }, + }); + + if (!data.event?.forms?.survey) { + notFound(); + } + + const title = getPageTitle({ + translations, + event: data.event, + subject: data.event.forms.survey.title, + viewTitle: t.actions.addDimension, + }); + + return { title }; +} + +export default async function NewDimensionPage({ params }: Props) { + const { eventSlug, surveySlug, locale } = params; + const translations = getTranslations(locale); + const t = translations.Survey; + + // TODO encap + const session = await auth(); + if (!session) { + return ; + } + + const { data } = await getClient().query({ + query, + variables: { locale, eventSlug, surveySlug }, + }); + + if (!data.event?.forms?.survey) { + notFound(); + } + + const survey = data.event.forms.survey; + + return ( + + + < {t.actions.returnToDimensionList} + + + + {t.actions.addDimension} + {survey.title} + + +
+ + {t.editDimensionModal.actions.submit} + +
+ ); +} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx index d80d8d96d..58cf9cac8 100644 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx @@ -2,6 +2,10 @@ import Link from "next/link"; import { notFound } from "next/navigation"; import { Fragment } from "react"; import { graphql } from "@/__generated__"; +import { + DimensionRowGroupFragment, + ValueFieldsFragment, +} from "@/__generated__/graphql"; import { getClient } from "@/apolloClient"; import { auth } from "@/auth"; import { makeColorTranslucent } from "@/components/dimensions/helpers"; @@ -11,6 +15,26 @@ import ViewHeading from "@/components/ViewHeading"; import getPageTitle from "@/helpers/getPageTitle"; import { getTranslations } from "@/translations"; +graphql(` + fragment ValueFields on SurveyDimensionValueType { + slug + color + titleFi: title(lang: "fi") + titleEn: title(lang: "en") + } +`); + +graphql(` + fragment DimensionRowGroup on SurveyDimensionType { + slug + titleFi: title(lang: "fi") + titleEn: title(lang: "en") + values { + ...ValueFields + } + } +`); + const query = graphql(` query DimensionsList( $eventSlug: String! @@ -23,15 +47,7 @@ const query = graphql(` survey(slug: $surveySlug) { title(lang: $locale) dimensions { - slug - titleFi: title(lang: "fi") - titleEn: title(lang: "en") - values { - slug - color - titleFi: title(lang: "fi") - titleEn: title(lang: "en") - } + ...DimensionRowGroup } } } @@ -39,6 +55,41 @@ const query = graphql(` } `); +function DimensionCells({ + dimension, +}: { + dimension: DimensionRowGroupFragment; +}) { + const rowspan = dimension.values.length + 1; + return ( + <> + + {dimension.slug} + + + {dimension.titleFi} + + + {dimension.titleEn} + + + ); +} + +function ValueCells({ value }: { value: ValueFieldsFragment }) { + const backgroundColor = value.color && makeColorTranslucent(value.color); + + return ( + <> + + {value.slug} + + {value.titleFi} + {value.titleEn} + + ); +} + interface Props { params: { locale: string; @@ -107,6 +158,56 @@ export default async function SurveyDimensionsPage({ params }: Props) { 0, ); + const countColumns = 6; + + function AddValueCell({ + dimension, + }: { + dimension: DimensionRowGroupFragment; + }) { + return ( + + + {t.actions.addValue}… + + + ); + } + + function DimensionRowGroup({ + dimension, + }: { + dimension: DimensionRowGroupFragment; + }) { + if (dimension.values.length === 0) { + return ( + + + + + ); + } + + return ( + <> + {dimension.values.map((value, valueIndex) => { + return ( + + {valueIndex === 0 && } + + + ); + })} + + + + + ); + } + return ( @@ -117,7 +218,7 @@ export default async function SurveyDimensionsPage({ params }: Props) { {survey.title} - +
@@ -129,36 +230,19 @@ export default async function SurveyDimensionsPage({ params }: Props) { - {dimensions.map((dimension, dimensionIndex) => ( - - {dimension.values.map((value, valueIndex) => { - const backgroundColor = - value.color && makeColorTranslucent(value.color); - return ( - - {valueIndex === 0 && ( - <> - - - - - )} - - - - - ); - })} - + {dimensions.map((dimension) => ( + ))} + + +
{t.attributes.dimension}
- {dimension.slug} - - {dimension.titleFi} - - {dimension.titleEn} - - {value.slug} - {value.titleFi}{value.titleEn}
+ + {t.actions.addDimension}… + +

{t.dimensionTableFooter(dimensions.length, countValues)}

diff --git a/frontend/src/app/[locale]/layout.tsx b/frontend/src/app/[locale]/layout.tsx index cf4253462..9a3c56046 100644 --- a/frontend/src/app/[locale]/layout.tsx +++ b/frontend/src/app/[locale]/layout.tsx @@ -10,17 +10,14 @@ export const metadata: Metadata = { description: "Event Management System", }; -interface RootLayoutProps { +interface Props { children: React.ReactNode; params: { locale: string; }; } -export default function RootLayout({ - children, - params: { locale }, -}: RootLayoutProps) { +export default function RootLayout({ children, params: { locale } }: Props) { const supportedLanguage = toSupportedLanguage(locale); // TODO implement bootstrap dark mode toggle () diff --git a/frontend/src/components/InterceptingRouteModal.tsx b/frontend/src/components/InterceptingRouteModal.tsx new file mode 100644 index 000000000..74ef96c41 --- /dev/null +++ b/frontend/src/components/InterceptingRouteModal.tsx @@ -0,0 +1,49 @@ +"use client"; + +import { useRouter } from "next/navigation"; +import { ReactNode, useCallback } from "react"; +import Button from "react-bootstrap/Button"; +import Modal from "react-bootstrap/Modal"; +import type { Translations } from "@/translations/en"; + +interface Props { + title: ReactNode; + children?: ReactNode; + action?(formData: FormData): void; + messages: Translations["Modal"]; +} + +// TODO make server component, split Modal stuff to separate client component +// client component calling getTranslations includes whole set of translations in bundle +export default function InterceptingRouteModal({ + title, + children, + action, + messages, +}: Props) { + const router = useRouter(); + const handleClose = useCallback(() => { + router.back(); + }, [router]); + + return ( + + + {title} + + +
+ {children} + + + + + +
+
+ ); +} diff --git a/frontend/src/components/SchemaForm/SchemaFormField.tsx b/frontend/src/components/SchemaForm/SchemaFormField.tsx index 51c5e705c..2509aa971 100644 --- a/frontend/src/components/SchemaForm/SchemaFormField.tsx +++ b/frontend/src/components/SchemaForm/SchemaFormField.tsx @@ -1,5 +1,6 @@ import { ReactNode } from "react"; +import { Heading, HeadingLevel } from "../helpers/Heading"; import { Field, Layout } from "./models"; function Label({ field, layout }: { field: Field; layout: Layout }) { @@ -25,6 +26,9 @@ interface SchemaFormFieldProps { layout: Layout; field: Field; children?: ReactNode; + + /// used for StaticText.title + headingLevel?: HeadingLevel; } /** @@ -35,6 +39,7 @@ export default function SchemaFormField({ layout, field, children, + headingLevel, }: SchemaFormFieldProps) { const { type, helpText } = field; const title = field.required ? `${field.title}*` : field.title; @@ -42,7 +47,7 @@ export default function SchemaFormField({ if (type === "StaticText") { return ( <> - {title &&

{title}

} + {title && {title}} {helpText &&

{helpText}

} {children} diff --git a/frontend/src/components/SchemaForm/index.tsx b/frontend/src/components/SchemaForm/index.tsx index 6c29ce4d4..6ac73e8fe 100644 --- a/frontend/src/components/SchemaForm/index.tsx +++ b/frontend/src/components/SchemaForm/index.tsx @@ -1,3 +1,4 @@ +import type { HeadingLevel } from "../helpers/Heading"; import { Field, Layout } from "./models"; import SchemaFormField from "./SchemaFormField"; import SchemaFormInput from "./SchemaFormInput"; @@ -8,10 +9,11 @@ interface SchemaFormProps { layout?: Layout; values?: Record; messages: Translations["SchemaForm"]; + headingLevel?: HeadingLevel; } export function SchemaForm(props: SchemaFormProps) { - const { fields, layout, values, messages } = props; + const { fields, layout, values, messages, headingLevel } = props; return ( <> {fields.map((field, index) => { @@ -26,6 +28,7 @@ export function SchemaForm(props: SchemaFormProps) { key={slug} field={field} layout={layout ?? Layout.Vertical} + headingLevel={headingLevel} > & { + level?: HeadingLevel; +}; + +/// A heading element with a level that can be specified as a prop. +/// NOTE: Use only if you need to change the level of the heading from the outside. +/// Otherwise, use the appropriate heading element directly. +/// Used by SchemaForm that needs to render headings of different levels depending on the context the form is used in. +export function Heading(props: HeadingProps) { + const { level, ...passthruProps } = props; + const HeadingElement = level || "h2"; + return ; +} diff --git a/frontend/src/translations/en.tsx b/frontend/src/translations/en.tsx index bd1944cb4..31d2ddee4 100644 --- a/frontend/src/translations/en.tsx +++ b/frontend/src/translations/en.tsx @@ -31,6 +31,11 @@ const translations = { }, }, }, + // Note that this also defines the type for the messages object that can be passed to the InterceptingRouteModal component + Modal: { + submit: "Submit", + cancel: "Cancel", + }, DataTable: { create: "Create", }, @@ -321,7 +326,10 @@ const translations = { downloadAsExcel: "Download as Excel", returnToResponseList: "Return to the list of responses", returnToSurveyList: "Return to the list of surveys", + returnToDimensionList: "Return to the list of dimensions", saveDimensions: "Save dimensions", + addDimension: "Add dimension", + addValue: "Add value", }, tabs: { summary: "Summary", @@ -350,6 +358,37 @@ const translations = { checked: "Checked", unchecked: "Not checked", }, + editDimensionModal: { + editTitle: "Edit dimension", + addTitle: "Add dimension", + actions: { + submit: "Save dimension", + cancel: "Cancel", + }, + attributes: { + slug: { + title: "Technical name", + // TODO add pattern for slug and document it in helpText + helpText: + "Machine-readable dimension name. Cannot be changed after creation.", + }, + localizedTitleHeader: { + title: "Localized titles", + helpText: + "The title of the dimension in different languages. The title need not be provided in all supported languages: if the title is missing in the selected language, it will fall back first to the default language and then to the technical name.", + }, + title: { + fi: "Title in Finnish", + en: "Title in English", + sv: "Title in Swedish", + }, + isKeyDimension: { + title: "This dimension is a key dimension", + helpText: + "Values of key dimensions are displayed in the response list.", + }, + }, + }, }, SignInRequired: { diff --git a/frontend/src/translations/fi.tsx b/frontend/src/translations/fi.tsx index b12a4471a..5b136bdab 100644 --- a/frontend/src/translations/fi.tsx +++ b/frontend/src/translations/fi.tsx @@ -33,6 +33,10 @@ const translations: Translations = { }, }, }, + Modal: { + submit: "Submit", + cancel: "Cancel", + }, DataTable: { create: "Luo uusi", }, @@ -321,7 +325,10 @@ const translations: Translations = { downloadAsExcel: "Lataa Excel-tiedostona", returnToResponseList: "Palaa vastauslistaukseen", returnToSurveyList: "Palaa kyselylistaukseen", + returnToDimensionList: "Palaa dimensiolistaukseen", saveDimensions: "Tallenna dimensiot", + addDimension: "Lisää dimensio", + addValue: "Lisää arvo", }, tabs: { summary: "Yhteenveto", @@ -354,6 +361,36 @@ const translations: Translations = { checked: "Valittu", unchecked: "Ei valittu", }, + editDimensionModal: { + editTitle: "Muokkaa dimensiota", + addTitle: "Lisää dimensio", + actions: { + submit: "Tallenna dimensio", + cancel: "Peruuta", + }, + attributes: { + slug: { + title: "Tekninen nimi", + // TODO add pattern for slug and document it in helpText + helpText: + "Koneluettava, lyhyt nimi dimensiolle. Teknistä nimeä ei voi muuttaa dimension luomisen jälkeen.", + }, + localizedTitleHeader: { + title: "Otsikko lokalisoituna", + helpText: + "Dimensiolle voi antaa otsikon eri kielillä. Otsikkoa ei tarvitse antaa kaikilla tuetuilla kielillä: jos otsikkoa ei ole annettu valitulla kielellä, käytetään tilalla oletuskieltä, ja jos sitäkään ei ole asetettu, teknistä nimeä.", + }, + title: { + fi: "Otsikko suomeksi", + en: "Otsikko englanniksi", + sv: "Otsikko ruotsiksi", + }, + isKeyDimension: { + title: "Tämä dimensio on avaindimensio", + helpText: "Avaindimensioiden arvot näytetään vastauslistassa.", + }, + }, + }, }, SignInRequired: { From c09c13dc91d5608ef70c79c097d4c113f668ede9 Mon Sep 17 00:00:00 2001 From: Santtu Pajukanta Date: Sat, 27 Jan 2024 19:00:32 +0200 Subject: [PATCH 2/8] feat(forms): in profile responses view, show dimensions designated as so --- .../forms/expense-claim-dimensions.yml | 1 + backend/forms/graphql/meta.py | 6 +- .../mutations/create_survey_response.py | 4 +- backend/forms/graphql/response.py | 68 ++++++++++++ .../0022_dimension_is_shown_to_respondent.py | 20 ++++ backend/forms/models/dimension.py | 12 +- frontend/src/__generated__/gql.ts | 12 +- frontend/src/__generated__/graphql.ts | 63 +++++++++-- .../surveys/[surveySlug]/dimensions/page.tsx | 5 +- .../profile/responses/[responseId]/page.tsx | 104 ++++++++++++++---- .../app/[locale]/profile/responses/page.tsx | 49 +++++++-- frontend/src/components/dimensions/helpers.ts | 4 + 12 files changed, 290 insertions(+), 58 deletions(-) create mode 100644 backend/forms/migrations/0022_dimension_is_shown_to_respondent.py diff --git a/backend/events/tracon2024/forms/expense-claim-dimensions.yml b/backend/events/tracon2024/forms/expense-claim-dimensions.yml index 0dd4cdc75..4ed9a80f7 100644 --- a/backend/events/tracon2024/forms/expense-claim-dimensions.yml +++ b/backend/events/tracon2024/forms/expense-claim-dimensions.yml @@ -24,6 +24,7 @@ fi: Maksun tila en: Payment status is_key_dimension: true + is_shown_to_respondent: true choices: - slug: new color: blue diff --git a/backend/forms/graphql/meta.py b/backend/forms/graphql/meta.py index 510eecc61..e64f3a590 100644 --- a/backend/forms/graphql/meta.py +++ b/backend/forms/graphql/meta.py @@ -8,7 +8,7 @@ from ..models.meta import FormsEventMeta, FormsProfileMeta from ..models.response import Response from ..models.survey import Survey -from .response import FullResponseType +from .response import ProfileResponseType from .survey import SurveyType DEFAULT_LANGUAGE: str = settings.LANGUAGE_CODE @@ -51,7 +51,7 @@ def resolve_responses(meta: FormsProfileMeta, info): responses = graphene.NonNull( graphene.List( - graphene.NonNull(FullResponseType), + graphene.NonNull(ProfileResponseType), ), description=normalize_whitespace(resolve_responses.__doc__ or ""), ) @@ -66,7 +66,7 @@ def resolve_response(meta: FormsProfileMeta, info, id: int): return Response.objects.get(created_by=meta.person.user, id=id) response = graphene.Field( - FullResponseType, + ProfileResponseType, id=graphene.String(required=True), description=normalize_whitespace(resolve_response.__doc__ or ""), ) diff --git a/backend/forms/graphql/mutations/create_survey_response.py b/backend/forms/graphql/mutations/create_survey_response.py index 6f117ee6d..63cf6e896 100644 --- a/backend/forms/graphql/mutations/create_survey_response.py +++ b/backend/forms/graphql/mutations/create_survey_response.py @@ -5,7 +5,7 @@ from ...models.response import Response from ...models.survey import Survey -from ..response import FullResponseType +from ..response import ProfileResponseType class CreateSurveyResponseInput(graphene.InputObjectType): @@ -19,7 +19,7 @@ class CreateSurveyResponse(graphene.Mutation): class Arguments: input = CreateSurveyResponseInput(required=True) - response = graphene.Field(FullResponseType) + response = graphene.Field(ProfileResponseType) @staticmethod def mutate( diff --git a/backend/forms/graphql/response.py b/backend/forms/graphql/response.py index 8a83b88a8..7d75b95e6 100644 --- a/backend/forms/graphql/response.py +++ b/backend/forms/graphql/response.py @@ -126,3 +126,71 @@ class Meta: "form_data", "created_at", ) + + +class ProfileResponseType(LimitedResponseType): + @staticmethod + def resolve_form(parent: Response, info): + return parent.form + + form = graphene.Field(graphene.NonNull(FormType)) + + @staticmethod + def resolve_dimensions(parent: Response, info, key_dimensions_only: bool = False): + """ + The respondent will only see values of dimensions that are designated as + being shown to the respondent. + """ + qs = parent.dimensions.filter(dimension__is_shown_to_respondent=True) + + if key_dimensions_only: + qs = qs.filter(dimension__is_key_dimension=True) + + return qs + + dimensions = graphene.List( + graphene.NonNull(ResponseDimensionValueType), + key_dimensions_only=graphene.Boolean(), + ) + + @staticmethod + def resolve_cached_dimensions(response: Response, info, key_dimensions_only: bool = False): + """ + Returns the dimensions of the response as + a dict of dimension slug -> list of dimension value slugs. If the response + is not related to a survey, there will be no dimensions and an empty dict + will always be returned. + + Using this field is more efficient than querying the dimensions field + on the response, as the dimensions are cached on the response object. + + The respondent will only see values of dimensions that are designated as + being shown to the respondent. + """ + cached_dimensions = response.cached_dimensions + + included_dimensions = response.dimensions.filter( + dimension__slug__in=cached_dimensions.keys(), + dimension__is_shown_to_respondent=True, + ) + + if key_dimensions_only: + included_dimensions = included_dimensions.filter(dimension__is_key_dimension=True) + + included_dimension_slugs = response.dimensions.values_list("dimension__slug", flat=True) + + return {k: v for k, v in cached_dimensions.items() if k in included_dimension_slugs} + + cached_dimensions = graphene.Field( + GenericScalar, + description=normalize_whitespace(resolve_cached_dimensions.__doc__ or ""), + key_dimensions_only=graphene.Boolean(), + ) + + class Meta: + model = Response + fields = ( + "id", + "form_data", + "created_at", + ) diff --git a/backend/forms/migrations/0022_dimension_is_shown_to_respondent.py b/backend/forms/migrations/0022_dimension_is_shown_to_respondent.py new file mode 100644 index 000000000..31acc3357 --- /dev/null +++ b/backend/forms/migrations/0022_dimension_is_shown_to_respondent.py @@ -0,0 +1,20 @@ +# Generated by Django 5.0.1 on 2024-01-27 16:03 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("forms", "0021_dimension_is_multi_value"), + ] + + operations = [ + migrations.AddField( + model_name="dimension", + name="is_shown_to_respondent", + field=models.BooleanField( + default=False, + help_text="If set, the respondent will see the value of the dimension in the profile survey responses list.", + ), + ), + ] diff --git a/backend/forms/models/dimension.py b/backend/forms/models/dimension.py index a5f32459e..329c67977 100644 --- a/backend/forms/models/dimension.py +++ b/backend/forms/models/dimension.py @@ -38,6 +38,10 @@ class Dimension(models.Model): "NOTE: In the database, all dimensions are multi-value, so this is just a UI hint." ), ) + is_shown_to_respondent = models.BooleanField( + default=False, + help_text="If set, the respondent will see the value of the dimension in the profile survey responses list.", + ) values: models.QuerySet[DimensionValue] @@ -104,7 +108,7 @@ class DimensionValueDTO(pydantic.BaseModel): is_initial: bool = False def save(self, dimension: Dimension): - # TODO change to get_or_create when form editor is implemented + # TODO(#386) change to get_or_create when form editor is implemented # so that these can be loaded once but user changes are not overwritten DimensionValue.objects.update_or_create( dimension=dimension, @@ -119,7 +123,7 @@ def save(self, dimension: Dimension): class DimensionDTO(pydantic.BaseModel): """ - Helper to load dimensions from YAML. + Helper to load dimensions from YAML, form data or similar external sources. """ model_config = pydantic.ConfigDict(populate_by_name=True) @@ -129,9 +133,10 @@ class DimensionDTO(pydantic.BaseModel): choices: list[DimensionValueDTO] = pydantic.Field(default_factory=list) is_key_dimension: bool = pydantic.Field(default=False, alias="isKeyDimension") is_multi_value: bool = pydantic.Field(default=False, alias="isMultiValue") + is_shown_to_respondent: bool = pydantic.Field(default=False, alias="isShownToRespondent") def save(self, survey: Survey, order: int = 0): - # TODO change to get_or_create when form editor is implemented + # TODO(#386) change to get_or_create when form editor is implemented # so that these can be loaded once but user changes are not overwritten dimension, _created = Dimension.objects.update_or_create( survey=survey, @@ -140,6 +145,7 @@ def save(self, survey: Survey, order: int = 0): title=self.title, is_key_dimension=self.is_key_dimension, is_multi_value=self.is_multi_value, + is_shown_to_respondent=self.is_shown_to_respondent, order=order, ), ) diff --git a/frontend/src/__generated__/gql.ts b/frontend/src/__generated__/gql.ts index fbc4ad620..615c54d29 100644 --- a/frontend/src/__generated__/gql.ts +++ b/frontend/src/__generated__/gql.ts @@ -31,9 +31,9 @@ const documents = { "\n query SurveyThankYouPageQuery(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n\n forms {\n survey(slug: $surveySlug) {\n form(lang: $locale) {\n title\n thankYouMessage\n }\n }\n }\n }\n }\n": types.SurveyThankYouPageQueryDocument, "\n fragment Survey on SurveyType {\n slug\n title(lang: $locale)\n isActive\n activeFrom\n activeUntil\n countResponses\n\n languages {\n language\n }\n }\n": types.SurveyFragmentDoc, "\n query Surveys($eventSlug: String!, $locale: String) {\n event(slug: $eventSlug) {\n name\n\n forms {\n surveys {\n ...Survey\n }\n }\n }\n }\n": types.SurveysDocument, - "\n query OwnResponseDetail($responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n": types.OwnResponseDetailDocument, - "\n fragment OwnResponse on FullResponseType {\n id\n createdAt\n form {\n slug\n title\n event {\n slug\n name\n }\n }\n }\n": types.OwnResponseFragmentDoc, - "\n query OwnFormResponses {\n profile {\n forms {\n responses {\n ...OwnResponse\n }\n }\n }\n }\n": types.OwnFormResponsesDocument, + "\n query ProfileSurveyResponsePage($locale: String!, $responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n\n dimensions {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n": types.ProfileSurveyResponsePageDocument, + "\n fragment ProfileResponsesTableRow on ProfileResponseType {\n id\n createdAt\n dimensions(keyDimensionsOnly: true) {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n form {\n slug\n title\n event {\n slug\n name\n }\n }\n }\n": types.ProfileResponsesTableRowFragmentDoc, + "\n query OwnFormResponses($locale: String!) {\n profile {\n forms {\n responses {\n ...ProfileResponsesTableRow\n }\n }\n }\n }\n": types.OwnFormResponsesDocument, }; /** @@ -125,15 +125,15 @@ export function graphql(source: "\n query Surveys($eventSlug: String!, $locale: /** * 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 OwnResponseDetail($responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query OwnResponseDetail($responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n"]; +export function graphql(source: "\n query ProfileSurveyResponsePage($locale: String!, $responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n\n dimensions {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query ProfileSurveyResponsePage($locale: String!, $responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n\n dimensions {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n"]; /** * 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 OwnResponse on FullResponseType {\n id\n createdAt\n form {\n slug\n title\n event {\n slug\n name\n }\n }\n }\n"): (typeof documents)["\n fragment OwnResponse on FullResponseType {\n id\n createdAt\n form {\n slug\n title\n event {\n slug\n name\n }\n }\n }\n"]; +export function graphql(source: "\n fragment ProfileResponsesTableRow on ProfileResponseType {\n id\n createdAt\n dimensions(keyDimensionsOnly: true) {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n form {\n slug\n title\n event {\n slug\n name\n }\n }\n }\n"): (typeof documents)["\n fragment ProfileResponsesTableRow on ProfileResponseType {\n id\n createdAt\n dimensions(keyDimensionsOnly: true) {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n form {\n slug\n title\n event {\n slug\n name\n }\n }\n }\n"]; /** * 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 OwnFormResponses {\n profile {\n forms {\n responses {\n ...OwnResponse\n }\n }\n }\n }\n"): (typeof documents)["\n query OwnFormResponses {\n profile {\n forms {\n responses {\n ...OwnResponse\n }\n }\n }\n }\n"]; +export function graphql(source: "\n query OwnFormResponses($locale: String!) {\n profile {\n forms {\n responses {\n ...ProfileResponsesTableRow\n }\n }\n }\n }\n"): (typeof documents)["\n query OwnFormResponses($locale: String!) {\n profile {\n forms {\n responses {\n ...ProfileResponsesTableRow\n }\n }\n }\n }\n"]; export function graphql(source: string) { return (documents as any)[source] ?? {}; diff --git a/frontend/src/__generated__/graphql.ts b/frontend/src/__generated__/graphql.ts index f09809103..65822e1e7 100644 --- a/frontend/src/__generated__/graphql.ts +++ b/frontend/src/__generated__/graphql.ts @@ -53,7 +53,7 @@ export type CreateSurveyDimensionInput = { export type CreateSurveyResponse = { __typename?: 'CreateSurveyResponse'; - response?: Maybe; + response?: Maybe; }; export type CreateSurveyResponseInput = { @@ -145,9 +145,9 @@ export enum FormsFormLayoutChoices { export type FormsProfileMetaType = { __typename?: 'FormsProfileMetaType'; /** Returns a single response submitted by the current user. */ - response?: Maybe; + response?: Maybe; /** Returns all responses submitted by the current user. */ - responses: Array; + responses: Array; }; @@ -335,6 +335,42 @@ export type OfferFormTypeShortDescriptionArgs = { lang?: InputMaybe; }; +export type ProfileResponseType = { + __typename?: 'ProfileResponseType'; + /** Returns the dimensions of the response as a dict of dimension slug -> list of dimension value slugs. If the response is not related to a survey, there will be no dimensions and an empty dict will always be returned. Using this field is more efficient than querying the dimensions field on the response, as the dimensions are cached on the response object. The respondent will only see values of dimensions that are designated as being shown to the respondent. */ + cachedDimensions?: Maybe; + createdAt: Scalars['DateTime']['output']; + /** + * + * Returns the user who submitted the response. If response is to an anonymous survey, + * this information will not be available. + * + */ + createdBy?: Maybe; + dimensions?: Maybe>; + form: FormType; + formData: Scalars['JSONString']['output']; + id: Scalars['UUID']['output']; + /** Language code of the form used to submit this response. */ + language: Scalars['String']['output']; + values?: Maybe; +}; + + +export type ProfileResponseTypeCachedDimensionsArgs = { + keyDimensionsOnly?: InputMaybe; +}; + + +export type ProfileResponseTypeDimensionsArgs = { + keyDimensionsOnly?: InputMaybe; +}; + + +export type ProfileResponseTypeValuesArgs = { + keyFieldsOnly?: InputMaybe; +}; + export type ProfileType = { __typename?: 'ProfileType'; displayName?: Maybe; @@ -555,7 +591,7 @@ export type CreateSurveyResponseMutationVariables = Exact<{ }>; -export type CreateSurveyResponseMutation = { __typename?: 'Mutation', createSurveyResponse?: { __typename?: 'CreateSurveyResponse', response?: { __typename?: 'FullResponseType', id: string } | null } | null }; +export type CreateSurveyResponseMutation = { __typename?: 'Mutation', createSurveyResponse?: { __typename?: 'CreateSurveyResponse', response?: { __typename?: 'ProfileResponseType', id: string } | null } | null }; export type InitFileUploadMutationMutationVariables = Exact<{ input: InitFileUploadInput; @@ -660,25 +696,28 @@ export type SurveysQueryVariables = Exact<{ export type SurveysQuery = { __typename?: 'Query', event?: { __typename?: 'FullEventType', name: string, forms?: { __typename?: 'FormsEventMetaType', surveys?: Array<{ __typename?: 'SurveyType', slug: string, title?: string | null, isActive: boolean, activeFrom?: string | null, activeUntil?: string | null, countResponses: number, languages: Array<{ __typename?: 'FormType', language: FormsFormLanguageChoices }> }> | null } | null } | null }; -export type OwnResponseDetailQueryVariables = Exact<{ +export type ProfileSurveyResponsePageQueryVariables = Exact<{ + locale: Scalars['String']['input']; responseId: Scalars['String']['input']; }>; -export type OwnResponseDetailQuery = { __typename?: 'Query', profile?: { __typename?: 'ProfileType', forms: { __typename?: 'FormsProfileMetaType', response?: { __typename?: 'FullResponseType', id: string, createdAt: string, values?: unknown | null, form: { __typename?: 'FormType', slug: string, title: string, language: FormsFormLanguageChoices, fields?: unknown | null, layout: FormsFormLayoutChoices, event: { __typename?: 'LimitedEventType', slug: string, name: string }, survey?: { __typename?: 'LimitedSurveyType', anonymity: FormsSurveyAnonymityChoices } | null } } | null } } | null }; +export type ProfileSurveyResponsePageQuery = { __typename?: 'Query', profile?: { __typename?: 'ProfileType', forms: { __typename?: 'FormsProfileMetaType', response?: { __typename?: 'ProfileResponseType', id: string, createdAt: string, values?: unknown | null, dimensions?: Array<{ __typename?: 'ResponseDimensionValueType', dimension: { __typename?: 'SurveyDimensionType', slug: string, title?: string | null }, value: { __typename?: 'SurveyDimensionValueType', slug: string, title?: string | null, color: string } }> | null, form: { __typename?: 'FormType', slug: string, title: string, language: FormsFormLanguageChoices, fields?: unknown | null, layout: FormsFormLayoutChoices, event: { __typename?: 'LimitedEventType', slug: string, name: string }, survey?: { __typename?: 'LimitedSurveyType', anonymity: FormsSurveyAnonymityChoices } | null } } | null } } | null }; -export type OwnResponseFragment = { __typename?: 'FullResponseType', id: string, createdAt: string, form: { __typename?: 'FormType', slug: string, title: string, event: { __typename?: 'LimitedEventType', slug: string, name: string } } }; +export type ProfileResponsesTableRowFragment = { __typename?: 'ProfileResponseType', id: string, createdAt: string, dimensions?: Array<{ __typename?: 'ResponseDimensionValueType', dimension: { __typename?: 'SurveyDimensionType', slug: string, title?: string | null }, value: { __typename?: 'SurveyDimensionValueType', slug: string, title?: string | null, color: string } }> | null, form: { __typename?: 'FormType', slug: string, title: string, event: { __typename?: 'LimitedEventType', slug: string, name: string } } }; -export type OwnFormResponsesQueryVariables = Exact<{ [key: string]: never; }>; +export type OwnFormResponsesQueryVariables = Exact<{ + locale: Scalars['String']['input']; +}>; -export type OwnFormResponsesQuery = { __typename?: 'Query', profile?: { __typename?: 'ProfileType', forms: { __typename?: 'FormsProfileMetaType', responses: Array<{ __typename?: 'FullResponseType', id: string, createdAt: string, form: { __typename?: 'FormType', slug: string, title: string, event: { __typename?: 'LimitedEventType', slug: string, name: string } } }> } } | null }; +export type OwnFormResponsesQuery = { __typename?: 'Query', profile?: { __typename?: 'ProfileType', forms: { __typename?: 'FormsProfileMetaType', responses: Array<{ __typename?: 'ProfileResponseType', id: string, createdAt: string, dimensions?: Array<{ __typename?: 'ResponseDimensionValueType', dimension: { __typename?: 'SurveyDimensionType', slug: string, title?: string | null }, value: { __typename?: 'SurveyDimensionValueType', slug: string, title?: string | null, color: string } }> | null, form: { __typename?: 'FormType', slug: string, title: string, event: { __typename?: 'LimitedEventType', slug: string, name: string } } }> } } | null }; export const ValueFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ValueFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]}]}}]} as unknown as DocumentNode; export const DimensionRowGroupFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionRowGroup"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]},{"kind":"Field","name":{"kind":"Name","value":"values"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ValueFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ValueFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]}]}}]} as unknown as DocumentNode; export const SurveyResponseFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SurveyResponse"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedResponseType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"displayName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"values"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyFieldsOnly"},"value":{"kind":"BooleanValue","value":true}}]},{"kind":"Field","name":{"kind":"Name","value":"cachedDimensions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyDimensionsOnly"},"value":{"kind":"BooleanValue","value":true}}]}]}}]} as unknown as DocumentNode; export const SurveyFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Survey"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyType"}},"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":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"activeFrom"}},{"kind":"Field","name":{"kind":"Name","value":"activeUntil"}},{"kind":"Field","name":{"kind":"Name","value":"countResponses"}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode; -export const OwnResponseFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OwnResponse"},"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":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const ProfileResponsesTableRowFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProfileResponsesTableRow"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProfileResponseType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyDimensionsOnly"},"value":{"kind":"BooleanValue","value":true}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimension"},"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":"value"},"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":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; export const NewProgramQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NewProgramQuery"},"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":"formSlug"}},"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":"program"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"skipOfferFormSelection"}},{"kind":"Field","name":{"kind":"Name","value":"offerForm"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"formSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"form"},"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":"title"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const NewProgramFormSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NewProgramFormSelectionQuery"},"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":"program"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"skipOfferFormSelection"}},{"kind":"Field","name":{"kind":"Name","value":"offerForms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"shortDescription"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"form"},"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":"title"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const CreateSurveyResponseDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSurveyResponse"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateSurveyResponseInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSurveyResponse"},"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":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; @@ -693,5 +732,5 @@ export const FormResponsesDocument = {"kind":"Document","definitions":[{"kind":" export const SurveySummaryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SurveySummary"},"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":"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":"name"}},{"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"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":"fields"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"summary"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}]},{"kind":"Field","alias":{"kind":"Name","value":"countFilteredResponses"},"name":{"kind":"Name","value":"countResponses"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}]},{"kind":"Field","name":{"kind":"Name","value":"countResponses"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"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":"values"},"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"}}}]}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const SurveyThankYouPageQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SurveyThankYouPageQuery"},"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":"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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"form"},"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":"title"}},{"kind":"Field","name":{"kind":"Name","value":"thankYouMessage"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const SurveysDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Surveys"},"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":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"surveys"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Survey"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Survey"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyType"}},"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":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"activeFrom"}},{"kind":"Field","name":{"kind":"Name","value":"activeUntil"}},{"kind":"Field","name":{"kind":"Name","value":"countResponses"}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode; -export const OwnResponseDetailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"OwnResponseDetail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"responseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"response"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"responseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"values"}},{"kind":"Field","name":{"kind":"Name","value":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"survey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"anonymity"}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; -export const OwnFormResponsesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"OwnFormResponses"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"responses"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OwnResponse"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OwnResponse"},"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":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file +export const ProfileSurveyResponsePageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProfileSurveyResponsePage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"responseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"response"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"responseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"values"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimension"},"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":"value"},"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":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"survey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"anonymity"}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const OwnFormResponsesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"OwnFormResponses"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"responses"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProfileResponsesTableRow"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProfileResponsesTableRow"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProfileResponseType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyDimensionsOnly"},"value":{"kind":"BooleanValue","value":true}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimension"},"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":"value"},"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":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx index 58cf9cac8..7c772d721 100644 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx @@ -8,7 +8,10 @@ import { } from "@/__generated__/graphql"; import { getClient } from "@/apolloClient"; import { auth } from "@/auth"; -import { makeColorTranslucent } from "@/components/dimensions/helpers"; +import { + makeColorTranslucent, + makeBadgeBackgroundColor, +} from "@/components/dimensions/helpers"; import SignInRequired from "@/components/SignInRequired"; import ViewContainer from "@/components/ViewContainer"; import ViewHeading from "@/components/ViewHeading"; diff --git a/frontend/src/app/[locale]/profile/responses/[responseId]/page.tsx b/frontend/src/app/[locale]/profile/responses/[responseId]/page.tsx index 912279d70..d2821c473 100644 --- a/frontend/src/app/[locale]/profile/responses/[responseId]/page.tsx +++ b/frontend/src/app/[locale]/profile/responses/[responseId]/page.tsx @@ -4,6 +4,10 @@ import { notFound } from "next/navigation"; import { graphql } from "@/__generated__"; import { getClient } from "@/apolloClient"; import { auth } from "@/auth"; +import { + makeBadgeBackgroundColor, + makeColorTranslucent, +} from "@/components/dimensions/helpers"; import { Field, validateFields } from "@/components/SchemaForm/models"; import SchemaFormField from "@/components/SchemaForm/SchemaFormField"; import SchemaFormInput from "@/components/SchemaForm/SchemaFormInput"; @@ -14,13 +18,27 @@ import ViewHeading from "@/components/ViewHeading"; import { getTranslations } from "@/translations"; const query = graphql(` - query OwnResponseDetail($responseId: String!) { + query ProfileSurveyResponsePage($locale: String!, $responseId: String!) { profile { forms { response(id: $responseId) { id createdAt values + + dimensions { + dimension { + slug + title(lang: $locale) + } + + value { + slug + title(lang: $locale) + color + } + } + form { slug title @@ -60,7 +78,7 @@ export async function generateMetadata({ params }: Props) { export const revalidate = 0; -export default async function SurveyResponsePage({ params }: Props) { +export default async function ProfileSurveyResponsePage({ params }: Props) { const { locale, responseId } = params; const translations = getTranslations(locale); const session = await auth(); @@ -72,7 +90,10 @@ export default async function SurveyResponsePage({ params }: Props) { const { data } = await getClient().query({ query, - variables: { responseId }, + variables: { + responseId, + locale, + }, }); if (!data.profile?.forms?.response) { @@ -110,16 +131,45 @@ export default async function SurveyResponsePage({ params }: Props) { title: t.attributes.language, }; + const dimensions = response.dimensions ?? []; + + function buildDimensionField(dimension: (typeof dimensions)[0]): Field { + return { + slug: dimension.dimension.slug, + type: "SingleLineText", + title: dimension.dimension.title ?? dimension.dimension.slug, + }; + } + return ( < {t.actions.returnToResponseList} - - {t.responseDetailTitle} - {form.title} - +
+ + {t.responseDetailTitle} + {form.title} + + {!!dimensions?.length && ( +

+ {dimensions.map((dimension) => ( + + {dimension.value.title} + + ))} +

+ )} +
{anonymity && (

@@ -130,23 +180,29 @@ export default async function SurveyResponsePage({ params }: Props) {

)} - - - - - - - +
+
+
{t.attributes.technicalDetails}
+ + + + + + + + +
+
; } - const { data } = await getClient().query({ query }); + const { data } = await getClient().query({ + query, + variables: { + locale, + }, + }); if (!data.profile?.forms.responses) { notFound(); } const t = translations.Survey; - const columns: Column[] = [ + const columns: Column[] = [ { slug: "createdAt", title: t.attributes.createdAt, @@ -91,7 +109,24 @@ export default async function OwnResponsesPage({ params }: Props) { { slug: "formTitle", title: t.attributes.formTitle, - getCellContents: (row) => row.form.title, + getCellContents: (row) => ( +
+ {row.form.title} + {row.dimensions?.map((dimension) => ( + + {dimension.value.title} + + ))} +
+ ), }, ]; diff --git a/frontend/src/components/dimensions/helpers.ts b/frontend/src/components/dimensions/helpers.ts index 9f5df3fd5..4277c5d4e 100644 --- a/frontend/src/components/dimensions/helpers.ts +++ b/frontend/src/components/dimensions/helpers.ts @@ -105,3 +105,7 @@ export function buildDimensionForm( export function makeColorTranslucent(color: string) { return `color-mix(in srgb, ${color}, transparent 85%)`; } + +export function makeBadgeBackgroundColor(color: string) { + return `color-mix(in srgb, ${color}, var(--bs-secondary) 50%)`; +} From 6c56a94f2d1a8ad07f7aa3431695123106034a0e Mon Sep 17 00:00:00 2001 From: Santtu Pajukanta Date: Sat, 27 Jan 2024 19:07:13 +0200 Subject: [PATCH 3/8] fix(forms): frontend build --- .../[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx index 2649934c5..d9a38aa7f 100644 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx @@ -1,6 +1,6 @@ interface Props { children: React.ReactNode; - modal?: React.ReactNode; + modal: React.ReactNode; } export default function Layout({ children, modal }: Props) { From b0b55206f502eddb5ade40e6b8e01c1ddb01eae2 Mon Sep 17 00:00:00 2001 From: Santtu Pajukanta Date: Sat, 27 Jan 2024 19:16:37 +0200 Subject: [PATCH 4/8] feat(forms): isMultiValue and isShownToRespondent on EditDimensionForm --- .../[surveySlug]/dimensions/EditDimensionForm.tsx | 12 ++++++++++++ frontend/src/translations/en.tsx | 14 ++++++++++++-- frontend/src/translations/fi.tsx | 12 +++++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/EditDimensionForm.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/EditDimensionForm.tsx index c2e4508f2..7bf467796 100644 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/EditDimensionForm.tsx +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/EditDimensionForm.tsx @@ -27,6 +27,18 @@ export default function EditDimensionForm({ messages, headingLevel }: Props) { title: t.attributes.isKeyDimension.title, helpText: t.attributes.isKeyDimension.helpText, }, + { + type: "SingleCheckbox", + slug: "isMultiValue", + title: t.attributes.isMultiValue.title, + helpText: t.attributes.isMultiValue.helpText, + }, + { + type: "SingleCheckbox", + slug: "isShownToRespondent", + title: t.attributes.isShownToRespondent.title, + helpText: t.attributes.isShownToRespondent.helpText, + }, { type: "StaticText", slug: "localizedTitleHeader", diff --git a/frontend/src/translations/en.tsx b/frontend/src/translations/en.tsx index 31d2ddee4..501ef3a3e 100644 --- a/frontend/src/translations/en.tsx +++ b/frontend/src/translations/en.tsx @@ -383,9 +383,19 @@ const translations = { sv: "Title in Swedish", }, isKeyDimension: { - title: "This dimension is a key dimension", + title: "Key dimension", helpText: - "Values of key dimensions are displayed in the response list.", + "Values of key dimensions are displayed to in the response list.", + }, + isMultiValue: { + title: "Multi-value", + helpText: + "If checked, multiple values can be selected for this dimension.", + }, + isShownToRespondent: { + title: "Shown to respondent", + helpText: + "If checked, the values of this dimension are shown to the respondent in the single response view under their profile. Additionally, if this dimension is also a key dimension, it is shown in the responses list under their profile.", }, }, }, diff --git a/frontend/src/translations/fi.tsx b/frontend/src/translations/fi.tsx index 5b136bdab..fcd87386b 100644 --- a/frontend/src/translations/fi.tsx +++ b/frontend/src/translations/fi.tsx @@ -386,9 +386,19 @@ const translations: Translations = { sv: "Otsikko ruotsiksi", }, isKeyDimension: { - title: "Tämä dimensio on avaindimensio", + title: "Avaindimensio", helpText: "Avaindimensioiden arvot näytetään vastauslistassa.", }, + isMultiValue: { + title: "Moniarvoinen", + helpText: + "Jos tämä on valittuna, tähän dimensioon voidaan valita useita arvoja.", + }, + isShownToRespondent: { + title: "Näytetään vastaajalle", + helpText: + "Jos tämä on valittuna, tämän dimension arvot näytetään vastaajalle yksittäisen vastauksen näkymässä hänen profiilissaan. Lisäksi, jos tämä dimensio on myös avaindimensio, se näytetään profiilin vastauslistassa.", + }, }, }, }, From 84edece34466e464ba3293f214ec02d33038dbd6 Mon Sep 17 00:00:00 2001 From: Santtu Pajukanta Date: Sat, 27 Jan 2024 21:12:48 +0200 Subject: [PATCH 5/8] feat(forms): encapsulate DimensionBadge into component --- frontend/src/__generated__/gql.ts | 9 ++++- frontend/src/__generated__/graphql.ts | 5 ++- .../[surveySlug]/dimensions/actions.ts | 2 + .../profile/responses/[responseId]/page.tsx | 29 +++----------- .../components/dimensions/DimensionBadge.tsx | 38 +++++++++++++++++++ 5 files changed, 56 insertions(+), 27 deletions(-) create mode 100644 frontend/src/components/dimensions/DimensionBadge.tsx diff --git a/frontend/src/__generated__/gql.ts b/frontend/src/__generated__/gql.ts index 615c54d29..9ee04b368 100644 --- a/frontend/src/__generated__/gql.ts +++ b/frontend/src/__generated__/gql.ts @@ -31,9 +31,10 @@ const documents = { "\n query SurveyThankYouPageQuery(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String\n ) {\n event(slug: $eventSlug) {\n name\n\n forms {\n survey(slug: $surveySlug) {\n form(lang: $locale) {\n title\n thankYouMessage\n }\n }\n }\n }\n }\n": types.SurveyThankYouPageQueryDocument, "\n fragment Survey on SurveyType {\n slug\n title(lang: $locale)\n isActive\n activeFrom\n activeUntil\n countResponses\n\n languages {\n language\n }\n }\n": types.SurveyFragmentDoc, "\n query Surveys($eventSlug: String!, $locale: String) {\n event(slug: $eventSlug) {\n name\n\n forms {\n surveys {\n ...Survey\n }\n }\n }\n }\n": types.SurveysDocument, - "\n query ProfileSurveyResponsePage($locale: String!, $responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n\n dimensions {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n": types.ProfileSurveyResponsePageDocument, + "\n query ProfileSurveyResponsePage($locale: String!, $responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n\n dimensions {\n ...DimensionBadge\n }\n\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n": types.ProfileSurveyResponsePageDocument, "\n fragment ProfileResponsesTableRow on ProfileResponseType {\n id\n createdAt\n dimensions(keyDimensionsOnly: true) {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n form {\n slug\n title\n event {\n slug\n name\n }\n }\n }\n": types.ProfileResponsesTableRowFragmentDoc, "\n query OwnFormResponses($locale: String!) {\n profile {\n forms {\n responses {\n ...ProfileResponsesTableRow\n }\n }\n }\n }\n": types.OwnFormResponsesDocument, + "\n fragment DimensionBadge on ResponseDimensionValueType {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n": types.DimensionBadgeFragmentDoc, }; /** @@ -125,7 +126,7 @@ export function graphql(source: "\n query Surveys($eventSlug: String!, $locale: /** * 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 ProfileSurveyResponsePage($locale: String!, $responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n\n dimensions {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query ProfileSurveyResponsePage($locale: String!, $responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n\n dimensions {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n"]; +export function graphql(source: "\n query ProfileSurveyResponsePage($locale: String!, $responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n\n dimensions {\n ...DimensionBadge\n }\n\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query ProfileSurveyResponsePage($locale: String!, $responseId: String!) {\n profile {\n forms {\n response(id: $responseId) {\n id\n createdAt\n values\n\n dimensions {\n ...DimensionBadge\n }\n\n form {\n slug\n title\n language\n fields\n layout\n event {\n slug\n name\n }\n survey {\n anonymity\n }\n }\n }\n }\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -134,6 +135,10 @@ export function graphql(source: "\n fragment ProfileResponsesTableRow on Profil * 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 OwnFormResponses($locale: String!) {\n profile {\n forms {\n responses {\n ...ProfileResponsesTableRow\n }\n }\n }\n }\n"): (typeof documents)["\n query OwnFormResponses($locale: String!) {\n profile {\n forms {\n responses {\n ...ProfileResponsesTableRow\n }\n }\n }\n }\n"]; +/** + * 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 DimensionBadge on ResponseDimensionValueType {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n"): (typeof documents)["\n fragment DimensionBadge on ResponseDimensionValueType {\n dimension {\n slug\n title(lang: $locale)\n }\n\n value {\n slug\n title(lang: $locale)\n color\n }\n }\n"]; export function graphql(source: string) { return (documents as any)[source] ?? {}; diff --git a/frontend/src/__generated__/graphql.ts b/frontend/src/__generated__/graphql.ts index 65822e1e7..2ee016e3e 100644 --- a/frontend/src/__generated__/graphql.ts +++ b/frontend/src/__generated__/graphql.ts @@ -713,11 +713,14 @@ export type OwnFormResponsesQueryVariables = Exact<{ export type OwnFormResponsesQuery = { __typename?: 'Query', profile?: { __typename?: 'ProfileType', forms: { __typename?: 'FormsProfileMetaType', responses: Array<{ __typename?: 'ProfileResponseType', id: string, createdAt: string, dimensions?: Array<{ __typename?: 'ResponseDimensionValueType', dimension: { __typename?: 'SurveyDimensionType', slug: string, title?: string | null }, value: { __typename?: 'SurveyDimensionValueType', slug: string, title?: string | null, color: string } }> | null, form: { __typename?: 'FormType', slug: string, title: string, event: { __typename?: 'LimitedEventType', slug: string, name: string } } }> } } | null }; +export type DimensionBadgeFragment = { __typename?: 'ResponseDimensionValueType', dimension: { __typename?: 'SurveyDimensionType', slug: string, title?: string | null }, value: { __typename?: 'SurveyDimensionValueType', slug: string, title?: string | null, color: string } }; + export const ValueFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ValueFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]}]}}]} as unknown as DocumentNode; export const DimensionRowGroupFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionRowGroup"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]},{"kind":"Field","name":{"kind":"Name","value":"values"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ValueFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ValueFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]}]}}]} as unknown as DocumentNode; export const SurveyResponseFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SurveyResponse"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedResponseType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"displayName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"values"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyFieldsOnly"},"value":{"kind":"BooleanValue","value":true}}]},{"kind":"Field","name":{"kind":"Name","value":"cachedDimensions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyDimensionsOnly"},"value":{"kind":"BooleanValue","value":true}}]}]}}]} as unknown as DocumentNode; export const SurveyFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Survey"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyType"}},"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":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"activeFrom"}},{"kind":"Field","name":{"kind":"Name","value":"activeUntil"}},{"kind":"Field","name":{"kind":"Name","value":"countResponses"}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode; export const ProfileResponsesTableRowFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProfileResponsesTableRow"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProfileResponseType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyDimensionsOnly"},"value":{"kind":"BooleanValue","value":true}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimension"},"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":"value"},"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":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; +export const DimensionBadgeFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionBadge"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ResponseDimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimension"},"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":"value"},"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"}}]}}]}}]} as unknown as DocumentNode; export const NewProgramQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NewProgramQuery"},"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":"formSlug"}},"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":"program"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"skipOfferFormSelection"}},{"kind":"Field","name":{"kind":"Name","value":"offerForm"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"formSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"form"},"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":"title"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const NewProgramFormSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NewProgramFormSelectionQuery"},"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":"program"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"skipOfferFormSelection"}},{"kind":"Field","name":{"kind":"Name","value":"offerForms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"shortDescription"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"form"},"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":"title"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const CreateSurveyResponseDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSurveyResponse"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateSurveyResponseInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSurveyResponse"},"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":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; @@ -732,5 +735,5 @@ export const FormResponsesDocument = {"kind":"Document","definitions":[{"kind":" export const SurveySummaryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SurveySummary"},"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":"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":"name"}},{"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"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":"fields"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"summary"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}]},{"kind":"Field","alias":{"kind":"Name","value":"countFilteredResponses"},"name":{"kind":"Name","value":"countResponses"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}]},{"kind":"Field","name":{"kind":"Name","value":"countResponses"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"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":"values"},"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"}}}]}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const SurveyThankYouPageQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SurveyThankYouPageQuery"},"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":"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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"form"},"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":"title"}},{"kind":"Field","name":{"kind":"Name","value":"thankYouMessage"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const SurveysDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Surveys"},"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":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"surveys"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Survey"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Survey"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyType"}},"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":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"activeFrom"}},{"kind":"Field","name":{"kind":"Name","value":"activeUntil"}},{"kind":"Field","name":{"kind":"Name","value":"countResponses"}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode; -export const ProfileSurveyResponsePageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProfileSurveyResponsePage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"responseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"response"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"responseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"values"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimension"},"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":"value"},"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":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"survey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"anonymity"}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const ProfileSurveyResponsePageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProfileSurveyResponsePage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"responseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"response"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"responseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"values"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionBadge"}}]}},{"kind":"Field","name":{"kind":"Name","value":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"survey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"anonymity"}}]}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionBadge"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ResponseDimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimension"},"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":"value"},"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"}}]}}]}}]} as unknown as DocumentNode; export const OwnFormResponsesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"OwnFormResponses"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"responses"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProfileResponsesTableRow"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProfileResponsesTableRow"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProfileResponseType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyDimensionsOnly"},"value":{"kind":"BooleanValue","value":true}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimension"},"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":"value"},"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":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts index 55ceb2416..52a16a46f 100644 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts @@ -1,5 +1,6 @@ "use server"; +import { revalidatePath } from "next/cache"; import { redirect } from "next/navigation"; import { graphql } from "@/__generated__"; import { getClient } from "@/apolloClient"; @@ -29,6 +30,7 @@ export async function createDimension( }, }, }); + revalidatePath(`/events/${eventSlug}/surveys/${surveySlug}`); redirect(`/events/${eventSlug}/surveys/${surveySlug}/dimensions`); } diff --git a/frontend/src/app/[locale]/profile/responses/[responseId]/page.tsx b/frontend/src/app/[locale]/profile/responses/[responseId]/page.tsx index d2821c473..2b3f91c5c 100644 --- a/frontend/src/app/[locale]/profile/responses/[responseId]/page.tsx +++ b/frontend/src/app/[locale]/profile/responses/[responseId]/page.tsx @@ -4,10 +4,7 @@ import { notFound } from "next/navigation"; import { graphql } from "@/__generated__"; import { getClient } from "@/apolloClient"; import { auth } from "@/auth"; -import { - makeBadgeBackgroundColor, - makeColorTranslucent, -} from "@/components/dimensions/helpers"; +import DimensionBadge from "@/components/dimensions/DimensionBadge"; import { Field, validateFields } from "@/components/SchemaForm/models"; import SchemaFormField from "@/components/SchemaForm/SchemaFormField"; import SchemaFormInput from "@/components/SchemaForm/SchemaFormInput"; @@ -27,16 +24,7 @@ const query = graphql(` values dimensions { - dimension { - slug - title(lang: $locale) - } - - value { - slug - title(lang: $locale) - color - } + ...DimensionBadge } form { @@ -155,17 +143,10 @@ export default async function ProfileSurveyResponsePage({ params }: Props) { {!!dimensions?.length && (

{dimensions.map((dimension) => ( - - {dimension.value.title} - + dimension={dimension} + /> ))}

)} diff --git a/frontend/src/components/dimensions/DimensionBadge.tsx b/frontend/src/components/dimensions/DimensionBadge.tsx new file mode 100644 index 000000000..fc1a40dbb --- /dev/null +++ b/frontend/src/components/dimensions/DimensionBadge.tsx @@ -0,0 +1,38 @@ +import { makeBadgeBackgroundColor } from "./helpers"; +import { graphql } from "@/__generated__"; +import { DimensionBadgeFragment } from "@/__generated__/graphql"; + +graphql(` + fragment DimensionBadge on ResponseDimensionValueType { + dimension { + slug + title(lang: $locale) + } + + value { + slug + title(lang: $locale) + color + } + } +`); + +interface Props { + dimension: DimensionBadgeFragment; +} + +export default function DimensionBadge({ dimension }: Props) { + return ( + + {dimension.value.title} + + ); +} From addcadbde51ebcb73753132b89f36068c522ed13 Mon Sep 17 00:00:00 2001 From: Santtu Pajukanta Date: Sat, 27 Jan 2024 22:16:12 +0200 Subject: [PATCH 6/8] feat(forms): beholden the monstrosity that is DimensionTable --- frontend/src/__generated__/gql.ts | 5 - frontend/src/__generated__/graphql.ts | 10 - frontend/src/app/[locale]/default.tsx | 3 - .../dimensions/@modal/(.)new/page.tsx | 34 --- .../dimensions/@modal/default.tsx | 3 - .../[surveySlug]/dimensions/ModalButton.tsx | 60 +++++ .../surveys/[surveySlug]/dimensions/TODO.md | 21 -- .../[surveySlug]/dimensions/layout.tsx | 13 -- .../[surveySlug]/dimensions/new/page.tsx | 119 ---------- .../surveys/[surveySlug]/dimensions/page.tsx | 217 +++++++++++++----- frontend/src/app/[locale]/globals.scss | 10 +- frontend/src/translations/en.tsx | 6 +- frontend/src/translations/fi.tsx | 6 +- 13 files changed, 243 insertions(+), 264 deletions(-) delete mode 100644 frontend/src/app/[locale]/default.tsx delete mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/(.)new/page.tsx delete mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/default.tsx create mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/ModalButton.tsx delete mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/TODO.md delete mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx delete mode 100644 frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/new/page.tsx diff --git a/frontend/src/__generated__/gql.ts b/frontend/src/__generated__/gql.ts index 9ee04b368..ba3fe0b49 100644 --- a/frontend/src/__generated__/gql.ts +++ b/frontend/src/__generated__/gql.ts @@ -18,7 +18,6 @@ const documents = { "\n mutation CreateSurveyResponse($input: CreateSurveyResponseInput!) {\n createSurveyResponse(input: $input) {\n response {\n id\n }\n }\n }\n": types.CreateSurveyResponseDocument, "\n mutation InitFileUploadMutation($input: InitFileUploadInput!) {\n initFileUpload(input: $input) {\n uploadUrl\n fileUrl\n }\n }\n": types.InitFileUploadMutationDocument, "\n mutation CreateSurveyDimension($input: CreateSurveyDimensionInput!) {\n createSurveyDimension(input: $input) {\n dimension {\n slug\n }\n }\n }\n": types.CreateSurveyDimensionDocument, - "\n query NewDimensionPage(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n }\n }\n }\n }\n": types.NewDimensionPageDocument, "\n fragment ValueFields on SurveyDimensionValueType {\n slug\n color\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n }\n": types.ValueFieldsFragmentDoc, "\n fragment DimensionRowGroup on SurveyDimensionType {\n slug\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n values {\n ...ValueFields\n }\n }\n": types.DimensionRowGroupFragmentDoc, "\n query DimensionsList(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n dimensions {\n ...DimensionRowGroup\n }\n }\n }\n }\n }\n": types.DimensionsListDocument, @@ -71,10 +70,6 @@ export function graphql(source: "\n mutation InitFileUploadMutation($input: Ini * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "\n mutation CreateSurveyDimension($input: CreateSurveyDimensionInput!) {\n createSurveyDimension(input: $input) {\n dimension {\n slug\n }\n }\n }\n"): (typeof documents)["\n mutation CreateSurveyDimension($input: CreateSurveyDimensionInput!) {\n createSurveyDimension(input: $input) {\n dimension {\n slug\n }\n }\n }\n"]; -/** - * 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 NewDimensionPage(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n }\n }\n }\n }\n"): (typeof documents)["\n query NewDimensionPage(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\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/frontend/src/__generated__/graphql.ts b/frontend/src/__generated__/graphql.ts index 2ee016e3e..54837cb8e 100644 --- a/frontend/src/__generated__/graphql.ts +++ b/frontend/src/__generated__/graphql.ts @@ -607,15 +607,6 @@ export type CreateSurveyDimensionMutationVariables = Exact<{ export type CreateSurveyDimensionMutation = { __typename?: 'Mutation', createSurveyDimension?: { __typename?: 'CreateSurveyDimension', dimension?: { __typename?: 'SurveyDimensionType', slug: string } | null } | null }; -export type NewDimensionPageQueryVariables = Exact<{ - eventSlug: Scalars['String']['input']; - surveySlug: Scalars['String']['input']; - locale: Scalars['String']['input']; -}>; - - -export type NewDimensionPageQuery = { __typename?: 'Query', event?: { __typename?: 'FullEventType', name: string, forms?: { __typename?: 'FormsEventMetaType', survey?: { __typename?: 'SurveyType', title?: string | null } | null } | null } | null }; - export type ValueFieldsFragment = { __typename?: 'SurveyDimensionValueType', slug: string, color: string, titleFi?: string | null, titleEn?: string | null }; export type DimensionRowGroupFragment = { __typename?: 'SurveyDimensionType', slug: string, titleFi?: string | null, titleEn?: string | null, values: Array<{ __typename?: 'SurveyDimensionValueType', slug: string, color: string, titleFi?: string | null, titleEn?: string | null }> }; @@ -726,7 +717,6 @@ export const NewProgramFormSelectionQueryDocument = {"kind":"Document","definiti export const CreateSurveyResponseDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSurveyResponse"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateSurveyResponseInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSurveyResponse"},"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":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; export const InitFileUploadMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InitFileUploadMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"InitFileUploadInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"initFileUpload"},"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":"uploadUrl"}},{"kind":"Field","name":{"kind":"Name","value":"fileUrl"}}]}}]}}]} as unknown as DocumentNode; export const CreateSurveyDimensionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSurveyDimension"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateSurveyDimensionInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSurveyDimension"},"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 NewDimensionPageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NewDimensionPage"},"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":"locale"}},"type":{"kind":"NonNullType","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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]}]}}]}}]}}]}}]} as unknown as DocumentNode; export const DimensionsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"DimensionsList"},"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":"locale"}},"type":{"kind":"NonNullType","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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"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":"dimensions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionRowGroup"}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ValueFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionRowGroup"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]},{"kind":"Field","name":{"kind":"Name","value":"values"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ValueFields"}}]}}]}}]} as unknown as DocumentNode; export const SurveyPageQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SurveyPageQuery"},"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":"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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"loginRequired"}},{"kind":"Field","name":{"kind":"Name","value":"anonymity"}},{"kind":"Field","name":{"kind":"Name","value":"maxResponsesPerUser"}},{"kind":"Field","name":{"kind":"Name","value":"countResponsesByCurrentUser"}},{"kind":"Field","name":{"kind":"Name","value":"form"},"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":"title"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const UpdateResponseDimensionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateResponseDimensions"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateResponseDimensionsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateResponseDimensions"},"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":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; diff --git a/frontend/src/app/[locale]/default.tsx b/frontend/src/app/[locale]/default.tsx deleted file mode 100644 index 0038780e6..000000000 --- a/frontend/src/app/[locale]/default.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export function Default() { - return null; -} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/(.)new/page.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/(.)new/page.tsx deleted file mode 100644 index f66f7ac9e..000000000 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/(.)new/page.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { createDimension } from "../../actions"; -import EditDimensionForm from "../../EditDimensionForm"; -import InterceptingRouteModal from "@/components/InterceptingRouteModal"; -import { getTranslations } from "@/translations"; - -interface Props { - params: { - locale: string; - eventSlug: string; - surveySlug: string; - }; -} - -export default function NewDimensionModal({ params }: Props) { - const { eventSlug, surveySlug, locale } = params; - const translations = getTranslations(locale); - const t = translations.Survey.editDimensionModal; - - return ( - - - - ); -} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/default.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/default.tsx deleted file mode 100644 index 6ddf1b76f..000000000 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/@modal/default.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Default() { - return null; -} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/ModalButton.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/ModalButton.tsx new file mode 100644 index 000000000..972b54d28 --- /dev/null +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/ModalButton.tsx @@ -0,0 +1,60 @@ +"use client"; + +import { ReactNode, useCallback, useState } from "react"; +import Button from "react-bootstrap/Button"; +import Modal from "react-bootstrap/Modal"; +import type { Translations } from "@/translations/en"; + +interface Props { + title: string; + label?: ReactNode; + children?: ReactNode; + action?(formData: FormData): void; + messages: Translations["Modal"]; + className?: string; +} + +/// Renders a button that opens a modal. Pass modal contents as children +export default function ModalButton({ + title, + label, + children, + action, + messages, + className = "btn btn-link p-0 link-subtle", +}: Props) { + const [isVisible, setIsVisible] = useState(false); + const close = useCallback(() => { + setIsVisible(false); + }, []); + + return ( + <> + + + + {title} + + +
+ {children} + + + + + +
+
+ + ); +} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/TODO.md b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/TODO.md deleted file mode 100644 index eb42ff9c0..000000000 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/TODO.md +++ /dev/null @@ -1,21 +0,0 @@ -# Intercepting routes may be too heavy machinery for the dimension editor - -The new dimension / edit dimension modal was written using an intercepting route. This allows both opening it as a modal on top of the dimensions view and navigating to it as a stand-alone view. - -While a fun exercise in intercepting routes, this may not be very useful or necessary for the actual use case. - -## On a hard reload, can we open the dimensions page and then the modal on top of it - -…without resorting to some `?intent=createValue(dimensionSlug)` that redirects to the intercepting route? - -For example: The user navigates to `/event/hitpoint2024/surveys/larp-survey/dimensions/new`. Instead of opening the form as a standalone page, could we make it open the dimensions view and then the modal on top of it, so that the Next.js recommended way of closing the modal with `router.back()` would work. - -## Check if the @modal can be pushed to root layout - -If we settle on using intercepting routes, there are still things we could do - -It's a bit unwieldy to have to create the layout containing a `@modal` slot, with its own `default.tsx`, in every page that happens to use modals via intercepting routes. See if it would be possible to move the `@modal` slot to the root layout. - -## See also - -- [Next.js documentation: Intercepting routes](https://nextjs.org/docs/app/building-your-application/routing/intercepting-routes) diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx deleted file mode 100644 index d9a38aa7f..000000000 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/layout.tsx +++ /dev/null @@ -1,13 +0,0 @@ -interface Props { - children: React.ReactNode; - modal: React.ReactNode; -} - -export default function Layout({ children, modal }: Props) { - return ( - <> - {children} - {modal} - - ); -} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/new/page.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/new/page.tsx deleted file mode 100644 index 1f03eaf17..000000000 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/new/page.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import Link from "next/link"; -import { notFound } from "next/navigation"; -import { createDimension } from "../actions"; -import EditDimensionForm from "../EditDimensionForm"; -import { graphql } from "@/__generated__"; -import { getClient } from "@/apolloClient"; -import { auth } from "@/auth"; -import SubmitButton from "@/components/SchemaForm/SubmitButton"; -import SignInRequired from "@/components/SignInRequired"; -import ViewContainer from "@/components/ViewContainer"; -import ViewHeading from "@/components/ViewHeading"; -import getPageTitle from "@/helpers/getPageTitle"; -import { getTranslations } from "@/translations"; - -const query = graphql(` - query NewDimensionPage( - $eventSlug: String! - $surveySlug: String! - $locale: String! - ) { - event(slug: $eventSlug) { - name - forms { - survey(slug: $surveySlug) { - title(lang: $locale) - } - } - } - } -`); - -interface Props { - params: { - locale: string; - eventSlug: string; - surveySlug: string; - }; -} - -export async function generateMetadata({ params }: Props) { - const { locale, eventSlug, surveySlug } = params; - const translations = getTranslations(locale); - - // TODO encap - const session = await auth(); - if (!session) { - return translations.SignInRequired.metadata; - } - - const t = translations.Survey; - - const { data } = await getClient().query({ - query, - variables: { locale, eventSlug, surveySlug }, - }); - - if (!data.event?.forms?.survey) { - notFound(); - } - - const title = getPageTitle({ - translations, - event: data.event, - subject: data.event.forms.survey.title, - viewTitle: t.actions.addDimension, - }); - - return { title }; -} - -export default async function NewDimensionPage({ params }: Props) { - const { eventSlug, surveySlug, locale } = params; - const translations = getTranslations(locale); - const t = translations.Survey; - - // TODO encap - const session = await auth(); - if (!session) { - return ; - } - - const { data } = await getClient().query({ - query, - variables: { locale, eventSlug, surveySlug }, - }); - - if (!data.event?.forms?.survey) { - notFound(); - } - - const survey = data.event.forms.survey; - - return ( - - - < {t.actions.returnToDimensionList} - - - - {t.actions.addDimension} - {survey.title} - - -
- - {t.editDimensionModal.actions.submit} - -
- ); -} diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx index 7c772d721..f7dc9ea90 100644 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/page.tsx @@ -1,6 +1,15 @@ import Link from "next/link"; import { notFound } from "next/navigation"; -import { Fragment } from "react"; +import { + createDimension, + createDimensionValue, + deleteDimension, + deleteDimensionValue, + updateDimension, + updateDimensionValue, +} from "./actions"; +import EditDimensionForm from "./EditDimensionForm"; +import ModalButton from "./ModalButton"; import { graphql } from "@/__generated__"; import { DimensionRowGroupFragment, @@ -8,10 +17,7 @@ import { } from "@/__generated__/graphql"; import { getClient } from "@/apolloClient"; import { auth } from "@/auth"; -import { - makeColorTranslucent, - makeBadgeBackgroundColor, -} from "@/components/dimensions/helpers"; +import { makeColorTranslucent } from "@/components/dimensions/helpers"; import SignInRequired from "@/components/SignInRequired"; import ViewContainer from "@/components/ViewContainer"; import ViewHeading from "@/components/ViewHeading"; @@ -58,41 +64,6 @@ const query = graphql(` } `); -function DimensionCells({ - dimension, -}: { - dimension: DimensionRowGroupFragment; -}) { - const rowspan = dimension.values.length + 1; - return ( - <> - - {dimension.slug} - - - {dimension.titleFi} - - - {dimension.titleEn} - - - ); -} - -function ValueCells({ value }: { value: ValueFieldsFragment }) { - const backgroundColor = value.color && makeColorTranslucent(value.color); - - return ( - <> - - {value.slug} - - {value.titleFi} - {value.titleEn} - - ); -} - interface Props { params: { locale: string; @@ -163,6 +134,62 @@ export default async function SurveyDimensionsPage({ params }: Props) { const countColumns = 6; + function DimensionCells({ + dimension, + }: { + dimension: DimensionRowGroupFragment; + }) { + const rowspan = dimension.values.length + 1; + return ( + <> + +
+ +
+ + ✏️ + {dimension.slug} + + } + messages={t.editDimensionModal.actions} + action={updateDimension.bind( + null, + eventSlug, + surveySlug, + dimension.slug, + )} + > +

TODO

+
+ + + {dimension.titleFi} + + + {dimension.titleEn} + + + ); + } + function AddValueCell({ dimension, }: { @@ -170,16 +197,86 @@ export default async function SurveyDimensionsPage({ params }: Props) { }) { return ( - + + {t.actions.addDimensionValue} + + } + messages={t.editDimensionModal.actions} + action={createDimensionValue.bind( + null, + eventSlug, + surveySlug, + dimension.slug, + )} > - {t.actions.addValue}… - +

TODO

+ ); } + function ValueCells({ + value, + dimension, + }: { + value: ValueFieldsFragment; + dimension: DimensionRowGroupFragment; + }) { + const backgroundColor = value.color && makeColorTranslucent(value.color); + + return ( + <> + +
+ +
+ + ✏️ + {value.slug} + + } + messages={t.editDimensionModal.actions} + action={updateDimensionValue.bind( + null, + eventSlug, + surveySlug, + dimension.slug, + value.slug, + )} + > +

TODO

+
+ + {value.titleFi} + {value.titleEn} + + ); + } + function DimensionRowGroup({ dimension, }: { @@ -187,7 +284,7 @@ export default async function SurveyDimensionsPage({ params }: Props) { }) { if (dimension.values.length === 0) { return ( - + @@ -200,7 +297,7 @@ export default async function SurveyDimensionsPage({ params }: Props) { return ( {valueIndex === 0 && } - + ); })} @@ -223,7 +320,7 @@ export default async function SurveyDimensionsPage({ params }: Props) { - + @@ -238,12 +335,26 @@ export default async function SurveyDimensionsPage({ params }: Props) { ))} diff --git a/frontend/src/app/[locale]/globals.scss b/frontend/src/app/[locale]/globals.scss index 051028758..01dab2098 100644 --- a/frontend/src/app/[locale]/globals.scss +++ b/frontend/src/app/[locale]/globals.scss @@ -2,10 +2,18 @@ $primary: rgb(11, 95, 138); $table-striped-bg-factor: 0.03; @import "~bootstrap/scss/bootstrap"; -a.link-subtle { +.link-subtle { color: $primary; text-decoration: none; &:hover { text-decoration: underline; } } + +.link-xsubtle { + color: $primary; + text-decoration: none; + &:hover { + text-decoration: none; + } +} diff --git a/frontend/src/translations/en.tsx b/frontend/src/translations/en.tsx index 501ef3a3e..7625e2bd2 100644 --- a/frontend/src/translations/en.tsx +++ b/frontend/src/translations/en.tsx @@ -329,7 +329,11 @@ const translations = { returnToDimensionList: "Return to the list of dimensions", saveDimensions: "Save dimensions", addDimension: "Add dimension", - addValue: "Add value", + addDimensionValue: "Add value", + deleteDimension: "Delete dimension", + deleteDimensionValue: "Delete value", + editDimension: "Edit dimension", + editDimensionValue: "Edit value", }, tabs: { summary: "Summary", diff --git a/frontend/src/translations/fi.tsx b/frontend/src/translations/fi.tsx index fcd87386b..de3f9454e 100644 --- a/frontend/src/translations/fi.tsx +++ b/frontend/src/translations/fi.tsx @@ -328,7 +328,11 @@ const translations: Translations = { returnToDimensionList: "Palaa dimensiolistaukseen", saveDimensions: "Tallenna dimensiot", addDimension: "Lisää dimensio", - addValue: "Lisää arvo", + addDimensionValue: "Lisää arvo", + deleteDimension: "Poista dimensio", + deleteDimensionValue: "Poista arvo", + editDimension: "Muokkaa dimensiota", + editDimensionValue: "Muokkaa arvoa", }, tabs: { summary: "Yhteenveto", From f57626a1fd8f75983bb16423e94a2c91d331767f Mon Sep 17 00:00:00 2001 From: Santtu Pajukanta Date: Sun, 28 Jan 2024 02:59:34 +0200 Subject: [PATCH 7/8] chore(tracon2024): expense claim form improvements --- .../forms/expense-claim-dimensions.yml | 20 +++++++++++ .../tracon2024/forms/expense-claim-fi.yml | 35 ++----------------- .../management/commands/setup_tracon2024.py | 2 +- 3 files changed, 23 insertions(+), 34 deletions(-) diff --git a/backend/events/tracon2024/forms/expense-claim-dimensions.yml b/backend/events/tracon2024/forms/expense-claim-dimensions.yml index 4ed9a80f7..9fafebac8 100644 --- a/backend/events/tracon2024/forms/expense-claim-dimensions.yml +++ b/backend/events/tracon2024/forms/expense-claim-dimensions.yml @@ -1,3 +1,23 @@ +- slug: event + title: + fi: Tapahtuma + en: Event + is_key_dimension: true + is_shown_to_respondent: true + choices: + - slug: tracon2024 + title: + fi: Tracon 2024 + en: Tracon 2024 + - slug: hitpoint2024 + title: + fi: Tracon Hitpoint 2024 + en: Tracon Hitpoint 2024 + - slug: no-event + title: + fi: Maksu ei liity tapahtumaan + en: The payment is not related to an event + - slug: type title: fi: Maksun tyyppi diff --git a/backend/events/tracon2024/forms/expense-claim-fi.yml b/backend/events/tracon2024/forms/expense-claim-fi.yml index 1871994c5..c9dbe53d3 100644 --- a/backend/events/tracon2024/forms/expense-claim-fi.yml +++ b/backend/events/tracon2024/forms/expense-claim-fi.yml @@ -1,30 +1,13 @@ title: Hae kulukorvausta layout: vertical description: | - Tällä lomakkeella voit hakea kulukorvausta vuoden 2024 Traconiin liittyvistä kuluista, + Tällä lomakkeella voit hakea kulukorvausta Tracon ry:ltä tapahtumaan tai yhdistystoimintaan liittyvästä kulusta, lähettää Tracon ry:lle laskun tai toimittaa Tracon ry:n pankkikortilla maksetun kulun kuitin. Täytä lomake huolellisesti ja liitä mukaan kaikki pyydetyt liitteet. - Jos haet kulukorvausta vuoden 2024 Tracon Hitpoint -tapahtumaan liittyvistä kuluista, - käytä Hitpointin kulukorvauslomaketta. - - Jos haet kulukorvausta kulusta, joka ei liity suoraan kumpaankaan tapahtumaan, - käytä yleistä kulukorvauslomaketta. - Jos sinulla on kysyttävää kulukorvauksista, ota yhteyttä Tracon ry:n rahastonhoitajaan sähköpostitse osoitteella rahat ät tracon piste fi tai Slackissa @Aketzu. fields: - - slug: type - type: SingleSelect - title: Kulukorvauksen tyyppi - helpText: | - Tilisiirto: Olet maksanut kulun itse ja haet korvausta tilisiirtona.
- Lasku: Laskuttaja on lähettänyt Tracon ry:lle laskun, joka maksetaan suoraan laskuttajalle.
- Korttimaksu: Olet maksanut kulun Tracon ry:n pankkikortilla. Kirjoita saajan tilinumero -kenttään "-" (viiva). - required: true - choicesFrom: - dimension: type - - slug: title type: SingleLineText title: Otsikko @@ -49,9 +32,9 @@ fields: - slug: recipient type: SingleLineText title: Saaja + required: true helpText: | Kenen tilille korvaus maksetaan? Kirjoita tähän etu- ja sukunimi tai yrityksen nimi. - Jos korvaus maksetaan omalle tilillesi, voit jättää tämän kentän tyhjäksi. - slug: recipient_iban type: SingleLineText @@ -60,20 +43,6 @@ fields: helpText: | Mille tilille korvaus maksetaan? Kirjoita IBAN-tilinumero muodossa FI12 3456 7890 1234 56. - - slug: recipient_bic - type: SingleLineText - title: Saajan pankin SWIFT/BIC-koodi - helpText: | - Minkä pankin tilille korvaus maksetaan? Kirjoita pankin SWIFT/BIC-koodi (esim. HOLVFIHH tai NDEAFIHH). - Jos saajan tili on suomalaisessa pankissa eli tilinumero alkaa FI, voit jättää tämän kentän tyhjäksi. - - - slug: reference_number - type: SingleLineText - title: Viitenumero - helpText: | - Jos kulukorvaukseen liittyy lasku jolla on viitenumero, kirjoita se tähän. - Muutoin voit jättää tämän kentän tyhjäksi. - - slug: attachments type: FileUpload title: Tositteet diff --git a/backend/events/tracon2024/management/commands/setup_tracon2024.py b/backend/events/tracon2024/management/commands/setup_tracon2024.py index 89ebda8c8..758ad394e 100644 --- a/backend/events/tracon2024/management/commands/setup_tracon2024.py +++ b/backend/events/tracon2024/management/commands/setup_tracon2024.py @@ -978,7 +978,7 @@ def setup_forms(self): slug="expense-claim", defaults=dict( active_from=now(), - key_fields=["title"], + key_fields=["title", "amount"], login_required=True, anonymity="NAME_AND_EMAIL", ), From ffd2aa60972b0bc6dfcc32d5eba7a3b2dc9ec733 Mon Sep 17 00:00:00 2001 From: Santtu Pajukanta Date: Sun, 28 Jan 2024 03:11:09 +0200 Subject: [PATCH 8/8] feat(forms): delete dimension --- .../mutations/delete_survey_dimension.py | 36 +++++++++++++++++++ backend/graphql_api/schema.py | 2 ++ frontend/src/__generated__/gql.ts | 5 +++ frontend/src/__generated__/graphql.ts | 25 +++++++++++++ .../[surveySlug]/dimensions/actions.ts | 22 ++++++++++-- 5 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 backend/forms/graphql/mutations/delete_survey_dimension.py diff --git a/backend/forms/graphql/mutations/delete_survey_dimension.py b/backend/forms/graphql/mutations/delete_survey_dimension.py new file mode 100644 index 000000000..49ff9ddef --- /dev/null +++ b/backend/forms/graphql/mutations/delete_survey_dimension.py @@ -0,0 +1,36 @@ +import graphene + +from access.cbac import graphql_check_access + +from ...models.survey import Survey + + +class DeleteSurveyDimensionInput(graphene.InputObjectType): + event_slug = graphene.String(required=True) + survey_slug = graphene.String(required=True) + dimension_slug = graphene.String(required=True) + + +class DeleteSurveyDimension(graphene.Mutation): + class Arguments: + input = DeleteSurveyDimensionInput(required=True) + + slug = graphene.Field(graphene.String) + + @staticmethod + def mutate( + root, + info, + input: DeleteSurveyDimensionInput, + ): + survey = Survey.objects.get(event__slug=input.event_slug, slug=input.survey_slug) + + # TODO bastardization of graphql_check_access, rethink + graphql_check_access(survey, info, "dimensions", "mutation") + + # TODO can_delete + + dimension = survey.dimensions.get(slug=input.dimension_slug) + dimension.delete() + + return DeleteSurveyDimension(slug=input.survey_slug) # type: ignore diff --git a/backend/graphql_api/schema.py b/backend/graphql_api/schema.py index fc396cd76..e78cf4481 100644 --- a/backend/graphql_api/schema.py +++ b/backend/graphql_api/schema.py @@ -8,6 +8,7 @@ from core.models import Event, Person from forms.graphql.mutations.create_survey_dimension import CreateSurveyDimension from forms.graphql.mutations.create_survey_response import CreateSurveyResponse +from forms.graphql.mutations.delete_survey_dimension import DeleteSurveyDimension from forms.graphql.mutations.init_file_upload import InitFileUpload from forms.graphql.mutations.update_response_dimensions import UpdateResponseDimensions @@ -62,6 +63,7 @@ def resolve_profile(root, info): class Mutation(graphene.ObjectType): create_survey_dimension = CreateSurveyDimension.Field() create_survey_response = CreateSurveyResponse.Field() + delete_survey_dimension = DeleteSurveyDimension.Field() init_file_upload = InitFileUpload.Field() update_response_dimensions = UpdateResponseDimensions.Field() diff --git a/frontend/src/__generated__/gql.ts b/frontend/src/__generated__/gql.ts index ba3fe0b49..6111d6960 100644 --- a/frontend/src/__generated__/gql.ts +++ b/frontend/src/__generated__/gql.ts @@ -18,6 +18,7 @@ const documents = { "\n mutation CreateSurveyResponse($input: CreateSurveyResponseInput!) {\n createSurveyResponse(input: $input) {\n response {\n id\n }\n }\n }\n": types.CreateSurveyResponseDocument, "\n mutation InitFileUploadMutation($input: InitFileUploadInput!) {\n initFileUpload(input: $input) {\n uploadUrl\n fileUrl\n }\n }\n": types.InitFileUploadMutationDocument, "\n mutation CreateSurveyDimension($input: CreateSurveyDimensionInput!) {\n createSurveyDimension(input: $input) {\n dimension {\n slug\n }\n }\n }\n": types.CreateSurveyDimensionDocument, + "\n mutation DeleteSurveyDimension($input: DeleteSurveyDimensionInput!) {\n deleteSurveyDimension(input: $input) {\n slug\n }\n }\n": types.DeleteSurveyDimensionDocument, "\n fragment ValueFields on SurveyDimensionValueType {\n slug\n color\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n }\n": types.ValueFieldsFragmentDoc, "\n fragment DimensionRowGroup on SurveyDimensionType {\n slug\n titleFi: title(lang: \"fi\")\n titleEn: title(lang: \"en\")\n values {\n ...ValueFields\n }\n }\n": types.DimensionRowGroupFragmentDoc, "\n query DimensionsList(\n $eventSlug: String!\n $surveySlug: String!\n $locale: String!\n ) {\n event(slug: $eventSlug) {\n name\n forms {\n survey(slug: $surveySlug) {\n title(lang: $locale)\n dimensions {\n ...DimensionRowGroup\n }\n }\n }\n }\n }\n": types.DimensionsListDocument, @@ -70,6 +71,10 @@ export function graphql(source: "\n mutation InitFileUploadMutation($input: Ini * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "\n mutation CreateSurveyDimension($input: CreateSurveyDimensionInput!) {\n createSurveyDimension(input: $input) {\n dimension {\n slug\n }\n }\n }\n"): (typeof documents)["\n mutation CreateSurveyDimension($input: CreateSurveyDimensionInput!) {\n createSurveyDimension(input: $input) {\n dimension {\n slug\n }\n }\n }\n"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "\n mutation DeleteSurveyDimension($input: DeleteSurveyDimensionInput!) {\n deleteSurveyDimension(input: $input) {\n slug\n }\n }\n"): (typeof documents)["\n mutation DeleteSurveyDimension($input: DeleteSurveyDimensionInput!) {\n deleteSurveyDimension(input: $input) {\n slug\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/frontend/src/__generated__/graphql.ts b/frontend/src/__generated__/graphql.ts index 54837cb8e..7e7046c01 100644 --- a/frontend/src/__generated__/graphql.ts +++ b/frontend/src/__generated__/graphql.ts @@ -63,6 +63,17 @@ export type CreateSurveyResponseInput = { surveySlug: Scalars['String']['input']; }; +export type DeleteSurveyDimension = { + __typename?: 'DeleteSurveyDimension'; + slug?: Maybe; +}; + +export type DeleteSurveyDimensionInput = { + dimensionSlug: Scalars['String']['input']; + eventSlug: Scalars['String']['input']; + surveySlug: Scalars['String']['input']; +}; + export type DimensionFilterInput = { dimension?: InputMaybe; values?: InputMaybe>>; @@ -292,6 +303,7 @@ export type Mutation = { __typename?: 'Mutation'; createSurveyDimension?: Maybe; createSurveyResponse?: Maybe; + deleteSurveyDimension?: Maybe; initFileUpload?: Maybe; updateResponseDimensions?: Maybe; }; @@ -307,6 +319,11 @@ export type MutationCreateSurveyResponseArgs = { }; +export type MutationDeleteSurveyDimensionArgs = { + input: DeleteSurveyDimensionInput; +}; + + export type MutationInitFileUploadArgs = { input: InitFileUploadInput; }; @@ -607,6 +624,13 @@ export type CreateSurveyDimensionMutationVariables = Exact<{ export type CreateSurveyDimensionMutation = { __typename?: 'Mutation', createSurveyDimension?: { __typename?: 'CreateSurveyDimension', dimension?: { __typename?: 'SurveyDimensionType', slug: string } | null } | null }; +export type DeleteSurveyDimensionMutationVariables = Exact<{ + input: DeleteSurveyDimensionInput; +}>; + + +export type DeleteSurveyDimensionMutation = { __typename?: 'Mutation', deleteSurveyDimension?: { __typename?: 'DeleteSurveyDimension', slug?: string | null } | null }; + export type ValueFieldsFragment = { __typename?: 'SurveyDimensionValueType', slug: string, color: string, titleFi?: string | null, titleEn?: string | null }; export type DimensionRowGroupFragment = { __typename?: 'SurveyDimensionType', slug: string, titleFi?: string | null, titleEn?: string | null, values: Array<{ __typename?: 'SurveyDimensionValueType', slug: string, color: string, titleFi?: string | null, titleEn?: string | null }> }; @@ -717,6 +741,7 @@ export const NewProgramFormSelectionQueryDocument = {"kind":"Document","definiti export const CreateSurveyResponseDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSurveyResponse"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateSurveyResponseInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSurveyResponse"},"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":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; export const InitFileUploadMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InitFileUploadMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"InitFileUploadInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"initFileUpload"},"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":"uploadUrl"}},{"kind":"Field","name":{"kind":"Name","value":"fileUrl"}}]}}]}}]} as unknown as DocumentNode; export const CreateSurveyDimensionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSurveyDimension"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateSurveyDimensionInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSurveyDimension"},"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 DeleteSurveyDimensionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteSurveyDimension"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"DeleteSurveyDimensionInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteSurveyDimension"},"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 DimensionsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"DimensionsList"},"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":"locale"}},"type":{"kind":"NonNullType","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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"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":"dimensions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionRowGroup"}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ValueFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionRowGroup"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SurveyDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","alias":{"kind":"Name","value":"titleFi"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"fi","block":false}}]},{"kind":"Field","alias":{"kind":"Name","value":"titleEn"},"name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"StringValue","value":"en","block":false}}]},{"kind":"Field","name":{"kind":"Name","value":"values"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ValueFields"}}]}}]}}]} as unknown as DocumentNode; export const SurveyPageQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SurveyPageQuery"},"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":"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":"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"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"loginRequired"}},{"kind":"Field","name":{"kind":"Name","value":"anonymity"}},{"kind":"Field","name":{"kind":"Name","value":"maxResponsesPerUser"}},{"kind":"Field","name":{"kind":"Name","value":"countResponsesByCurrentUser"}},{"kind":"Field","name":{"kind":"Name","value":"form"},"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":"title"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"fields"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const UpdateResponseDimensionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateResponseDimensions"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateResponseDimensionsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateResponseDimensions"},"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":"response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; diff --git a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts index 52a16a46f..8c7ed4524 100644 --- a/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts +++ b/frontend/src/app/[locale]/events/[eventSlug]/surveys/[surveySlug]/dimensions/actions.ts @@ -50,13 +50,31 @@ export async function updateDimension( ); } +const deleteDimensionMutation = graphql(` + mutation DeleteSurveyDimension($input: DeleteSurveyDimensionInput!) { + deleteSurveyDimension(input: $input) { + slug + } + } +`); + export async function deleteDimension( eventSlug: string, surveySlug: string, dimensionSlug: string, ) { - // TODO stubb - console.log("deleteDimension", eventSlug, surveySlug, dimensionSlug); + await getClient().mutate({ + mutation: deleteDimensionMutation, + variables: { + input: { + eventSlug, + surveySlug, + dimensionSlug, + }, + }, + }); + revalidatePath(`/events/${eventSlug}/surveys/${surveySlug}`); + redirect(`/events/${eventSlug}/surveys/${surveySlug}/dimensions`); } export async function createDimensionValue(
{t.attributes.dimension} {t.attributes.dimension} (fi) {t.attributes.dimension} (en)
- + + {t.actions.addDimension} + + } + messages={t.editDimensionModal.actions} + action={createDimension.bind(null, eventSlug, surveySlug)} > - {t.actions.addDimension}… - + +