diff --git a/packages/squeak/src/lib/api/topics.ts b/packages/squeak/src/lib/api/topics.ts index d8d2a06f..54803f5b 100644 --- a/packages/squeak/src/lib/api/topics.ts +++ b/packages/squeak/src/lib/api/topics.ts @@ -20,12 +20,19 @@ export function patchTopic({ organizationId, id, topicGroupId, + label, }: { organizationId: string id: ID topicGroupId: string | null + label?: string }) { - return doPatch(`/api/topics/${id}`, { organizationId, id, topicGroupId }) + return doPatch(`/api/topics/${id}`, { + organizationId, + id, + topicGroupId, + label, + }) } export function createTopicGroup(label: string) { @@ -35,3 +42,7 @@ export function createTopicGroup(label: string) { export function getTopicGroups(organizationId: string) { return doGet('/api/topic-groups', { organizationId }) } + +export function patchTopicGroup({ organizationId, id, label }) { + return doPatch('/api/topic-groups', { organizationId, id, label }) +} diff --git a/packages/squeak/src/pages/api/topic-groups.ts b/packages/squeak/src/pages/api/topic-groups.ts index 843fbe31..ec0af7f6 100644 --- a/packages/squeak/src/pages/api/topic-groups.ts +++ b/packages/squeak/src/pages/api/topic-groups.ts @@ -1,7 +1,7 @@ import { TopicGroup, Prisma } from '@prisma/client' import { NextApiRequest, NextApiResponse } from 'next' import { getSessionUser } from 'src/lib/auth' - +import { requireOrgAdmin } from '../../lib/api/apiUtils' import { methodNotAllowed, orgIdNotFound, safeJson } from '../../lib/api/apiUtils' import prisma from '../../lib/db' @@ -19,6 +19,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) switch (req.method) { case 'POST': return handlePost(req, res) + case 'PATCH': + return handlePatch(req, res) case 'GET': return handleGet(req, res) default: @@ -43,6 +45,28 @@ async function handlePost(req: NextApiRequest, res: NextApiResponse) { safeJson(res, topicGroup, 201) } +async function handlePatch(req: NextApiRequest, res: NextApiResponse) { + if (!(await requireOrgAdmin(req, res))) return + const user = await getSessionUser(req) + + if (!user) return orgIdNotFound(res) + + const body = req.body + + if (!body?.id || !body?.label) return res.status(400).json({ error: 'Missing required fields' }) + + const topicGroup: TopicGroup = await prisma.topicGroup.update({ + where: { + id: BigInt(body?.id), + }, + data: { + label: body?.label, + }, + }) + + safeJson(res, topicGroup, 201) +} + async function handleGet(req: NextApiRequest, res: NextApiResponse) { const organizationId = req.body.organizationId || req.query.organizationId diff --git a/packages/squeak/src/pages/api/topics/[id].ts b/packages/squeak/src/pages/api/topics/[id].ts index bcead87d..42616da9 100644 --- a/packages/squeak/src/pages/api/topics/[id].ts +++ b/packages/squeak/src/pages/api/topics/[id].ts @@ -59,12 +59,13 @@ async function handlePatch(req: NextApiRequest, res: NextApiResponse) { if (!user) return orgIdNotFound(res) - const { id, topicGroupId } = req.body + const { id, topicGroupId, label } = req.body await prisma.topic.updateMany({ where: { id: parseInt(id), organization_id: user.organizationId }, data: { topic_group_id: topicGroupId && parseInt(topicGroupId), + ...(label ? { label } : {}), }, }) diff --git a/packages/squeak/src/pages/topics.tsx b/packages/squeak/src/pages/topics.tsx index f55e25fb..c599ed1e 100644 --- a/packages/squeak/src/pages/topics.tsx +++ b/packages/squeak/src/pages/topics.tsx @@ -7,7 +7,7 @@ import Modal from '../components/Modal' import { useEffect, useState } from 'react' import { Form, Formik } from 'formik' import Input from '../components/Input' -import { createTopicGroup, getTopicGroups, getTopics, patchTopic } from '../lib/api/topics' +import { createTopicGroup, getTopicGroups, getTopics, patchTopic, patchTopicGroup } from '../lib/api/topics' import Select from '../components/Select' import { ID } from '../lib/types' import { GetTopicsResponse } from './api/topics' @@ -29,20 +29,26 @@ const Row = ({ label, topic_group, id, organizationId, handleSubmit, topicGroups const [modalOpen, setModalOpen] = useState(false) const [loading, setLoading] = useState(false) - const handleAddTopicToGroup = async ({ + const handleUpdateTopic = async ({ topicGroup, newTopicGroup, + label, + editTopicGroup, }: { topicGroup: string | bigint newTopicGroup: string + label: string + editTopicGroup: string | null }) => { setLoading(true) let topicGroupId: bigint | string = topicGroup if (newTopicGroup) { const topicGroupRes = await createTopicGroup(newTopicGroup.trim()) if (topicGroupRes?.body?.id) topicGroupId = topicGroupRes?.body?.id + } else if (editTopicGroup) { + await patchTopicGroup({ organizationId, id: topicGroupId, label: editTopicGroup }) } - await patchTopic({ organizationId, id, topicGroupId: topicGroupId as string }) + await patchTopic({ organizationId, id, label, topicGroupId: topicGroupId as string }) setModalOpen(false) handleSubmit() setLoading(false) @@ -58,7 +64,12 @@ const Row = ({ label, topic_group, id, organizationId, handleSubmit, topicGroups <> setModalOpen(false)}> { const errors: { @@ -70,16 +81,27 @@ const Row = ({ label, topic_group, id, organizationId, handleSubmit, topicGroups return errors }} - onSubmit={({ newTopicGroup, topicGroup }) => handleAddTopicToGroup({ newTopicGroup, topicGroup })} + onSubmit={({ newTopicGroup, topicGroup, label, editTopicGroup }) => + handleUpdateTopic({ newTopicGroup, topicGroup, label, editTopicGroup }) + } > - {() => { + {({ values, setFieldValue }) => { return (
+ +
+ +
) }} @@ -94,17 +116,35 @@ const Row = ({ label, topic_group, id, organizationId, handleSubmit, topicGroups {topic_group?.label || 'Add to a group'} + + + ) } -const TopicGroupForm = ({ loading, topicGroups, handleRemoveTopicGroup }) => { +const TopicGroupForm = ({ loading, topicGroups, handleRemoveTopicGroup, topicGroup, values, setFieldValue }) => { const [createNewGroup, setCreateNewGroup] = useState(false) + const [editGroup, setEditGroup] = useState(false) + + useEffect(() => { + setFieldValue('editTopicGroup', topicGroups.find((group) => group?.id === values.topicGroup)?.label) + }, [values?.topicGroup]) return ( <> - {createNewGroup ? ( + {editGroup ? ( + + ) : createNewGroup ? ( ) : (