#11 backend: nodeId -> id and id -> rowId
To be more in sync with typical graphql servers.
This commit is contained in:
parent
96e78eb7f5
commit
dd2f414f00
|
@ -1,12 +1,12 @@
|
|||
-- create table for users
|
||||
create table candymat_data.person
|
||||
(
|
||||
id serial primary key,
|
||||
row_id serial primary key,
|
||||
first_name character varying(200) check (first_name <> ''),
|
||||
last_name character varying(200) check (last_name <> ''),
|
||||
about character varying(2000),
|
||||
created_at timestamp default now(),
|
||||
role candymat_data.role not null default 'candymat_person'
|
||||
created_at timestamp default now(),
|
||||
role candymat_data.role not null default 'candymat_person'
|
||||
);
|
||||
grant select, update, delete on table candymat_data.person to candymat_person;
|
||||
-- the following is only necessary as long as anonymous should be able to view candidates and editors
|
||||
|
@ -15,16 +15,16 @@ grant select on table candymat_data.person to candymat_anonymous;
|
|||
-- create table for accounts
|
||||
create table candymat_data_privat.person_account
|
||||
(
|
||||
person_id integer primary key references candymat_data.person (id) on delete cascade,
|
||||
person_row_id integer primary key references candymat_data.person (row_id) on delete cascade,
|
||||
email character varying(320) not null unique check (email ~* '^.+@.+\..+$'),
|
||||
password_hash character varying(256) not null
|
||||
);
|
||||
alter table candymat_data.person
|
||||
enable row level security;
|
||||
create policy update_person on candymat_data.person for update to candymat_person
|
||||
with check (id = nullif(current_setting('jwt.claims.person_id', true), '')::integer);
|
||||
with check (row_id = nullif(current_setting('jwt.claims.person_row_id', true), '')::integer);
|
||||
create policy delete_person on candymat_data.person for delete to candymat_person
|
||||
using (id = nullif(current_setting('jwt.claims.person_id', true), '')::integer);
|
||||
using (row_id = nullif(current_setting('jwt.claims.person_row_id', true), '')::integer);
|
||||
-- The following enables viewing candidates and editors information for every person.
|
||||
-- This may be changed to only enable registered (and verified) persons.
|
||||
create policy select_person_public
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
-- create table for categories
|
||||
create table candymat_data.category
|
||||
(
|
||||
id serial primary key,
|
||||
row_id serial primary key,
|
||||
title character varying(300) UNIQUE NOT NULL,
|
||||
description character varying(5000)
|
||||
);
|
||||
|
@ -9,31 +9,31 @@ grant select on table candymat_data.category to candymat_person;
|
|||
-- the following line is only necessary as long as the candymat should be publicly accessible
|
||||
grant select on table candymat_data.category to candymat_anonymous;
|
||||
grant insert, update, delete on table candymat_data.category to candymat_editor;
|
||||
grant usage on sequence candymat_data.category_id_seq to candymat_editor;
|
||||
grant usage on sequence candymat_data.category_row_id_seq to candymat_editor;
|
||||
|
||||
-- create table for questions
|
||||
create table candymat_data.question
|
||||
(
|
||||
id serial primary key,
|
||||
category_id integer REFERENCES candymat_data.category (id) ON UPDATE CASCADE ON DELETE SET NULL,
|
||||
text character varying(3000) NOT NULL,
|
||||
description character varying(5000)
|
||||
row_id serial primary key,
|
||||
category_row_id integer REFERENCES candymat_data.category (row_id) ON UPDATE CASCADE ON DELETE SET NULL,
|
||||
text character varying(3000) NOT NULL,
|
||||
description character varying(5000)
|
||||
);
|
||||
grant select on table candymat_data.question to candymat_person;
|
||||
-- the following line is only necessary as long as the candymat should be publicly accessible
|
||||
grant select on table candymat_data.question to candymat_anonymous;
|
||||
grant insert, update, delete on table candymat_data.question to candymat_editor;
|
||||
grant usage on sequence candymat_data.question_id_seq to candymat_editor;
|
||||
grant usage on sequence candymat_data.question_row_id_seq to candymat_editor;
|
||||
|
||||
-- create table for answers
|
||||
create table candymat_data.answer
|
||||
(
|
||||
question_id integer REFERENCES candymat_data.question (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
person_id integer REFERENCES candymat_data.person (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
position integer NOT NULL,
|
||||
text character varying(5000),
|
||||
created_at timestamp default now(),
|
||||
primary key (question_id, person_id)
|
||||
question_row_id integer REFERENCES candymat_data.question (row_id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
person_row_id integer REFERENCES candymat_data.person (row_id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
position integer NOT NULL,
|
||||
text character varying(5000),
|
||||
created_at timestamp default now(),
|
||||
primary key (question_row_id, person_row_id)
|
||||
);
|
||||
grant select on table candymat_data.answer to candymat_person;
|
||||
-- the following line is only necessary as long as the candymat should be publicly accessible
|
||||
|
@ -43,7 +43,7 @@ grant insert, update, delete on table candymat_data.answer to candymat_candidate
|
|||
alter table candymat_data.answer
|
||||
enable row level security;
|
||||
create policy change_answer on candymat_data.answer to candymat_candidate
|
||||
using (person_id = nullif(current_setting('jwt.claims.person_id', true), '')::integer);
|
||||
using (person_row_id = nullif(current_setting('jwt.claims.person_row_id', true), '')::integer);
|
||||
create policy select_answer
|
||||
on candymat_data.answer
|
||||
for select
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
create extension if not exists "pgcrypto";
|
||||
|
||||
-- Define JWT claim structure
|
||||
create type candymat_data.jwt_token as (
|
||||
role text,
|
||||
person_id integer,
|
||||
exp bigint
|
||||
create type candymat_data.jwt_token as
|
||||
(
|
||||
role text,
|
||||
person_row_id integer,
|
||||
exp bigint
|
||||
);
|
||||
|
||||
create function candymat_data.current_person() returns candymat_data.person as $$
|
||||
select *
|
||||
from candymat_data.person
|
||||
where id = nullif(current_setting('jwt.claims.person_id', true), '')::integer
|
||||
create function candymat_data.current_person(
|
||||
) returns candymat_data.person as
|
||||
$$
|
||||
select *
|
||||
from candymat_data.person
|
||||
where row_id = nullif(current_setting('jwt.claims.person_row_id', true), '')::integer
|
||||
$$ language sql stable;
|
||||
grant execute on function candymat_data.current_person() to candymat_person;
|
||||
|
||||
|
@ -37,8 +40,8 @@ begin
|
|||
values ($1, $2)
|
||||
returning * into person;
|
||||
|
||||
insert into candymat_data_privat.person_account (person_id, email, password_hash)
|
||||
values (person.id, $3, crypt($4, gen_salt('bf')));
|
||||
insert into candymat_data_privat.person_account (person_row_id, email, password_hash)
|
||||
values (person.row_id, $3, crypt($4, gen_salt('bf')));
|
||||
|
||||
return person;
|
||||
end ;
|
||||
|
@ -48,9 +51,10 @@ $$ language plpgsql strict
|
|||
grant execute on function candymat_data.register_person(text, text, text, text) to candymat_anonymous;
|
||||
|
||||
create function candymat_data.authenticate(
|
||||
email text,
|
||||
password text
|
||||
) returns candymat_data.jwt_token as $$
|
||||
email text,
|
||||
password text
|
||||
) returns candymat_data.jwt_token as
|
||||
$$
|
||||
declare
|
||||
account candymat_data_privat.person_account;
|
||||
declare person candymat_data.person;
|
||||
|
@ -63,30 +67,39 @@ begin
|
|||
select p.*
|
||||
into person
|
||||
from candymat_data.person as p
|
||||
where p.id = account.person_id;
|
||||
where p.row_id = account.person_row_id;
|
||||
|
||||
if account.password_hash = crypt(password, account.password_hash) then
|
||||
return (person.role, account.person_id,
|
||||
return (person.role, account.person_row_id,
|
||||
extract(epoch from (now() + interval '2 days')))::candymat_data.jwt_token;
|
||||
else
|
||||
return null;
|
||||
end if;
|
||||
end;
|
||||
$$ language plpgsql strict security definer;
|
||||
$$ language plpgsql strict
|
||||
security definer;
|
||||
grant execute on function candymat_data.authenticate(text, text) to candymat_anonymous, candymat_person;
|
||||
|
||||
create function candymat_data.change_role(
|
||||
person_id integer,
|
||||
new_role candymat_data.role
|
||||
) returns table(first_name text, last_name text, role candymat_data.role) as $$
|
||||
person_row_id integer,
|
||||
new_role candymat_data.role
|
||||
)
|
||||
returns table
|
||||
(
|
||||
first_name text,
|
||||
last_name text,
|
||||
role candymat_data.role
|
||||
)
|
||||
as
|
||||
$$
|
||||
begin
|
||||
update candymat_data.person
|
||||
set role = new_role
|
||||
where candymat_data.person.id = $1;
|
||||
where candymat_data.person.row_id = $1;
|
||||
|
||||
return query select candymat_data.person.first_name::text, candymat_data.person.last_name::text, new_role
|
||||
from candymat_data.person
|
||||
where person.id = person_id;
|
||||
where person.row_id = person_row_id;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
grant execute on function candymat_data.change_role(integer, candymat_data.role) to candymat_editor;
|
||||
|
|
|
@ -3,7 +3,7 @@ insert into candymat_data.category (title, description) values
|
|||
insert into candymat_data.category (title, description) values
|
||||
('Sonstiges', '');
|
||||
|
||||
insert into candymat_data.question (category_id, text, description) values
|
||||
insert into candymat_data.question (category_row_id, text, description) values
|
||||
(1, 'Was sagen Sie zur 10H Regel?', 'In Bayern dürfen Windräder nur ...');
|
||||
insert into candymat_data.question (category_id, text, description) values
|
||||
insert into candymat_data.question (category_row_id, text, description) values
|
||||
(2, 'Umgehungsstraße XY?', 'Zur Entlastung der Hauptstraße ...');
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
insert into candymat_data.answer (question_id, person_id, position, text) values
|
||||
(1, 2, 2, 'bin dagegen');
|
||||
insert into candymat_data.answer (question_id, person_id, position, text) values
|
||||
(2, 2, 0, 'bin dafür');
|
||||
insert into candymat_data.answer (question_row_id, person_row_id, position, text)
|
||||
values (1, 2, 2, 'bin dagegen');
|
||||
insert into candymat_data.answer (question_row_id, person_row_id, position, text)
|
||||
values (2, 2, 0, 'bin dafür');
|
||||
|
||||
insert into candymat_data.answer (question_id, person_id, position, text) values
|
||||
(1, 3, 1, 'mir egal');
|
||||
insert into candymat_data.answer (question_id, person_id, position, text) values
|
||||
(2, 3, 3, 'keine lust mehr');
|
||||
insert into candymat_data.answer (question_row_id, person_row_id, position, text)
|
||||
values (1, 3, 1, 'mir egal');
|
||||
insert into candymat_data.answer (question_row_id, person_row_id, position, text)
|
||||
values (2, 3, 3, 'keine lust mehr');
|
||||
|
|
|
@ -59,7 +59,8 @@ services:
|
|||
"--jwt-secret", $JWT_SECRET,
|
||||
"--watch",
|
||||
"--retry-on-init-fail",
|
||||
"--enhance-graphiql"
|
||||
"--enhance-graphiql",
|
||||
"--classic-ids",
|
||||
]
|
||||
networks:
|
||||
- frontend
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {ApolloClient, createHttpLink, defaultDataIdFromObject, InMemoryCache} from "@apollo/client";
|
||||
import {ApolloClient, createHttpLink, InMemoryCache} from "@apollo/client";
|
||||
import {setContext} from "@apollo/client/link/context";
|
||||
|
||||
|
||||
|
@ -17,12 +17,6 @@ const authLink = setContext((_, { headers }) => {
|
|||
});
|
||||
|
||||
export const client = new ApolloClient({
|
||||
cache: new InMemoryCache({
|
||||
dataIdFromObject(responseObject) {
|
||||
return responseObject.nodeId
|
||||
? responseObject.nodeId as string
|
||||
: defaultDataIdFromObject(responseObject);
|
||||
}
|
||||
}),
|
||||
cache: new InMemoryCache(),
|
||||
link: authLink.concat(httpLink),
|
||||
});
|
||||
|
|
|
@ -1,16 +1,38 @@
|
|||
import {gql} from "@apollo/client";
|
||||
import {GetQuestionResponse} from "../queries/question";
|
||||
import {BasicQuestionFragment, BasicQuestionResponse} from "../queries/question";
|
||||
|
||||
export const EDIT_QUESTION = gql`
|
||||
mutation UpdateQuestion($nodeId: ID!, $text: String, $description: String, $categoryId: Int) {
|
||||
updateQuestion(input: {nodeId: $nodeId, questionPatch: {categoryId: $categoryId, description: $description, text: $text}}) {
|
||||
mutation UpdateQuestion($id: ID!, $text: String, $description: String, $categoryRowId: Int) {
|
||||
updateQuestion(input: {id: $id, questionPatch: {categoryRowId: $categoryRowId, description: $description, text: $text}}) {
|
||||
question {
|
||||
nodeId
|
||||
...BasicQuestionFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
${BasicQuestionFragment}
|
||||
`
|
||||
|
||||
export interface EditQuestionResponse {
|
||||
updateQuestion?: BasicQuestionResponse
|
||||
}
|
||||
|
||||
export interface EditQuestionVariables {
|
||||
id: string,
|
||||
text?: string,
|
||||
description?: string,
|
||||
categoryRowId?: number | null,
|
||||
}
|
||||
|
||||
export const ADD_QUESTION = gql`
|
||||
mutation AddQuestion($text: String!, $description: String, $categoryRowId: Int) {
|
||||
createQuestion(input: {question: {text: $text, categoryRowId: $categoryRowId, description: $description}}) {
|
||||
question {
|
||||
id
|
||||
text
|
||||
description
|
||||
categoryByCategoryId {
|
||||
nodeId
|
||||
categoryByCategoryRowId {
|
||||
id
|
||||
rowId
|
||||
title
|
||||
}
|
||||
}
|
||||
|
@ -18,13 +40,39 @@ export const EDIT_QUESTION = gql`
|
|||
}
|
||||
`
|
||||
|
||||
export interface EditQuestionVariables {
|
||||
nodeId: string,
|
||||
text?: string,
|
||||
description?: string,
|
||||
categoryId?: number | null,
|
||||
export interface AddQuestionResponse {
|
||||
createQuestion?: BasicQuestionResponse
|
||||
}
|
||||
|
||||
export interface EditQuestionResponse {
|
||||
updateQuestion?: GetQuestionResponse
|
||||
export interface AddQuestionVariables {
|
||||
text: string,
|
||||
description?: string,
|
||||
categoryRowId?: number | null
|
||||
}
|
||||
|
||||
export const DELETE_QUESTION = gql`
|
||||
mutation AddQuestion($text: String!, $description: String, $categoryRowId: Int) {
|
||||
createQuestion(input: {question: {text: $text, categoryRowId: $categoryRowId, description: $description}}) {
|
||||
question {
|
||||
id
|
||||
text
|
||||
description
|
||||
categoryByCategoryRowId {
|
||||
id
|
||||
rowId
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export interface DeleteQuestionResponse {
|
||||
deleteQuestion?: BasicQuestionResponse
|
||||
}
|
||||
|
||||
export interface DeleteQuestionVariables {
|
||||
id: string,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ export const SIGN_UP = gql`
|
|||
mutation CreateAccount($firstName: String!, $lastName: String!, $email: String!, $password: String!) {
|
||||
registerPerson(input: {firstName: $firstName, lastName: $lastName, email: $email, password: $password}) {
|
||||
person {
|
||||
nodeId
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ export interface SignUpVariables {
|
|||
export interface SignUpResponse {
|
||||
registerPerson: {
|
||||
person: {
|
||||
nodeId: string
|
||||
id: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
import {gql} from "@apollo/client";
|
||||
|
||||
export const BasicCategoryFragment = gql`
|
||||
fragment BasicCategory on Category {
|
||||
id
|
||||
rowId
|
||||
title
|
||||
description
|
||||
}
|
||||
`
|
||||
|
||||
export interface BasicCategoryResponse {
|
||||
id: string,
|
||||
rowId: number,
|
||||
title: string,
|
||||
description?: string,
|
||||
}
|
||||
|
||||
export const GET_ALL_CATEGORIES = gql`
|
||||
query AllCategories {
|
||||
allCategories {
|
||||
nodes {
|
||||
nodeId
|
||||
id
|
||||
title
|
||||
description
|
||||
...BasicCategory
|
||||
}
|
||||
}
|
||||
}
|
||||
${BasicCategoryFragment}
|
||||
`
|
||||
|
||||
export interface GetAllCategoriesResponse {
|
||||
allCategories: {
|
||||
nodes: Array<GetCategoryResponse>
|
||||
nodes: Array<BasicCategoryResponse>
|
||||
}
|
||||
}
|
||||
|
||||
export interface GetCategoryResponse {
|
||||
nodeId: string,
|
||||
id: number,
|
||||
title: string,
|
||||
description?: string,
|
||||
}
|
||||
|
|
|
@ -1,36 +1,53 @@
|
|||
import {gql} from "@apollo/client";
|
||||
|
||||
const QuestionCategoryFragment = gql`
|
||||
fragment QuestionCategoryFragment on Category {
|
||||
id
|
||||
rowId
|
||||
title
|
||||
}
|
||||
`
|
||||
|
||||
interface GetQuestionsCategoryResponse {
|
||||
id: string,
|
||||
rowId: number,
|
||||
title: string,
|
||||
}
|
||||
|
||||
export const BasicQuestionFragment = gql`
|
||||
fragment BasicQuestionFragment on Question {
|
||||
id
|
||||
text
|
||||
description
|
||||
categoryByCategoryRowId {
|
||||
...QuestionCategoryFragment
|
||||
}
|
||||
}
|
||||
${QuestionCategoryFragment}
|
||||
`
|
||||
|
||||
export interface BasicQuestionResponse {
|
||||
id: string,
|
||||
text: string,
|
||||
description?: string,
|
||||
categoryByCategoryRowId?: GetQuestionsCategoryResponse
|
||||
}
|
||||
|
||||
export const GET_ALL_QUESTIONS = gql`
|
||||
query AllQuestions {
|
||||
allQuestions {
|
||||
nodes {
|
||||
nodeId
|
||||
text
|
||||
description
|
||||
categoryByCategoryId {
|
||||
nodeId
|
||||
title
|
||||
}
|
||||
...BasicQuestionFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
${BasicQuestionFragment}
|
||||
`
|
||||
|
||||
export interface GetAllQuestionsResponse {
|
||||
allQuestions: {
|
||||
nodes: Array<GetQuestionResponse>
|
||||
nodes: Array<BasicQuestionResponse>
|
||||
}
|
||||
}
|
||||
|
||||
export interface GetQuestionResponse {
|
||||
nodeId: string,
|
||||
text: string,
|
||||
description?: string,
|
||||
categoryByCategoryId?: GetQuestionsCategoryResponse
|
||||
}
|
||||
|
||||
interface GetQuestionsCategoryResponse {
|
||||
nodeId: string,
|
||||
id: number,
|
||||
title: string,
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import {makeStyles} from "@material-ui/core/styles";
|
|||
import {useQuery} from "@apollo/client";
|
||||
import AddCard from "./AddCard";
|
||||
import AccordionWithEdit from "./AccordionWithEdit";
|
||||
import {GET_ALL_CATEGORIES, GetAllCategoriesResponse, GetCategoryResponse} from "../backend/queries/category";
|
||||
import {GET_ALL_CATEGORIES, GetAllCategoriesResponse, BasicCategoryResponse} from "../backend/queries/category";
|
||||
import ChangeCategoryDialog, {ChangeCategoryDialogContent} from "./ChangeCategoryDialog";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
|
@ -38,12 +38,12 @@ export default function CategoryList() {
|
|||
setDialogOpen(true);
|
||||
}
|
||||
|
||||
const handleEditButtonClick = (category: GetCategoryResponse) => {
|
||||
const handleEditButtonClick = (category: BasicCategoryResponse) => {
|
||||
setDialogTitle("Kategorie bearbeiten");
|
||||
setDialogConfirmButtonText("Speichern")
|
||||
if (dialogContent.id !== category.nodeId) {
|
||||
if (dialogContent.id !== category.id) {
|
||||
setDialogContent({
|
||||
id: category.nodeId,
|
||||
id: category.id,
|
||||
title: category.title,
|
||||
details: category.description,
|
||||
})
|
||||
|
@ -59,7 +59,7 @@ export default function CategoryList() {
|
|||
<Paper className={classes.root}>
|
||||
<Typography component={"h2"} variant="h6" color="primary" gutterBottom>Kategorien</Typography>
|
||||
{data?.allCategories.nodes.map(category => <AccordionWithEdit
|
||||
key={category.nodeId}
|
||||
key={category.id}
|
||||
title={category.title}
|
||||
description={category.description}
|
||||
onEditButtonClick={() => handleEditButtonClick(category)}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React, {ChangeEvent} from 'react';
|
||||
import {FormControl, InputLabel, MenuItem, Select} from "@material-ui/core";
|
||||
import {GetCategoryResponse} from "../backend/queries/category";
|
||||
import {BasicCategoryResponse} from "../backend/queries/category";
|
||||
|
||||
|
||||
interface CategorySelectionMenuProps {
|
||||
selectedCategoryId: number | null
|
||||
categories?: Array<GetCategoryResponse>,
|
||||
categories?: Array<BasicCategoryResponse>,
|
||||
|
||||
handleCategoryChange(categoryId: number | null): void
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ export default function CategorySelectionMenu(props: CategorySelectionMenuProps)
|
|||
<MenuItem value={undefined}>
|
||||
<em>None</em>
|
||||
</MenuItem>
|
||||
{props.categories?.map(category => <MenuItem key={category.nodeId} value={category.id}>
|
||||
{props.categories?.map(category => <MenuItem key={category.id} value={category.rowId}>
|
||||
{category.title}
|
||||
</MenuItem>)}
|
||||
</Select>
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import Dialog from '@material-ui/core/Dialog';
|
||||
import DialogContent from '@material-ui/core/DialogContent';
|
||||
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||
import {GetCategoryResponse} from "../backend/queries/category";
|
||||
import {BasicCategoryResponse} from "../backend/queries/category";
|
||||
import CategorySelectionMenu from "./CategorySelectionMenu";
|
||||
import {DialogActionBar} from "./DialogActionBar";
|
||||
import {DialogTitleAndDetails} from "./DialogTitleAndDetails";
|
||||
|
@ -21,7 +21,7 @@ interface ChangeQuestionDialogProps {
|
|||
open: boolean,
|
||||
content: ChangeQuestionDialogContent,
|
||||
loading: boolean,
|
||||
categories?: Array<GetCategoryResponse>,
|
||||
categories?: Array<BasicCategoryResponse>,
|
||||
|
||||
handleContentChange(content: ChangeQuestionDialogContent): void
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import {makeStyles} from "@material-ui/core/styles";
|
|||
import {useMutation, useQuery} from "@apollo/client";
|
||||
import AddCard from "./AddCard";
|
||||
import AccordionWithEdit from "./AccordionWithEdit";
|
||||
import {GET_ALL_QUESTIONS, GetAllQuestionsResponse, GetQuestionResponse} from "../backend/queries/question";
|
||||
import {GET_ALL_QUESTIONS, GetAllQuestionsResponse, BasicQuestionResponse} from "../backend/queries/question";
|
||||
import ChangeQuestionDialog, {ChangeQuestionDialogContent} from "./ChangeQuestionDialog";
|
||||
import {GET_ALL_CATEGORIES, GetAllCategoriesResponse} from "../backend/queries/category";
|
||||
import {EDIT_QUESTION, EditQuestionResponse, EditQuestionVariables} from "../backend/mutations/question";
|
||||
|
@ -51,15 +51,15 @@ export default function QuestionList() {
|
|||
setDialogOpen(true);
|
||||
}
|
||||
|
||||
const handleEditButtonClick = (question: GetQuestionResponse) => {
|
||||
const handleEditButtonClick = (question: BasicQuestionResponse) => {
|
||||
setDialogTitle("Frage bearbeiten");
|
||||
setDialogConfirmButtonText("Speichern")
|
||||
if (dialogContent.id !== question.nodeId) {
|
||||
if (dialogContent.id !== question.id) {
|
||||
setDialogContent({
|
||||
id: question.nodeId,
|
||||
id: question.id,
|
||||
title: question.text,
|
||||
details: question.description,
|
||||
categoryId: question.categoryByCategoryId ? question.categoryByCategoryId.id : null,
|
||||
categoryId: question.categoryByCategoryRowId ? question.categoryByCategoryRowId.rowId : null,
|
||||
})
|
||||
}
|
||||
setDialogOpen(true);
|
||||
|
@ -73,10 +73,10 @@ export default function QuestionList() {
|
|||
if (dialogContent.id !== "") {
|
||||
const response = await editQuestion({
|
||||
variables: {
|
||||
nodeId: dialogContent.id,
|
||||
id: dialogContent.id,
|
||||
text: dialogContent.title,
|
||||
description: dialogContent.details,
|
||||
categoryId: dialogContent.categoryId
|
||||
categoryRowId: dialogContent.categoryId
|
||||
}
|
||||
})
|
||||
if (response.data?.updateQuestion) {
|
||||
|
@ -97,9 +97,9 @@ export default function QuestionList() {
|
|||
<Typography component={"h2"} variant="h6" color="primary" gutterBottom>Fragen</Typography>
|
||||
{questions?.map(question => {
|
||||
return <AccordionWithEdit
|
||||
key={question.nodeId}
|
||||
key={question.id}
|
||||
title={question.text}
|
||||
subTitle={question.categoryByCategoryId?.title}
|
||||
subTitle={question.categoryByCategoryRowId?.title}
|
||||
description={question.description}
|
||||
onEditButtonClick={() => handleEditButtonClick(question)}
|
||||
/>;
|
||||
|
|
Loading…
Reference in a new issue