Skip to content
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
135 changes: 77 additions & 58 deletions bun.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@
"@playwright/test": "^1.59.1",
"@posthog/nextjs-config": "^1.9.55",
"@tailwindcss/postcss": "^4.0.15",
"@testing-library/dom": "^10.4.1",
"@testing-library/react": "^16.3.2",
"@types/bun": "^1.2.5",
"@types/node": "22.10.10",
"@types/react": "19.2.3",
Expand All @@ -158,6 +160,7 @@
"@vitest/coverage-v8": "^3.0.7",
"@vitest/ui": "3.0.7",
"babel-plugin-react-compiler": "^19.1.0-rc.2",
"jsdom": "^29.1.1",
"knip": "^6.11.0",
"openapi-typescript": "^7.8.0",
"pino-pretty": "^13.1.1",
Expand Down
4 changes: 2 additions & 2 deletions src/app/(auth)/auth/cli/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ async function handleLegacyCLIAuth(
}).listUserTeams()

if (!teamsResult.ok) {
throw new Error('Failed to resolve default team')
throw new Error('Failed to resolve default project')
}

const defaultTeam =
teamsResult.data.find((team) => team.isDefault && team.slug) ??
teamsResult.data.find((team) => team.slug)

if (!defaultTeam) {
throw new Error('Failed to resolve default team')
throw new Error('Failed to resolve default project')
}

const e2bAccessToken = await generateE2BUserAccessToken(
Expand Down
2 changes: 1 addition & 1 deletion src/app/dashboard/[teamSlug]/connections/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export default async function ConnectionsPage({
<header className="flex flex-col gap-1">
<h1 className="prose-title text-fg">Connections</h1>
<p className="prose-body text-fg-tertiary max-w-2xl">
Connect services that run workloads in your E2B team.
Connect services that run workloads in your E2B project.
</p>
</header>

Expand Down
8 changes: 6 additions & 2 deletions src/app/dashboard/[teamSlug]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { featureFlags } from '@/core/modules/feature-flags/feature-flags.server'
import { getAuthContext } from '@/core/server/auth'
import DashboardLayoutView from '@/features/dashboard/layouts/layout'
import { DashboardPostHogErrorBoundary } from '@/features/dashboard/posthog-error-boundary'
import { ProjectsAnnouncementBanner } from '@/features/dashboard/projects-announcement/banner'
import Sidebar from '@/features/dashboard/sidebar/sidebar'
import {
getQueryClient,
Expand Down Expand Up @@ -95,8 +96,11 @@ export default async function DashboardLayout({
}
>
<div className="fixed inset-0 flex max-h-full min-h-0 w-full flex-col overflow-hidden">
<div className="flex h-full max-h-full min-h-0 w-full flex-1 overflow-hidden">
<Sidebar />
<ProjectsAnnouncementBanner />
<div className="relative flex h-full max-h-full min-h-0 w-full flex-1 overflow-hidden">
{/* Anchored to this row instead of the viewport so the
announcement banner above stays fully visible. */}
<Sidebar anchor="container" />
<SidebarInset>
<DashboardPostHogErrorBoundary>
<DashboardLayoutView params={params}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default async function SandboxInspectPage({

const teamId = await getTeamIdFromSlug(teamSlug, authContext.accessToken)
if (!teamId.ok) {
throw new Error('Failed to resolve team for sandbox filesystem')
throw new Error('Failed to resolve project for sandbox filesystem')
}
if (!teamId.data) {
redirect(PROTECTED_URLS.DASHBOARD)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default async function SandboxTerminalPage({

const teamId = await getTeamIdFromSlug(teamSlug, authContext.accessToken)
if (!teamId.ok) {
throw new Error('Failed to resolve team for sandbox terminal')
throw new Error('Failed to resolve project for sandbox terminal')
}
if (!teamId.data) {
redirect(PROTECTED_URLS.DASHBOARD)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function TemplateNotFound() {
<CardDescription>Template not found</CardDescription>
</CardHeader>
<CardContent className="text-center text-fg-secondary">
<p>We couldn’t find this template in your team.</p>
<p>We couldn’t find this template in your project.</p>
</CardContent>
<CardFooter>
<Button
Expand Down
2 changes: 1 addition & 1 deletion src/app/dashboard/[teamSlug]/terminal/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ function TerminalSignIn({
}

function TerminalUnavailable({
message = 'We could not resolve a dashboard team for this account.',
message = 'We could not resolve a dashboard project for this account.',
}: {
message?: string
}) {
Expand Down
6 changes: 3 additions & 3 deletions src/app/dashboard/unauthorized.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export default function Unauthorized() {
</CardHeader>
<CardContent className="text-center text-fg-secondary">
<p>
You don't have permission to access this team. Please contact the
team owner or administrator to request access.
You don't have permission to access this project. Please contact the
project owner or administrator to request access.
</p>
</CardContent>
<CardFooter className="flex flex-col gap-1">
Expand All @@ -47,7 +47,7 @@ export default function Unauthorized() {
<Button variant="secondary" asChild className="flex-1">
<Link href={PROTECTED_URLS.DASHBOARD}>
<PersonsIcon />
My Teams
My Projects
</Link>
</Button>
</div>
Expand Down
8 changes: 4 additions & 4 deletions src/configs/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,26 +86,26 @@ export const SIDEBAR_MAIN_LINKS: SidebarNavItem[] = [
]
: []),

// Team
// Project
{
label: 'General',
href: (args) => PROTECTED_URLS.GENERAL(args.teamSlug!),
icon: SettingsIcon,
group: 'team',
group: 'project',
activeMatch: `/dashboard/*/general`,
},
{
label: 'API Keys',
href: (args) => PROTECTED_URLS.KEYS(args.teamSlug!),
icon: KeyIcon,
group: 'team',
group: 'project',
activeMatch: `/dashboard/*/keys`,
},
{
label: 'Members',
href: (args) => PROTECTED_URLS.MEMBERS(args.teamSlug!),
icon: PersonsIcon,
group: 'team',
group: 'project',
activeMatch: `/dashboard/*/members`,
},

Expand Down
4 changes: 2 additions & 2 deletions src/configs/user-messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const USER_MESSAGES = {
message: 'Password updated.',
},
teamNameUpdated: {
message: 'Team name updated.',
message: 'Project name updated.',
},
failedUpdateName: {
message: 'Failed to update name.',
Expand All @@ -21,6 +21,6 @@ export const USER_MESSAGES = {
message: 'Failed to update password.',
},
failedUpdateTeamName: {
message: 'Failed to update team name.',
message: 'Failed to update project name.',
},
}
4 changes: 2 additions & 2 deletions src/core/modules/sandboxes/repository.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ export function createSandboxesRepository(
return err(
repoErrorFromHttp(
result.response.status,
result.error?.message ?? 'Failed to fetch team metrics',
result.error?.message ?? 'Failed to fetch project metrics',
result.error
)
)
Expand Down Expand Up @@ -550,7 +550,7 @@ export function createSandboxesRepository(
return err(
repoErrorFromHttp(
result.response.status,
result.error?.message ?? 'Failed to fetch team metrics max',
result.error?.message ?? 'Failed to fetch project metrics max',
result.error
)
)
Expand Down
9 changes: 7 additions & 2 deletions src/core/modules/support/repository.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'server-only'

import { AttachmentType, PlainClient } from '@team-plain/typescript-sdk'
import { createUserTeamsRepository } from '@/core/modules/teams/user-teams-repository.server'
import { getTeamDisplayName } from '@/core/modules/teams/utils'
import { l, serializeErrorForLog } from '@/core/shared/clients/logger/logger'
import { repoErrorFromHttp } from '@/core/shared/errors'
import type { TeamRequestScope } from '@/core/shared/repository-scope'
Expand Down Expand Up @@ -149,13 +150,17 @@ export function createSupportRepository(

if (!team) {
return err(
repoErrorFromHttp(403, 'Team not found or access denied', {
repoErrorFromHttp(403, 'Project not found or access denied', {
teamId: scope.teamId,
})
)
}

return ok({ name: team.name, email: team.email, tier: team.tier })
return ok({
name: getTeamDisplayName(team),
email: team.email,
tier: team.tier,
})
},
async createSupportThread(input) {
if (!process.env.PLAIN_API_KEY) {
Expand Down
8 changes: 4 additions & 4 deletions src/core/modules/teams/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ const TEAM_NAME_MAX_LENGTH = 32
const TeamNameSchema = z
.string()
.trim()
.min(1, { message: 'Team name cannot be empty' })
.min(1, { message: 'Project name cannot be empty' })
.max(TEAM_NAME_MAX_LENGTH, {
message: `Team name cannot be longer than ${TEAM_NAME_MAX_LENGTH} characters`,
message: `Project name cannot be longer than ${TEAM_NAME_MAX_LENGTH} characters`,
})
.regex(/^[a-zA-Z0-9]+(?:[ _.-][a-zA-Z0-9]+)*$/, {
.regex(/^[a-zA-Z0-9]+(?:[ '_.-][a-zA-Z0-9]+)*$/, {
message:
'Names can only contain letters and numbers, separated by spaces, underscores, hyphens, or dots',
'Names can only contain letters and numbers, separated by spaces, apostrophes, underscores, hyphens, or dots',
})

const UpdateTeamNameSchema = z.object({
Expand Down
8 changes: 4 additions & 4 deletions src/core/modules/teams/teams-repository.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function createTeamsRepository(
return err(
repoErrorFromHttp(
response.status,
error?.message ?? 'Failed to fetch team members',
error?.message ?? 'Failed to fetch project members',
error
)
)
Expand Down Expand Up @@ -112,7 +112,7 @@ export function createTeamsRepository(
return err(
repoErrorFromHttp(
response.status,
error?.message ?? 'Failed to update team name',
error?.message ?? 'Failed to update project name',
error
)
)
Expand All @@ -139,7 +139,7 @@ export function createTeamsRepository(
return err(
repoErrorFromHttp(
response.status,
error?.message ?? 'Failed to add team member',
error?.message ?? 'Failed to add project member',
error
)
)
Expand All @@ -165,7 +165,7 @@ export function createTeamsRepository(
return err(
repoErrorFromHttp(
response.status,
error?.message ?? 'Failed to remove team member',
error?.message ?? 'Failed to remove project member',
error
)
)
Expand Down
8 changes: 4 additions & 4 deletions src/core/modules/teams/user-teams-repository.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function createUserTeamsRepository(
return err(
repoErrorFromHttp(
response.status,
error?.message ?? 'Failed to fetch user teams',
error?.message ?? 'Failed to fetch user projects',
error
)
)
Expand Down Expand Up @@ -89,7 +89,7 @@ export function createUserTeamsRepository(
createRepoError({
code: 'validation',
status: response.status,
message: error?.message ?? 'Failed to create team',
message: error?.message ?? 'Failed to create project',
cause: error,
})
)
Expand All @@ -98,7 +98,7 @@ export function createUserTeamsRepository(
return err(
repoErrorFromHttp(
response.status,
error?.message ?? 'Failed to create team',
error?.message ?? 'Failed to create project',
error
)
)
Expand Down Expand Up @@ -126,7 +126,7 @@ export function createUserTeamsRepository(
return err(
repoErrorFromHttp(
response.status,
error?.message ?? 'Failed to resolve team',
error?.message ?? 'Failed to resolve project',
error
)
)
Expand Down
4 changes: 2 additions & 2 deletions src/core/modules/teams/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ export function getTransformedDefaultTeamName(

const [username] = team.email.split('@')
if (!username) {
return null
return 'Personal Project'
}

return `${username.charAt(0).toUpperCase()}${username.slice(1)}'s Team`
return `${username.charAt(0).toUpperCase()}${username.slice(1)}'s Project`
}

export function getTeamDisplayName(
Expand Down
12 changes: 10 additions & 2 deletions src/core/modules/templates/repository.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,11 @@ export function createTemplatesRepository(
)
if (!template) {
return err(
repoErrorFromHttp(404, 'Template not found in this team', undefined)
repoErrorFromHttp(
404,
'Template not found in this project',
undefined
)
)
}

Expand Down Expand Up @@ -141,7 +145,11 @@ export function createTemplatesRepository(

if (!res.data) {
return err(
repoErrorFromHttp(404, 'Template not found in this team', undefined)
repoErrorFromHttp(
404,
'Template not found in this project',
undefined
)
)
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/shared/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const PUBLIC_ERROR_MESSAGE_UNAUTHORIZED = 'Unauthorized'
export const PUBLIC_ERROR_MESSAGE_FORBIDDEN =
'You are not authorized to access this resource'
export const PUBLIC_ERROR_MESSAGE_FORBIDDEN_TEAM =
'You are not authorized to access this team'
'You are not authorized to access this project'
export const PUBLIC_ERROR_MESSAGE_UNAUTHENTICATED = 'User not authenticated'
export const PUBLIC_ERROR_MESSAGE_INTERNAL =
'An Unexpected Error Occurred, please try again. If the problem persists, please contact support.'
Expand Down
2 changes: 1 addition & 1 deletion src/features/dashboard/account/name-settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export function NameSettings({ className }: NameSettingsProps) {
<CardHeader>
<CardTitle>Name</CardTitle>
<CardDescription>
Update your account name, which will be visible to your team
Update your account name, which will be visible to your project
members.
</CardDescription>
</CardHeader>
Expand Down
2 changes: 1 addition & 1 deletion src/features/dashboard/members/add-member-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const AddMemberForm = ({ className, onSuccess }: AddMemberFormProps) => {
await queryClient.invalidateQueries({
queryKey: trpc.teams.members.queryKey({ teamSlug: team.slug }),
})
toast(defaultSuccessToast('The member has been added to the team.'))
toast(defaultSuccessToast('The member has been added to the project.'))
form.reset()
onSuccess?.()
},
Expand Down
4 changes: 2 additions & 2 deletions src/features/dashboard/members/member-table-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ export const MemberTableRow = ({ member, addedByMember }: TableRowProps) => {

router.push(PROTECTED_URLS.DASHBOARD)

toast(defaultSuccessToast('You have left the team.'))
toast(defaultSuccessToast('You have left the project.'))
} else {
await queryClient.invalidateQueries({
queryKey: trpc.teams.members.queryKey({ teamSlug: team.slug }),
})
toast(
defaultSuccessToast('The member has been removed from the team.')
defaultSuccessToast('The member has been removed from the project.')
)
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/features/dashboard/members/members-page-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const MembersTableRows = ({ query }: { query: string }) => {
<TableEmptyState colSpan={3}>
<p className="prose-body-highlight text-fg-tertiary">
{members.length === 0
? 'No team members found.'
? 'No project members found.'
: 'No members match your search.'}
</p>
</TableEmptyState>
Expand Down
Loading
Loading