Skip to content
Open
3 changes: 2 additions & 1 deletion apps/pro-web/app/actions/thread.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { FileAttachment } from '@/lib/hooks/use-chat-attachments'
import type {
ThreadMetadata,
WorkspaceDocumentMetadata,
WorkspaceDocumentType,
WorkspaceDocumentVersion,
} from '@/types/thread.types'
import { Storage } from '@google-cloud/storage'
Expand Down Expand Up @@ -306,7 +307,7 @@ export async function uploadWorkspaceDocumentToBucket({
project: string
name: string
content: string
type?: 'text' | 'image' | 'spreadsheet'
type?: WorkspaceDocumentType
}) {
if (!content) throw new Error('Document content required')
const existingThread = await getThreadBySlug(threadSlug)
Expand Down
18 changes: 1 addition & 17 deletions apps/pro-web/app/api/workspace/state/route.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,12 @@
import { computeChecksum } from '@/lib/checksum'
import { logErrorToSentry } from '@/lib/sentry'
import type { WorkspaceStatePayload } from '@/types/thread.types'
import { appConfig } from 'mb-env'

// In-memory cache (ephemeral per server instance)
let cachedWorkspaceState: WorkspaceStatePayload | null = null
let cachedChecksum: string | null = null

export interface WorkspaceStatePayload {
organisationsVersion: number
updatedAt: number
organizations: string[]
departmentsByOrg: Record<string, string[]>
projectsByDept: Record<string, Record<string, string[]>>
textDocuments: Record<string, string[]>
imageDocuments: Record<string, string[]>
spreadsheetDocuments: Record<string, string[]>
documentContent: Record<string, string>
activeOrganization: string | null
activeDepartment: string | null
activeProject: string | null
activeDocument: string | null
activeDocumentType: 'all' | 'text' | 'image' | 'spreadsheet'
}

export async function GET() {
return new Response(
JSON.stringify({
Expand Down
26 changes: 13 additions & 13 deletions apps/pro-web/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ import '@/app/globals.css'
export default function RootLayout({ children }: RootLayoutProps) {
return (
<html lang="en" suppressHydrationWarning>
{/* Google Translate init function */}
<Script id="google-translate-init" strategy="beforeInteractive">
{`
<head>
{/* Google Translate init function */}
<Script id="google-translate-init" strategy="beforeInteractive">
{`
function googleTranslateElementInit() {
new google.translate.TranslateElement({
pageLanguage: 'en',
Expand All @@ -28,23 +29,22 @@ export default function RootLayout({ children }: RootLayoutProps) {
}, 'google_translate_element');
}
`}
</Script>
</Script>

{/* Google Translate script */}
<Script
src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"
strategy="beforeInteractive"
/>
{appConfig.ads.twitterAds.enabled && (
<head>
{/* Google Translate script */}
<Script
src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"
strategy="beforeInteractive"
/>
{appConfig.ads.twitterAds.enabled && (
<Script id="twitter-pixel">
{`!function(e,t,n,s,u,a){e.twq||(s=e.twq=function(){s.exe?s.exe.apply(s,arguments):s.queue.push(arguments);
},s.version='1.1',s.queue=[],u=t.createElement(n),u.async=!0,u.src='https://static.ads-twitter.com/uwt.js',
a=t.getElementsByTagName(n)[0],a.parentNode.insertBefore(u,a))}(window,document,'script');
twq('config','${appConfig.ads.twitterAds.campaignId}');`}
</Script>
</head>
)}
)}
</head>
<body
className={cn(
'font-sans antialiased',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { useWorkspace } from '@/lib/hooks/use-workspace'
import { cn } from '@/lib/utils'
import type { WorkspaceDocumentType } from '@/types/thread.types'
import {
ChevronDown,
FileSpreadsheetIcon,
Expand All @@ -53,9 +54,9 @@ export function CreateDocumentAlert({
isDocumentDialogOpen: boolean
activeProject: string
documentName: string
documentType: 'text' | 'image' | 'spreadsheet'
documentType: WorkspaceDocumentType
setDocumentName: (name: string) => void
setDocumentType: (type: 'text' | 'image' | 'spreadsheet') => void
setDocumentType: (type: WorkspaceDocumentType) => void
handleCreateDocument: (templateId: string) => void
setIsDocumentDialogOpen: (open: boolean) => void
}) {
Expand Down
3 changes: 2 additions & 1 deletion apps/pro-web/components/layout/header/crumb-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { cn } from '@/lib/utils'
import type { WorkspaceDocumentType } from '@/types/thread.types'
import {
ChevronDown,
FileSpreadsheetIcon,
Expand Down Expand Up @@ -105,7 +106,7 @@ export function DocumentCrumb({
userDocuments: { name: string }[]
activeThread: Thread | null
documentOptions: string[]
threadDocsByName: Map<string, { type?: 'text' | 'image' | 'spreadsheet' }>
threadDocsByName: Map<string, { type?: WorkspaceDocumentType }>
onNewItem: (
type: 'organization' | 'department' | 'project' | 'document',
) => void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { cn } from '@/lib/utils'
import type { WorkspaceDocumentTypeFilter } from '@/types/thread.types'
import {
ChevronDown,
FileSpreadsheetIcon,
Expand All @@ -16,11 +17,9 @@ import {
} from 'lucide-react'
import { useMemo } from 'react'

type DocumentType = 'all' | 'text' | 'image' | 'spreadsheet'

export interface DocumentTypeFilterProps {
activeType: DocumentType
onTypeChange: (type: DocumentType) => void
activeType: WorkspaceDocumentTypeFilter
onTypeChange: (type: WorkspaceDocumentTypeFilter) => void
disabled?: boolean
className?: string
}
Expand Down
10 changes: 6 additions & 4 deletions apps/pro-web/components/layout/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import { useWorkspace } from '@/lib/hooks/use-workspace'
import { useWorkspaceDocuments } from '@/lib/hooks/use-workspace-documents'
import { cn, getRouteColor, getRouteType } from '@/lib/utils'

import type { WorkspaceDocumentMetadata } from '@/types/thread.types'
import type {
WorkspaceDocumentMetadata,
WorkspaceDocumentType,
} from '@/types/thread.types'
import { uniq } from 'lodash'
import { useSession } from 'next-auth/react'
import { useTheme } from 'next-themes'
Expand Down Expand Up @@ -152,9 +155,8 @@ export function Header() {

const [isDocumentDialogOpen, setIsDocumentDialogOpen] = useState(false)
const [documentName, setDocumentName] = useState('')
const [alertDocumentType, setAlertDocumentType] = useState<
'text' | 'image' | 'spreadsheet'
>('text')
const [alertDocumentType, setAlertDocumentType] =
useState<WorkspaceDocumentType>('text')
const [mounted, setMounted] = useState(false)

const resetNavigation = (e: React.MouseEvent) => {
Expand Down
3 changes: 2 additions & 1 deletion apps/pro-web/components/routes/chat/chat-message-actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useWorkspace } from '@/lib/hooks/use-workspace'
import { useSonner } from '@/lib/hooks/useSonner'
import { createStructuredMarkdown } from '@/lib/markdown-utils'
import { cn } from '@/lib/utils'
import type { WorkspaceDocumentType } from '@/types/thread.types'
import type { Message as AiMessage } from 'ai'
import { FileCheck2Icon, FileInputIcon, FilePlus2Icon } from 'lucide-react'
import type { Message } from 'mb-genql'
Expand Down Expand Up @@ -115,7 +116,7 @@ export function ChatMessageActions({
addDocument(
activeProject,
newDocumentTitle,
docType as 'text' | 'image' | 'spreadsheet',
docType as WorkspaceDocumentType,
)

// Set document content
Expand Down
7 changes: 2 additions & 5 deletions apps/pro-web/components/routes/chat/chat-options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import type { MessagePair } from '@/lib/threads'
import { getCanonicalDomain, urlBuilders } from '@/lib/url'
import { cn } from '@/lib/utils'
import { deleteMessages, getThread } from '@/services/hasura'
import type { WorkspaceDocumentType } from '@/types/thread.types'
import { Eye, EyeOff, FileTextIcon, MoreVertical, Trash } from 'lucide-react'
import type { Thread } from 'mb-genql'
import { toSlug } from 'mb-lib'
Expand Down Expand Up @@ -122,11 +123,7 @@ export function ChatOptions({

// Add the document to workspace
const docType = activeDocumentType === 'all' ? 'text' : activeDocumentType
addDocument(
activeProject,
docTitle,
docType as 'text' | 'image' | 'spreadsheet',
)
addDocument(activeProject, docTitle, docType as WorkspaceDocumentType)

// Set document content
setDocumentContent(activeProject, docTitle, structuredContent)
Expand Down
39 changes: 21 additions & 18 deletions apps/pro-web/components/routes/pro/chat-panel-pro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,30 +199,31 @@ export function ChatPanelPro({
projectList,
documentList,
documentContent,
documentSections,
activeDocumentType,
toggleWorkspace,
setActiveDocument,
setDocumentContent,
setActiveDocumentType,
} = useWorkspace()

// Add debug logging to track ChatPanelPro re-renders
useEffect(() => {
console.log('🔍 ChatPanelPro re-render detected:', {
isWorkspaceActive,
activeProject,
activeDocument,
activeDocumentType,
hasDocumentContent: !!documentContent,
timestamp: Date.now(),
})
}, [
isWorkspaceActive,
activeProject,
activeDocument,
activeDocumentType,
documentContent,
])
// // Add debug logging to track ChatPanelPro re-renders
// useEffect(() => {
// console.log('🔍 ChatPanelPro re-render detected:', {
// isWorkspaceActive,
// activeProject,
// activeDocument,
// activeDocumentType,
// hasDocumentContent: !!documentContent,
// timestamp: Date.now(),
// })
// }, [
// isWorkspaceActive,
// activeProject,
// activeDocument,
// activeDocumentType,
// documentContent,
// ])

// Keep a local mirror for UI only, but source of truth is workspace
const documentType =
Expand Down Expand Up @@ -345,14 +346,16 @@ export function ChatPanelPro({
// Get current document content for meta prompt
const documentKey = `${activeProject}:${activeDocument}`
const currentContent = documentContent?.[documentKey] || ''
const currentSections =
documentSections?.[documentKey] ?? parseMarkdownSections(currentContent)
// Create meta prompt with document context
const metaPrompt = createWorkspaceMetaPrompt({
userPrompt: value,
taskType: 'edit',
projectName: activeProject as string,
documentName: activeDocument as string,
documentType,
sections: parseMarkdownSections(currentContent),
sections: currentSections,
activeSectionTitle: activeWorkspaceSection as string,
})

Expand Down
3 changes: 2 additions & 1 deletion apps/pro-web/components/routes/thread/thread-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { useWorkspace } from '@/lib/hooks/use-workspace'
import { useSonner } from '@/lib/hooks/useSonner'
import { getOpeningActiveThreadHelper } from '@/lib/threads'
import { getRouteType } from '@/lib/utils'
import type { WorkspaceDocumentType } from '@/types/thread.types'
import type { Thread } from 'mb-genql'
import { usePathname } from 'next/navigation'
import { useEffect, useState } from 'react'
Expand Down Expand Up @@ -61,7 +62,7 @@ export default function ThreadList({
type DocMeta = {
project: string
name: string
type: 'text' | 'image' | 'spreadsheet'
type: WorkspaceDocumentType
}
const filteredThreads = threads.filter((thread) => {
const sidebarFilter =
Expand Down
Loading