feat: add feed template string of survey
This commit is contained in:
parent
d9862105ed
commit
22fc5f98f8
@ -504,6 +504,9 @@ importers:
|
||||
lodash:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
lodash-es:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
maxmind:
|
||||
specifier: ^4.3.18
|
||||
version: 4.3.18
|
||||
@ -592,6 +595,9 @@ importers:
|
||||
'@types/lodash':
|
||||
specifier: ^4.14.198
|
||||
version: 4.14.198
|
||||
'@types/lodash-es':
|
||||
specifier: ^4.17.12
|
||||
version: 4.17.12
|
||||
'@types/md5':
|
||||
specifier: ^2.3.5
|
||||
version: 2.3.5
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
FormMessage,
|
||||
} from '@/components/ui/form';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { useForm, useFieldArray } from 'react-hook-form';
|
||||
import { useForm, useFieldArray, useWatch } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { generateRandomString } from '@/utils/common';
|
||||
import { LuArrowDown, LuArrowUp, LuMinus, LuPlus } from 'react-icons/lu';
|
||||
@ -48,6 +48,7 @@ const addFormSchema = z.object({
|
||||
),
|
||||
}),
|
||||
feedChannelIds: z.array(z.string()),
|
||||
feedTemplate: z.string(),
|
||||
});
|
||||
|
||||
export type SurveyEditFormValues = z.infer<typeof addFormSchema>;
|
||||
@ -78,9 +79,12 @@ export const SurveyEditForm: React.FC<SurveyEditFormProps> = React.memo(
|
||||
items: [generateDefaultItem()],
|
||||
},
|
||||
feedChannelIds: [],
|
||||
feedTemplate: '',
|
||||
},
|
||||
});
|
||||
|
||||
const feedChannelIds = form.watch('feedChannelIds');
|
||||
|
||||
const [handleSubmit, isLoading] = useEventWithLoading(
|
||||
async (values: SurveyEditFormValues) => {
|
||||
await props.onSubmit(values);
|
||||
@ -263,6 +267,36 @@ export const SurveyEditForm: React.FC<SurveyEditFormProps> = React.memo(
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{feedChannelIds.length > 0 && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="feedTemplate"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t('Feed Template')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder="survey {{_surveyName}} receive a new record."
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
<p>
|
||||
{t(
|
||||
'Survey Template String, here are available variables:'
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
{'{{_surveyName}} '}
|
||||
{fields.map((f) => `{{${f.name}}}`).join(' ')}
|
||||
</p>
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</CardContent>
|
||||
|
||||
<CardFooter>
|
||||
|
@ -51,6 +51,7 @@
|
||||
"isolated-vm": "^4.7.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"maxmind": "^4.3.18",
|
||||
"md5": "^2.3.0",
|
||||
"morgan": "^1.10.0",
|
||||
@ -82,6 +83,7 @@
|
||||
"@types/fs-extra": "^11.0.3",
|
||||
"@types/jsonwebtoken": "^9.0.5",
|
||||
"@types/lodash": "^4.14.198",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/md5": "^2.3.5",
|
||||
"@types/morgan": "^1.9.5",
|
||||
"@types/node": "^18.17.12",
|
||||
|
@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Survey" ADD COLUMN "feedTemplate" TEXT NOT NULL DEFAULT '';
|
@ -459,6 +459,7 @@ model Survey {
|
||||
/// @zod.custom(imports.SurveyPayloadSchema)
|
||||
payload Json @db.Json
|
||||
feedChannelIds String[] @default([]) // send survey result to feed channel
|
||||
feedTemplate String @default("") // send survey result to feed channel
|
||||
createdAt DateTime @default(now()) @db.Timestamptz(6)
|
||||
updatedAt DateTime @updatedAt @db.Timestamptz(6)
|
||||
|
||||
|
@ -17,6 +17,7 @@ export const SurveyModelSchema = z.object({
|
||||
*/
|
||||
payload: imports.SurveyPayloadSchema,
|
||||
feedChannelIds: z.string().array(),
|
||||
feedTemplate: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
})
|
||||
|
@ -20,6 +20,8 @@ import { buildCursorResponseSchema } from '../../utils/schema.js';
|
||||
import { fetchDataByCursor } from '../../utils/prisma.js';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { createFeedEvent } from '../../model/feed/event.js';
|
||||
import { formatString } from '../../utils/template.js';
|
||||
import { logger } from '../../utils/logger.js';
|
||||
|
||||
export const surveyRouter = router({
|
||||
all: workspaceProcedure
|
||||
@ -185,15 +187,33 @@ export const surveyRouter = router({
|
||||
Array.isArray(survey.feedChannelIds) &&
|
||||
survey.feedChannelIds.length > 0
|
||||
) {
|
||||
const templateStr =
|
||||
survey.feedTemplate ||
|
||||
'survey {{_surveyName}} receive a new record.';
|
||||
|
||||
survey.feedChannelIds.forEach((channelId) => {
|
||||
try {
|
||||
const surveyPayload = SurveyPayloadSchema.parse(survey.payload);
|
||||
|
||||
createFeedEvent(workspaceId, {
|
||||
channelId: channelId,
|
||||
eventName: 'receive',
|
||||
eventContent: `survey [${survey.name}] receive a new record.`,
|
||||
eventContent: formatString(templateStr, {
|
||||
_surveyName: survey.name,
|
||||
...Object.fromEntries(
|
||||
surveyPayload.items.map((item) => [
|
||||
item.name,
|
||||
payload[item.name] ?? '',
|
||||
])
|
||||
),
|
||||
}),
|
||||
tags: [],
|
||||
source: 'survey',
|
||||
important: false,
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error('[surveySubmitSendFeed]', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -212,11 +232,13 @@ export const surveyRouter = router({
|
||||
name: z.string(),
|
||||
payload: SurveyPayloadSchema,
|
||||
feedChannelIds: z.array(z.string()),
|
||||
feedTemplate: z.string(),
|
||||
})
|
||||
)
|
||||
.output(SurveyModelSchema)
|
||||
.mutation(async ({ input }) => {
|
||||
const { workspaceId, name, payload, feedChannelIds } = input;
|
||||
const { workspaceId, name, payload, feedChannelIds, feedTemplate } =
|
||||
input;
|
||||
|
||||
const res = await prisma.survey.create({
|
||||
data: {
|
||||
@ -224,6 +246,7 @@ export const surveyRouter = router({
|
||||
name,
|
||||
payload,
|
||||
feedChannelIds,
|
||||
feedTemplate,
|
||||
},
|
||||
});
|
||||
|
||||
@ -242,11 +265,19 @@ export const surveyRouter = router({
|
||||
name: z.string().optional(),
|
||||
payload: SurveyPayloadSchema.optional(),
|
||||
feedChannelIds: z.array(z.string()).optional(),
|
||||
feedTemplate: z.string().optional(),
|
||||
})
|
||||
)
|
||||
.output(SurveyModelSchema)
|
||||
.mutation(async ({ input }) => {
|
||||
const { workspaceId, surveyId, name, payload, feedChannelIds } = input;
|
||||
const {
|
||||
workspaceId,
|
||||
surveyId,
|
||||
name,
|
||||
payload,
|
||||
feedChannelIds,
|
||||
feedTemplate,
|
||||
} = input;
|
||||
|
||||
const res = await prisma.survey.update({
|
||||
where: {
|
||||
@ -257,6 +288,7 @@ export const surveyRouter = router({
|
||||
name,
|
||||
payload,
|
||||
feedChannelIds,
|
||||
feedTemplate,
|
||||
},
|
||||
});
|
||||
|
||||
|
4
src/server/types/global.d.ts
vendored
4
src/server/types/global.d.ts
vendored
@ -1,8 +1,8 @@
|
||||
import type { JWTPayload } from '../middleware/auth';
|
||||
import type { JWTPayload } from '../middleware/auth.ts';
|
||||
import type {
|
||||
MonitorStatusPageListSchema,
|
||||
SurveyPayloadSchema,
|
||||
} from '../prisma/zod/schemas';
|
||||
} from '../prisma/zod/schemas/index.ts';
|
||||
|
||||
declare global {
|
||||
namespace Express {
|
||||
|
13
src/server/utils/template.ts
Normal file
13
src/server/utils/template.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { template, templateSettings } from 'lodash-es';
|
||||
|
||||
templateSettings.interpolate = /{{([\s\S]+?)}}/g;
|
||||
|
||||
/**
|
||||
* @example
|
||||
*
|
||||
* buildTemplate('hello {{ user }}!', { user: 'mustache' })
|
||||
* => 'hello mustache!'
|
||||
*/
|
||||
export function formatString(raw: string, variable: Record<string, string>) {
|
||||
return template(raw)(variable);
|
||||
}
|
Loading…
Reference in New Issue
Block a user