Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🛂 Improve editor authorization feedback #856

Merged
merged 2 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 ||
baptisteArno marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -122,7 +124,9 @@ export const WorkspaceProvider = ({
setWorkspaceIdInLocalStorage(newWorkspaceId)
setWorkspaceId(newWorkspaceId)
}, [
isRouterReady,
members,
pathname,
query.workspaceId,
typebot?.workspaceId,
typebotId,
Expand Down