feat: add survey result send to feed channel feature

This commit is contained in:
moonrailgun 2024-08-14 01:03:26 +08:00
parent 5f6147e3b6
commit d9862105ed
9 changed files with 77 additions and 12 deletions

View File

@ -105,8 +105,6 @@ export function VirtualizedInfiniteDataTable<TData>(
return colSizes; return colSizes;
}, [table.getState().columnSizingInfo, table.getState().columnSizing]); }, [table.getState().columnSizingInfo, table.getState().columnSizing]);
console.log('columnSizeVars', columnSizeVars);
if (isLoading) { if (isLoading) {
return <div>Loading...</div>; return <div>Loading...</div>;
} }

View File

@ -6,7 +6,7 @@ import { PlusOutlined } from '@ant-design/icons';
import { useTranslation } from '@i18next-toolkit/react'; import { useTranslation } from '@i18next-toolkit/react';
import { useNavigate } from '@tanstack/react-router'; import { useNavigate } from '@tanstack/react-router';
interface FeedChannelPickerProps extends SelectProps<string[]> {} interface FeedChannelPickerProps extends SelectProps<string | string[]> {}
export const FeedChannelPicker: React.FC<FeedChannelPickerProps> = React.memo( export const FeedChannelPicker: React.FC<FeedChannelPickerProps> = React.memo(
(props) => { (props) => {
const { t } = useTranslation(); const { t } = useTranslation();

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { LuCloudy, LuGithub, LuPlug } from 'react-icons/lu'; import { LuCloudy, LuGithub, LuPlug } from 'react-icons/lu';
import { RiSurveyLine } from 'react-icons/ri';
interface FeedIconProps { interface FeedIconProps {
source: string; source: string;
@ -12,6 +13,9 @@ export const FeedIcon: React.FC<FeedIconProps> = React.memo((props) => {
if (props.source === 'tencent-cloud') { if (props.source === 'tencent-cloud') {
return <LuCloudy size={props.size} />; return <LuCloudy size={props.size} />;
} }
if (props.source === 'survey') {
return <RiSurveyLine size={props.size} />;
}
return <LuPlug size={props.size} />; return <LuPlug size={props.size} />;
}); });

View File

@ -33,6 +33,7 @@ import React, { useState } from 'react';
import { TipIcon } from '../TipIcon'; import { TipIcon } from '../TipIcon';
import { cn } from '@/utils/style'; import { cn } from '@/utils/style';
import { Switch } from '../ui/switch'; import { Switch } from '../ui/switch';
import { FeedChannelPicker } from '../feed/FeedChannelPicker';
const addFormSchema = z.object({ const addFormSchema = z.object({
name: z.string(), name: z.string(),
@ -46,6 +47,7 @@ const addFormSchema = z.object({
}) })
), ),
}), }),
feedChannelIds: z.array(z.string()),
}); });
export type SurveyEditFormValues = z.infer<typeof addFormSchema>; export type SurveyEditFormValues = z.infer<typeof addFormSchema>;
@ -75,6 +77,7 @@ export const SurveyEditForm: React.FC<SurveyEditFormProps> = React.memo(
payload: { payload: {
items: [generateDefaultItem()], items: [generateDefaultItem()],
}, },
feedChannelIds: [],
}, },
}); });
@ -239,6 +242,27 @@ export const SurveyEditForm: React.FC<SurveyEditFormProps> = React.memo(
/> />
</div> </div>
</div> </div>
<FormField
control={form.control}
name="feedChannelIds"
render={({ field }) => (
<FormItem>
<FormLabel>{t('Feed Channels')}</FormLabel>
<FormControl className="w-full">
<FeedChannelPicker
allowClear={true}
mode="multiple"
{...field}
/>
</FormControl>
<FormDescription>
{t('Select Feed Channel for send')}
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</CardContent> </CardContent>
<CardFooter> <CardFooter>

View File

@ -33,6 +33,9 @@ const { get: getFeedEventNotify, del: delFeedEventNotifyCache } =
export { delFeedEventNotifyCache }; export { delFeedEventNotifyCache };
/**
* create feed event
*/
export async function createFeedEvent( export async function createFeedEvent(
workspaceId: string, workspaceId: string,
eventData: Prisma.FeedEventCreateArgs['data'] eventData: Prisma.FeedEventCreateArgs['data']
@ -86,7 +89,7 @@ export async function sendFeedEventsNotify(
token.list( token.list(
events.map((event) => events.map((event) =>
token.text( token.text(
`[${event.eventName}] ${event.senderName}: ${event.eventContent}` `[${event.source}:${event.eventName}] ${event.senderName ?? ''}: ${event.eventContent}`
) )
) )
), ),

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Survey" ADD COLUMN "feedChannelIds" TEXT[] DEFAULT ARRAY[]::TEXT[];

View File

@ -452,14 +452,15 @@ enum WorkspaceAuditLogType {
} }
model Survey { model Survey {
id String @id @default(cuid()) @db.VarChar(30) id String @id @default(cuid()) @db.VarChar(30)
workspaceId String @db.VarChar(30) workspaceId String @db.VarChar(30)
name String name String
/// [SurveyPayload] /// [SurveyPayload]
/// @zod.custom(imports.SurveyPayloadSchema) /// @zod.custom(imports.SurveyPayloadSchema)
payload Json @db.Json payload Json @db.Json
createdAt DateTime @default(now()) @db.Timestamptz(6) feedChannelIds String[] @default([]) // send survey result to feed channel
updatedAt DateTime @updatedAt @db.Timestamptz(6) createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
workspace Workspace @relation(fields: [workspaceId], references: [id], onUpdate: Cascade, onDelete: Cascade) workspace Workspace @relation(fields: [workspaceId], references: [id], onUpdate: Cascade, onDelete: Cascade)
surveyResultList SurveyResult[] surveyResultList SurveyResult[]

View File

@ -16,6 +16,7 @@ export const SurveyModelSchema = z.object({
* [SurveyPayload] * [SurveyPayload]
*/ */
payload: imports.SurveyPayloadSchema, payload: imports.SurveyPayloadSchema,
feedChannelIds: z.string().array(),
createdAt: z.date(), createdAt: z.date(),
updatedAt: z.date(), updatedAt: z.date(),
}) })

View File

@ -19,6 +19,7 @@ import { SurveyPayloadSchema } from '../../prisma/zod/schemas/index.js';
import { buildCursorResponseSchema } from '../../utils/schema.js'; import { buildCursorResponseSchema } from '../../utils/schema.js';
import { fetchDataByCursor } from '../../utils/prisma.js'; import { fetchDataByCursor } from '../../utils/prisma.js';
import { Prisma } from '@prisma/client'; import { Prisma } from '@prisma/client';
import { createFeedEvent } from '../../model/feed/event.js';
export const surveyRouter = router({ export const surveyRouter = router({
all: workspaceProcedure 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'; return 'success';
}), }),
create: workspaceOwnerProcedure create: workspaceOwnerProcedure
@ -183,17 +211,19 @@ export const surveyRouter = router({
z.object({ z.object({
name: z.string(), name: z.string(),
payload: SurveyPayloadSchema, payload: SurveyPayloadSchema,
feedChannelIds: z.array(z.string()),
}) })
) )
.output(SurveyModelSchema) .output(SurveyModelSchema)
.mutation(async ({ input }) => { .mutation(async ({ input }) => {
const { workspaceId, name, payload } = input; const { workspaceId, name, payload, feedChannelIds } = input;
const res = await prisma.survey.create({ const res = await prisma.survey.create({
data: { data: {
workspaceId, workspaceId,
name, name,
payload, payload,
feedChannelIds,
}, },
}); });
@ -211,11 +241,12 @@ export const surveyRouter = router({
surveyId: z.string(), surveyId: z.string(),
name: z.string().optional(), name: z.string().optional(),
payload: SurveyPayloadSchema.optional(), payload: SurveyPayloadSchema.optional(),
feedChannelIds: z.array(z.string()).optional(),
}) })
) )
.output(SurveyModelSchema) .output(SurveyModelSchema)
.mutation(async ({ input }) => { .mutation(async ({ input }) => {
const { workspaceId, surveyId, name, payload } = input; const { workspaceId, surveyId, name, payload, feedChannelIds } = input;
const res = await prisma.survey.update({ const res = await prisma.survey.update({
where: { where: {
@ -225,6 +256,7 @@ export const surveyRouter = router({
data: { data: {
name, name,
payload, payload,
feedChannelIds,
}, },
}); });