chore: xmas cleanup (#19938)

This commit is contained in:
Kevin Grüneberg authored and GitHub committed 2024-01-04 17:27:49 +01:00
1 parent 29bc6f78ec
commit d12332ea5a
168 files changed
+132 -3009

No files matched your search

@@ -177,7 +177,7 @@ export function parseSupaTable(
}
}
export function onLoadStorage(storageRef: string, tableName: string, schema?: string | null) {
function onLoadStorage(storageRef: string, tableName: string, schema?: string | null) {
const storageKey = getStorageKey(STORAGE_KEY_PREFIX, storageRef)
const jsonStr = localStorage.getItem(storageKey)
if (!jsonStr) return
@@ -5,7 +5,7 @@ import { IconMaximize, Popover } from 'ui'
import { BlockKeys, MonacoEditor, NullValue } from 'components/grid/components/common'
import { useTrackedState } from 'components/grid/store'
import { tryParseJson } from 'lib/helpers'
import { prettifyJSON, tryParseJson } from 'lib/helpers'
import { isNil } from 'lodash'
interface JsonEditorProps<TRow, TSummaryRow = unknown>
@@ -147,29 +147,7 @@ export const JsonEditor = <TRow, TSummaryRow = unknown>({
)
}
export const prettifyJSON = (value: string) => {
if (value.length > 0) {
try {
return JSON.stringify(JSON.parse(value), undefined, 2)
} catch (err) {
// dont need to throw error, just return text value
// Users have to fix format if they want to save
return value
}
} else {
return value
}
}
export const minifyJSON = (value: string) => {
try {
return JSON.stringify(JSON.parse(value))
} catch (err) {
throw err
}
}
export const verifyJSON = (value: string) => {
const verifyJSON = (value: string) => {
try {
JSON.parse(value)
return true
@@ -1,6 +1,5 @@
import { useEffect, useState } from 'react'
import AwesomeDebouncePromise from 'awesome-debounce-promise'
import { formatFilterURLParams } from 'components/grid/SupabaseGrid.utils'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import ConfirmationModal from 'components/ui/ConfirmationModal'
@@ -1,7 +1,7 @@
import * as Tooltip from '@radix-ui/react-tooltip'
import { getForeignKeyCascadeAction } from 'components/interfaces/TableGridEditor/SidePanelEditor/ColumnEditor/ColumnEditor.utils'
import { FOREIGN_KEY_CASCADE_ACTION } from 'data/database/database-query-constants'
import { XYCoord } from 'dnd-core'
import type { XYCoord } from 'dnd-core'
import * as React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { IconArrowRight, IconKey, IconLink, IconLock } from 'ui'
@@ -1,6 +1,6 @@
import { XYCoord } from 'dnd-core'
import type { XYCoord } from 'dnd-core'
import { memo, useRef } from 'react'
import { DropTargetMonitor, useDrag, useDrop } from 'react-dnd'
import { useDrag, useDrop } from 'react-dnd'
import { Button, IconMenu, IconX, Toggle } from 'ui'
import { DragItem, Sort, SupaTable } from 'components/grid/types'
+1 -1
View File
@@ -15,7 +15,7 @@ export const ADD_COLUMN_KEY = 'supabase-grid-add-column'
export const ERROR_PRIMARY_KEY_NOTFOUND =
'Please add a primary key column to your table to update or delete rows'
export const RLS_ACKNOWLEDGED_KEY = 'supabase-acknowledge-rls-warning'
const RLS_ACKNOWLEDGED_KEY = 'supabase-acknowledge-rls-warning'
export const rlsAcknowledgedKey = (tableID?: string | number) =>
`${RLS_ACKNOWLEDGED_KEY}-${String(tableID)}`
@@ -1,11 +0,0 @@
import * as React from 'react'
export function useFocusRef<T extends HTMLOrSVGElement>(isCellSelected: boolean) {
const ref = React.useRef<T>(null)
React.useLayoutEffect(() => {
if (!isCellSelected) return
ref.current?.focus({ preventScroll: true })
}, [isCellSelected])
return ref
}
@@ -1,4 +1,3 @@
export * from './common'
export * from './column'
export * from './hooks'
export * from './types'
@@ -14,8 +14,6 @@ const FeaturePreviewContext = createContext<FeaturePreviewContextType>({
onUpdateFlag: noop,
})
export default FeaturePreviewContext
export const useFeaturePreviewContext = () => useContext(FeaturePreviewContext)
export const FeaturePreviewContextProvider = ({ children }: PropsWithChildren<{}>) => {
@@ -53,10 +51,6 @@ export const FeaturePreviewContextProvider = ({ children }: PropsWithChildren<{}
}
// Helpers
export const useIsNavigationPreviewEnabled = () => {
const { flags } = useFeaturePreviewContext()
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_NAVIGATION_LAYOUT]
}
export const useIsAPIDocsSidePanelEnabled = () => {
const { flags } = useFeaturePreviewContext()
@@ -14,7 +14,6 @@ import {
IconEyeOff,
Input,
InputNumber,
Radio,
Toggle,
} from 'ui'
import { boolean, number, object, string } from 'yup'
@@ -58,9 +58,7 @@ export const createSQLPolicy = (
return {}
}
export const createSQLStatementForCreatePolicy = (
policyFormFields: PolicyFormField
): PolicyForReview => {
const createSQLStatementForCreatePolicy = (policyFormFields: PolicyFormField): PolicyForReview => {
const { name, definition, check, command, schema, table } = policyFormFields
const roles = policyFormFields.roles.length === 0 ? ['public'] : policyFormFields.roles
const description = `Add policy for the ${command} operation under the policy "${name}"`
@@ -7,7 +7,7 @@ interface InvoiceStatusBadgeProps {
status: InvoiceStatus
}
export const invoiceStatusMapping: Record<InvoiceStatus, { label: string; badgeColor: string }> = {
const invoiceStatusMapping: Record<InvoiceStatus, { label: string; badgeColor: string }> = {
[InvoiceStatus.DRAFT]: {
label: 'Upcoming',
badgeColor: 'yellow',
@@ -40,14 +40,6 @@ export const formatTimeToTimeString = (time: Time) => {
)}:${formatNumberToTwoDigits(time.s)}`
}
export const getTimezoneOffsetText = (timezone: Timezone) => {
return timezone.text.split(')')[0].slice(1)
}
export const getTimezoneOffset = (timezone: Timezone) => {
return timezone.text.split(')')[0].slice(4)
}
export function constrainDateToRange(current: dayjs.Dayjs, lower: dayjs.Dayjs, upper: dayjs.Dayjs) {
if (current.isBefore(lower)) {
return lower
@@ -15,7 +15,6 @@ import {
IconAlertTriangle,
IconChevronLeft,
IconChevronRight,
IconExternalLink,
IconHelpCircle,
Modal,
} from 'ui'
@@ -1,20 +1,5 @@
import { BASE_PATH, IS_PLATFORM } from 'lib/constants'
export const ENABLED_MODE_OPTIONS = [
{ label: 'Origin', value: 'ORIGIN', description: 'This is the default behaviour' },
{
label: 'Replica',
value: 'REPLICA',
description: 'Will only fire if the session is in “replica” mode',
},
{
label: 'Always',
value: 'ALWAYS',
description: 'Will fire regardless of the current replication role',
},
{ label: 'Disabled', value: 'DISABLED', description: 'Will not fire' },
]
export const HOOK_EVENTS = [
{
label: 'Insert',
@@ -50,33 +50,6 @@ const PublicationsTables = ({ selectedPublication, onSelectBack }: PublicationsT
}
)
// const publication = selectedPublication
// const enabledForAllTables = publication.tables == null
// const toggleReplicationForAllTables = async (publication: any, disable: boolean) => {
// const toggle = disable ? 'disable' : 'enable'
// ConfirmAlert({
// title: 'Confirm',
// type: 'warn',
// message: `Are you sure you want to ${toggle} replication for all tables in ${publication.name}?`,
// onAsyncConfirm: async () => {
// try {
// const res: any = await meta.publications.recreate(publication.id)
// if (res.error) {
// throw res.error
// } else {
// onPublicationUpdated(res)
// }
// } catch (error: any) {
// ui.setNotification({
// category: 'error',
// message: `Failed to toggle replication for all tables: ${error.message}`,
// })
// }
// },
// })
// }
return (
<>
<div className="mb-4">
@@ -1,4 +1,3 @@
import { PostgresFunction } from '@supabase/postgres-meta'
import { has, isEmpty, mapValues, union, without } from 'lodash'
import { makeAutoObservable } from 'mobx'
import { observer, useLocalObservable } from 'mobx-react-lite'
@@ -1,7 +1,7 @@
import ColumnType from 'components/interfaces/TableGridEditor/SidePanelEditor/ColumnEditor/ColumnType'
import useLatest from 'hooks/misc/useLatest'
import { useEffect, useReducer } from 'react'
import { Button, IconX, IconXCircle, Input } from 'ui'
import { Button, IconX, Input } from 'ui'
export type SimpleColumn = {
id: number
@@ -219,13 +219,6 @@ export const WRAPPERS: WrapperMeta[] = [
required: true,
type: 'text',
},
// {
// name: 'rowid_column',
// label: 'Row ID Column',
// defaultValue: 'id',
// editable: true,
// required: true,
// },
],
},
{
@@ -367,13 +360,6 @@ export const WRAPPERS: WrapperMeta[] = [
required: true,
type: 'text',
},
// {
// name: 'rowid_column',
// label: 'Row ID Column',
// defaultValue: 'id',
// editable: true,
// required: true,
// },
],
},
{
@@ -413,13 +399,6 @@ export const WRAPPERS: WrapperMeta[] = [
required: true,
type: 'text',
},
// {
// name: 'rowid_column',
// label: 'Row ID Column',
// defaultValue: 'id',
// editable: true,
// required: true,
// },
],
},
],
@@ -450,15 +429,6 @@ export const WRAPPERS: WrapperMeta[] = [
isTextArea: true,
urlHelper: 'https://firebase.google.com/docs/admin/setup#initialize-sdk',
},
// NOTE(alaister): this is a valid option, but it may confuse the basic use case
// so I'm omitting it for now. We can add back once we make it's use clearer.
// {
// name: 'access_token',
// label: 'OAuth2 token to access Firebase',
// required: false,
// encrypted: false,
// hidden: false,
// },
],
},
tables: [
@@ -1,4 +1,4 @@
import { WRAPPERS, WRAPPER_HANDLERS } from './Wrappers.constants'
import { WRAPPER_HANDLERS } from './Wrappers.constants'
import { WrapperMeta } from './Wrappers.types'
export const makeValidateRequired = (options: { name: string; required: boolean }[]) => {
@@ -32,7 +32,6 @@ const RpcContent = ({
const rpcParams = Object.entries(rpcParamsObject)
.map(([k, v]: any) => ({ name: k, ...v }))
.filter((x) => !!x.name)
const paramList = rpcParams.map((x) => x.type).join(', ')
return (
<>
@@ -71,7 +71,7 @@ interface GraphiQLInterfaceProps {
theme: 'dark' | 'light'
}
export const GraphiQLInterface = ({ theme }: GraphiQLInterfaceProps) => {
const GraphiQLInterface = ({ theme }: GraphiQLInterfaceProps) => {
const editorContext = useEditorContext({ nonNull: true })
const executionContext = useExecutionContext({ nonNull: true })
const schemaContext = useSchemaContext({ nonNull: true })
@@ -1,4 +1,3 @@
import { useParams } from 'common'
import { observer } from 'mobx-react-lite'
import { IconAlertCircle } from 'ui'
@@ -35,8 +35,7 @@ const ServiceStatus = () => {
// [Joshen] Need pooler service check eventually
const { data: status, isLoading } = useProjectServiceStatusQuery({ projectRef: ref })
const { data: edgeFunctionsStatus, isLoading: isLoadingEdgeFunctions } =
useEdgeFunctionServiceStatusQuery({ projectRef: ref })
const { data: edgeFunctionsStatus } = useEdgeFunctionServiceStatusQuery({ projectRef: ref })
const { isLoading: isLoadingPostgres, isSuccess: isSuccessPostgres } =
usePostgresServiceStatusQuery({
projectRef: ref,
@@ -68,7 +68,7 @@ const Avatar = ({ src }: { src: string | undefined }) => {
}
const IntegrationInstallation = React.forwardRef<HTMLLIElement, IntegrationInstallationProps>(
({ title, integration, disabled, ...props }, ref) => {
({ integration, disabled, ...props }, ref) => {
const IntegrationIconBlock = () => {
return (
<div className="bg-black text-white w-8 h-8 rounded flex items-center justify-center">
@@ -206,7 +206,7 @@ const IntegrationConnection = React.forwardRef<HTMLLIElement, IntegrationConnect
)
const IntegrationConnectionOption = React.forwardRef<HTMLLIElement, IntegrationConnectionProps>(
({ className, connection, type, ...props }, ref) => {
({ connection, type, ...props }, ref) => {
const { data: projects } = useProjectsQuery()
const project = projects?.find((project) => project.ref === connection.supabase_project_ref)
@@ -246,7 +246,7 @@ const EmptyIntegrationConnection = React.forwardRef<
orgSlug?: string
onClick: () => void
}
>(({ className, showNode = true, orgSlug = '_', onClick, ...props }, ref) => {
>(({ className, showNode = true, onClick, ...props }, ref) => {
return (
<div
ref={ref}
@@ -285,7 +285,7 @@ interface IntegrationConnectionHeader extends React.HTMLAttributes<HTMLDivElemen
}
const IntegrationConnectionHeader = React.forwardRef<HTMLDivElement, IntegrationConnectionHeader>(
({ className, name, markdown = '', showNode = true, ...props }, ref) => {
({ className, markdown = '', showNode = true, ...props }, ref) => {
return (
<div
{...props}
@@ -1,4 +1,4 @@
export const ENV_VAR_KEYS = {
const ENV_VAR_KEYS = {
POSTGRES_URL: {
key: 'POSTGRES_URL',
type: 'encrypted',
@@ -6,9 +6,6 @@ import { useMemo, useRef, useState } from 'react'
import { Organization } from 'types'
import {
AlertDescription_Shadcn_,
AlertTitle_Shadcn_,
Alert_Shadcn_,
Badge,
Button,
CommandEmpty_Shadcn_,
@@ -17,9 +14,7 @@ import {
CommandItem_Shadcn_,
CommandList_Shadcn_,
Command_Shadcn_,
IconAlertCircle,
IconChevronDown,
IconHexagon,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
Popover_Shadcn_,
@@ -7,7 +7,6 @@ export interface Metric {
name: string
units: string
anchor: string
// metric?: string
category: string
unitName: string
}
@@ -34,7 +33,6 @@ export const BILLING_BREAKDOWN_METRICS: Metric[] = [
name: 'Monthly Active Users',
units: 'absolute',
anchor: 'mau',
// metric: 'MONTHLY_ACTIVE_USERS',
category: 'Authentication',
unitName: 'MAU',
},
@@ -43,7 +41,6 @@ export const BILLING_BREAKDOWN_METRICS: Metric[] = [
name: 'Monthly Active SSO Users',
units: 'absolute',
anchor: 'mauSso',
// metric: 'MONTHLY_ACTIVE_SSO_USERS',
category: 'Authentication',
unitName: 'MAU',
},
@@ -52,7 +49,6 @@ export const BILLING_BREAKDOWN_METRICS: Metric[] = [
name: 'Storage Size',
units: 'bytes',
anchor: 'storageSize',
// metric: 'STORAGE_SIZE',
category: 'Storage',
unitName: 'GB',
},
@@ -61,7 +57,6 @@ export const BILLING_BREAKDOWN_METRICS: Metric[] = [
name: 'Storage Image Transformations',
units: 'absolute',
anchor: 'storageImageTransformations',
// metric: 'STORAGE_IMAGES_TRANSFORMED',
category: 'Storage',
unitName: 'image',
},
@@ -70,7 +65,6 @@ export const BILLING_BREAKDOWN_METRICS: Metric[] = [
name: 'Realtime Peak Connections',
units: 'absolute',
anchor: 'realtimePeakConnections',
// metric: 'REALTIME_PEAK_CONNECTIONS',
category: 'Realtime',
unitName: 'connection',
},
@@ -79,7 +73,6 @@ export const BILLING_BREAKDOWN_METRICS: Metric[] = [
name: 'Realtime Messages',
units: 'absolute',
anchor: 'realtimeMessageCount',
// metric: 'REALTIME_MESSAGE_COUNT',
category: 'Realtime',
unitName: 'message',
},
@@ -88,7 +81,6 @@ export const BILLING_BREAKDOWN_METRICS: Metric[] = [
name: 'Edge Function Invocations',
units: 'absolute',
anchor: 'funcInvocations',
// metric: 'FUNCTION_INVOCATIONS',
category: 'Edge Functions',
unitName: 'invocation',
},
@@ -97,7 +89,6 @@ export const BILLING_BREAKDOWN_METRICS: Metric[] = [
name: 'Edge Function Count',
units: 'absolute',
anchor: 'funcCount',
// metric: 'FUNCTION_COUNT',
category: 'Edge Functions',
unitName: 'function',
},
@@ -3,7 +3,6 @@ import Link from 'next/link'
import { useParams } from 'common'
import {
ScaffoldContainer,
ScaffoldSection,
ScaffoldSectionContent,
ScaffoldSectionDetail,
@@ -1,6 +1,6 @@
import { PricingMetric } from 'data/analytics/org-daily-stats-query'
export const pricingMetricBytes = [
const pricingMetricBytes = [
PricingMetric.DATABASE_SIZE,
PricingMetric.EGRESS,
PricingMetric.STORAGE_SIZE,
@@ -2,7 +2,7 @@ import { useParams } from 'common'
import { useAuthorizedAppRevokeMutation } from 'data/oauth/authorized-app-revoke-mutation'
import { AuthorizedApp } from 'data/oauth/authorized-apps-query'
import { useStore } from 'hooks'
import { Alert, IconAlertOctagon, IconLock, Modal } from 'ui'
import { Alert, IconLock, Modal } from 'ui'
export interface RevokeAppModalProps {
selectedApp?: AuthorizedApp
@@ -45,7 +45,6 @@ const MemberActions = ({ member, roles }: MemberActionsProps) => {
permissions ?? []
)
const isExpired = isInviteExpired(member?.invited_at ?? '')
const isPendingInviteAcceptance = member.invited_id
const roleId = member.role_ids?.[0] ?? -1
@@ -2,7 +2,7 @@ import { DataPoint } from 'data/analytics/constants'
import { ComputeUsageMetric, computeUsageMetricLabel } from 'data/analytics/org-daily-stats-query'
import { OrgSubscription } from 'data/subscriptions/org-subscription-query'
import SectionContent from './SectionContent'
import ShimmeringLoader, { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
import AlertError from 'components/ui/AlertError'
import Panel from 'components/ui/Panel'
import { IconBarChart2 } from 'ui'
@@ -18,8 +18,6 @@ export const COLOR_MAP = {
purple: { bar: 'fill-purple-900', marker: 'bg-purple-900' },
}
export const Y_DOMAIN_CEILING_MULTIPLIER = 4 / 3
export const USAGE_STATUS = {
NORMAL: 'NORMAL',
APPROACHING: 'APPROACHING',
@@ -12,7 +12,7 @@ import { useProjectsQuery } from 'data/projects/projects-query'
import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query'
import { useOrgUsageQuery } from 'data/usage/org-usage-query'
import { useSelectedOrganization } from 'hooks'
import { TIME_PERIODS_BILLING, TIME_PERIODS_REPORTS } from 'lib/constants'
import { TIME_PERIODS_BILLING, TIME_PERIODS_REPORTS } from 'lib/constants/metrics'
import Link from 'next/link'
import { Alert, Button, IconExternalLink, IconInfo, Listbox } from 'ui'
import Activity from './Activity'
@@ -60,7 +60,7 @@ export const ChartTooltipValueFormatter = (number: number | string, unit: string
const sizes = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
export const formatBytesCompact = (bytes: number) => {
const formatBytesCompact = (bytes: number) => {
if (bytes === 0 || bytes === undefined) return '0 bytes'
const k = 1024
@@ -78,7 +78,7 @@ export const formatBytesCompact = (bytes: number) => {
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + unit
}
export const formatBytesPrecision = (bytes: any) => {
const formatBytesPrecision = (bytes: any) => {
if (bytes === 0 || bytes === undefined) return '0 bytes'
const k = 1024
@@ -1,4 +1,3 @@
import { PlayCircle } from 'lucide-react'
import { Button, IconExternalLink } from 'ui'
const NoChannelEmptyState = () => {
@@ -118,9 +118,6 @@ export const useRealtimeMessages = ({
// Hack to confirm Postgres is subscribed
// Need to add 'extension' key in the 'payload'
newChannel.on('system' as any, {} as any, (payload: any) => {
// if (payload.extension === 'postgres_changes' && payload.status === 'ok') {
// pushMessageTo('#conn_info', 'postgres_subscribed', {})
// }
pushMessage('SYSTEM', payload)
})
@@ -67,15 +67,6 @@ const PRODUCT_FILTERS = [
description: 'Realtime connection requests',
icon: IconZap,
},
// TODO: support functions once union parsing is fixed
// {
// key: 'functions',
// filterKey: 'request.host',
// filterValue: '.functions.',
// label: 'Edge Functions',
// description: 'Edge function calls',
// icon: IconCode,
// },
{
key: 'graphql',
filterKey: 'request.path',
@@ -379,6 +379,3 @@ select
},
},
}
export const DATETIME_FORMAT = 'MMM D, ha'
export const DATETIME_SECOND_FORMAT = 'MMM D, ha'
@@ -27,7 +27,7 @@ import DateRangePicker from 'components/to-be-cleaned/DateRangePicker'
import Loading from 'components/ui/Loading'
import NoPermission from 'components/ui/NoPermission'
import { useCheckPermissions, useIsFeatureEnabled } from 'hooks'
import { METRICS, METRIC_CATEGORIES, TIME_PERIODS_REPORTS } from 'lib/constants'
import { METRICS, METRIC_CATEGORIES, TIME_PERIODS_REPORTS } from 'lib/constants/metrics'
import { uuidv4 } from 'lib/helpers'
import { useProfile } from 'lib/profile'
import { useProjectContentStore } from 'stores/projectContentStore'
@@ -10,7 +10,6 @@ import { Fragment, useState } from 'react'
import { Button, Collapsible, IconChevronRight } from 'ui'
import { queryParamsToObject } from '../Reports.utils'
import { ReportWidgetProps, ReportWidgetRendererProps } from '../ReportWidget'
import Link from 'next/link'
import { useParams } from 'common/hooks'
export const NetworkTrafficRenderer = (
@@ -1,6 +1,6 @@
import * as Popover from '@radix-ui/react-popover'
import { motion } from 'framer-motion'
import { useLocalStorageQuery, useSelectedOrganization, useSelectedProject } from 'hooks'
import { useLocalStorageQuery, useSelectedOrganization } from 'hooks'
import { IS_PLATFORM, OPT_IN_TAGS } from 'lib/constants'
import { PropsWithChildren, useEffect, useState } from 'react'
import { Button, IconInfo } from 'ui'
@@ -2,7 +2,7 @@ import { ModalProps } from '@ui/components/Modal/Modal'
import { snakeCase } from 'lodash'
import Link from 'next/link'
import { useState } from 'react'
import { Button, CodeBlock, IconExternalLink, Modal, Separator, Tabs, TabsProvider } from 'ui'
import { Button, CodeBlock, IconExternalLink, Modal, Tabs, TabsProvider } from 'ui'
import TwoOptionToggle from 'components/ui/TwoOptionToggle'
import { useSqlEditorStateSnapshot } from 'state/sql-editor'
@@ -3,7 +3,7 @@ import { useParams } from 'common'
import { useSqlTitleGenerateMutation } from 'data/ai/sql-title-mutation'
import { SqlSnippet } from 'data/content/sql-snippets-query'
import { isError } from 'data/utils/error-check'
import { useFlag, useSelectedOrganization, useStore } from 'hooks'
import { useSelectedOrganization, useStore } from 'hooks'
import { useEffect, useState } from 'react'
import { useSqlEditorStateSnapshot } from 'state/sql-editor'
import { AiIconAnimation, Button, Form, Input, Modal } from 'ui'
@@ -1513,7 +1513,7 @@ revoke execute on function public.custom_access_token_hook from authenticated, a
},
]
export const SQL_SNIPPET_SCHEMA_VERSION = '1.0'
const SQL_SNIPPET_SCHEMA_VERSION = '1.0'
export const NEW_SQL_SNIPPET_SKELETON: UserContent<SqlSnippets.Content> = {
name: 'New Query',
@@ -1,22 +1,10 @@
// @ts-ignore
import MarkdownTable from 'markdown-table'
import { NEW_SQL_SNIPPET_SKELETON, destructiveSqlRegex } from './SQLEditor.constants'
import { SqlSnippets, UserContent } from 'types'
import { DiffType } from './SQLEditor.types'
import { removeCommentsFromSql } from 'lib/helpers'
import { stripIndent } from 'common-tags'
export const getResultsMarkdown = (results: any[]) => {
const columns = Object.keys(results[0])
const rows = results.map((x: any) => {
const temp: any[] = []
columns.forEach((col) => temp.push(x[col]))
return temp
})
const table = [columns].concat(rows)
return MarkdownTable(table)
}
export const createSqlSnippetSkeleton = ({
id,
name,
@@ -2,13 +2,7 @@ import { subscriptionHasHipaaAddon } from 'components/interfaces/Billing/Subscri
import { useSqlDebugMutation } from 'data/ai/sql-debug-mutation'
import { useEntityDefinitionsQuery } from 'data/database/entity-definitions-query'
import { isError } from 'data/utils/error-check'
import {
useFlag,
useLocalStorageQuery,
useSelectedOrganization,
useSelectedProject,
useStore,
} from 'hooks'
import { useLocalStorageQuery, useSelectedOrganization, useSelectedProject, useStore } from 'hooks'
import { IS_PLATFORM, OPT_IN_TAGS } from 'lib/constants'
import { format } from 'sql-formatter'
import { useSqlEditorStateSnapshot } from 'state/sql-editor'
@@ -1,4 +0,0 @@
import SQLTemplates from './SQLTemplates/SQLTemplates'
import SQLQuickstarts from './SQLTemplates/SQLQuickstarts'
export { SQLTemplates, SQLQuickstarts }
@@ -125,7 +125,7 @@ interface MainConfigProps {
poolingInfo: PoolingConfigurationData
}
export const MainConfig = ({ projectRef, poolingInfo }: MainConfigProps) => {
const MainConfig = ({ projectRef, poolingInfo }: MainConfigProps) => {
const { ui } = useStore()
const { project } = useProjectContext()
@@ -1,6 +1,6 @@
import { useParams, useTelemetryProps } from 'common'
import { useRouter } from 'next/router'
import { useEffect, useRef, useState } from 'react'
import { useEffect, useRef } from 'react'
import { Input, Tabs } from 'ui'
import AlertError from 'components/ui/AlertError'
@@ -16,14 +16,13 @@ import {
import { useProjectApiQuery } from 'data/config/project-api-query'
import { useCheckCNAMERecordMutation } from 'data/custom-domains/check-cname-mutation'
import { useCustomDomainCreateMutation } from 'data/custom-domains/custom-domains-create-mutation'
import { useCheckPermissions, useStore } from 'hooks'
import { useCheckPermissions } from 'hooks'
const schema = yup.object({
domain: yup.string().required('A value for your custom domain is required'),
})
const CustomDomainsConfigureHostname = () => {
const { ui } = useStore()
const { ref } = useParams()
const { project } = useProjectContext()
@@ -27,7 +27,7 @@ import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-que
import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query'
import { useResourceWarningsQuery } from 'data/usage/resource-warnings-query'
import { useFlag, useSelectedOrganization } from 'hooks'
import { TIME_PERIODS_BILLING, TIME_PERIODS_REPORTS } from 'lib/constants'
import { TIME_PERIODS_BILLING, TIME_PERIODS_REPORTS } from 'lib/constants/metrics'
import { INFRA_ACTIVITY_METRICS } from './Infrastructure.constants'
const InfrastructureActivity = () => {
@@ -1,5 +1,5 @@
import { useParams } from 'common'
import { isEqual, partition } from 'lodash'
import { partition } from 'lodash'
import { Globe2, Loader2, Network } from 'lucide-react'
import { useTheme } from 'next-themes'
import { useEffect, useMemo, useRef, useState } from 'react'
@@ -55,12 +55,7 @@ const GitHubIntegrationConnectionForm = ({
const [repoOwner, repoName] = githubProjectIntegration?.metadata.name.split('/') ?? []
const {
data: githubBranches,
error: githubBranchesError,
isLoading: isLoadingBranches,
isSuccess: isSuccessBranches,
} = useGithubBranchesQuery({
const { data: githubBranches, isLoading: isLoadingBranches } = useGithubBranchesQuery({
organizationIntegrationId: integration?.id,
repoOwner,
repoName,
@@ -76,7 +71,7 @@ const GitHubIntegrationConnectionForm = ({
},
})
const { data: previewBranches, isLoading: isLoadingPreviewBranches } = useBranchesQuery(
const { data: previewBranches } = useBranchesQuery(
{ projectRef: project?.parentRef },
{ enabled: project !== undefined }
)
@@ -52,15 +52,14 @@ const VercelIntegrationConnectionForm = ({
},
})
const { mutate: updateVercelConnection, isLoading: isUpdatingVercelConnection } =
useVercelConnectionUpdateMutation({
onSuccess: (data) => {
ui.setNotification({
category: 'success',
message: `Updated Supabase directory`,
})
},
})
const { mutate: updateVercelConnection } = useVercelConnectionUpdateMutation({
onSuccess: (data) => {
ui.setNotification({
category: 'success',
message: `Updated Supabase directory`,
})
},
})
function onSubmit(data: z.infer<typeof FormSchema>) {
/**
@@ -1,6 +1,6 @@
import BarChart, { BarChartProps } from 'components/ui/Charts/BarChart'
import BarChart from 'components/ui/Charts/BarChart'
import { Datum } from 'components/ui/Charts/Charts.types'
import { EventChartData, isUnixMicro, LogData, unixMicroToIsoTimestamp } from '.'
import { EventChartData } from '.'
export interface LogEventChartProps {
data: EventChartData[]
@@ -60,11 +60,4 @@ const DatabaseApiSelectionRender = ({ log }: any) => {
)
}
export const DatabaseApiSelectionHeaderRender = (log: any) => {
const method = log?.metadata[0]?.request[0]?.method
const path = log?.metadata[0]?.request[0]?.path
return `${method} ${path}`
}
export default DatabaseApiSelectionRender
@@ -63,11 +63,4 @@ const FunctionInvocationSelectionRender = ({ log }: { log: PreviewLogData }) =>
)
}
export const FunctionInvocationHeaderRender = (log: any) => {
const method = log?.method
const path = log?.request?.url
return `${method} ${path}`
}
export default FunctionInvocationSelectionRender
@@ -7,18 +7,7 @@ export default {
}
export const Functions = (args: any) => (
<div
// style={{
// height: '600px',
// display: 'flex',
// flexDirection: 'column',
// flexGrow: 1,
// position: 'relative',
// }}
// className="
// flex flex-col flex-grow relative pt-4 flex h-full flex-grow transition-opacity
// "
>
<div>
<LogTable
params={{}}
queryType="functions"
@@ -247,12 +247,6 @@ limit 100
},
]
export const LOG_TYPE_LABEL_MAPPING: { [k: string]: string } = {
explorer: 'Explorer',
api: 'API',
database: 'Database',
}
const _SQL_FILTER_COMMON = {
search_query: (value: string) => `regexp_contains(event_message, '${value}')`,
}
@@ -240,7 +240,7 @@ export const genCountQuery = (table: LogsTableName, filters: Filters): string =>
}
/** calculates how much the chart start datetime should be offset given the current datetime filter params */
export const calcChartStart = (params: Partial<LogsEndpointParams>): [Dayjs, string] => {
const calcChartStart = (params: Partial<LogsEndpointParams>): [Dayjs, string] => {
const ite = params.iso_timestamp_end ? dayjs(params.iso_timestamp_end) : dayjs()
// todo @TzeYiing needs typing
const its: any = params.iso_timestamp_start ? dayjs(params.iso_timestamp_start) : dayjs()
@@ -458,7 +458,7 @@ export const fillTimeseries = (
return newData
}
export const getTimestampTruncation = (samples: Dayjs[]): 'second' | 'minute' | 'hour' | 'day' => {
const getTimestampTruncation = (samples: Dayjs[]): 'second' | 'minute' | 'hour' | 'day' => {
const truncationCounts = samples.reduce(
(acc, sample) => {
const truncation = _getTruncation(sample)
@@ -244,20 +244,6 @@ export const timestampLocalFormatter = (value: string | number) => {
return dayjs(timestamp).format('DD MMM HH:mm:ss')
}
/*
* Header Formatter
*
* for http response codes
*/
export const HeaderFormmater = ({ value }: any) => {
return (
<div className="flex h-full items-center text-xs font-normal text-foreground-lighter">
{value}
</div>
)
}
/*
* JSON Syntax Highlighter
*
@@ -11,7 +11,6 @@ import {
LogTemplate,
LogsTableName,
QueryType,
TEMPLATES,
ensureNoTimestampConflict,
maybeShowUpgradePrompt,
} from 'components/interfaces/Settings/Logs'
@@ -5,4 +5,3 @@ export { default as LogsSavedQueriesItem } from './Logs.SavedQueriesItem'
export { default as LogsQueryPanel } from './LogsQueryPanel'
export { default as LogTable } from './LogTable'
export { default as LogEventChart } from './LogEventChart'
export { default as LogsFilterPopover } from './LogsFilterPopover'
@@ -124,21 +124,3 @@ export const SERVICE_OPTIONS = [
disabled: false,
},
]
export const GITHUB_LINKS = [
{
name: 'supabase-js',
description: 'For issues with our Javascript client',
url: 'https://github.com/supabase/supabase-js/issues',
},
{
name: 'supabase-flutter',
description: 'For issues with our Flutter integration',
url: 'https://github.com/supabase-community/supabase-flutter/issues',
},
{
name: 'supabase',
description: 'For other issues about our API',
url: 'https://github.com/supabase/supabase/issues',
},
]
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react'
import { Button, IconAlignLeft, IconAlignRight, SidePanel } from 'ui'
import { Button, IconAlignLeft, SidePanel } from 'ui'
import * as Tooltip from '@radix-ui/react-tooltip'
import TwoOptionToggle from 'components/ui/TwoOptionToggle'
@@ -82,7 +82,7 @@ export const validateFields = (fields: RowField[]) => {
return errors
}
export const parseValue = (originalValue: any, format: string) => {
const parseValue = (originalValue: any, format: string) => {
try {
if (
originalValue === null ||
@@ -1,16 +1,7 @@
import { sortBy, concat } from 'lodash'
import { PostgresDataTypeOption } from './SidePanelEditor.types'
export const DATE_FORMAT = 'YYYY-MM-DDTHH:mm:ssZ'
export const NUMERICAL_TYPES = [
'int2',
'int4',
'int8',
'float4',
'float8',
'numeric',
'double precision',
]
const NUMERICAL_TYPES = ['int2', 'int4', 'int8', 'float4', 'float8', 'numeric', 'double precision']
export const JSON_TYPES = ['json', 'jsonb']
export const TEXT_TYPES = ['text', 'varchar']
@@ -19,7 +10,7 @@ export const DATE_TYPES = ['date']
export const TIME_TYPES = ['time', 'timetz']
export const DATETIME_TYPES = concat(TIMESTAMP_TYPES, DATE_TYPES, TIME_TYPES)
export const OTHER_DATA_TYPES = ['uuid', 'bool', 'vector']
const OTHER_DATA_TYPES = ['uuid', 'bool', 'vector']
export const POSTGRES_DATA_TYPES = sortBy(
concat(NUMERICAL_TYPES, JSON_TYPES, TEXT_TYPES, DATETIME_TYPES, OTHER_DATA_TYPES)
)
@@ -97,7 +97,7 @@ export const revertSpreadsheet = (headers: string[], rows: any[]) => {
return Papa.unparse(rows, { columns: headers })
}
export const inferColumnType = (column: string, rows: object[]) => {
const inferColumnType = (column: string, rows: object[]) => {
// General strategy is to check the first row first, before checking across all the rows
// to ensure uniformity in data type. Thinking we do this as an optimization instead of
// checking all the rows up front.
@@ -1,5 +1,3 @@
import type { PostgresTable } from '@supabase/postgres-meta'
interface HeaderTitleProps {
schema: string
table?: { name: string }
@@ -172,5 +172,3 @@ const AccountLayout = ({ children, title, breadcrumbs }: PropsWithChildren<Accou
}
export default withAuth(AccountLayout)
export const AccountLayoutWithoutAuth = AccountLayout
@@ -67,7 +67,7 @@ const WithSidebar = ({
<div className="-mt-1">
<Menu>
{customSidebarContent}
{sections.map((section, i) => {
{sections.map((section) => {
return Boolean(section.heading) ? (
<SectionWithHeaders
key={section.key}
@@ -2,13 +2,11 @@ import { useParams } from 'common'
import Link from 'next/link'
import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Button } from 'ui'
import { useSelectedOrganization } from 'hooks'
import { useAppStateSnapshot } from 'state/app-state'
const BranchingPITRNotice = () => {
const { ref } = useParams()
const snap = useAppStateSnapshot()
const org = useSelectedOrganization()
return (
<Alert_Shadcn_ className="rounded-none px-7 py-6 [&>svg]:top-6 [&>svg]:left-6 !border-t-0 !border-l-0 !border-r-0">
@@ -1,4 +1,3 @@
import { useParams } from 'common'
import Link from 'next/link'
import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Button } from 'ui'
@@ -1,4 +1,3 @@
import { useParams } from 'common'
import { useFlag, withAuth } from 'hooks'
import { BASE_PATH } from 'lib/constants'
import { PropsWithChildren, ReactNode, forwardRef } from 'react'
@@ -13,7 +13,6 @@ import Link from 'next/link'
import { Button, IconArrowRight, IconExternalLink } from 'ui'
import { Markdown } from 'components/interfaces/Markdown'
import { Project } from 'data/projects/project-detail-query'
export const formatNotificationText = (projectName: string, notification: Notification) => {
if (notification.data.name === NotificationName.ProjectExceedingTierLimit) {
+1 -2
View File
@@ -1,4 +1,4 @@
import AccountLayout, { AccountLayoutWithoutAuth } from './AccountLayout/AccountLayout'
import AccountLayout from './AccountLayout/AccountLayout'
import AuthLayout from './AuthLayout/AuthLayout'
import BillingLayout from './BillingLayout'
import DatabaseLayout from './DatabaseLayout/DatabaseLayout'
@@ -18,7 +18,6 @@ import WizardLayout, { WizardLayoutWithoutAuth } from './WizardLayout'
export {
AccountLayout,
AccountLayoutWithoutAuth,
AuthLayout,
BillingLayout,
DatabaseLayout,
@@ -1,5 +1,4 @@
import { IconDatabase } from 'ui'
import SVG from 'react-inlinesvg'
export const vercelIcon = (
<div className="flex items-center justify-center rounded bg-black p-1">
@@ -22,27 +22,3 @@ export const createReport = async ({ router }: any) => {
await contentStore.load()
router.push(`/project/${ref}/reports/${newReport[0].id}`)
}
/*
* deleteReport()
*
* Deletes a new report with a basic skeleton
* also pushes route another report in list
*
* returns :object
*/
export const deleteReport = async ({ router, id }: any) => {
const { ref } = router.query
// [Alaister] despite it's name, useProjectContentStore is not a real react hook
// so we can safely disable the eslint rule here
// eslint-disable-next-line react-hooks/rules-of-hooks
const contentStore = useProjectContentStore(ref)
const { data: delReport, error } = await contentStore.del(id)
if (error) throw error
await contentStore.load()
// push route to report index
router.push(`/project/${ref}/reports`)
return delReport
}
@@ -33,16 +33,6 @@ export const STORAGE_ROW_STATUS = {
EDITING: 'EDITING',
}
export const STORAGE_POLICY_DEFAULT_DEFINITION_PLACEHOLDER = `/*
Example: Apply this policy to all authenticated users
for a folder called 'public'
storage.foldername(name))[[1]] = 'public'
and auth.role() = 'authenticated'
*/
`
export const STORAGE_CLIENT_LIBRARY_MAPPINGS = {
upload: ['INSERT'],
download: ['SELECT'],
@@ -1,8 +1,8 @@
import { trimEnd, groupBy, difference } from 'lodash'
import { groupBy, difference } from 'lodash'
import { STORAGE_CLIENT_LIBRARY_MAPPINGS } from './Storage.constants'
import { StoragePolicyFormField } from 'components/interfaces/Storage/Storage.types'
export const shortHash = (str: string) => {
const shortHash = (str: string) => {
let hash = 0
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i)
@@ -40,7 +40,7 @@ export const formatPoliciesForStorage = (buckets: any[], policies: any[]) => {
}
/* Start: Internal methods to support formatPoliciesForStorage but exported for tests to cover */
export const formatStoragePolicies = (buckets: any[], policies: any[]) => {
const formatStoragePolicies = (buckets: any[], policies: any[]) => {
const availableBuckets = buckets.map((bucket) => bucket.name)
const formattedPolicies = policies.map((policy) => {
const { definition: policyDefinition, check: policyCheck } = policy
@@ -65,14 +65,7 @@ export const formatStoragePolicies = (buckets: any[], policies: any[]) => {
return formattedPolicies
}
export const truncateDefinitionToExcludeBucket = (definition: string) => {
const definitionSegments = definition?.split(' AND ') ?? []
return definitionSegments.length > 1
? trimEnd(definitionSegments.slice(1).join(' AND '), ')') + ')'
: ''
}
export const extractBucketNameFromDefinition = (definition: string) => {
const extractBucketNameFromDefinition = (definition: string) => {
const definitionSegments = definition?.split(' AND ') ?? []
const [bucketDefinition] = definitionSegments.filter((segment: string) =>
segment.includes('bucket_id')
@@ -80,7 +73,7 @@ export const extractBucketNameFromDefinition = (definition: string) => {
return bucketDefinition ? bucketDefinition.split("'")[1] : null
}
export const groupPoliciesByBucket = (policies: any[]) => {
const groupPoliciesByBucket = (policies: any[]) => {
const policiesByBucket = groupBy(policies, 'bucket')
return Object.keys(policiesByBucket).map((bucketName) => {
return { name: bucketName, policies: policiesByBucket[bucketName] }
@@ -144,7 +137,7 @@ export const deriveAllowedClientLibraryMethods = (allowedOperations = []) => {
// Create policy SQL statements on save based on configuration.
// Used purely for previewing in the review step, not actually fired
export const createSQLStatementForCreatePolicy = (
const createSQLStatementForCreatePolicy = (
idx: number,
bucketName: string,
policyName: string,
@@ -6,15 +6,11 @@ import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuRadioGroup,
DropdownMenuSeparator,
DropdownMenuItem,
DropdownMenuTrigger,
IconChevronLeft,
IconChevronRight,
IconChevronsDown,
IconChevronsUp,
IconCode,
IconColumns,
IconEdit2,
IconFolderPlus,
@@ -29,14 +25,12 @@ import {
DropdownMenuSub,
DropdownMenuSubTrigger,
DropdownMenuSubContent,
DropdownMenuRadioItem,
} from 'ui'
import { useCheckPermissions } from 'hooks'
import { useStorageStore } from 'localStores/storageExplorer/StorageExplorerStore'
import { useStorageExplorerStateSnapshot } from 'state/storage-explorer'
import { STORAGE_SORT_BY, STORAGE_SORT_BY_ORDER, STORAGE_VIEWS } from '../Storage.constants'
import { useAppStateSnapshot } from 'state/app-state'
import APIDocsButton from 'components/ui/APIDocsButton'
import { useIsAPIDocsSidePanelEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
@@ -7,7 +7,7 @@ import { useProjectSettingsQuery } from 'data/config/project-settings-query'
import { useCustomDomainsQuery } from 'data/custom-domains/custom-domains-query'
import { Bucket } from 'data/storage/buckets-query'
import { useStore } from 'hooks'
import { DEFAULT_PROJECT_API_SERVICE_ID, IS_PLATFORM } from 'lib/constants'
import { DEFAULT_PROJECT_API_SERVICE_ID } from 'lib/constants'
import { copyToClipboard } from 'lib/helpers'
import { useStorageStore } from 'localStores/storageExplorer/StorageExplorerStore'
import { STORAGE_ROW_TYPES, STORAGE_VIEWS } from '../Storage.constants'
@@ -1,42 +1,20 @@
import { TextAreaProps } from '@ui/components/Input/Input'
import { useRef, useState } from 'react'
import { Input } from 'ui'
const AutoTextArea = (props: TextAreaProps) => {
const textAreaRef = useRef(null)
const [text, setText] = useState('')
const [textAreaHeight, setTextAreaHeight] = useState('auto')
const [parentHeight, setParentHeight] = useState('auto')
// useEffect(() => {
// setParentHeight(`${textAreaRef?.current.scrollHeight}px`)
// setTextAreaHeight(`${textAreaRef?.current.scrollHeight}px`)
// }, [text])
// const onChangeHandler = (event) => {
// setTextAreaHeight('auto')
// setParentHeight(`${textAreaRef?.current.scrollHeight}px`)
// setText(event.target.value)
// if (props.onChange) {
// props.onChange(event)
// }
// }
return (
<div
style={{
minHeight: parentHeight,
minHeight: 'auto',
}}
>
<Input.TextArea
{...props}
label={props.label}
size="small"
// ref={textAreaRef}
rows={1}
style={{
height: textAreaHeight,
height: 'auto',
overflow: 'hidden',
resize: 'none',
}}
@@ -1,4 +1,3 @@
import { DATETIME_FORMAT } from 'components/interfaces/Reports/Reports.constants'
import dayjs from 'dayjs'
import React, { useMemo } from 'react'
import { ResponsiveContainer } from 'recharts'
@@ -1,47 +0,0 @@
import React from 'react'
import { ComponentMeta } from '@storybook/react'
import dayjs from 'dayjs'
import Chart from './Sparkline'
export default {
title: 'Charts/Sparkline',
} as ComponentMeta<typeof Chart>
const DATA = [290, 430, 649, 422, 321].flatMap((value, index) => [
{
count: value,
level: 'error',
timestamp: dayjs().subtract(index, 'day').toISOString(),
},
])
const PROPS = {
title: 'Memory usage',
xAxisKey: 'timestamp',
yAxisKey: 'count',
data: DATA,
}
export const Sparkline = () => (
<div className="flex flex-col gap-4 ">
<ExampleName>Examples</ExampleName>
<div className="flex flex-row gap-4 flex-wrap pb-10">
{[
{ title: 'Small', props: { size: 'small' as const } },
{ title: 'Normal', props: {} },
{ title: 'Large', props: { size: 'large' as const } },
{ title: 'No data', props: { data: [] } },
].map(({ title, props }, i) => (
<div key={i} className="w-32 h-72">
<ExampleName>{title}</ExampleName>
<div className="w-full h-full mt-4">
<Chart {...PROPS} {...props} />
</div>
</div>
))}
</div>
</div>
)
const ExampleName: React.FC<React.PropsWithChildren> = ({ children }) => (
<h1 className="font-bold text-light">{children}</h1>
)
@@ -1,43 +0,0 @@
import { LineChart, XAxis, Line } from 'recharts'
import { CHART_COLORS } from './Charts.constants'
import { CommonChartProps } from './Charts.types'
import { useChartSize } from './Charts.utils'
interface Props extends CommonChartProps<any> {
xAxisKey: string
yAxisKey: string
}
const Sparkline: React.FC<Props> = ({ size, data, xAxisKey, yAxisKey }) => {
const { Container } = useChartSize(size, {
tiny: 30,
small: 50,
normal: 90,
large: 140,
})
if (data.length === 0) return null
return (
<Container>
<LineChart
data={data}
margin={{
top: 2,
right: 10,
left: 10,
bottom: 2,
}}
className="overflow-visible max-w-sm"
>
<XAxis hide dataKey={xAxisKey} />
<Line
type="monotone"
dataKey={yAxisKey}
stroke={CHART_COLORS.GREEN_1}
dot={false}
animationDuration={600}
strokeWidth={1.5}
/>
</LineChart>
</Container>
)
}
export default Sparkline
@@ -1,864 +0,0 @@
import React from 'react'
import { ComponentStory, ComponentMeta } from '@storybook/react'
import StackedAreaChart from './StackedAreaChart'
export default {
title: 'Charts/StackedAreaChart',
component: StackedAreaChart,
} as ComponentMeta<typeof StackedAreaChart>
const Template: ComponentStory<typeof StackedAreaChart> = (args) => <StackedAreaChart {...args} />
export const Default = Template.bind({})
Default.args = {
stackKey: 'status_code',
xAxisKey: 'timestamp',
yAxisKey: 'count',
isLoading: false,
xAxisFormatAsDate: true,
size: 'large',
dateFormat: 'MMM D, ha',
data: [
{
count: 8656,
status_code: 503,
timestamp: 1647777600000000,
},
{
count: 2,
status_code: 524,
timestamp: 1647777600000000,
},
{
count: 502195,
status_code: 200,
timestamp: 1647777600000000,
},
{
count: 423,
status_code: 204,
timestamp: 1647777600000000,
},
{
count: 1,
status_code: 429,
timestamp: 1647777600000000,
},
{
count: 27,
status_code: 304,
timestamp: 1647777600000000,
},
{
count: 1052,
status_code: 206,
timestamp: 1647777600000000,
},
{
count: 1,
status_code: 101,
timestamp: 1647777600000000,
},
{
count: 51,
status_code: 404,
timestamp: 1647777600000000,
},
{
count: 191,
status_code: 400,
timestamp: 1647777600000000,
},
{
count: 46,
status_code: 303,
timestamp: 1647777600000000,
},
{
count: 1,
status_code: 416,
timestamp: 1647777600000000,
},
{
count: 71635,
status_code: 401,
timestamp: 1647777600000000,
},
{
count: 437,
status_code: 201,
timestamp: 1647777600000000,
},
{
count: 5,
status_code: 409,
timestamp: 1647777600000000,
},
{
count: 48,
status_code: 303,
timestamp: 1647781200000000,
},
{
count: 257,
status_code: 400,
timestamp: 1647781200000000,
},
{
count: 7,
status_code: 404,
timestamp: 1647781200000000,
},
{
count: 2,
status_code: 416,
timestamp: 1647781200000000,
},
{
count: 1093,
status_code: 206,
timestamp: 1647781200000000,
},
{
count: 1,
status_code: 524,
timestamp: 1647781200000000,
},
{
count: 7,
status_code: 409,
timestamp: 1647781200000000,
},
{
count: 1,
status_code: 500,
timestamp: 1647781200000000,
},
{
count: 530460,
status_code: 200,
timestamp: 1647781200000000,
},
{
count: 490,
status_code: 204,
timestamp: 1647781200000000,
},
{
count: 6963,
status_code: 503,
timestamp: 1647781200000000,
},
{
count: 70794,
status_code: 401,
timestamp: 1647781200000000,
},
{
count: 441,
status_code: 201,
timestamp: 1647781200000000,
},
{
count: 14,
status_code: 304,
timestamp: 1647781200000000,
},
{
count: 1,
status_code: 502,
timestamp: 1647781200000000,
},
{
count: 2,
status_code: 429,
timestamp: 1647781200000000,
},
{
count: 255,
status_code: 400,
timestamp: 1647784800000000,
},
{
count: 3,
status_code: 429,
timestamp: 1647784800000000,
},
{
count: 475,
status_code: 201,
timestamp: 1647784800000000,
},
{
count: 469,
status_code: 204,
timestamp: 1647784800000000,
},
{
count: 7,
status_code: 404,
timestamp: 1647784800000000,
},
{
count: 2,
status_code: 524,
timestamp: 1647784800000000,
},
{
count: 12624,
status_code: 503,
timestamp: 1647784800000000,
},
{
count: 8,
status_code: 409,
timestamp: 1647784800000000,
},
{
count: 23,
status_code: 304,
timestamp: 1647784800000000,
},
{
count: 508621,
status_code: 200,
timestamp: 1647784800000000,
},
{
count: 751,
status_code: 206,
timestamp: 1647784800000000,
},
{
count: 2,
status_code: 416,
timestamp: 1647784800000000,
},
{
count: 53,
status_code: 303,
timestamp: 1647784800000000,
},
{
count: 70778,
status_code: 401,
timestamp: 1647784800000000,
},
{
count: 1,
status_code: 502,
timestamp: 1647788400000000,
},
{
count: 372,
status_code: 204,
timestamp: 1647788400000000,
},
{
count: 71464,
status_code: 401,
timestamp: 1647788400000000,
},
{
count: 38,
status_code: 303,
timestamp: 1647788400000000,
},
{
count: 502675,
status_code: 200,
timestamp: 1647788400000000,
},
{
count: 20941,
status_code: 503,
timestamp: 1647788400000000,
},
{
count: 409,
status_code: 201,
timestamp: 1647788400000000,
},
{
count: 889,
status_code: 206,
timestamp: 1647788400000000,
},
{
count: 52,
status_code: 304,
timestamp: 1647788400000000,
},
{
count: 1,
status_code: 409,
timestamp: 1647788400000000,
},
{
count: 48,
status_code: 404,
timestamp: 1647788400000000,
},
{
count: 345,
status_code: 400,
timestamp: 1647788400000000,
},
{
count: 1,
status_code: 416,
timestamp: 1647788400000000,
},
{
count: 9,
status_code: 416,
timestamp: 1647792000000000,
},
{
count: 12694,
status_code: 503,
timestamp: 1647792000000000,
},
{
count: 554,
status_code: 206,
timestamp: 1647792000000000,
},
{
count: 15,
status_code: 304,
timestamp: 1647792000000000,
},
{
count: 269,
status_code: 204,
timestamp: 1647792000000000,
},
{
count: 180,
status_code: 201,
timestamp: 1647792000000000,
},
{
count: 4,
status_code: 524,
timestamp: 1647792000000000,
},
{
count: 72056,
status_code: 401,
timestamp: 1647792000000000,
},
{
count: 3,
status_code: 429,
timestamp: 1647792000000000,
},
{
count: 1,
status_code: 502,
timestamp: 1647792000000000,
},
{
count: 139,
status_code: 400,
timestamp: 1647792000000000,
},
{
count: 37,
status_code: 303,
timestamp: 1647792000000000,
},
{
count: 1,
status_code: 409,
timestamp: 1647792000000000,
},
{
count: 81,
status_code: 404,
timestamp: 1647792000000000,
},
{
count: 505478,
status_code: 200,
timestamp: 1647792000000000,
},
{
count: 71971,
status_code: 401,
timestamp: 1647795600000000,
},
{
count: 573,
status_code: 206,
timestamp: 1647795600000000,
},
{
count: 35,
status_code: 303,
timestamp: 1647795600000000,
},
{
count: 2790,
status_code: 503,
timestamp: 1647795600000000,
},
{
count: 536343,
status_code: 200,
timestamp: 1647795600000000,
},
{
count: 284,
status_code: 204,
timestamp: 1647795600000000,
},
{
count: 9,
status_code: 409,
timestamp: 1647795600000000,
},
{
count: 231,
status_code: 400,
timestamp: 1647795600000000,
},
{
count: 32,
status_code: 304,
timestamp: 1647795600000000,
},
{
count: 2,
status_code: 524,
timestamp: 1647795600000000,
},
{
count: 9,
status_code: 416,
timestamp: 1647795600000000,
},
{
count: 6,
status_code: 429,
timestamp: 1647795600000000,
},
{
count: 8,
status_code: 404,
timestamp: 1647795600000000,
},
{
count: 263,
status_code: 201,
timestamp: 1647795600000000,
},
{
count: 2,
status_code: 429,
timestamp: 1647799200000000,
},
{
count: 1,
status_code: 404,
timestamp: 1647799200000000,
},
{
count: 1,
status_code: 524,
timestamp: 1647799200000000,
},
{
count: 285,
status_code: 201,
timestamp: 1647799200000000,
},
{
count: 680,
status_code: 206,
timestamp: 1647799200000000,
},
{
count: 22,
status_code: 304,
timestamp: 1647799200000000,
},
{
count: 3449,
status_code: 503,
timestamp: 1647799200000000,
},
{
count: 1,
status_code: 422,
timestamp: 1647799200000000,
},
{
count: 4,
status_code: 409,
timestamp: 1647799200000000,
},
{
count: 8,
status_code: 416,
timestamp: 1647799200000000,
},
{
count: 31,
status_code: 303,
timestamp: 1647799200000000,
},
{
count: 549926,
status_code: 200,
timestamp: 1647799200000000,
},
{
count: 151,
status_code: 400,
timestamp: 1647799200000000,
},
{
count: 72473,
status_code: 401,
timestamp: 1647799200000000,
},
{
count: 374,
status_code: 204,
timestamp: 1647799200000000,
},
{
count: 27,
status_code: 303,
timestamp: 1647802800000000,
},
{
count: 240,
status_code: 201,
timestamp: 1647802800000000,
},
{
count: 493,
status_code: 206,
timestamp: 1647802800000000,
},
{
count: 1,
status_code: 502,
timestamp: 1647802800000000,
},
{
count: 19,
status_code: 404,
timestamp: 1647802800000000,
},
{
count: 72814,
status_code: 401,
timestamp: 1647802800000000,
},
{
count: 5,
status_code: 409,
timestamp: 1647802800000000,
},
{
count: 112,
status_code: 400,
timestamp: 1647802800000000,
},
{
count: 236,
status_code: 204,
timestamp: 1647802800000000,
},
{
count: 3,
status_code: 416,
timestamp: 1647802800000000,
},
{
count: 554578,
status_code: 200,
timestamp: 1647802800000000,
},
{
count: 28,
status_code: 304,
timestamp: 1647802800000000,
},
{
count: 1,
status_code: 524,
timestamp: 1647802800000000,
},
{
count: 2733,
status_code: 503,
timestamp: 1647802800000000,
},
{
count: 3,
status_code: 429,
timestamp: 1647802800000000,
},
{
count: 566745,
status_code: 200,
timestamp: 1647806400000000,
},
{
count: 369,
status_code: 201,
timestamp: 1647806400000000,
},
{
count: 11,
status_code: 416,
timestamp: 1647806400000000,
},
{
count: 1,
status_code: 502,
timestamp: 1647806400000000,
},
{
count: 72115,
status_code: 401,
timestamp: 1647806400000000,
},
{
count: 103,
status_code: 400,
timestamp: 1647806400000000,
},
{
count: 756,
status_code: 206,
timestamp: 1647806400000000,
},
{
count: 18,
status_code: 304,
timestamp: 1647806400000000,
},
{
count: 19,
status_code: 404,
timestamp: 1647806400000000,
},
{
count: 21,
status_code: 303,
timestamp: 1647806400000000,
},
{
count: 367,
status_code: 204,
timestamp: 1647806400000000,
},
{
count: 3174,
status_code: 503,
timestamp: 1647806400000000,
},
{
count: 3,
status_code: 524,
timestamp: 1647806400000000,
},
{
count: 208,
status_code: 204,
timestamp: 1647810000000000,
},
{
count: 1,
status_code: 404,
timestamp: 1647810000000000,
},
{
count: 71259,
status_code: 401,
timestamp: 1647810000000000,
},
{
count: 3,
status_code: 416,
timestamp: 1647810000000000,
},
{
count: 561794,
status_code: 200,
timestamp: 1647810000000000,
},
{
count: 3503,
status_code: 503,
timestamp: 1647810000000000,
},
{
count: 151,
status_code: 400,
timestamp: 1647810000000000,
},
{
count: 14,
status_code: 304,
timestamp: 1647810000000000,
},
{
count: 453,
status_code: 206,
timestamp: 1647810000000000,
},
{
count: 4,
status_code: 524,
timestamp: 1647810000000000,
},
{
count: 103,
status_code: 201,
timestamp: 1647810000000000,
},
{
count: 8,
status_code: 409,
timestamp: 1647810000000000,
},
{
count: 31,
status_code: 303,
timestamp: 1647810000000000,
},
{
count: 1,
status_code: 502,
timestamp: 1647813600000000,
},
{
count: 2,
status_code: 409,
timestamp: 1647813600000000,
},
{
count: 23,
status_code: 304,
timestamp: 1647813600000000,
},
{
count: 2,
status_code: 524,
timestamp: 1647813600000000,
},
{
count: 564270,
status_code: 200,
timestamp: 1647813600000000,
},
{
count: 15,
status_code: 404,
timestamp: 1647813600000000,
},
{
count: 70733,
status_code: 401,
timestamp: 1647813600000000,
},
{
count: 79,
status_code: 400,
timestamp: 1647813600000000,
},
{
count: 617,
status_code: 206,
timestamp: 1647813600000000,
},
{
count: 4,
status_code: 429,
timestamp: 1647813600000000,
},
{
count: 3810,
status_code: 503,
timestamp: 1647813600000000,
},
{
count: 35,
status_code: 303,
timestamp: 1647813600000000,
},
{
count: 219,
status_code: 204,
timestamp: 1647813600000000,
},
{
count: 3,
status_code: 416,
timestamp: 1647813600000000,
},
{
count: 157,
status_code: 201,
timestamp: 1647813600000000,
},
{
count: 3,
status_code: 524,
timestamp: 1647817200000000,
},
{
count: 172,
status_code: 201,
timestamp: 1647817200000000,
},
{
count: 552900,
status_code: 200,
timestamp: 1647817200000000,
},
{
count: 21,
status_code: 304,
timestamp: 1647817200000000,
},
{
count: 1,
status_code: 429,
timestamp: 1647817200000000,
},
{
count: 246,
status_code: 204,
timestamp: 1647817200000000,
},
{
count: 2,
status_code: 409,
timestamp: 1647817200000000,
},
{
count: 446,
status_code: 206,
timestamp: 1647817200000000,
},
{
count: 35,
status_code: 303,
timestamp: 1647817200000000,
},
{
count: 233,
status_code: 400,
timestamp: 1647817200000000,
},
],
}
@@ -1,123 +0,0 @@
import dayjs from 'dayjs'
import { useMemo } from 'react'
import {
AreaChart,
XAxis,
YAxis,
Area,
Tooltip,
ResponsiveContainer,
CartesianGrid,
AreaProps,
} from 'recharts'
import EmptyState from './EmptyState'
type Datum = {
[key: string]: any
}
type Data = Datum[]
interface Props {
data?: Data
isLoading: boolean
xAxisKey: string
xAxisFormatAsDate?: boolean
dateFormat?: string
yAxisKey: string
stackKey: string
size?: 'small' | 'normal' | 'large'
styleMap: {
[key: string]: Pick<AreaProps, 'fill' | 'stroke'>
}
}
const StackedAreaChart: React.FC<Props> = ({
data,
xAxisKey,
dateFormat,
yAxisKey,
stackKey,
isLoading,
size = 'normal',
styleMap = {},
xAxisFormatAsDate = false,
}) => {
const transformed = useMemo(() => {
if (!data) return []
const mapping = data.reduce((acc, datum) => {
const x = datum[xAxisKey]
const y = datum[yAxisKey]
const s = datum[stackKey]
if (!acc[x]) {
acc[x] = {}
}
acc[x][s] = y
return acc
}, {})
const flattened = Object.entries(mapping).map(([x, sMap]) => ({
...(sMap as Datum),
[xAxisKey]: x,
}))
return flattened
}, [JSON.stringify(data)])
if (!isLoading && (data === undefined || data === null)) return <EmptyState />
const dataKeys = Object.keys(transformed[0] || {}).filter((k) => k !== xAxisKey && k !== yAxisKey)
const formatToDate = (value: string | number | any) => {
if (!dateFormat) return value
if (!isNaN(Number(value))) {
const unix = String(value).length > 10 ? Number(String(value).slice(0, 10)) : value
return dayjs.unix(unix).format(dateFormat)
} else {
return dayjs(value).format(dateFormat)
}
}
const minHeight = { small: 120, normal: 160, large: 280 }[size]
return (
<ResponsiveContainer height={minHeight} minHeight={minHeight} width="100%">
<AreaChart data={transformed} onClick={(_tooltipData: any) => {}}>
<CartesianGrid strokeDasharray="3 3" style={{ stroke: '#444444' }} />
<XAxis
dataKey={xAxisKey}
angle={0}
axisLine={{ stroke: '#444444' }}
tickLine={{ stroke: '#444444' }}
tickFormatter={xAxisFormatAsDate ? formatToDate : undefined}
tickMargin={12}
interval="preserveStartEnd"
style={{ fontSize: '12px' }}
/>
<YAxis
style={{ fontSize: '12px' }}
minTickGap={10}
axisLine={{ stroke: '#444444' }}
tickLine={{ stroke: '#444444' }}
/>
{dataKeys.map((k, index) => (
<Area
key={index}
dataKey={String(k)}
type="monotone"
legendType="circle"
fill={'rgba(62, 207, 142, 0.2)'}
stroke="#4884d8"
connectNulls
stackId={1}
{...(styleMap[k] || {})}
/>
))}
<Tooltip
labelFormatter={xAxisFormatAsDate ? formatToDate : undefined}
labelClassName="text-white"
contentStyle={{ backgroundColor: '#444444', borderColor: '#444444', fontSize: '12px' }}
wrapperClassName="bg-gray-600"
/>
</AreaChart>
</ResponsiveContainer>
)
}
export default StackedAreaChart
@@ -1,8 +1,7 @@
import React from 'react'
import { ComponentStory, ComponentMeta } from '@storybook/react'
import { ComponentMeta } from '@storybook/react'
import dayjs from 'dayjs'
import Chart from './StackedBarChart'
import { StackedChartProps } from './Charts.types'
import { DEFAULT_STACK_COLORS, genStackColorScales } from './Charts.constants'
export default {
@@ -17,11 +17,3 @@ export interface TimeSplitInputProps {
startDate: any
endDate: any
}
export type Date = {
YYYY: string
MM: string
DD: string
}
export type DateType = 'YYYY' | 'MM' | 'DD'
-17
View File
@@ -1,17 +0,0 @@
import React, { ReactNode } from 'react'
import { useFlag } from 'hooks'
interface Props {
children: ReactNode
name: string
}
function Flag({ children, name }: Props) {
const flagValue = useFlag(name)
if (!flagValue) {
return null
}
return <>{children}</>
}
export default Flag
@@ -1,6 +1,5 @@
import { User } from '@supabase/supabase-js'
import { PropsWithChildren, useEffect, useState } from 'react'
import * as configcat from 'configcat-js'
import { IS_PLATFORM } from 'lib/constants'
import FlagContext from './FlagContext'
@@ -81,7 +81,7 @@ const FormSectionContent = ({
${className}
`}
>
{loading ? Children.map(children, (child) => <Shimmer />) : children}
{loading ? Children.map(children, () => <Shimmer />) : children}
</div>
)
}
@@ -1,6 +1,6 @@
import clsx from 'clsx'
import { filter, orderBy, without } from 'lodash'
import { KeyboardEvent, ReactNode, useEffect, useRef, useState } from 'react'
import { ReactNode, useEffect, useRef, useState } from 'react'
import {
IconAlertCircle,
IconCheck,
@@ -120,14 +120,6 @@ export default function MultiSelect({
onChange(formattedPayload)
}
const onKeyPress = (e: KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
if (searchString.length > 0 && filteredOptions.length === 1) {
handleChange(filteredOptions[0])
}
}
}
return (
<div className={`form-group ${disabled ? 'pointer-events-none opacity-50' : ''}`}>
{label && <label className="!w-full">{label}</label>}
@@ -1,7 +1,6 @@
import { useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query'
import { useQuery, UseQueryOptions } from '@tanstack/react-query'
import { get, isResponseOk } from 'lib/common/fetch'
import { API_URL } from 'lib/constants'
import { useCallback } from 'react'
import { accessTokenKeys } from './keys'
export type AccessToken = {
@@ -37,11 +36,3 @@ export const useAccessTokensQuery = <TData = AccessTokensData>({
({ signal }) => getAccessTokens(signal),
options
)
export const useAccessTokensPrefetch = () => {
const client = useQueryClient()
return useCallback(() => {
client.prefetchQuery(accessTokenKeys.list(), ({ signal }) => getAccessTokens(signal))
}, [])
}
@@ -1,8 +1,7 @@
import { OAuthScope } from '@supabase/shared-types/out/constants'
import { useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query'
import { useQuery, UseQueryOptions } from '@tanstack/react-query'
import { get } from 'lib/common/fetch'
import { API_ADMIN_URL } from 'lib/constants'
import { useCallback } from 'react'
import { resourceKeys } from './keys'
export type ApiAuthorizationVariables = {
@@ -46,15 +45,3 @@ export const useApiAuthorizationQuery = <TData = ResourceData>(
...options,
}
)
export const useApiAuthorizationPrefetch = ({ id }: ApiAuthorizationVariables) => {
const client = useQueryClient()
return useCallback(() => {
if (id) {
client.prefetchQuery(resourceKeys.resource(id), ({ signal }) =>
getApiAuthorizationDetails({ id }, signal)
)
}
}, [id])
}
@@ -1,8 +1,7 @@
import { useCallback } from 'react'
import { useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query'
import { useQuery, UseQueryOptions } from '@tanstack/react-query'
import { authKeys } from './keys'
import { auth, getAccessToken } from 'lib/gotrue'
import { getAccessToken } from 'lib/gotrue'
export async function getSessionAccessToken() {
// ignore if server-side
@@ -28,11 +27,3 @@ export const useSessionAccessTokenQuery = <TData = SessionAccessTokenData>({
() => getSessionAccessToken(),
options
)
export const useSessionAccessTokenPrefetch = () => {
const client = useQueryClient()
return useCallback(
() => client.prefetchQuery(authKeys.accessToken(), () => getSessionAccessToken()),
[]
)
}
-31
View File
@@ -1,31 +0,0 @@
import { useQuery, UseQueryOptions } from '@tanstack/react-query'
import { get } from 'data/fetchers'
import { branchKeys } from './keys'
import { ResponseError } from 'types'
export type BranchVariables = {
id: string
}
export async function getBranch({ id }: BranchVariables, signal?: AbortSignal) {
const { data, error } = await get(`/v1/branches/{branch_id}`, {
params: { path: { branch_id: id } },
signal,
})
if (error) throw error
return data
}
export type BranchData = Awaited<ReturnType<typeof getBranch>>
export type BranchError = ResponseError
export const useBranchQuery = <TData = BranchData>(
{ id }: BranchVariables,
{ enabled = true, ...options }: UseQueryOptions<BranchData, BranchError, TData> = {}
) =>
useQuery<BranchData, BranchError, TData>(
branchKeys.detail(id),
({ signal }) => getBranch({ id }, signal),
{ enabled: enabled && typeof id !== 'undefined', ...options }
)
Loaded 100 of 168 files, more files were not shown because too many files have changed in this diff. Show more