2
0

feat(editor): Restore published version button

Had to migrate webhooks into a standalone table
This commit is contained in:
Baptiste Arnaud
2022-03-01 07:13:09 +01:00
parent 0df719d531
commit e17a1a0869
46 changed files with 578 additions and 348 deletions

View File

@ -1,17 +1,16 @@
import { Block, PublicBlock, PublicStep, PublicTypebot, Typebot } from 'models'
import { PublicTypebot, Typebot } from 'models'
import shortId from 'short-uuid'
import { HStack, Text } from '@chakra-ui/react'
import { CalendarIcon, CodeIcon } from 'assets/icons'
import { StepIcon } from 'components/editor/StepsSideBar/StepIcon'
import { byId, isInputStep, sendRequest } from 'utils'
import { isDefined } from '@udecode/plate-common'
export const parseTypebotToPublicTypebot = (
typebot: Typebot
): PublicTypebot => ({
id: shortId.generate(),
typebotId: typebot.id,
blocks: parseBlocksToPublicBlocks(typebot.blocks),
blocks: typebot.blocks,
edges: typebot.edges,
name: typebot.name,
publicId: typebot.publicId,
@ -19,18 +18,29 @@ export const parseTypebotToPublicTypebot = (
theme: typebot.theme,
variables: typebot.variables,
customDomain: typebot.customDomain,
createdAt: new Date(),
updatedAt: new Date(),
})
export const parseBlocksToPublicBlocks = (blocks: Block[]): PublicBlock[] =>
blocks.map((b) => ({
...b,
steps: b.steps.map(
(s) =>
('webhook' in s && isDefined(s.webhook)
? { ...s, webhook: s.webhook.id }
: s) as PublicStep
),
}))
export const parsePublicTypebotToTypebot = (
typebot: PublicTypebot,
existingTypebot: Typebot
): Typebot => ({
id: typebot.typebotId,
blocks: typebot.blocks,
edges: typebot.edges,
name: typebot.name,
publicId: typebot.publicId,
settings: typebot.settings,
theme: typebot.theme,
variables: typebot.variables,
customDomain: typebot.customDomain,
createdAt: existingTypebot.createdAt,
updatedAt: existingTypebot.updatedAt,
publishedTypebotId: typebot.id,
folderId: existingTypebot.folderId,
ownerId: existingTypebot.ownerId,
})
export const createPublishedTypebot = async (typebot: PublicTypebot) =>
sendRequest<PublicTypebot>({

View File

@ -29,8 +29,6 @@ import {
defaultGoogleAnalyticsOptions,
defaultWebhookOptions,
StepWithOptionsType,
defaultWebhookAttributes,
Webhook,
Item,
ItemType,
defaultConditionContent,
@ -39,7 +37,7 @@ import {
import shortId, { generate } from 'short-uuid'
import { Typebot } from 'models'
import useSWR from 'swr'
import { fetcher, omit, toKebabCase } from '../utils'
import { fetcher, toKebabCase } from '../utils'
import {
isBubbleStepType,
stepTypeHasItems,
@ -48,8 +46,8 @@ import {
} from 'utils'
import { deepEqual } from 'fast-equals'
import { stringify } from 'qs'
import { isChoiceInput, isConditionStep, sendRequest } from 'utils'
import { parseBlocksToPublicBlocks } from '../publicTypebot'
import { isChoiceInput, isConditionStep, sendRequest, omit } from 'utils'
import cuid from 'cuid'
export type TypebotInDashboard = Pick<
Typebot,
@ -173,16 +171,11 @@ export const parseNewStep = (
options: stepTypeHasOption(type)
? parseDefaultStepOptions(type)
: undefined,
webhook: stepTypeHasWebhook(type) ? parseDefaultWebhook() : undefined,
webhookId: stepTypeHasWebhook(type) ? cuid() : undefined,
items: stepTypeHasItems(type) ? parseDefaultItems(type, id) : undefined,
} as DraggableStep
}
const parseDefaultWebhook = (): Webhook => ({
id: generate(),
...defaultWebhookAttributes,
})
const parseDefaultItems = (
type: LogicStepType.CONDITION | InputStepType.CHOICE,
stepId: string
@ -255,7 +248,7 @@ export const checkIfPublished = (
typebot: Typebot,
publicTypebot: PublicTypebot
) =>
deepEqual(parseBlocksToPublicBlocks(typebot.blocks), publicTypebot.blocks) &&
deepEqual(typebot.blocks, publicTypebot.blocks) &&
deepEqual(typebot.settings, publicTypebot.settings) &&
deepEqual(typebot.theme, publicTypebot.theme) &&
deepEqual(typebot.variables, publicTypebot.variables)

View File

@ -1,6 +1,6 @@
import imageCompression from 'browser-image-compression'
import { Parser } from 'htmlparser2'
import { PublicStep, Step, Typebot } from 'models'
import { Step, Typebot } from 'models'
export const fetcher = async (input: RequestInfo, init?: RequestInit) => {
const res = await fetch(input, init)
@ -36,26 +36,6 @@ export const toKebabCase = (value: string) => {
return matched.map((x) => x.toLowerCase()).join('-')
}
interface Omit {
// eslint-disable-next-line @typescript-eslint/ban-types
<T extends object, K extends [...(keyof T)[]]>(obj: T, ...keys: K): {
[K2 in Exclude<keyof T, K[number]>]: T[K2]
}
}
export const omit: Omit = (obj, ...keys) => {
const ret = {} as {
[K in keyof typeof obj]: typeof obj[K]
}
let key: keyof typeof obj
for (key in obj) {
if (!keys.includes(key)) {
ret[key] = obj[key]
}
}
return ret
}
export const uploadFile = async (file: File, key: string) => {
const res = await fetch(
`/api/storage/upload-url?key=${encodeURIComponent(
@ -98,7 +78,7 @@ export const removeUndefinedFields = <T>(obj: T): T =>
{} as T
)
export const stepHasOptions = (step: Step | PublicStep) => 'options' in step
export const stepHasOptions = (step: Step) => 'options' in step
export const parseVariableHighlight = (content: string, typebot: Typebot) => {
const varNames = typebot.variables.map((v) => v.name)
@ -128,3 +108,32 @@ export const readFile = (file: File): Promise<string> => {
fr.readAsText(file)
})
}
export const timeSince = (date: string) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
const seconds = Math.floor((new Date() - new Date(date)) / 1000)
let interval = seconds / 31536000
if (interval > 1) {
return Math.floor(interval) + ' years'
}
interval = seconds / 2592000
if (interval > 1) {
return Math.floor(interval) + ' months'
}
interval = seconds / 86400
if (interval > 1) {
return Math.floor(interval) + ' days'
}
interval = seconds / 3600
if (interval > 1) {
return Math.floor(interval) + ' hours'
}
interval = seconds / 60
if (interval > 1) {
return Math.floor(interval) + ' minutes'
}
return Math.floor(seconds) + ' seconds'
}

View File

@ -0,0 +1,9 @@
import { Webhook } from 'models'
import { sendRequest } from 'utils'
export const saveWebhook = (webhookId: string, webhook: Partial<Webhook>) =>
sendRequest<{ webhook: Webhook }>({
method: 'PUT',
url: `/api/webhooks/${webhookId}`,
body: webhook,
})