diff --git a/apps/docs/content/guides/platform/access-control.mdx b/apps/docs/content/guides/platform/access-control.mdx
index 7ca44c31e80..2483a8f1ddb 100644
--- a/apps/docs/content/guides/platform/access-control.mdx
+++ b/apps/docs/content/guides/platform/access-control.mdx
@@ -260,14 +260,6 @@ The table below shows the actions each role can take on the resources belonging
| | View | | | | |
| | List | | | | |
| | Run | | | | |
-| Events Collections | Create | | | | |
-| | Update | | | | |
-| | Delete | | | | |
-| | View | | | | |
-| | List | | | | |
-| Warehouse Access Tokens | Create | | | | |
-| | Revoke | | | | |
-| | List | | | | |
| **Branching** | | | | | |
| Production Branch | Read | | | | |
| | Write | | | | |
diff --git a/apps/studio/components/interfaces/DataWarehouse/CollectionForm.tsx b/apps/studio/components/interfaces/DataWarehouse/CollectionForm.tsx
deleted file mode 100644
index 5bb7e906d59..00000000000
--- a/apps/studio/components/interfaces/DataWarehouse/CollectionForm.tsx
+++ /dev/null
@@ -1,154 +0,0 @@
-import { zodResolver } from '@hookform/resolvers/zod'
-import { useForm } from 'react-hook-form'
-import { z } from 'zod'
-
-import {
- Button,
- FormControl_Shadcn_,
- FormField_Shadcn_,
- FormMessage_Shadcn_,
- Form_Shadcn_,
- Input_Shadcn_,
- Modal,
-} from 'ui'
-import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
-import { useCurrentOrgPlan } from 'hooks/misc/useCurrentOrgPlan'
-import { Admonition } from 'ui-patterns'
-import { useRouter } from 'next/router'
-import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
-
-export interface CollectionFormValues {
- name: string
- retention_days: number
-}
-
-interface CollectionFormProps {
- initialValues?: Partial
- onSubmit: (values: CollectionFormValues) => void
- isLoading?: boolean
- onCancelClick: () => void
-}
-
-export const CollectionForm = ({
- initialValues,
- onSubmit,
- isLoading,
- onCancelClick,
-}: CollectionFormProps) => {
- const { plan, isLoading: planLoading } = useCurrentOrgPlan()
- const router = useRouter()
- const currentOrg = useSelectedOrganization()
-
- function getMaxRetentionDays() {
- if (planLoading) return 1
- if (plan?.id === 'free') return 3
- else return 90
- }
- const maxRetentionDays = getMaxRetentionDays()
-
- const FormSchema = z.object({
- name: z.string().min(1),
- retention_days: z.coerce.number().min(1).max(maxRetentionDays).multipleOf(1).positive().int(),
- })
-
- const form = useForm({
- resolver: zodResolver(FormSchema),
- defaultValues: {
- name: initialValues?.name || '',
- retention_days: initialValues?.retention_days || maxRetentionDays,
- },
- })
-
- const handleSubmit = form.handleSubmit(onSubmit)
-
- const formatDays = (days: number) => {
- return days === 1 ? `1 day` : `${days} days`
- }
-
- const retentionDescription = (days: number) => {
- if (!Boolean(days) || days < 1)
- return <>Your plan allows for a maximum of {formatDays(maxRetentionDays)}.>
- return (
- <>
- Your logs will be removed after {formatDays(days)}.
- Your plan allows for a maximum of {formatDays(maxRetentionDays)}.
- >
- )
- }
-
- return (
-
-
-
- )
-}
diff --git a/apps/studio/components/interfaces/DataWarehouse/CreateWarehouseCollection.tsx b/apps/studio/components/interfaces/DataWarehouse/CreateWarehouseCollection.tsx
deleted file mode 100644
index 4b2126065e4..00000000000
--- a/apps/studio/components/interfaces/DataWarehouse/CreateWarehouseCollection.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { useRouter } from 'next/router'
-import { toast } from 'sonner'
-
-import { useParams } from 'common'
-import { useCreateCollection } from 'data/analytics/warehouse-collections-create-mutation'
-import { Modal } from 'ui'
-import { CollectionForm } from './CollectionForm'
-
-export const CreateWarehouseCollectionModal = ({
- open,
- onOpenChange,
-}: {
- open: boolean
- onOpenChange: (open: boolean) => void
-}) => {
- const router = useRouter()
- const { ref } = useParams()
-
- const { mutate: createCollection, isLoading } = useCreateCollection({
- onSuccess: (data) => {
- onOpenChange(false)
- toast.success('Collection created successfully')
- router.push(`/project/${ref}/logs/collections/${data.token}`)
- },
- onError: (error) => {
- toast.error(error.message)
- },
- })
-
- return (
- onOpenChange(false)}
- header="Create collection"
- visible={open}
- hideFooter
- >
- onOpenChange(false)}
- isLoading={isLoading}
- onSubmit={(vals) => {
- if (!ref) {
- return
- }
- createCollection({
- projectRef: ref,
- name: vals.name,
- retention_days: vals.retention_days,
- })
- }}
- />
-
- )
-}
diff --git a/apps/studio/components/interfaces/DataWarehouse/TestCollectionDialog.tsx b/apps/studio/components/interfaces/DataWarehouse/TestCollectionDialog.tsx
deleted file mode 100644
index 489a9e29860..00000000000
--- a/apps/studio/components/interfaces/DataWarehouse/TestCollectionDialog.tsx
+++ /dev/null
@@ -1,186 +0,0 @@
-import { Select, SelectContent, SelectItem, SelectTrigger } from '@ui/components/shadcn/ui/select'
-import CopyButton from 'components/ui/CopyButton'
-import type { WarehouseAccessTokensData } from 'data/analytics/warehouse-access-tokens-query'
-import type { WarehouseCollectionsData } from 'data/analytics/warehouse-collections-query'
-import { useRouter } from 'next/router'
-import { useEffect, useState } from 'react'
-import {
- Button,
- Checkbox_Shadcn_,
- CodeBlock,
- Input_Shadcn_,
- Label_Shadcn_,
- Separator,
- Sheet,
- SheetContent,
- SheetDescription,
- SheetFooter,
- SheetHeader,
- SheetSection,
- SheetTitle,
- SheetTrigger,
- Tooltip,
- TooltipContent,
- TooltipTrigger,
-} from 'ui'
-import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
-
-export function TestCollectionDialog({
- accessTokens,
- collectionToken,
- collections,
- open,
- onOpenChange,
- onSubmit,
-}: {
- accessTokens: WarehouseAccessTokensData['data']
- collections: WarehouseCollectionsData
- collectionToken: string
- projectRef: string
- open: boolean
- onOpenChange: (open: boolean) => void
- onSubmit: () => void
-}) {
- const router = useRouter()
- const BASE_WAREHOUSE_URL = `https://api.warehouse.tech/api/events`
- const [testAccessToken, setTestAccessToken] = useState('')
- const [selectedCollection, setSelectedCollection] = useState(collectionToken || '')
- const [showAccessToken, setShowAccessToken] = useState(false)
-
- useEffect(() => {
- setSelectedCollection(collectionToken)
- }, [collectionToken])
-
- useEffect(() => {
- if (accessTokens.length > 0) {
- setTestAccessToken(accessTokens[0].token)
- }
- }, [accessTokens])
-
- const selectedAccessToken = accessTokens.find((token) => token.token === testAccessToken)
- const selectedCollectionName = collections?.find((col) => col.token === selectedCollection)?.name
-
- function getcURL(accessToken: string) {
- return `curl -X "POST" "${BASE_WAREHOUSE_URL}?source=${selectedCollection}" \\
- -H 'Content-Type: application/json' \\
- -H 'Authorization: Bearer ${accessToken}' \\
- -d $'{
- "event_message": "Test event message",
- "metadata": {
- "ip_address": "100.100.100.100",
- "request_method": "POST",
- "custom_user_data": {
- "foo": "bar"
- },
- "datacenter": "aws",
- "request_headers": {
- "connection": "close",
- "user_agent": "chrome"
- }
- }
- }'
-`
- }
-
- return (
-
-
-
-
-
- Connect
-
-
-
- {accessTokens.length === 0 && (
- Create an access token to connect to your collection
- )}
-
-
-
-
- Send events to this collection
-
- Use the following cURL command to send events to this collection
-
-
-
-
-
-
-
- {selectedCollectionName || 'Collection'}
-
-
- {collections?.map((col) => (
-
- {col.name}
-
- ))}
-
-
-
-
-
-
-
- {selectedAccessToken?.description || 'Access token'}
-
-
-
- {accessTokens?.map((token: any) => (
-
- {token.description || 'No description'}
-
- ))}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- setShowAccessToken(!showAccessToken)}
- />
- Show access token
-
-
-
-
-
-
- {getcURL(showAccessToken ? testAccessToken : '********************')}
-
-
-
-
-
-
- Once you send an event, refresh the page to see it in the collection.
-
-
- Refresh results
-
-
-
-
- )
-}
diff --git a/apps/studio/components/interfaces/DataWarehouse/WarehouseCollectionDetail.tsx b/apps/studio/components/interfaces/DataWarehouse/WarehouseCollectionDetail.tsx
deleted file mode 100644
index f0be4402a71..00000000000
--- a/apps/studio/components/interfaces/DataWarehouse/WarehouseCollectionDetail.tsx
+++ /dev/null
@@ -1,323 +0,0 @@
-import { useKeyboardShortcuts } from 'components/grid/components/common/Hooks'
-import ProductEmptyState from 'components/to-be-cleaned/ProductEmptyState'
-import AlertError from 'components/ui/AlertError'
-import LoadingOpacity from 'components/ui/LoadingOpacity'
-import ShimmerLine from 'components/ui/ShimmerLine'
-import { useWarehouseAccessTokensQuery } from 'data/analytics/warehouse-access-tokens-query'
-import { useWarehouseLogDetailQuery } from 'data/analytics/warehouse-collection-log-detail-query'
-import { useWarehouseCollectionsQuery } from 'data/analytics/warehouse-collections-query'
-import { useWarehouseQueryQuery } from 'data/analytics/warehouse-query'
-import dayjs from 'dayjs'
-import { useSelectedLog } from 'hooks/analytics/useSelectedLog'
-import { useFlag } from 'hooks/ui/useFlag'
-import { RefreshCcw, Rewind, Terminal } from 'lucide-react'
-import Link from 'next/link'
-import { useRouter } from 'next/router'
-import { useEffect, useState } from 'react'
-import { Button, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
-import { LogsDatePicker } from '../Settings/Logs/Logs.DatePickers'
-import { DatetimeHelper } from '../Settings/Logs/Logs.types'
-import LogTable from '../Settings/Logs/LogTable'
-import { TestCollectionDialog } from './TestCollectionDialog'
-
-const INTERVALS: DatetimeHelper[] = [
- {
- text: 'Last hour',
- calcFrom: () => dayjs().subtract(1, 'hour').toISOString(),
- calcTo: () => dayjs().toISOString(),
- default: true,
- },
- {
- text: 'Last 12 hours',
- calcFrom: () => dayjs().subtract(12, 'hour').toISOString(),
- calcTo: () => dayjs().toISOString(),
- },
- {
- text: 'Last day',
- calcFrom: () => dayjs().subtract(1, 'day').toISOString(),
- calcTo: () => dayjs().toISOString(),
- },
- {
- text: 'Last 7 days',
- calcFrom: () => dayjs().subtract(7, 'day').toISOString(),
- calcTo: () => dayjs().toISOString(),
- },
-]
-
-export const WarehouseCollectionDetail = () => {
- const router = useRouter()
- const collectionToken = router.query.collectionToken as string
- const projectRef = router.query.ref as string
- const accessTokens = useWarehouseAccessTokensQuery({ projectRef })
- const [testDialogOpen, setTestDialogOpen] = useState(false)
- const hasWarehouse = useFlag('warehouse')
-
- const { data: collections, isLoading: collectionsLoading } = useWarehouseCollectionsQuery(
- { projectRef },
- { enabled: hasWarehouse }
- )
- const collection = collections?.find((c) => c.token === collectionToken)
- const [search, setSearch] = useState('')
- const [filters, setFilters] = useState({
- limit: 100,
- offset: 0,
- search: '',
- interval: {
- to: INTERVALS[0].calcTo,
- from: INTERVALS[0].calcFrom,
- },
- })
- const [sql, setSQL] = useState('')
-
- useEffect(() => {
- if (collection) {
- const from = filters.interval.from()
- const to = filters.interval.to()
-
- const sql = `select id, timestamp from \`${collection.name}\`
-where timestamp >= TIMESTAMP('${from}')
-and timestamp <= TIMESTAMP('${to}')
-order by timestamp desc limit ${filters.limit} offset ${filters.offset}
- `
-
- setSQL(sql)
- }
- }, [filters.interval, filters.limit, filters.offset, collection])
-
- const {
- isLoading: queryLoading,
- data: queryData,
- isError,
- isRefetching,
- } = useWarehouseQueryQuery(
- { ref: projectRef, sql },
- {
- enabled: !!sql && hasWarehouse,
- }
- )
-
- const formatResults = (results: any) => {
- if (!results || !results.length) {
- return []
- }
-
- const r = results.map(({ timestamp, ...r }: any) => {
- return {
- timestamp: new Date(timestamp / 1000).toLocaleString(),
- ...r,
- }
- })
-
- return r
- }
-
- const results = formatResults(queryData?.result)
-
- function loadMore() {
- setFilters({ ...filters, offset: filters.offset + filters.limit })
- }
-
- const isLoading = queryLoading || collectionsLoading || isRefetching
-
- function refreshResults(e?: React.FormEvent) {
- e?.preventDefault()
- setFilters({
- ...filters,
- search,
- interval: {
- to: () => dayjs().toISOString(),
- from: () => filters.interval.from() || dayjs().subtract(1, 'hour').toISOString(),
- },
- })
- }
-
- const queryUrl = `/project/${projectRef}/logs/explorer?q=${encodeURIComponent(
- sql || ''
- )}&source=warehouse`
-
- useKeyboardShortcuts(
- {
- r: () => {
- document.getElementById('refresh-button')?.focus()
- },
- s: () => {
- document.getElementById('search-input')?.focus()
- },
- },
- ['INPUT', 'BUTTON', 'TEXTAREA']
- )
-
- function KeyboardShortcut({ children }: { children: React.ReactNode }) {
- return (
-
- {children}
-
- )
- }
-
- // Selected Log Detail
- const [selectedLogId, setSelectedLogId] = useSelectedLog()
- const {
- data: selectedLogDetail,
- isLoading: selectedLogDetailLoading,
- error: selectedLogDetailError,
- } = useWarehouseLogDetailQuery({
- ref: projectRef,
- collectionName: collection?.name,
- logId: selectedLogId ?? undefined,
- })
-
- return (
-
-
-
-
-
-
-
-
-
- }>
-
-
-
-
- Open query in Collections Explorer
-
-
-
- {
- refreshResults()
- setTestDialogOpen(false)
- }}
- />
-
-
-
- {isError && (
-
- )}
-
- {!isError && (
-
setSelectedLogId(log?.id ?? null)}
- selectedLog={selectedLogDetail?.result[0] ?? undefined}
- selectedLogError={selectedLogDetailError ?? undefined}
- isSelectedLogLoading={!!selectedLogId && selectedLogDetailLoading}
- data={results}
- showHeader={false}
- EmptyState={
-
-
-
Try adjusting your filters, send a test event or refresh the results.
-
- {
- setTestDialogOpen(true)
- }}
- >
- Send test event
-
- refreshResults()}>
- Refresh
-
-
-
-
- }
- />
- )}
-
-
-
- {!isError && (
-
-
- {results.length > 0 && (
- }
- type="default"
- loading={isLoading}
- disabled={isLoading}
- >
- Load more
-
- )}
- {filters.offset !== 0 && (
- <>
- setFilters({ ...filters, offset: 0 })}
- type="default"
- loading={isLoading}
- disabled={isLoading}
- >
- Load latest
-
- >
- )}
-
-
- )}
-
- )
-}
diff --git a/apps/studio/components/interfaces/DataWarehouse/WarehouseMenuItem.tsx b/apps/studio/components/interfaces/DataWarehouse/WarehouseMenuItem.tsx
deleted file mode 100644
index 9b2c656e254..00000000000
--- a/apps/studio/components/interfaces/DataWarehouse/WarehouseMenuItem.tsx
+++ /dev/null
@@ -1,154 +0,0 @@
-import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { Database, EditIcon, TrashIcon } from 'lucide-react'
-import { useRouter } from 'next/router'
-import { useState } from 'react'
-import { toast } from 'sonner'
-
-import { useParams } from 'common'
-import { useDeleteCollectionMutation } from 'data/analytics/warehouse-collections-delete-mutation'
-import { useUpdateCollection } from 'data/analytics/warehouse-collections-update-mutation'
-import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
-import {
- DropdownMenuItem,
- DropdownMenuSeparator,
- Modal,
- Tooltip,
- TooltipContent,
- TooltipTrigger,
-} from 'ui'
-
-import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
-import { LogsSidebarItem } from '../Settings/Logs/SidebarV2/SidebarItem'
-import { CollectionForm } from './CollectionForm'
-
-type Props = {
- item: {
- id: number
- token: string
- name: string
- retention_days: number
- }
-}
-
-export const WarehouseMenuItem = ({ item }: Props) => {
- const router = useRouter()
- const { ref, collectionToken } = useParams()
- const projectRef = ref || 'default'
-
- const [showUpdateDialog, setShowUpdateDialog] = useState(false)
- const [showDeleteDialog, setDeleteDialog] = useState(false)
-
- const canUpdateCollection = useCheckPermissions(PermissionAction.ANALYTICS_WRITE, 'logflare')
-
- const updateCollection = useUpdateCollection({
- onSuccess: () => {
- toast.success('Collection updated successfully')
- setShowUpdateDialog(false)
- },
- })
- const deleteCollection = useDeleteCollectionMutation({
- onSuccess: () => {
- // If the current collection is deleted, redirect to default logs view
- if (item.token === collectionToken) {
- router.push(`/project/${projectRef}/logs/explorer`)
- }
- setDeleteDialog(false)
- toast.success('Collection deleted successfully')
- },
- })
-
- const isLoading = updateCollection.isLoading || deleteCollection.isLoading
-
- return (
- <>
- }
- href={`/project/${projectRef}/logs/collections/${item.token}`}
- dropdownItems={
- <>
-
-
- {
- e.preventDefault()
- setShowUpdateDialog(true)
- }}
- >
-
- Update collection
-
-
- {!canUpdateCollection && (
-
- You need additional permissions to update collections
-
- )}
-
-
-
-
- {
- e.preventDefault()
- setDeleteDialog(true)
- }}
- >
-
- Delete collection
-
-
- {!canUpdateCollection && (
-
- You need additional permissions to delete collections
-
- )}
-
- >
- }
- >
-
- setShowUpdateDialog(false)}
- hideFooter
- header={`Update collection "${item.name}"`}
- >
- setShowUpdateDialog(false)}
- isLoading={isLoading}
- initialValues={{ name: item.name, retention_days: item.retention_days }}
- onSubmit={({ name, retention_days }) => {
- updateCollection.mutate({
- projectRef,
- collectionToken: item.token,
- name,
- retention_days,
- })
- }}
- />
-
- setDeleteDialog(false)}
- confirmLabel="Delete collection"
- title={`Delete collection "${item.name}"`}
- size="small"
- onConfirm={() => {
- deleteCollection.mutate({ projectRef, collectionToken: item.token })
- }}
- >
-
- All data in this collection will be deleted.
-
-
This action cannot be undone.
-
-
- >
- )
-}
diff --git a/apps/studio/components/interfaces/Settings/Logs/LogSelection.tsx b/apps/studio/components/interfaces/Settings/Logs/LogSelection.tsx
index ffa1e699e22..0f42bf05878 100644
--- a/apps/studio/components/interfaces/Settings/Logs/LogSelection.tsx
+++ b/apps/studio/components/interfaces/Settings/Logs/LogSelection.tsx
@@ -22,7 +22,6 @@ export interface LogSelectionProps {
onClose: () => void
queryType?: QueryType
projectRef: string
- collectionName?: string
isLoading: boolean
error?: string | object
}
@@ -41,8 +40,6 @@ const LogSelection = ({ log, onClose, queryType, isLoading, error }: LogSelectio
if (!log) return
switch (queryType) {
- // case 'warehouse':
- // return
case 'api':
const status = log?.metadata?.[0]?.response?.[0]?.status_code
const method = log?.metadata?.[0]?.request?.[0]?.method
diff --git a/apps/studio/components/interfaces/Settings/Logs/LogSelectionRenderers/WarehouseSelectionRenderer.tsx b/apps/studio/components/interfaces/Settings/Logs/LogSelectionRenderers/WarehouseSelectionRenderer.tsx
deleted file mode 100644
index 43047d1882e..00000000000
--- a/apps/studio/components/interfaces/Settings/Logs/LogSelectionRenderers/WarehouseSelectionRenderer.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import { cn } from 'ui'
-import { LOGS_TAILWIND_CLASSES } from '../Logs.constants'
-import { jsonSyntaxHighlight, SelectionDetailedRow } from '../LogsFormatters'
-
-const DetailedJsonRow = ({
- label,
- value,
- code,
-}: {
- label: string
- value: Object
- code?: boolean
-}) => {
- return (
-
- )
-}
-
-export const WarehouseSelectionRenderer = ({ log }: any) => {
- return (
-
- {Object.entries(log).map(([key, value], index) => {
- return (
-
- {value && typeof value === 'object' ? (
-
- ) : (
-
- )}
-
- )
- })}
-
- )
-}
diff --git a/apps/studio/components/interfaces/Settings/Logs/LogTable.tsx b/apps/studio/components/interfaces/Settings/Logs/LogTable.tsx
index 7e043920a4b..bb5e4015af7 100644
--- a/apps/studio/components/interfaces/Settings/Logs/LogTable.tsx
+++ b/apps/studio/components/interfaces/Settings/Logs/LogTable.tsx
@@ -49,8 +49,6 @@ interface Props {
onSave?: () => void
hasEditorValue?: boolean
className?: string
- collectionName?: string // Used for warehouse queries
- warehouseError?: string
EmptyState?: ReactNode
showHeader?: boolean
showHistogramToggle?: boolean
@@ -79,7 +77,6 @@ const LogTable = ({
onSave,
hasEditorValue,
className,
- collectionName,
EmptyState,
showHeader = true,
showHistogramToggle = true,
@@ -154,9 +151,6 @@ const LogTable = ({
columns
} else {
switch (queryType) {
- case 'warehouse':
- columns = DEFAULT_COLUMNS
- break
case 'api':
columns = DatabaseApiColumnRender
break
@@ -460,7 +454,6 @@ const LogTable = ({
log={selectedLog}
error={selectedLogError}
queryType={queryType}
- collectionName={collectionName}
/>
)}
diff --git a/apps/studio/components/interfaces/Settings/Logs/Logs.constants.ts b/apps/studio/components/interfaces/Settings/Logs/Logs.constants.ts
index c84fe325cc8..9044fd26bd9 100644
--- a/apps/studio/components/interfaces/Settings/Logs/Logs.constants.ts
+++ b/apps/studio/components/interfaces/Settings/Logs/Logs.constants.ts
@@ -369,7 +369,6 @@ export enum LogsTableName {
POSTGREST = 'postgrest_logs',
SUPAVISOR = 'supavisor_logs',
PGBOUNCER = 'pgbouncer_logs',
- WAREHOUSE = 'warehouse_logs',
PG_UPGRADE = 'pg_upgrade_logs',
PG_CRON = 'pg_cron_logs',
}
@@ -384,7 +383,6 @@ export const LOGS_TABLES = {
storage: LogsTableName.STORAGE,
postgrest: LogsTableName.POSTGREST,
supavisor: LogsTableName.SUPAVISOR,
- warehouse: LogsTableName.WAREHOUSE,
pg_upgrade: LogsTableName.PG_UPGRADE,
pg_cron: LogsTableName.POSTGRES,
pgbouncer: LogsTableName.PGBOUNCER,
@@ -401,7 +399,6 @@ export const LOGS_SOURCE_DESCRIPTION = {
[LogsTableName.POSTGREST]: 'RESTful API web server logs',
[LogsTableName.SUPAVISOR]: 'Shared connection pooler logs for PostgreSQL',
[LogsTableName.PGBOUNCER]: 'Dedicated connection pooler for PostgreSQL',
- [LogsTableName.WAREHOUSE]: 'Logs obtained from a data warehouse collection',
[LogsTableName.PG_UPGRADE]: 'Logs generated by the Postgres version upgrade process',
[LogsTableName.PG_CRON]: 'Postgres logs from pg_cron cron jobs',
}
diff --git a/apps/studio/components/interfaces/Settings/Logs/Logs.types.ts b/apps/studio/components/interfaces/Settings/Logs/Logs.types.ts
index d1f606a72ff..377f542ebb9 100644
--- a/apps/studio/components/interfaces/Settings/Logs/Logs.types.ts
+++ b/apps/studio/components/interfaces/Settings/Logs/Logs.types.ts
@@ -90,7 +90,6 @@ export type QueryType =
| 'storage'
| 'supavisor'
| 'postgrest'
- | 'warehouse'
| 'pg_upgrade'
| 'pg_cron'
| 'pgbouncer'
@@ -145,9 +144,3 @@ export interface DatetimeHelper {
disabled?: boolean
availableIn?: PlanId[]
}
-
-export interface WarehouseCollection {
- name: string
- id: number
- token: string
-}
diff --git a/apps/studio/components/interfaces/Settings/Logs/LogsQueryPanel.tsx b/apps/studio/components/interfaces/Settings/Logs/LogsQueryPanel.tsx
index 5ea8b4292a3..f67aef39e04 100644
--- a/apps/studio/components/interfaces/Settings/Logs/LogsQueryPanel.tsx
+++ b/apps/studio/components/interfaces/Settings/Logs/LogsQueryPanel.tsx
@@ -6,7 +6,6 @@ import { ReactNode, useState } from 'react'
import { IS_PLATFORM } from 'common'
import Table from 'components/to-be-cleaned/Table'
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
-import { useFlag } from 'hooks/ui/useFlag'
import { logConstants } from 'shared-data'
import {
Badge,
@@ -28,23 +27,16 @@ import {
LogsTableName,
} from './Logs.constants'
import { DatePickerValue, LogsDatePicker } from './Logs.DatePickers'
-import { LogsWarning, LogTemplate, WarehouseCollection } from './Logs.types'
-import { WarehouseQueryTemplate } from './Warehouse.utils'
+import { LogsWarning, LogTemplate } from './Logs.types'
-export type SourceType = 'logs' | 'warehouse'
export interface LogsQueryPanelProps {
templates?: LogTemplate[]
- warehouseTemplates?: WarehouseQueryTemplate[]
defaultFrom: string
defaultTo: string
warnings: LogsWarning[]
- warehouseCollections: WarehouseCollection[]
- dataSource: SourceType
onSelectTemplate: (template: LogTemplate) => void
- onSelectWarehouseTemplate: (template: WarehouseQueryTemplate) => void
onSelectSource: (source: string) => void
onDateChange: (value: DatePickerValue) => void
- onDataSourceChange: (sourceType: SourceType) => void
}
function DropdownMenuItemContent({ name, desc }: { name: ReactNode; desc?: string }) {
@@ -58,17 +50,12 @@ function DropdownMenuItemContent({ name, desc }: { name: ReactNode; desc?: strin
const LogsQueryPanel = ({
templates = [],
- warehouseTemplates = [],
defaultFrom,
defaultTo,
warnings,
- warehouseCollections,
- dataSource,
onSelectTemplate,
- onSelectWarehouseTemplate,
onSelectSource,
onDateChange,
- onDataSourceChange,
}: LogsQueryPanelProps) => {
const [showReference, setShowReference] = useState(false)
@@ -78,15 +65,12 @@ const LogsQueryPanel = ({
projectEdgeFunctionAll: edgeFunctionsEnabled,
} = useIsFeatureEnabled(['project_auth:all', 'project_storage:all', 'project_edge_function:all'])
- const warehouseEnabled = useFlag('warehouse')
-
const logsTableNames = Object.entries(LogsTableName)
.filter(([key]) => {
if (key === 'AUTH') return authEnabled
if (key === 'STORAGE') return storageEnabled
if (key === 'FN_EDGE') return edgeFunctionsEnabled
if (key === 'PG_CRON') return false
- if (key === 'WAREHOUSE') return false
return true
})
.map(([, value]) => value)
@@ -117,90 +101,31 @@ const LogsQueryPanel = ({
- {warehouseEnabled && (
-
-
- }>
- Data source{' '}
-
- {dataSource === 'warehouse' ? 'collections' : 'logs'}
-
-
-
-
- onDataSourceChange('logs')}>
-
-
- onDataSourceChange('warehouse')}>
-
- Collections NEW
-
- }
- desc="Query your collections"
- />
-
-
-
- )}
-
- {dataSource === 'warehouse' && (
-
-
- }>
- Templates
-
-
-
- {warehouseTemplates.map((template) => (
- onSelectWarehouseTemplate(template)}
- >
-
-
- ))}
- {warehouseCollections.length === 0 && (
-
+
+
+ }>
+ Insert source
+
+
+
+ {logsTableNames
+ .sort((a, b) => a.localeCompare(b))
+ .map((source) => (
+ onSelectSource(source)}>
- )}
-
-
- )}
+ ))}
+
+
- {dataSource === 'logs' && (
-
-
- }>
- Insert source
-
-
-
- {dataSource === 'logs' &&
- logsTableNames
- .sort((a, b) => a.localeCompare(b))
- .map((source) => (
- onSelectSource(source)}>
-
-
- ))}
-
-
- )}
-
- {dataSource === 'logs' && IS_PLATFORM && (
+ {IS_PLATFORM && (
}>
@@ -222,16 +147,14 @@ const LogsQueryPanel = ({
)}
- {dataSource === 'logs' && (
-
{
- setSelectedDatePickerValue(value)
- onDateChange(value)
- }}
- helpers={EXPLORER_DATEPICKER_HELPERS}
- />
- )}
+ {
+ setSelectedDatePickerValue(value)
+ onDateChange(value)
+ }}
+ helpers={EXPLORER_DATEPICKER_HELPERS}
+ />
- {dataSource === 'logs' && (
-
- Field Reference
- setShowReference(false)}
- icon={ }
- />
-
- }
- visible={showReference}
- cancelText="Close"
- onCancel={() => setShowReference(false)}
- hideFooter
- triggerElement={
+
+
+ Field Reference
setShowReference(true)}
- icon={ }
- className="px-2"
- >
- Field Reference
-
- }
- >
-
-
-
- The following table shows all the available paths that can be queried from each
- respective source. Do note that to access nested keys, you would need to perform
- the necessary{' '}
-
- unnesting joins
-
-
-
-
-
-
- setShowReference(false)}
+ icon={ }
+ />
+
+ }
+ visible={showReference}
+ cancelText="Close"
+ onCancel={() => setShowReference(false)}
+ hideFooter
+ triggerElement={
+ setShowReference(true)}
+ icon={ }
+ className="px-2"
>
- {logConstants.schemas.map((schema) => (
- Field Reference
+
+ }
+ >
+
+
+
+ The following table shows all the available paths that can be queried from each
+ respective source. Do note that to access nested keys, you would need to perform
+ the necessary{' '}
+
-
- Path
- ,
-
- Type
- ,
- ]}
- body={schema.fields
- .sort((a: any, b: any) => a.path - b.path)
- .map((field) => (
-
- ))}
+ unnesting joins
+
-
- ))}
-
-
- )}
+
+
+
+
+
+
+ {logConstants.schemas.map((schema) => (
+
+
+ Path
+ ,
+
+ Type
+ ,
+ ]}
+ body={schema.fields
+ .sort((a: any, b: any) => a.path - b.path)
+ .map((field) => (
+
+ ))}
+ />
+
+ ))}
+
+
diff --git a/apps/studio/components/interfaces/Settings/Logs/Warehouse.utils.ts b/apps/studio/components/interfaces/Settings/Logs/Warehouse.utils.ts
deleted file mode 100644
index fdb60183e09..00000000000
--- a/apps/studio/components/interfaces/Settings/Logs/Warehouse.utils.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-export type WarehouseQueryTemplate = {
- query: string
- name: string
- description: string
-}
-
-export function createWarehouseQueryTemplates(
- collections: { name: string }[]
-): WarehouseQueryTemplate[] {
- return collections.flatMap((collection) => [
- {
- query: `select count(*) as event_count from \`${collection.name}\`
-where timestamp > timestamp_sub(current_timestamp(), interval 1 day)`,
- name: `${collection.name} - Daily Event Count`,
- description: `Count events in the last 24 hours from ${collection.name} collection`,
- },
- {
- query: `select id, timestamp, event_message from \`${collection.name}\`
- where timestamp > timestamp_sub(current_timestamp(), interval 1 day)
- and event_message like '%YOUR_TEXT_HERE%'
- order by timestamp desc limit 10`,
- name: `${collection.name} - Filter by text`,
- description: `Select last 10 events from ${collection.name} collection`,
- },
- ])
-}
diff --git a/apps/studio/components/interfaces/Sidebar.tsx b/apps/studio/components/interfaces/Sidebar.tsx
index e729bc0b732..44bfc0797c0 100644
--- a/apps/studio/components/interfaces/Sidebar.tsx
+++ b/apps/studio/components/interfaces/Sidebar.tsx
@@ -223,8 +223,6 @@ const ProjectLinks = () => {
const isNewAPIDocsEnabled = useIsAPIDocsSidePanelEnabled()
const { securityLints, errorLints } = useLints()
- const showWarehouse = useFlag('warehouse')
-
const activeRoute = router.pathname.split('/')[3]
const {
@@ -310,14 +308,11 @@ const ProjectLinks = () => {
)
} else if (route.key === 'logs') {
- // TODO: Undo this when warehouse flag is removed
- const label = showWarehouse ? 'Logs & Analytics' : route.label
- const newRoute = { ...route, label }
return (
)
} else {
diff --git a/apps/studio/components/layouts/LogsLayout/LogsSidebarMenuV2.tsx b/apps/studio/components/layouts/LogsLayout/LogsSidebarMenuV2.tsx
index 86f999ecd7f..785bb992b68 100644
--- a/apps/studio/components/layouts/LogsLayout/LogsSidebarMenuV2.tsx
+++ b/apps/studio/components/layouts/LogsLayout/LogsSidebarMenuV2.tsx
@@ -9,13 +9,9 @@ import {
useFeaturePreviewModal,
useUnifiedLogsPreview,
} from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
-import { CreateWarehouseCollectionModal } from 'components/interfaces/DataWarehouse/CreateWarehouseCollection'
-import { WarehouseMenuItem } from 'components/interfaces/DataWarehouse/WarehouseMenuItem'
import SavedQueriesItem from 'components/interfaces/Settings/Logs/Logs.SavedQueriesItem'
import { LogsSidebarItem } from 'components/interfaces/Settings/Logs/SidebarV2/SidebarItem'
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
-import { useWarehouseCollectionsQuery } from 'data/analytics/warehouse-collections-query'
-import { useWarehouseTenantQuery } from 'data/analytics/warehouse-tenant-query'
import { useContentQuery } from 'data/content/content-query'
import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { useCurrentOrgPlan } from 'hooks/misc/useCurrentOrgPlan'
@@ -27,14 +23,7 @@ import {
Collapsible_Shadcn_,
CollapsibleContent_Shadcn_,
CollapsibleTrigger_Shadcn_,
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuTrigger,
Separator,
- Tooltip,
- TooltipContent,
- TooltipTrigger,
} from 'ui'
import {
InnerSideBarEmptyPanel,
@@ -90,16 +79,11 @@ export function LogsSidebarMenuV2() {
const router = useRouter()
const { ref } = useParams() as { ref: string }
- const warehouseEnabled = useFlag('warehouse')
const unifiedLogsFlagEnabled = useFlag('unifiedLogs')
const { selectFeaturePreview } = useFeaturePreviewModal()
const { enable: enableUnifiedLogs } = useUnifiedLogsPreview()
const [searchText, setSearchText] = useState('')
- const [createCollectionOpen, setCreateCollectionOpen] = useState(false)
- const canCreateCollection = useCheckPermissions(PermissionAction.ANALYTICS_WRITE, 'logflare')
-
- const { data: tenantData } = useWarehouseTenantQuery({ projectRef: ref })
const {
projectAuthAll: authEnabled,
@@ -107,11 +91,6 @@ export function LogsSidebarMenuV2() {
realtimeAll: realtimeEnabled,
} = useIsFeatureEnabled(['project_storage:all', 'project_auth:all', 'realtime:all'])
- const { data: whCollections, isLoading: whCollectionsLoading } = useWarehouseCollectionsQuery(
- { projectRef: ref },
- { enabled: IS_PLATFORM && warehouseEnabled && !!tenantData }
- )
-
const { plan: orgPlan, isLoading: isOrgPlanLoading } = useCurrentOrgPlan()
const isFreePlan = !isOrgPlanLoading && orgPlan?.id === 'free'
@@ -223,9 +202,6 @@ export function LogsSidebarMenuV2() {
const filteredOperationalLogs = OPERATIONAL_COLLECTIONS.filter((collection) => {
return collection?.name.toLowerCase().includes(searchText.toLowerCase())
})
- const filteredWarehouse = whCollections?.filter((collection) => {
- return collection.name.toLowerCase().includes(searchText.toLowerCase())
- })
return (
@@ -285,56 +261,11 @@ export function LogsSidebarMenuV2() {
>
- {warehouseEnabled ? (
-
-
- }
- className="w-[26px]"
- />
-
-
-
-
-
- Create query
-
-
-
-
-
-
- setCreateCollectionOpen(true)}
- className="w-full flex items-center text-xs px-2 py-1"
- disabled={!canCreateCollection}
- >
-
- Create collection
-
-
-
- {!canCreateCollection && (
-
- You need additional permissions to create a collection
-
- )}
-
-
-
- ) : (
-
}
- className="w-[26px]"
- onClick={() => router.push(`/project/${ref}/logs/explorer`)}
- />
- )}
-
-
}
+ className="w-[26px]"
+ onClick={() => router.push(`/project/${ref}/logs/explorer`)}
/>
@@ -361,17 +292,6 @@ export function LogsSidebarMenuV2() {
/>
)
})}
- {whCollectionsLoading && warehouseEnabled ? (
-
-
-
- ) : filteredWarehouse?.length ? (
-
- {filteredWarehouse.map((collection) => (
-
- ))}
-
- ) : null}
{OPERATIONAL_COLLECTIONS.length > 0 && (
<>
diff --git a/apps/studio/data/analytics/keys.ts b/apps/studio/data/analytics/keys.ts
index 5f1e97e656d..fa77be8e2c4 100644
--- a/apps/studio/data/analytics/keys.ts
+++ b/apps/studio/data/analytics/keys.ts
@@ -1,19 +1,4 @@
export const analyticsKeys = {
- // warehouse
- warehouseQuery: (projectRef: string, query: string) =>
- ['projects', projectRef, 'warehouse', 'query', query] as const,
- warehouseTenant: (projectRef: string) => ['projects', projectRef, 'warehouse', 'tenant'] as const,
- warehouseCollections: (projectRef: string) =>
- ['projects', projectRef, 'warehouse', 'collections'] as const,
- warehouseCollectionsCreate: (projectRef: string) =>
- ['projects', projectRef, 'warehouse', 'collections', 'create'] as const,
- warehouseEndpoints: (projectRef: string) =>
- ['projects', projectRef, 'warehouse', 'endpoints'] as const,
- warehouseBackends: (projectRef: string) =>
- ['projects', projectRef, 'warehouse', 'backends'] as const,
- warehouseAccessTokens: (projectRef: string) =>
- ['projects', projectRef, 'warehouse', 'access-tokens'] as const,
-
// logs/reports endpoints
functionsInvStats: (
projectRef: string | undefined,
diff --git a/apps/studio/data/analytics/warehouse-access-tokens-query.ts b/apps/studio/data/analytics/warehouse-access-tokens-query.ts
deleted file mode 100644
index bfa30ccb304..00000000000
--- a/apps/studio/data/analytics/warehouse-access-tokens-query.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { useQuery, UseQueryOptions } from '@tanstack/react-query'
-import { analyticsKeys } from './keys'
-import { get, handleError } from 'data/fetchers'
-import { ResponseError } from 'types'
-
-export type WarehouseAccessTokensVariables = {
- projectRef: string
-}
-
-export async function getWarehouseAccessTokens(
- { projectRef }: WarehouseAccessTokensVariables,
- signal?: AbortSignal
-) {
- if (!projectRef) {
- throw new Error('projectRef is required')
- }
-
- // TODO: Remove typecast when codegen types are fixed
- const response = await get(`/platform/projects/{ref}/analytics/warehouse/access-tokens`, {
- params: { path: { ref: projectRef } },
- signal,
- })
-
- if (response.error) {
- handleError(response)
- }
-
- return response
-}
-
-export type WarehouseAccessTokensData = Awaited
>
-export type WarehouseAccessTokensError = ResponseError
-/**
- * This will be deprecated or rewritten in favor of the new project API keys
- */
-export const useWarehouseAccessTokensQuery = (
- { projectRef }: WarehouseAccessTokensVariables,
- {
- enabled = true,
- ...options
- }: UseQueryOptions = {}
-) =>
- useQuery(
- analyticsKeys.warehouseAccessTokens(projectRef),
- ({ signal }) => getWarehouseAccessTokens({ projectRef }, signal),
- {
- enabled: enabled && typeof projectRef !== 'undefined',
- ...options,
- }
- )
diff --git a/apps/studio/data/analytics/warehouse-collection-log-detail-query.ts b/apps/studio/data/analytics/warehouse-collection-log-detail-query.ts
deleted file mode 100644
index 4d8beefd712..00000000000
--- a/apps/studio/data/analytics/warehouse-collection-log-detail-query.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { useWarehouseQueryQuery } from './warehouse-query'
-
-export function useWarehouseLogDetailQuery({
- ref,
- collectionName,
- logId,
- columns = ['id', 'timestamp'],
-}: {
- ref: string
- collectionName?: string
- logId?: string
- columns?: string[]
-}) {
- const enabled = !!logId && !!collectionName
- const sql = `select ${columns.join(',')} from \`${collectionName}\`
- where id = '${logId}' and timestamp > '2024-01-01' limit 1`
-
- return useWarehouseQueryQuery({ ref, sql }, { enabled })
-}
diff --git a/apps/studio/data/analytics/warehouse-collections-create-mutation.ts b/apps/studio/data/analytics/warehouse-collections-create-mutation.ts
deleted file mode 100644
index f1ec421ae3d..00000000000
--- a/apps/studio/data/analytics/warehouse-collections-create-mutation.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
-import { handleError, post } from 'data/fetchers'
-import { toast } from 'sonner'
-import type { ResponseError } from 'types'
-import { analyticsKeys } from './keys'
-
-export type CreateCollectionArgs = {
- projectRef: string
- name: string
- retention_days: number
-}
-
-export async function createCollection({ projectRef, name, retention_days }: CreateCollectionArgs) {
- const { data, error } = await post('/platform/projects/{ref}/analytics/warehouse/collections', {
- params: { path: { ref: projectRef } },
- body: { name, retention_days },
- } as any)
-
- if (error) handleError(error)
- return data
-}
-
-type CreateCollectionData = Awaited>
-
-export const useCreateCollection = ({
- onSuccess,
- onError,
- ...options
-}: Omit<
- UseMutationOptions,
- 'mutationFn'
-> = {}) => {
- const queryClient = useQueryClient()
-
- return useMutation(
- (vars) => {
- // temporal fix
- // prevent users from creating collections with the same name
- // this will be handled by the backend
- // - jordi
-
- const existingCollectionNames = queryClient
- .getQueryData(analyticsKeys.warehouseCollections(vars.projectRef))
- ?.map((c) => c.name)
-
- if (existingCollectionNames?.includes(vars.name)) {
- throw new Error(`Collection with the name ${vars.name} already exists`)
- }
-
- return createCollection(vars)
- },
- {
- async onSuccess(data, variables, context) {
- const { projectRef } = variables
-
- await queryClient.invalidateQueries(analyticsKeys.warehouseCollections(projectRef))
-
- await onSuccess?.(data, variables, context)
- },
- async onError(data, variables, context) {
- if (onError === undefined) {
- toast.error(`Failed to create collection: ${data.message}`)
- } else {
- onError(data, variables, context)
- }
- },
- ...options,
- }
- )
-}
diff --git a/apps/studio/data/analytics/warehouse-collections-delete-mutation.ts b/apps/studio/data/analytics/warehouse-collections-delete-mutation.ts
deleted file mode 100644
index 376e5f378f3..00000000000
--- a/apps/studio/data/analytics/warehouse-collections-delete-mutation.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
-import { toast } from 'sonner'
-
-import { del, handleError } from 'data/fetchers'
-import type { ResponseError } from 'types'
-import { analyticsKeys } from './keys'
-
-export type DeleteCollectionVariables = {
- projectRef: string
- collectionToken: string
-}
-
-export async function deleteCollection({ projectRef, collectionToken }: DeleteCollectionVariables) {
- const { data, error } = await del(
- '/platform/projects/{ref}/analytics/warehouse/collections/{token}',
- {
- params: { path: { ref: projectRef, token: collectionToken } } as any,
- }
- )
-
- if (error) handleError(error)
- return data
-}
-
-type DeleteCollectionData = Awaited>
-
-export const useDeleteCollectionMutation = ({
- onSuccess,
- onError,
- ...options
-}: Omit<
- UseMutationOptions,
- 'mutationFn'
-> = {}) => {
- const queryClient = useQueryClient()
-
- return useMutation(
- (vars) => deleteCollection(vars),
- {
- async onSuccess(data, variables, context) {
- const { projectRef } = variables
-
- await queryClient.invalidateQueries(analyticsKeys.warehouseCollections(projectRef))
-
- await onSuccess?.(data, variables, context)
- },
- async onError(data, variables, context) {
- if (onError === undefined) {
- toast.error(`Failed to delete collection: ${data.message}`)
- } else {
- onError(data, variables, context)
- }
- },
- ...options,
- }
- )
-}
diff --git a/apps/studio/data/analytics/warehouse-collections-query.ts b/apps/studio/data/analytics/warehouse-collections-query.ts
deleted file mode 100644
index 4fde686a646..00000000000
--- a/apps/studio/data/analytics/warehouse-collections-query.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { useQuery } from '@tanstack/react-query'
-import { get, handleError } from 'data/fetchers'
-import { IS_PLATFORM } from 'lib/constants'
-import { analyticsKeys } from './keys'
-
-type WarehouseCollectionsVariables = {
- projectRef: string
-}
-
-export async function getWarehouseCollections(
- { projectRef }: WarehouseCollectionsVariables,
- signal?: AbortSignal
-) {
- if (!projectRef) {
- throw new Error('projectRef is required')
- }
-
- // TODO: Remove type cast when codegen types are fixed
- const { data, error } = await get(`/platform/projects/{ref}/analytics/warehouse/collections`, {
- params: { path: { ref: projectRef } },
- signal,
- })
-
- if (error) handleError(error)
-
- return data
-}
-
-export type WarehouseCollectionsData = Awaited>
-
-export const useWarehouseCollectionsQuery = (
- { projectRef }: WarehouseCollectionsVariables,
- { enabled }: { enabled: boolean } = { enabled: true }
-) =>
- useQuery(
- analyticsKeys.warehouseCollections(projectRef),
- ({ signal }) => getWarehouseCollections({ projectRef }, signal),
- {
- enabled: enabled && !!projectRef && IS_PLATFORM,
- }
- )
diff --git a/apps/studio/data/analytics/warehouse-collections-update-mutation.ts b/apps/studio/data/analytics/warehouse-collections-update-mutation.ts
deleted file mode 100644
index 6f96ef05575..00000000000
--- a/apps/studio/data/analytics/warehouse-collections-update-mutation.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
-import { toast } from 'sonner'
-
-import { handleError, patch } from 'data/fetchers'
-import type { ResponseError } from 'types'
-import { analyticsKeys } from './keys'
-
-export type UpdateCollectionArgs = {
- projectRef: string
- collectionToken: string
-}
-
-export type UpdateCollectionPayload = {
- name?: string
- // description?: string
- retention_days?: number
-}
-
-export async function updateCollection(
- { projectRef, collectionToken }: UpdateCollectionArgs,
- payload: UpdateCollectionPayload
-) {
- const { data, error } = await patch(
- '/platform/projects/{ref}/analytics/warehouse/collections/{token}',
- {
- params: { path: { ref: projectRef, token: collectionToken } },
- body: payload,
- } as any
- )
-
- if (error) handleError(error)
- return data
-}
-
-type UpdateCollectionData = Awaited>
-
-export const useUpdateCollection = ({
- onSuccess,
- onError,
- ...options
-}: Omit<
- UseMutationOptions,
- 'mutationFn'
-> = {}) => {
- const queryClient = useQueryClient()
-
- return useMutation<
- UpdateCollectionData,
- ResponseError,
- UpdateCollectionPayload & UpdateCollectionArgs
- >(
- (payload) =>
- updateCollection(
- { projectRef: payload.projectRef, collectionToken: payload.collectionToken },
- { name: payload.name, retention_days: payload.retention_days }
- ),
- {
- async onSuccess(data, variables, context) {
- const { projectRef } = variables
-
- await queryClient.invalidateQueries(analyticsKeys.warehouseCollections(projectRef))
-
- await onSuccess?.(data, variables, context)
- },
- async onError(data, variables, context) {
- if (onError === undefined) {
- toast.error(`Failed to update collection: ${data.message}`)
- } else {
- onError(data, variables, context)
- }
- },
- ...options,
- }
- )
-}
diff --git a/apps/studio/data/analytics/warehouse-query.ts b/apps/studio/data/analytics/warehouse-query.ts
deleted file mode 100644
index 54c34a18414..00000000000
--- a/apps/studio/data/analytics/warehouse-query.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { useQuery, UseQueryOptions } from '@tanstack/react-query'
-import { get, handleError } from 'data/fetchers'
-import { analyticsKeys } from './keys'
-import { ResponseError } from 'types'
-
-export type WarehouseQueryVariables = {
- ref: string
- sql: string
-}
-
-export async function getWarehouseQuery(
- { ref, sql }: WarehouseQueryVariables,
- signal?: AbortSignal
-) {
- if (!sql) {
- throw new Error('SQL must be provided')
- }
-
- const { data, error } = await get(`/platform/projects/{ref}/analytics/warehouse/query`, {
- params: { path: { ref: ref }, query: { bq_sql: sql } },
- signal,
- } as any)
-
- if (error) {
- handleError(error)
- }
-
- // TODO!: Remove type assertion when we have a proper type for the response
- return data as { result: any[] }
-}
-
-export type WarehouseQueryData = Awaited>
-export type WarehouseQueryError = ResponseError
-
-export const useWarehouseQueryQuery = (
- { ref, sql }: WarehouseQueryVariables,
- { enabled, ...options }: UseQueryOptions = {}
-) =>
- useQuery(
- analyticsKeys.warehouseQuery(ref, sql),
- ({ signal }) => getWarehouseQuery({ ref, sql }, signal),
- {
- enabled,
- staleTime: Infinity,
- cacheTime: 15 * 60 * 1000, // 15 mins cache time
- refetchOnMount: false,
- refetchInterval: false,
- ...options,
- }
- )
diff --git a/apps/studio/data/analytics/warehouse-tenant-query.ts b/apps/studio/data/analytics/warehouse-tenant-query.ts
deleted file mode 100644
index 624a6719641..00000000000
--- a/apps/studio/data/analytics/warehouse-tenant-query.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { useQuery, UseQueryOptions } from '@tanstack/react-query'
-import { get, handleError } from 'data/fetchers'
-import { IS_PLATFORM } from 'lib/constants'
-import { ResponseError } from 'types'
-import { analyticsKeys } from './keys'
-
-export type WarehouseTenantVariables = {
- projectRef: string
-}
-
-export type WarehouseTenantResponse = any
-
-export async function getWarehouseTenant(
- { projectRef }: WarehouseTenantVariables,
- signal?: AbortSignal
-) {
- if (!projectRef) {
- throw new Error('projectRef is required')
- }
- const { data, error } = await get(`/platform/projects/{ref}/analytics/warehouse/tenant`, {
- params: { path: { ref: projectRef } },
- signal,
- })
- if (error) {
- handleError(error)
- }
-
- return data
-}
-
-export type WarehouseTenantData = Awaited>
-export type WarehouseTenantError = ResponseError
-
-export const useWarehouseTenantQuery = (
- { projectRef }: WarehouseTenantVariables,
- {
- enabled = true,
- ...options
- }: UseQueryOptions = {}
-) =>
- useQuery(
- analyticsKeys.warehouseTenant(projectRef),
- ({ signal }) => getWarehouseTenant({ projectRef }, signal),
- {
- enabled: enabled && !!projectRef && IS_PLATFORM,
- staleTime: Infinity,
- // 2H mins cache time
- cacheTime: 120 * 60 * 1000,
- refetchOnMount: false,
- refetchInterval: false,
- ...options,
- }
- )
diff --git a/apps/studio/hooks/analytics/useSelectedLog.ts b/apps/studio/hooks/analytics/useSelectedLog.ts
index 5b52ce62d38..f156222e89b 100644
--- a/apps/studio/hooks/analytics/useSelectedLog.ts
+++ b/apps/studio/hooks/analytics/useSelectedLog.ts
@@ -1,6 +1,5 @@
import { useQueryState } from 'nuqs'
-// Used in logs and warehouse.
export function useSelectedLog() {
return useQueryState('log')
}
diff --git a/apps/studio/hooks/analytics/useSingleLog.tsx b/apps/studio/hooks/analytics/useSingleLog.tsx
index 6ca288c2122..b773b45e673 100644
--- a/apps/studio/hooks/analytics/useSingleLog.tsx
+++ b/apps/studio/hooks/analytics/useSingleLog.tsx
@@ -33,9 +33,7 @@ function useSingleLog({
const params: LogsEndpointParams = { ...paramsToMerge, sql }
- const isWarehouseQuery = queryType === 'warehouse'
- // Warehouse queries are handled differently
- const enabled = Boolean(id && table && !isWarehouseQuery)
+ const enabled = Boolean(id && table)
const {
data,
diff --git a/apps/studio/pages/project/[ref]/logs/collections/[collectionToken].tsx b/apps/studio/pages/project/[ref]/logs/collections/[collectionToken].tsx
deleted file mode 100644
index f10f5f2a3da..00000000000
--- a/apps/studio/pages/project/[ref]/logs/collections/[collectionToken].tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { WarehouseCollectionDetail } from 'components/interfaces/DataWarehouse/WarehouseCollectionDetail'
-import DefaultLayout from 'components/layouts/DefaultLayout'
-import LogsLayout from 'components/layouts/LogsLayout/LogsLayout'
-import { NextPageWithLayout } from 'types'
-
-const PageLayout: NextPageWithLayout = () =>
-
-PageLayout.getLayout = (page) => (
-
- {page}
-
-)
-
-export default PageLayout
diff --git a/apps/studio/pages/project/[ref]/logs/explorer/index.tsx b/apps/studio/pages/project/[ref]/logs/explorer/index.tsx
index 85dca740843..32a15ef2413 100644
--- a/apps/studio/pages/project/[ref]/logs/explorer/index.tsx
+++ b/apps/studio/pages/project/[ref]/logs/explorer/index.tsx
@@ -22,17 +22,14 @@ import {
maybeShowUpgradePrompt,
useEditorHints,
} from 'components/interfaces/Settings/Logs/Logs.utils'
-import LogsQueryPanel, { SourceType } from 'components/interfaces/Settings/Logs/LogsQueryPanel'
+import LogsQueryPanel from 'components/interfaces/Settings/Logs/LogsQueryPanel'
import LogTable from 'components/interfaces/Settings/Logs/LogTable'
import UpgradePrompt from 'components/interfaces/Settings/Logs/UpgradePrompt'
-import { createWarehouseQueryTemplates } from 'components/interfaces/Settings/Logs/Warehouse.utils'
import DefaultLayout from 'components/layouts/DefaultLayout'
import LogsLayout from 'components/layouts/LogsLayout/LogsLayout'
import CodeEditor from 'components/ui/CodeEditor/CodeEditor'
import LoadingOpacity from 'components/ui/LoadingOpacity'
import ShimmerLine from 'components/ui/ShimmerLine'
-import { useWarehouseCollectionsQuery } from 'data/analytics/warehouse-collections-query'
-import { useWarehouseQueryQuery } from 'data/analytics/warehouse-query'
import { useContentQuery } from 'data/content/content-query'
import {
UpsertContentPayload,
@@ -55,8 +52,6 @@ import {
ResizablePanelGroup,
} from 'ui'
-const PLACEHOLDER_WAREHOUSE_QUERY =
- '-- Fetch the last 10 logs in the last 7 days \nselect id, timestamp, event_message from `COLLECTION_NAME` \nwhere timestamp > timestamp_sub(current_timestamp(), interval 7 day) \norder by timestamp desc limit 10'
const LOCAL_PLACEHOLDER_QUERY =
'select\n timestamp, event_message, metadata\n from edge_logs limit 5'
@@ -79,13 +74,8 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
const { timestampStart, timestampEnd, setTimeRange } = useLogsUrlState()
const [editorValue, setEditorValue] = useState(PLACEHOLDER_QUERY)
- const [warehouseEditorId, setWarehouseEditorId] = useState(uuidv4())
- const [warehouseEditorValue, setWarehouseEditorValue] = useState(
- PLACEHOLDER_WAREHOUSE_QUERY
- )
const [saveModalOpen, setSaveModalOpen] = useState(false)
const [warnings, setWarnings] = useState([])
- const [sourceType, setSourceType] = useState((routerSource as SourceType) || 'logs')
const [selectedLog, setSelectedLog] = useState(null)
const [recentLogs, setRecentLogs] = useLocalStorage(
@@ -98,7 +88,6 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
type: 'log_sql',
})
const query = content?.content.find((x) => x.id === queryId)
-
const {
params,
logData,
@@ -112,24 +101,11 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
iso_timestamp_start: timestampStart,
iso_timestamp_end: timestampEnd,
},
- sourceType === 'logs'
+ true
)
- const {
- refetch: runWarehouseQuery,
- data: warehouseResults,
- isFetching: warehouseFetching,
- error: warehouseError,
- } = useWarehouseQueryQuery(
- { ref: projectRef, sql: warehouseEditorValue },
- {
- enabled: false,
- }
- )
- const results = sourceType === 'warehouse' ? warehouseResults?.result : logData
- const isLoading = logsLoading || warehouseFetching
-
- const { data: warehouseCollections } = useWarehouseCollectionsQuery({ projectRef })
+ const results = logData
+ const isLoading = logsLoading
const { mutate: upsertContent, isLoading: isUpsertingContent } = useContentUpsertMutation({
onError: (e) => {
@@ -187,40 +163,6 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
const handleRun = (value?: string | React.MouseEvent) => {
const query = typeof value === 'string' ? value || editorValue : editorValue
- if (sourceType === 'warehouse') {
- const whQuery = warehouseEditorValue
-
- if (!warehouseCollections?.length) {
- toast.error('You do not have any collections yet.')
- return
- }
-
- // Check that a collection name is included in the query
- const collectionNames = warehouseCollections?.map((collection) => collection.name)
- const collectionExists = collectionNames?.find((collectionName) =>
- whQuery.includes(collectionName)
- )
-
- if (!collectionExists) {
- toast.error('Please specify a collection name in the query')
- return
- }
-
- // Check that the user is not trying to query logs tables and warehouse collections at the same time
- const logsSources = Object.values(LOGS_TABLES)
- const logsSourceExists = logsSources.find((source) => whQuery.includes(source))
-
- if (logsSourceExists) {
- return toast.error('Cannot query logs tables from current query.')
- }
-
- runWarehouseQuery()
- return router.push({
- pathname: router.pathname,
- query: { ...router.query, q: query },
- })
- }
-
changeQuery(query)
runQuery()
router.push({
@@ -231,30 +173,25 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
}
const handleInsertSource = (source: string) => {
- if (sourceType === 'warehouse') {
- //TODO: Only one collection can be queried at a time, we need to replace the current collection from the query for the new one
- return setWarehouseEditorId(uuidv4())
- } else {
- if (editorRef.current && monaco) {
- const editorModel = editorRef.current?.getModel()
- const currentValue = editorRef.current.getValue()
- const index = currentValue.indexOf('from')
+ if (editorRef.current && monaco) {
+ const editorModel = editorRef.current?.getModel()
+ const currentValue = editorRef.current.getValue()
+ const index = currentValue.indexOf('from')
- const updatedValue =
- index < 0
- ? `${currentValue}${source}`
- : `${currentValue.substring(0, index + 4)} ${source} ${currentValue.substring(index + 5)}`
+ const updatedValue =
+ index < 0
+ ? `${currentValue}${source}`
+ : `${currentValue.substring(0, index + 4)} ${source} ${currentValue.substring(index + 5)}`
- editorRef.current.pushUndoStop()
- editorRef.current.executeEdits(`insert-identifier`, [
- {
- text: updatedValue,
- range: editorModel?.getFullModelRange() ?? new monaco.Range(1, 1, 1, 1),
- },
- ])
- editorRef.current.pushUndoStop()
- editorRef.current.focus()
- }
+ editorRef.current.pushUndoStop()
+ editorRef.current.executeEdits(`insert-identifier`, [
+ {
+ text: updatedValue,
+ range: editorModel?.getFullModelRange() ?? new monaco.Range(1, 1, 1, 1),
+ },
+ ])
+ editorRef.current.pushUndoStop()
+ editorRef.current.focus()
}
}
@@ -316,14 +253,8 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
}
useEffect(() => {
- if (warehouseError) toast.error(warehouseError.message)
- }, [warehouseError])
-
- useEffect(() => {
- // on mount, set initial values
if (q) {
setEditorValue(q)
- setWarehouseEditorValue(q)
}
}, [q])
@@ -368,43 +299,18 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
onDateChange={handleDateChange}
onSelectSource={handleInsertSource}
templates={TEMPLATES.filter((template) => template.mode === 'custom')}
- warehouseCollections={warehouseCollections || []}
onSelectTemplate={onSelectTemplate}
- warehouseTemplates={createWarehouseQueryTemplates(warehouseCollections || [])}
- onSelectWarehouseTemplate={(template) => {
- setWarehouseEditorValue(template.query)
- setWarehouseEditorId(uuidv4())
- }}
warnings={warnings}
- dataSource={sourceType}
- onDataSourceChange={(srcType) => {
- setSourceType(srcType)
- router.push({
- pathname: router.pathname,
- query: { ...router.query, source: srcType },
- })
- }}
/>
-
- {sourceType === 'warehouse' ? (
- setWarehouseEditorValue(v || '')}
- actions={{ runQuery: { enabled: true, callback: handleRun } }}
- />
- ) : (
- setEditorValue(v || '')}
- actions={{ runQuery: { enabled: true, callback: handleRun } }}
- />
- )}
+ setEditorValue(v || '')}
+ actions={{ runQuery: { enabled: true, callback: handleRun } }}
+ />
diff --git a/apps/studio/tests/features/logs/LogsQueryPanel.test.tsx b/apps/studio/tests/features/logs/LogsQueryPanel.test.tsx
index df741c9a2e6..7e860a924e9 100644
--- a/apps/studio/tests/features/logs/LogsQueryPanel.test.tsx
+++ b/apps/studio/tests/features/logs/LogsQueryPanel.test.tsx
@@ -13,12 +13,7 @@ test('run and clear', async () => {
onSelectSource={() => {}}
onSelectTemplate={() => {}}
warnings={[]}
- warehouseCollections={[]}
- dataSource="logs"
- onDataSourceChange={() => {}}
templates={[]}
- warehouseTemplates={[]}
- onSelectWarehouseTemplate={() => {}}
/>
)
await expect(screen.findByPlaceholderText(/Search/)).rejects.toThrow()