From d9862105edd0f528dcf91d29142eaca9d78a8001 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Wed, 14 Aug 2024 01:03:26 +0800 Subject: [PATCH] feat: add survey result send to feed channel feature --- .../VirtualizedInfiniteDataTable.tsx | 2 -- .../components/feed/FeedChannelPicker.tsx | 2 +- src/client/components/feed/FeedIcon.tsx | 4 +++ .../components/survey/SurveyEditForm.tsx | 24 +++++++++++++ src/server/model/feed/event.ts | 5 ++- .../migration.sql | 2 ++ src/server/prisma/schema.prisma | 13 +++---- src/server/prisma/zod/survey.ts | 1 + src/server/trpc/routers/survey.ts | 36 +++++++++++++++++-- 9 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 src/server/prisma/migrations/20240813163057_add_survey_feedchannelids/migration.sql diff --git a/src/client/components/VirtualizedInfiniteDataTable.tsx b/src/client/components/VirtualizedInfiniteDataTable.tsx index 6043412..a9c0f47 100644 --- a/src/client/components/VirtualizedInfiniteDataTable.tsx +++ b/src/client/components/VirtualizedInfiniteDataTable.tsx @@ -105,8 +105,6 @@ export function VirtualizedInfiniteDataTable( return colSizes; }, [table.getState().columnSizingInfo, table.getState().columnSizing]); - console.log('columnSizeVars', columnSizeVars); - if (isLoading) { return
Loading...
; } diff --git a/src/client/components/feed/FeedChannelPicker.tsx b/src/client/components/feed/FeedChannelPicker.tsx index e2d0573..714a220 100644 --- a/src/client/components/feed/FeedChannelPicker.tsx +++ b/src/client/components/feed/FeedChannelPicker.tsx @@ -6,7 +6,7 @@ import { PlusOutlined } from '@ant-design/icons'; import { useTranslation } from '@i18next-toolkit/react'; import { useNavigate } from '@tanstack/react-router'; -interface FeedChannelPickerProps extends SelectProps {} +interface FeedChannelPickerProps extends SelectProps {} export const FeedChannelPicker: React.FC = React.memo( (props) => { const { t } = useTranslation(); diff --git a/src/client/components/feed/FeedIcon.tsx b/src/client/components/feed/FeedIcon.tsx index 5c35aac..4dfdd93 100644 --- a/src/client/components/feed/FeedIcon.tsx +++ b/src/client/components/feed/FeedIcon.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { LuCloudy, LuGithub, LuPlug } from 'react-icons/lu'; +import { RiSurveyLine } from 'react-icons/ri'; interface FeedIconProps { source: string; @@ -12,6 +13,9 @@ export const FeedIcon: React.FC = React.memo((props) => { if (props.source === 'tencent-cloud') { return ; } + if (props.source === 'survey') { + return ; + } return ; }); diff --git a/src/client/components/survey/SurveyEditForm.tsx b/src/client/components/survey/SurveyEditForm.tsx index b4c97f7..dcf1a79 100644 --- a/src/client/components/survey/SurveyEditForm.tsx +++ b/src/client/components/survey/SurveyEditForm.tsx @@ -33,6 +33,7 @@ import React, { useState } from 'react'; import { TipIcon } from '../TipIcon'; import { cn } from '@/utils/style'; import { Switch } from '../ui/switch'; +import { FeedChannelPicker } from '../feed/FeedChannelPicker'; const addFormSchema = z.object({ name: z.string(), @@ -46,6 +47,7 @@ const addFormSchema = z.object({ }) ), }), + feedChannelIds: z.array(z.string()), }); export type SurveyEditFormValues = z.infer; @@ -75,6 +77,7 @@ export const SurveyEditForm: React.FC = React.memo( payload: { items: [generateDefaultItem()], }, + feedChannelIds: [], }, }); @@ -239,6 +242,27 @@ export const SurveyEditForm: React.FC = React.memo( /> + + ( + + {t('Feed Channels')} + + + + + {t('Select Feed Channel for send')} + + + + )} + /> diff --git a/src/server/model/feed/event.ts b/src/server/model/feed/event.ts index d223bc1..2a65379 100644 --- a/src/server/model/feed/event.ts +++ b/src/server/model/feed/event.ts @@ -33,6 +33,9 @@ const { get: getFeedEventNotify, del: delFeedEventNotifyCache } = export { delFeedEventNotifyCache }; +/** + * create feed event + */ export async function createFeedEvent( workspaceId: string, eventData: Prisma.FeedEventCreateArgs['data'] @@ -86,7 +89,7 @@ export async function sendFeedEventsNotify( token.list( events.map((event) => token.text( - `[${event.eventName}] ${event.senderName}: ${event.eventContent}` + `[${event.source}:${event.eventName}] ${event.senderName ?? ''}: ${event.eventContent}` ) ) ), diff --git a/src/server/prisma/migrations/20240813163057_add_survey_feedchannelids/migration.sql b/src/server/prisma/migrations/20240813163057_add_survey_feedchannelids/migration.sql new file mode 100644 index 0000000..d3d25f5 --- /dev/null +++ b/src/server/prisma/migrations/20240813163057_add_survey_feedchannelids/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Survey" ADD COLUMN "feedChannelIds" TEXT[] DEFAULT ARRAY[]::TEXT[]; diff --git a/src/server/prisma/schema.prisma b/src/server/prisma/schema.prisma index a97b1ae..8550ebb 100644 --- a/src/server/prisma/schema.prisma +++ b/src/server/prisma/schema.prisma @@ -452,14 +452,15 @@ enum WorkspaceAuditLogType { } model Survey { - id String @id @default(cuid()) @db.VarChar(30) - workspaceId String @db.VarChar(30) - name String + id String @id @default(cuid()) @db.VarChar(30) + workspaceId String @db.VarChar(30) + name String /// [SurveyPayload] /// @zod.custom(imports.SurveyPayloadSchema) - payload Json @db.Json - createdAt DateTime @default(now()) @db.Timestamptz(6) - updatedAt DateTime @updatedAt @db.Timestamptz(6) + payload Json @db.Json + feedChannelIds String[] @default([]) // send survey result to feed channel + createdAt DateTime @default(now()) @db.Timestamptz(6) + updatedAt DateTime @updatedAt @db.Timestamptz(6) workspace Workspace @relation(fields: [workspaceId], references: [id], onUpdate: Cascade, onDelete: Cascade) surveyResultList SurveyResult[] diff --git a/src/server/prisma/zod/survey.ts b/src/server/prisma/zod/survey.ts index 24b955d..7b7d64f 100644 --- a/src/server/prisma/zod/survey.ts +++ b/src/server/prisma/zod/survey.ts @@ -16,6 +16,7 @@ export const SurveyModelSchema = z.object({ * [SurveyPayload] */ payload: imports.SurveyPayloadSchema, + feedChannelIds: z.string().array(), createdAt: z.date(), updatedAt: z.date(), }) diff --git a/src/server/trpc/routers/survey.ts b/src/server/trpc/routers/survey.ts index 5ee8e87..d7f914f 100644 --- a/src/server/trpc/routers/survey.ts +++ b/src/server/trpc/routers/survey.ts @@ -19,6 +19,7 @@ import { SurveyPayloadSchema } from '../../prisma/zod/schemas/index.js'; import { buildCursorResponseSchema } from '../../utils/schema.js'; import { fetchDataByCursor } from '../../utils/prisma.js'; import { Prisma } from '@prisma/client'; +import { createFeedEvent } from '../../model/feed/event.js'; export const surveyRouter = router({ all: workspaceProcedure @@ -170,6 +171,33 @@ export const surveyRouter = router({ }, }); + // async to push into survey + prisma.survey + .findFirst({ + where: { + id: surveyId, + workspaceId, + }, + }) + .then((survey) => { + if ( + survey && + Array.isArray(survey.feedChannelIds) && + survey.feedChannelIds.length > 0 + ) { + survey.feedChannelIds.forEach((channelId) => { + createFeedEvent(workspaceId, { + channelId: channelId, + eventName: 'receive', + eventContent: `survey [${survey.name}] receive a new record.`, + tags: [], + source: 'survey', + important: false, + }); + }); + } + }); + return 'success'; }), create: workspaceOwnerProcedure @@ -183,17 +211,19 @@ export const surveyRouter = router({ z.object({ name: z.string(), payload: SurveyPayloadSchema, + feedChannelIds: z.array(z.string()), }) ) .output(SurveyModelSchema) .mutation(async ({ input }) => { - const { workspaceId, name, payload } = input; + const { workspaceId, name, payload, feedChannelIds } = input; const res = await prisma.survey.create({ data: { workspaceId, name, payload, + feedChannelIds, }, }); @@ -211,11 +241,12 @@ export const surveyRouter = router({ surveyId: z.string(), name: z.string().optional(), payload: SurveyPayloadSchema.optional(), + feedChannelIds: z.array(z.string()).optional(), }) ) .output(SurveyModelSchema) .mutation(async ({ input }) => { - const { workspaceId, surveyId, name, payload } = input; + const { workspaceId, surveyId, name, payload, feedChannelIds } = input; const res = await prisma.survey.update({ where: { @@ -225,6 +256,7 @@ export const surveyRouter = router({ data: { name, payload, + feedChannelIds, }, });