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
2 changes: 1 addition & 1 deletion apps/studio/components/grid/SupabaseGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { Shortcuts } from './components/common/Shortcuts'
import { Footer } from './components/footer/Footer'
import { Grid } from './components/grid/Grid'
import { Header, HeaderProps } from './components/header/Header'
import { RowContextMenu } from './components/menu'
import { RowContextMenu } from './components/menu/RowContextMenu'
import { GridProps } from './types'

import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Clipboard, Edit, Trash } from 'lucide-react'
import { Copy, Edit, Trash } from 'lucide-react'
import { useCallback } from 'react'
import { Item, ItemParams, Menu } from 'react-contexify'
import { toast } from 'sonner'
Expand All @@ -14,7 +14,7 @@ export type RowContextMenuProps = {
rows: SupaRow[]
}

const RowContextMenu = ({ rows }: RowContextMenuProps) => {
export const RowContextMenu = ({ rows }: RowContextMenuProps) => {
const tableEditorSnap = useTableEditorStateSnapshot()
const snap = useTableEditorTableStateSnapshot()

Expand Down Expand Up @@ -68,11 +68,11 @@ const RowContextMenu = ({ rows }: RowContextMenuProps) => {
return (
<Menu id={ROW_CONTEXT_MENU_ID} animation={false} className="!min-w-36">
<Item onClick={onCopyCellContent}>
<Clipboard size={12} />
<Copy size={12} />
<span className="ml-2 text-xs">Copy cell</span>
</Item>
<Item onClick={onCopyRowContent}>
<Clipboard size={12} />
<Copy size={12} />
<span className="ml-2 text-xs">Copy row</span>
</Item>
<DialogSectionSeparator className="my-1.5" />
Expand All @@ -88,4 +88,3 @@ const RowContextMenu = ({ rows }: RowContextMenuProps) => {
</Menu>
)
}
export default RowContextMenu
1 change: 0 additions & 1 deletion apps/studio/components/grid/components/menu/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { default as ColumnMenu } from './ColumnMenu'
export { default as RowContextMenu } from './RowContextMenu'
4 changes: 2 additions & 2 deletions apps/studio/components/interfaces/Auth/Users/Users.utils.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import dayjs from 'dayjs'
import { Clipboard, Trash, UserIcon } from 'lucide-react'
import { Copy, Trash, UserIcon } from 'lucide-react'
import { Column, useRowSelection } from 'react-data-grid'

import { User } from 'data/auth/users-infinite-query'
Expand Down Expand Up @@ -386,7 +386,7 @@ export const formatUserColumns = ({
copyToClipboard(value)
}}
>
<Clipboard size={12} />
<Copy size={12} />
<span>Copy {col.id === 'id' ? col.name : col.name.toLowerCase()}</span>
</ContextMenuItem_Shadcn_>
<ContextMenuSeparator_Shadcn_ />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { PostgresSchema } from '@supabase/postgres-meta'
import { toPng, toSvg } from 'html-to-image'
import { Check, Clipboard, Download, Loader2 } from 'lucide-react'
import { Check, Copy, Download, Loader2 } from 'lucide-react'
import { useTheme } from 'next-themes'
import { useEffect, useMemo, useState } from 'react'
import ReactFlow, { Background, BackgroundVariant, MiniMap, useReactFlow } from 'reactflow'
Expand Down Expand Up @@ -207,7 +207,7 @@ export const SchemaGraph = () => {
<div className="flex items-center gap-x-2">
<ButtonTooltip
type="outline"
icon={copied ? <Check /> : <Clipboard />}
icon={copied ? <Check /> : <Copy />}
onClick={() => {
if (tables) {
copyToClipboard(tablesToSQL(tables))
Expand Down
4 changes: 2 additions & 2 deletions apps/studio/components/interfaces/Functions/CommandRender.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Check, Clipboard } from 'lucide-react'
import { Check, Copy } from 'lucide-react'
import { forwardRef, useState } from 'react'

import { cn, copyToClipboard } from 'ui'
Expand Down Expand Up @@ -45,7 +45,7 @@ const Command = ({ item }: any) => {
{isCopied ? (
<Check size={14} strokeWidth={3} className="text-brand" />
) : (
<Clipboard size={14} />
<Copy size={14} />
)}
</button>
</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import dayjs from 'dayjs'
import { Check, Clipboard } from 'lucide-react'
import { Check, Copy } from 'lucide-react'
import { useRouter } from 'next/router'
import { useState } from 'react'

Expand Down Expand Up @@ -66,7 +66,7 @@ export const EdgeFunctionsListItem = ({ function: item }: EdgeFunctionsListItemP
) : (
<div className="relative">
<div className="block">
<Clipboard size={14} strokeWidth={1.5} />
<Copy size={14} strokeWidth={1.5} />
</div>
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { BarChart, Shield } from 'lucide-react'
import { useCallback, useMemo, useState } from 'react'

import { useParams } from 'common'
import LintDetail from 'components/interfaces/Linter/LintDetail'
import { LINTER_LEVELS } from 'components/interfaces/Linter/Linter.constants'
import {
createLintSummaryPrompt,
Expand All @@ -28,7 +29,6 @@ import {
} from 'ui'
import { Row } from 'ui-patterns'
import ShimmeringLoader from 'ui-patterns/ShimmeringLoader'
import LintDetail from 'components/interfaces/Linter/LintDetail'

export const AdvisorSection = () => {
const { ref: projectRef } = useParams()
Expand Down
137 changes: 68 additions & 69 deletions apps/studio/components/interfaces/HomeNew/CustomReportSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ export function CustomReportSection() {
reportContent
)

useEffect(() => {
if (reportContent) setEditableReport(reportContent)
}, [reportContent])
const { can: canCreateReport } = useAsyncCheckPermissions(
PermissionAction.CREATE,
'user_content',
{ resource: { type: 'report', owner_id: profile?.id }, subject: { id: profile?.id } }
)

const { can: canUpdateReport } = useAsyncCheckPermissions(
PermissionAction.UPDATE,
Expand All @@ -67,12 +69,6 @@ export function CustomReportSection() {
}
)

const { can: canCreateReport } = useAsyncCheckPermissions(
PermissionAction.CREATE,
'user_content',
{ resource: { type: 'report', owner_id: profile?.id }, subject: { id: profile?.id } }
)

const { mutate: upsertContent } = useContentUpsertMutation()

const persistReport = useCallback(
Expand Down Expand Up @@ -275,10 +271,14 @@ export function CustomReportSection() {

const layout = useMemo(() => editableReport?.layout ?? [], [editableReport])

useEffect(() => {
if (reportContent) setEditableReport(reportContent)
}, [reportContent])

return (
<div className="space-y-6">
<div className="flex items-center justify-between">
<h3 className="heading-section">At a glance</h3>
<h3 className="heading-section">Reports</h3>
{canUpdateReport || canCreateReport ? (
<SnippetDropdown
projectRef={ref}
Expand All @@ -295,66 +295,65 @@ export function CustomReportSection() {
) : null}
</div>
<div className="relative">
{(() => {
if (layout.length === 0) {
return (
<div className="flex min-h-[270px] items-center justify-center rounded border-2 border-dashed p-16 border-default">
{canUpdateReport || canCreateReport ? (
<SnippetDropdown
projectRef={ref}
onSelect={addSnippetToReport}
trigger={
<Button type="default" iconRight={<Plus size={14} />}>
Add your first chart
</Button>
}
side="bottom"
align="center"
autoFocus
/>
) : (
<p className="text-sm text-foreground-light">No charts set up yet in report</p>
)}
</div>
)
}
return (
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
{layout.length === 0 ? (
<div className="h-64 flex flex-col items-center justify-center rounded border-2 border-dashed p-16 border-default">
<h4>Build a custom report</h4>
<p className="text-sm text-foreground-light mb-4">
Keep track of your most important metrics
</p>
{canUpdateReport || canCreateReport ? (
<SnippetDropdown
projectRef={ref}
onSelect={addSnippetToReport}
trigger={
<Button type="default" iconRight={<Plus size={14} />}>
Add your first block
</Button>
}
side="bottom"
align="center"
autoFocus
/>
) : (
<p className="text-sm text-foreground-light">No charts set up yet in report</p>
)}
</div>
) : (
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
>
<SortableContext
items={(editableReport?.layout ?? []).map((x) => String(x.id))}
strategy={rectSortingStrategy}
>
<SortableContext
items={(editableReport?.layout ?? []).map((x) => String(x.id))}
strategy={rectSortingStrategy}
>
<Row columns={[3, 2, 1]}>
{layout.map((item) => (
<SortableReportBlock key={item.id} id={String(item.id)}>
<div className="h-64">
<ReportBlock
key={item.id}
item={item}
startDate={startDate}
endDate={endDate}
interval={
(editableReport?.interval as AnalyticsInterval) ??
('1d' as AnalyticsInterval)
}
disableUpdate={false}
isRefreshing={false}
onRemoveChart={handleRemoveChart}
onUpdateChart={(config) => handleUpdateChart(item.id, config)}
/>
</div>
</SortableReportBlock>
))}
</Row>
</SortableContext>
</DndContext>
)
})()}
<Row columns={[3, 2, 1]}>
{layout.map((item) => (
<SortableReportBlock key={item.id} id={String(item.id)}>
<div className="h-64">
<ReportBlock
key={item.id}
item={item}
startDate={startDate}
endDate={endDate}
interval={
(editableReport?.interval as AnalyticsInterval) ??
('1d' as AnalyticsInterval)
}
disableUpdate={false}
isRefreshing={false}
onRemoveChart={handleRemoveChart}
onUpdateChart={(config) => handleUpdateChart(item.id, config)}
/>
</div>
</SortableReportBlock>
))}
</Row>
</SortableContext>
</DndContext>
)}
</div>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import { Check, ChevronLeft, ChevronRight } from 'lucide-react'
import Image from 'next/image'
import Link from 'next/link'
import { useEffect, useState } from 'react'

import { cn, Button, Card, CardContent, Badge } from 'ui'
import { GettingStartedStep, GettingStartedAction } from './GettingStarted.types'
import { BASE_PATH } from 'lib/constants'
import { Badge, Button, Card, CardContent, cn } from 'ui'
import { GettingStartedAction, GettingStartedStep } from './GettingStartedSection'

// Determine action type for tracking
const getActionType = (action: GettingStartedAction): 'primary' | 'ai_assist' | 'external_link' => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ComponentProps, ReactNode } from 'react'

import { Button } from 'ui'

export type GettingStartedAction = {
label: string
href?: string
variant?: ComponentProps<typeof Button>['type']
icon?: ReactNode
component?: ReactNode
onClick?: () => void
}

export type GettingStartedStep = {
key: string
status: 'complete' | 'incomplete'
icon?: ReactNode
title: string
description: string
image?: string
actions: GettingStartedAction[]
}

export type GettingStartedState = 'empty' | 'code' | 'no-code' | 'hidden'
Loading
Loading