Skip to content

Commit

Permalink
🛂 Improve editor authorization feedback (#856)
Browse files Browse the repository at this point in the history
Closes #844, closes #839

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
### Summary by CodeRabbit

- New Feature: Added a `logOut` function to the user context for
improved logout handling.
- Refactor: Updated the redirect path in the `SignInForm` component for
better user redirection after authentication.
- New Feature: Enhanced the "Add" button and "Connect new" menu item in
`CredentialsDropdown` with role-based access control.
- Refactor: Replaced the `signOut` function with the `logOut` function
from the `useUser` hook in `DashboardHeader`.
- Bug Fix: Prevented execution of certain code blocks in
`TypebotProvider` when `typebotData` is read-only.
- Refactor: Optimized the `handleObserver` function in `ResultsTable`
with a `useCallback` hook.
- Bug Fix: Improved router readiness check in `WorkspaceProvider` to
prevent premature execution of certain operations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
baptisteArno authored Sep 26, 2023
1 parent 1ca742f commit 801fea8
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 37 deletions.
12 changes: 11 additions & 1 deletion apps/builder/src/features/account/UserProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useSession } from 'next-auth/react'
import { signOut, useSession } from 'next-auth/react'
import { useRouter } from 'next/router'
import { createContext, ReactNode, useEffect, useState } from 'react'
import { isDefined, isNotDefined } from '@typebot.io/lib'
Expand All @@ -15,9 +15,13 @@ export const userContext = createContext<{
user?: User
isLoading: boolean
currentWorkspaceId?: string
logOut: () => void
updateUser: (newUser: Partial<User>) => void
}>({
isLoading: false,
logOut: () => {
console.log('logOut not implemented')
},
updateUser: () => {
console.log('updateUser not implemented')
},
Expand Down Expand Up @@ -91,6 +95,11 @@ export const UserProvider = ({ children }: { children: ReactNode }) => {
env.NEXT_PUBLIC_E2E_TEST ? 0 : debounceTimeout
)

const logOut = () => {
signOut()
setUser(undefined)
}

useEffect(() => {
return () => {
saveUser.flush()
Expand All @@ -103,6 +112,7 @@ export const UserProvider = ({ children }: { children: ReactNode }) => {
user,
isLoading: status === 'loading',
currentWorkspaceId,
logOut,
updateUser,
}}
>
Expand Down
2 changes: 1 addition & 1 deletion apps/builder/src/features/auth/components/SignInForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const SignInForm = ({

useEffect(() => {
if (status === 'authenticated') {
router.replace(router.query.callbackUrl?.toString() ?? '/typebots')
router.replace(router.query.redirectPath?.toString() ?? '/typebots')
return
}
;(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useRouter } from 'next/router'
import { useToast } from '../../../hooks/useToast'
import { Credentials } from '@typebot.io/schemas'
import { trpc } from '@/lib/trpc'
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'

type Props = Omit<ButtonProps, 'type'> & {
type: Credentials['type']
Expand All @@ -38,6 +39,7 @@ export const CredentialsDropdown = ({
}: Props) => {
const router = useRouter()
const { showToast } = useToast()
const { currentRole } = useWorkspace()
const { data, refetch } = trpc.credentials.listCredentials.useQuery({
workspaceId,
type,
Expand Down Expand Up @@ -107,6 +109,7 @@ export const CredentialsDropdown = ({
textAlign="left"
leftIcon={<PlusIcon />}
onClick={onCreateNewClick}
isDisabled={currentRole === 'GUEST'}
{...props}
>
Add {credentialsName}
Expand Down Expand Up @@ -165,16 +168,18 @@ export const CredentialsDropdown = ({
/>
</MenuItem>
))}
<MenuItem
maxW="500px"
overflow="hidden"
whiteSpace="nowrap"
textOverflow="ellipsis"
icon={<PlusIcon />}
onClick={onCreateNewClick}
>
Connect new
</MenuItem>
{currentRole === 'GUEST' ? null : (
<MenuItem
maxW="500px"
overflow="hidden"
whiteSpace="nowrap"
textOverflow="ellipsis"
icon={<PlusIcon />}
onClick={onCreateNewClick}
>
Connect new
</MenuItem>
)}
</Stack>
</MenuList>
</Menu>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react'
import { HStack, Flex, Button, useDisclosure } from '@chakra-ui/react'
import { HardDriveIcon, SettingsIcon } from '@/components/icons'
import { signOut } from 'next-auth/react'
import { useUser } from '@/features/account/hooks/useUser'
import { isNotDefined } from '@typebot.io/lib'
import Link from 'next/link'
Expand All @@ -13,15 +12,11 @@ import { WorkspaceSettingsModal } from '@/features/workspace/components/Workspac

export const DashboardHeader = () => {
const scopedT = useScopedI18n('dashboard.header')
const { user } = useUser()
const { user, logOut } = useUser()
const { workspace, switchWorkspace, createWorkspace } = useWorkspace()

const { isOpen, onOpen, onClose } = useDisclosure()

const handleLogOut = () => {
signOut()
}

const handleCreateNewWorkspace = () =>
createWorkspace(user?.name ?? undefined)

Expand Down Expand Up @@ -59,7 +54,7 @@ export const DashboardHeader = () => {
</Button>
<WorkspaceDropdown
currentWorkspace={workspace}
onLogoutClick={handleLogOut}
onLogoutClick={logOut}
onCreateNewWorkspaceClick={handleCreateNewWorkspace}
onWorkspaceSelected={switchWorkspace}
/>
Expand Down
14 changes: 10 additions & 4 deletions apps/builder/src/features/editor/providers/TypebotProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export const TypebotProvider = ({

const saveTypebot = useCallback(
async (updates?: Partial<Typebot>) => {
if (!localTypebot || !typebot) return
if (!localTypebot || !typebot || typebotData?.isReadOnly) return
const typebotToSave = { ...localTypebot, ...updates }
if (dequal(omit(typebot, 'updatedAt'), omit(typebotToSave, 'updatedAt')))
return
Expand All @@ -180,7 +180,13 @@ export const TypebotProvider = ({
setLocalTypebot({ ...newTypebot })
return newTypebot
},
[localTypebot, setLocalTypebot, typebot, updateTypebot]
[
localTypebot,
setLocalTypebot,
typebot,
typebotData?.isReadOnly,
updateTypebot,
]
)

useAutoSave(
Expand Down Expand Up @@ -212,15 +218,15 @@ export const TypebotProvider = ({
)

useEffect(() => {
if (!localTypebot || !typebot) return
if (!localTypebot || !typebot || typebotData?.isReadOnly) return
if (!areTypebotsEqual(localTypebot, typebot)) {
window.addEventListener('beforeunload', preventUserFromRefreshing)
}

return () => {
window.removeEventListener('beforeunload', preventUserFromRefreshing)
}
}, [localTypebot, typebot])
}, [localTypebot, typebot, typebotData?.isReadOnly])

const updateLocalTypebot = async ({
updates,
Expand Down
30 changes: 17 additions & 13 deletions apps/builder/src/features/results/components/table/ResultsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from '@chakra-ui/react'
import { AlignLeftTextIcon } from '@/components/icons'
import { ResultHeaderCell, ResultsTablePreferences } from '@typebot.io/schemas'
import React, { useEffect, useRef, useState } from 'react'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { LoadingRows } from './LoadingRows'
import {
useReactTable,
Expand Down Expand Up @@ -48,7 +48,7 @@ export const ResultsTable = ({
onResultExpandIndex,
}: ResultsTableProps) => {
const background = useColorModeValue('white', colors.gray[900])
const { updateTypebot } = useTypebot()
const { updateTypebot, isReadOnly } = useTypebot()
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({})
const [isTableScrolled, setIsTableScrolled] = useState(false)
const bottomElement = useRef<HTMLDivElement | null>(null)
Expand Down Expand Up @@ -185,6 +185,14 @@ export const ResultsTable = ({
getCoreRowModel: getCoreRowModel(),
})

const handleObserver = useCallback(
(entities: IntersectionObserverEntry[]) => {
const target = entities[0]
if (target.isIntersecting) onScrollToBottom()
},
[onScrollToBottom]
)

useEffect(() => {
if (!bottomElement.current) return
const options: IntersectionObserverInit = {
Expand All @@ -197,21 +205,17 @@ export const ResultsTable = ({
return () => {
observer.disconnect()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [bottomElement.current])

const handleObserver = (entities: IntersectionObserverEntry[]) => {
const target = entities[0]
if (target.isIntersecting) onScrollToBottom()
}
}, [handleObserver])

return (
<Stack maxW="1600px" px="4" overflowY="hidden" spacing={6}>
<HStack w="full" justifyContent="flex-end">
<SelectionToolbar
selectedResultsId={Object.keys(rowSelection)}
onClearSelection={() => setRowSelection({})}
/>
{isReadOnly ? null : (
<SelectionToolbar
selectedResultsId={Object.keys(rowSelection)}
onClearSelection={() => setRowSelection({})}
/>
)}
<TableSettingsButton
resultHeader={resultHeader}
columnVisibility={columnsVisibility}
Expand Down
6 changes: 5 additions & 1 deletion apps/builder/src/features/workspace/WorkspaceProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const WorkspaceProvider = ({
typebotId,
children,
}: WorkspaceContextProps) => {
const { pathname, query, push } = useRouter()
const { pathname, query, push, isReady: isRouterReady } = useRouter()
const { user } = useUser()
const userId = user?.id
const [workspaceId, setWorkspaceId] = useState<string | undefined>()
Expand Down Expand Up @@ -102,6 +102,8 @@ export const WorkspaceProvider = ({

useEffect(() => {
if (
pathname === '/signin' ||
!isRouterReady ||
!workspaces ||
workspaces.length === 0 ||
workspaceId ||
Expand All @@ -122,7 +124,9 @@ export const WorkspaceProvider = ({
setWorkspaceIdInLocalStorage(newWorkspaceId)
setWorkspaceId(newWorkspaceId)
}, [
isRouterReady,
members,
pathname,
query.workspaceId,
typebot?.workspaceId,
typebotId,
Expand Down

4 comments on commit 801fea8

@vercel
Copy link

@vercel vercel bot commented on 801fea8 Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

app.typebot.io
builder-v2-typebot-io.vercel.app
builder-v2-git-main-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 801fea8 Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

viewer-v2 – ./apps/viewer

bii.bj
1stop.au
houss.io
wasap.nl
x.cr8.ai
yobot.me
klujo.com
me.cr8.ai
p1314.fun
sifuim.co
wachat.io
wassep.io
247987.com
8jours.top
aginap.com
ai.mprs.in
bee.cr8.ai
bot.aws.bj
bot.bbc.bj
cat.cr8.ai
ecombot.me
finplex.be
jxi.cr8.ai
linkz.chat
nepkit.com
pig.cr8.ai
sat.cr8.ai
typebot.io
wachats.me
wsapio.com
zamrin.net
blogely.com
bot.aipr.kr
bot.kloo.me
broprio.com
bull.cr8.ai
chatjer.com
docs.cr8.ai
getyour.sbs
icon.cr8.ai
minipost.uk
mole.cr8.ai
nurraysa.me
saas.yachts
team.cr8.ai
triprint.my
wolf.cr8.ai
ai.meant.com
amostra-safe.click
andreimayer.com.br
bebesemcolicas.com
bot.innovacion.fun
infomakeracademy.com
kuiz.sistemniaga.com
leoborges-app.online
linspecteuremma.site
malayanboosterhq.com
menukb.wpwakanda.com
offer.botscientis.us
ore.barrettamario.it
sellmycarglasgow.com
site100seguro.online
stephanesampa.online
superglicemia.com.br
talkbot.agfunnel.com
tenorioadvogados.com
uppity.wpwakanda.com
web.whatisappweb.com
www.acordo-certo.com
83701274.21000000.lol
87186327.21000000.one
90945247.21000000.one
97320578.21000000.one
98650901.21000000.one
abutton.wpwakanda.com
acelera.maxbot.com.br
agendaestrategica.com
aidigitalmarketing.kr
atendimento.vrauu.com
bbutton.wpwakanda.com
bot.anovaerarb.online
bot.coachayongzul.com
bot.digitalpointer.id
bot.eikju.photography
bot.eymaleggingsg.com
bot.gamesimples.store
bot.incusservices.com
bot.jogomoderno.store
bot.mejoralasalud.fun
bot.meuesocial.com.br
bot.mycompany.reviews
bot.outstandbrand.com
bot.ramonmatos.com.br
bot.sharemyreview.net
bot.synapsegameia.com
bot.truongnguyen.live
bots.baptistearno.com
botz.cloudsiteapp.com
cdd.searchcube.com.sg
chat.jogonobrasil.com

@vercel
Copy link

@vercel vercel bot commented on 801fea8 Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

docs – ./apps/docs

docs.typebot.io
docs-git-main-typebot-io.vercel.app
docs-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 801fea8 Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.