Add Feedback mutation call, also codegen for typing

This commit is contained in:
Ramon Wenger 2022-11-24 21:30:52 +01:00
parent be0a53c16d
commit 69fc7f7dbb
6 changed files with 2263 additions and 127 deletions

17
client/codegen.ts Normal file
View File

@ -0,0 +1,17 @@
import type { CodegenConfig } from "@graphql-codegen/cli";
const config: CodegenConfig = {
schema: "../server/schema.graphql",
documents: ["src/**/*.vue"],
ignoreNoDocuments: true,
generates: {
"./src/gql/": {
preset: "client",
config: {
useTypeImports: true,
},
plugins: [],
},
},
};
export default config;

View File

@ -1,141 +1,266 @@
<template>
<div>
<h1>Feedback</h1>
<div>
<p>Würden Sie den Kurs weiterempfehlen?</p>
<ItCheckbox :checked="recommend" @toggle="recommend = !recommend"/>
<ItCheckbox :checked="wouldRecommend" @toggle="recommend = !recommend" />
</div>
<div>
<ItRadioGroup v-model="satisfaction" label="Zufriedenheit insgesamt" :items="ratings"/>
<ItRadioGroup v-model="goalAttainment" label="Zielerreichung insgesamt" :items="ratings"/>
<ItRadioGroup v-model="proficiency"
label="Wie beurteilen Sie Ihre Sicherheit bezüglichen den Themen nach dem Kurs?"
:items="percentages"/>
<ItRadioGroup
v-model="satisfaction"
label="Zufriedenheit insgesamt"
:items="ratings"
/>
<ItRadioGroup
v-model="goalAttainment"
label="Zielerreichung insgesamt"
:items="ratings"
/>
<ItRadioGroup
v-model="proficiency"
label="Wie beurteilen Sie Ihre Sicherheit bezüglichen den Themen nach dem Kurs?"
:items="percentages"
/>
</div>
<ItRadioGroup
v-model="receivedMaterials"
label="Haben Sie Vorbereitungsunterlagen (z.B. eLearning) erhalten?"
:items="yesNo"
/>
<ItRadioGroup
v-model="materialsRating"
label="Falls ja: Wie beurteilen Sie die Vorbereitungsunterlagen (z.B.
eLearning)?"
:items="ratings"
/>
<ItRadioGroup
v-model="instructorCompetence"
label="Der Kursleiter war themenstark, fachkompetent."
:items="ratings"
/>
<ItRadioGroup
v-model="instructorRespect"
label="Fragen und Anregungen der Kursteilnehmenden wurden ernst
genommen u. aufgegriffen."
:items="ratings"
/>
<ItRadioGroup
v-model="howDiscovered"
label="Wie sind Sie auf das Kursangebot aufmerksam geworden?"
:items="discoveryReasons"
/>
<p>Was ich dem Kursleiter sonst noch sagen wollte:</p>
<textarea
v-model="instructorOpenFeedback"
rows="4"
class="block w-96 rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
/>
<div>
<p>Wo sehen Sie Verbesserungspotenzial?</p>
<textarea
v-model="courseNegativeFeedback"
rows="4"
class="block w-96 rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
/>
<!-- class="block w-full rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"-->
</div>
<div>
<p>Was hat Ihnen besonders gut gefallen?</p>
<textarea
v-model="coursePositiveFeedback"
rows="4"
class="block w-96 rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
/>
<!-- class="block w-full rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"-->
</div>
<ItRadioGroup label="Motivation" v-model="selected" :items="motivations"/>
<ItRadioGroup v-model="materialsReceived" label="Haben Sie Vorbereitungsunterlagen (z.B. eLearning) erhalten?" :items="yesNo" />
<ItRadioGroup v-model="materialsRating" label="Falls ja: Wie beurteilen Sie die Vorbereitungsunterlagen (z.B.
eLearning)?" :items="ratings" />
<ItRadioGroup v-model="instructorCompetence" label="Der Kursleiter war themenstark, fachkompetent." :items="ratings" />
<ItRadioGroup v-model="instructorRespect" label="Fragen und Anregungen der Kursteilnehmenden wurden ernst
genommen u. aufgegriffen." :items="ratings" />
<ItRadioGroup v-model="howDiscovered" label="Wie sind Sie auf das Kursangebot aufmerksam geworden?" :items="discoveryReasons" />
<h3>Motivation</h3>
<ItCheckbox /> Persönliches Interesse
<ItCheckbox /> Berufliches Interesse
<ItCheckbox /> Pflichtkurs
<ItCheckbox /> Andere Gründe
<ItCheckbox />
Persönliches Interesse
<ItCheckbox />
Berufliches Interesse
<ItCheckbox />
Pflichtkurs
<ItCheckbox />
Andere Gründe
<button @click="sendFeedback">Send!</button>
<pre>
satisfaction {{ satisfaction }}
goalAttainment {{ goalAttainment }}
proficiency {{ proficiency }}
receivedMaterials {{ receivedMaterials }}
materialsRating {{ materialsRating }}
instructorCompetence {{ instructorCompetence }}
instructorRespect {{ instructorRespect }}
instructorOpenFeedback {{ instructorOpenFeedback }}
wouldRecommend {{ wouldRecommend }}
coursePositiveFeedback {{ coursePositiveFeedback }}
courseNegativeFeedback {{ courseNegativeFeedback }}
howDiscovered {{ howDiscovered }}
motivation {{ motivation }}
mutationResult: {{ mutationResult }}
</pre>
</div>
</template>
<script setup>
import ItCheckbox from '@/components/ui/ItCheckbox.vue';
import {ref} from 'vue';
import ItRadioGroup from '@/components/ui/ItRadioGroup.vue';
<script setup lang="ts">
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
import ItRadioGroup from "@/components/ui/ItRadioGroup.vue";
import { graphql } from "@/gql/";
import type { SendFeedbackInput } from "@/gql/graphql";
import { useMutation } from "@urql/vue";
import log from "loglevel";
import { reactive, ref } from "vue";
const discoveryReasons = [
{
name: 'Internet',
id: 'I'
},
{
name: 'Prospekt',
id: 'L'
},
{
name: 'Zeitung',
id: 'N'
},
{
name: 'Persönliche Empfehlung',
id: 'R'
},
{
name: 'Öffentliche Veranstaltung',
id: 'E'
},
{
name: 'Andere',
id: 'O'
},
];
const yesNo = [
{
name: 'Ja',
id: true
},
{
name: 'Nein',
id: false
},
];
const ratings = [
{
name: 'sehr unzufrieden',
id: 1,
},
{
name: 'unzufrieden',
id: 2,
},
{
name: 'zufrieden',
id: 3,
},
{
name: 'sehr zufrieden',
id: 4,
},
];
const percentages = [
{
name: '20%',
id: 20,
},
{
name: '40%',
id: 40,
},
{
name: '60%',
id: 60,
},
{
name: '80%',
id: 80,
},
{
name: '100%',
id: 100,
},
];
const motivations = [
{
name: 'Persönliches Interesse',
id: 1,
},
{
name: 'Berufliches Interesse',
id: 2,
},
{
name: 'Pflichtkurs',
id: 3,
},
{
name: 'Andere Gründe',
id: 4,
},
];
const sendFeedbackMutation = graphql(`
mutation SendFeedbackMutation($input: SendFeedbackInput!) {
sendFeedback(input: $input) {
id
satisfaction
goalAttainment
proficiency
receivedMaterials
materialsRating
errors {
field
messages
}
}
}
`);
const { executeMutation } = useMutation(sendFeedbackMutation);
const selected = ref(null);
const satisfaction = ref(null);
const goalAttainment = ref(null);
const recommend = ref(true);
const proficiency = ref(null);
const materialsReceived = ref(null);
const materialsRating = ref(null);
const instructorCompetence = ref(null);
const instructorRespect = ref(null);
const howDiscovered = ref(null);
const discoveryReasons = [
{
name: "Internet",
id: "I",
},
{
name: "Prospekt",
id: "L",
},
{
name: "Zeitung",
id: "N",
},
{
name: "Persönliche Empfehlung",
id: "R",
},
{
name: "Öffentliche Veranstaltung",
id: "E",
},
{
name: "Andere",
id: "O",
},
];
const yesNo = [
{
name: "Ja",
id: true,
},
{
name: "Nein",
id: false,
},
];
const ratings = [
{
name: "sehr unzufrieden",
id: 1,
},
{
name: "unzufrieden",
id: 2,
},
{
name: "zufrieden",
id: 3,
},
{
name: "sehr zufrieden",
id: 4,
},
];
const percentages = [
{
name: "20%",
id: 20,
},
{
name: "40%",
id: 40,
},
{
name: "60%",
id: 60,
},
{
name: "80%",
id: 80,
},
{
name: "100%",
id: 100,
},
];
const motivations = [
{
name: "Persönliches Interesse",
id: 1,
},
{
name: "Berufliches Interesse",
id: 2,
},
{
name: "Pflichtkurs",
id: 3,
},
{
name: "Andere Gründe",
id: 4,
},
];
const motivation = ref("");
const satisfaction = ref(0);
const goalAttainment = ref(0);
const wouldRecommend = ref(true);
const proficiency = ref(0);
const receivedMaterials = ref(false);
const materialsRating = ref(null);
const instructorCompetence = ref(0);
const instructorRespect = ref(0);
const howDiscovered = ref("");
const coursePositiveFeedback = ref("");
const courseNegativeFeedback = ref("");
const instructorOpenFeedback = ref("");
const mutationResult = ref<any>(null);
const sendFeedback = () => {
const input: SendFeedbackInput = reactive({
materialsRating,
courseNegativeFeedback,
coursePositiveFeedback,
goalAttainment,
howDiscovered,
instructorCompetence,
instructorRespect,
instructorOpenFeedback,
satisfaction,
proficiency,
receivedMaterials,
wouldRecommend,
motivation,
});
const variables = reactive({
input,
});
executeMutation(variables).then(({ data }) => {
log.debug(data);
mutationResult.value = data;
});
};
</script>

View File

@ -0,0 +1,40 @@
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
export type FragmentType<TDocumentType extends DocumentNode<any, any>> = TDocumentType extends DocumentNode<
infer TType,
any
>
? TType extends { ' $fragmentName'?: infer TKey }
? TKey extends string
? { ' $fragmentRefs'?: { [key in TKey]: TType } }
: never
: never
: never;
// return non-nullable if `fragmentType` is non-nullable
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: FragmentType<DocumentNode<TType, any>>
): TType;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: FragmentType<DocumentNode<TType, any>> | null | undefined
): TType | null | undefined;
// return array of non-nullable if `fragmentType` is array of non-nullable
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: ReadonlyArray<FragmentType<DocumentNode<TType, any>>>
): ReadonlyArray<TType>;
// return array of nullable if `fragmentType` is array of nullable
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: ReadonlyArray<FragmentType<DocumentNode<TType, any>>> | null | undefined
): ReadonlyArray<TType> | null | undefined
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: FragmentType<DocumentNode<TType, any>> | ReadonlyArray<FragmentType<DocumentNode<TType, any>>> | null | undefined
): TType | ReadonlyArray<TType> | null | undefined {
return fragmentType as any
}

16
client/src/gql/gql.ts Normal file
View File

@ -0,0 +1,16 @@
/* eslint-disable */
import * as types from './graphql';
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
const documents = {
"\n mutation SendFeedbackMutation($input: SendFeedbackInput!) {\n sendFeedback(input: $input) {\n id\n satisfaction\n goalAttainment\n proficiency\n receivedMaterials\n materialsRating\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument,
};
export function graphql(source: "\n mutation SendFeedbackMutation($input: SendFeedbackInput!) {\n sendFeedback(input: $input) {\n id\n satisfaction\n goalAttainment\n proficiency\n receivedMaterials\n materialsRating\n errors {\n field\n messages\n }\n }\n }\n"): (typeof documents)["\n mutation SendFeedbackMutation($input: SendFeedbackInput!) {\n sendFeedback(input: $input) {\n id\n satisfaction\n goalAttainment\n proficiency\n receivedMaterials\n materialsRating\n errors {\n field\n messages\n }\n }\n }\n"];
export function graphql(source: string): unknown;
export function graphql(source: string) {
return (documents as any)[source] ?? {};
}
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;

1936
client/src/gql/graphql.ts Normal file

File diff suppressed because it is too large Load Diff

2
client/src/gql/index.ts Normal file
View File

@ -0,0 +1,2 @@
export * from "./gql"
export * from "./fragment-masking"