Skip to content

Commit

Permalink
Chore/make api docs permanent (supabase#18749)
Browse files Browse the repository at this point in the history
* Make all UI components behind useIsAPIDocsSidePanelEnabled permanent

* Deprecate table editor api side panel component

* Simplify table editor grid code RE API docs button

* Deprecate all old API page and components

* Fix NewProjectPanel

* Clean up Modal component in UI library and add empty state for feature preview

* Reinstate closable prop in Modal, add deprecated comment

* Add deprecate comments for lib/common/fetchers, to use data/fetchers instead
  • Loading branch information
joshenlim authored Nov 7, 2023
1 parent b91532f commit 9bc6b8e
Show file tree
Hide file tree
Showing 45 changed files with 309 additions and 3,152 deletions.
67 changes: 21 additions & 46 deletions packages/ui/src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { AnimationTailwindClasses } from '../../types'

import * as Dialog from '@radix-ui/react-dialog'

import { Transition } from '@headlessui/react'
import styleHandler from '../../lib/theme/styleHandler'

// import { Transition } from '@tailwindui/react'
Expand All @@ -28,7 +27,6 @@ interface RadixProps
interface Props {
children?: React.ReactNode
customFooter?: React.ReactNode
closable?: boolean
description?: string
hideFooter?: boolean
alignFooter?: 'right' | 'left'
Expand All @@ -39,7 +37,12 @@ interface Props {
cancelText?: string
onConfirm?: any
confirmText?: string
/**
* @deprecated This prop is no longer being used in the Modal component
*/
closable?: boolean
showIcon?: boolean
showCloseButton?: boolean
footerBackground?: boolean
title?: string | React.ReactNode
variant?: 'danger' | 'warning' | 'success'
Expand All @@ -59,7 +62,6 @@ interface Props {
const Modal = ({
children,
customFooter = undefined,
closable,
description,
hideFooter = false,
alignFooter = 'left',
Expand All @@ -69,7 +71,9 @@ const Modal = ({
onConfirm = () => {},
onCancel = () => {},
confirmText = 'Confirm',
closable = false,
showIcon = false,
showCloseButton = false,
title,
footerBackground,
icon,
Expand All @@ -86,32 +90,12 @@ const Modal = ({
...props
}: ModalProps) => {
const [open, setOpen] = React.useState(visible ? visible : false)

const __styles = styleHandler('modal')

useEffect(() => {
setOpen(visible)
}, [visible])

function stopPropagation(e: React.MouseEvent) {
e.stopPropagation()
}

// let footerClasses = [ModalStyles['sbui-modal-footer']]
if (footerBackground) {
// footerClasses.push(ModalStyles['sbui-modal-footer--with-bg'])
}

let modalClasses = [
__styles.base,
// ModalStyles[`sbui-modal`],
// ModalStyles[`sbui-modal--${size}`],
]
// if (className) modalClasses.push(className)

// let overlayClasses = [ModalStyles['sbui-modal-overlay']]
// if (overlayClassName) overlayClasses.push(overlayClassName)

const footerContent = customFooter ? (
customFooter
) : (
Expand Down Expand Up @@ -149,13 +133,7 @@ const Modal = ({

return (
<Dialog.Root open={open} onOpenChange={handleOpenChange}>
{triggerElement && (
<Dialog.Trigger
// className={ModalStyles[`sbui-modal__trigger`]}
>
{triggerElement}
</Dialog.Trigger>
)}
{triggerElement && <Dialog.Trigger>{triggerElement}</Dialog.Trigger>}
<Dialog.Portal>
<Dialog.Overlay className={__styles.overlay} />
<Dialog.Overlay className={__styles.scroll_overlay}>
Expand All @@ -164,24 +142,21 @@ const Modal = ({
onInteractOutside={props.onInteractOutside}
onEscapeKeyDown={props.onEscapeKeyDown}
>
{header && <div className={__styles.header}>{header}</div>}
{/* <div
className={ModalStyles['sbui-modal-content']}
style={contentStyle}
> */}
{header && (
<div className={__styles.header}>
{header}
{showCloseButton && (
<Button
onClick={onCancel}
type="text"
icon={<IconX size="medium" />}
className="px-1"
/>
)}
</div>
)}
{children}
{/* </div> */}
{!hideFooter && <div className={__styles.footer}>{footerContent}</div>}
{/* {closable && (
<div className={ModalStyles['sbui-modal-close-container']}>
<Button
onClick={onCancel}
type="text"
shadow={false}
icon={<IconX size="medium" />}
/>
</div>
)} */}
</Dialog.Content>
</Dialog.Overlay>
</Dialog.Portal>
Expand Down
9 changes: 0 additions & 9 deletions studio/components/grid/types/grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,6 @@ export interface SupabaseGridProps {
*/
onEditRow?: (row: SupaRow) => void
onError?: (error: any) => void
/**
* Toggle api preview panel open
*/
apiPreviewPanelOpen?: boolean
setApiPreviewPanelOpen?: () => void
/**
* Refresh the docs after a change is made to the table
*/
refreshDocs: () => void
onExpandJSONEditor: (column: string, row: SupaRow) => void
updateTableRow: (previousRow: any, updatedData: any) => void
onEditForeignKeyColumnValue: (args: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,13 @@ export const useFeaturePreviewContext = () => useContext(FeaturePreviewContext)
export const FeaturePreviewContextProvider = ({ children }: PropsWithChildren<{}>) => {
const [flags, setFlags] = useState({
[LOCAL_STORAGE_KEYS.UI_PREVIEW_NAVIGATION_LAYOUT]: false,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL]: false,
})

useEffect(() => {
if (typeof window !== 'undefined') {
setFlags({
[LOCAL_STORAGE_KEYS.UI_PREVIEW_NAVIGATION_LAYOUT]:
localStorage.getItem(LOCAL_STORAGE_KEYS.UI_PREVIEW_NAVIGATION_LAYOUT) === 'true',
[LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL]:
localStorage.getItem(LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL) === 'true',
})
}
}, [])
Expand All @@ -54,8 +51,3 @@ export const useIsNavigationPreviewEnabled = () => {
const { flags } = useFeaturePreviewContext()
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_NAVIGATION_LAYOUT]
}

export const useIsAPIDocsSidePanelEnabled = () => {
const { flags } = useFeaturePreviewContext()
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL]
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,28 @@ import { useRouter } from 'next/router'
import { useState } from 'react'
import { Button, IconExternalLink, IconEye, IconEyeOff, Modal, ScrollArea, cn } from 'ui'

import { LOCAL_STORAGE_KEYS } from 'lib/constants'
import Telemetry from 'lib/telemetry'
import { FlaskConical } from 'lucide-react'
import Link from 'next/link'
import { useAppStateSnapshot } from 'state/app-state'
import APISidePanelPreview from './APISidePanelPreview'
import { useFeaturePreviewContext } from './FeaturePreviewContext'
import Link from 'next/link'

// [Ivan] We should probably move this to a separate file, together with LOCAL_STORAGE_KEYS. We should make adding new feature previews as simple as possible.

const FEATURE_PREVIEWS = [
const FEATURE_PREVIEWS: { key: string; name: string; content: any; discussionsUrl?: string }[] = [
// {
// key: LOCAL_STORAGE_KEYS.UI_PREVIEW_NAVIGATION_LAYOUT,
// name: 'Global navigation update',
// content: null
// content: null,
// },
{
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL,
name: 'Project API documentation',
content: <APISidePanelPreview />,
discussionsUrl: 'https://github.com/orgs/supabase/discussions/18038',
},
]

const FeaturePreviewModal = () => {
const router = useRouter()
const snap = useAppStateSnapshot()
const telemetryProps = useTelemetryProps()
const featurePreviewContext = useFeaturePreviewContext()
const [selectedFeatureKey, setSelectedFeatureKey] = useState<string>(FEATURE_PREVIEWS[0].key)
const [selectedFeatureKey, setSelectedFeatureKey] = useState<string>(FEATURE_PREVIEWS?.[0]?.key)

const { flags, onUpdateFlag } = featurePreviewContext
const selectedFeature = FEATURE_PREVIEWS.find((preview) => preview.key === selectedFeatureKey)
Expand All @@ -53,57 +46,79 @@ const FeaturePreviewModal = () => {
return (
<Modal
hideFooter
showCloseButton
size="xlarge"
className="max-w-4xl"
header="Dashboard feature previews"
visible={snap.showFeaturePreviewModal}
onCancel={() => snap.setShowFeaturePreviewModal(false)}
>
<div className="flex">
<div>
<ScrollArea className="h-[550px] w-[240px] border-r">
{FEATURE_PREVIEWS.map((feature) => {
const isEnabled = flags[feature.key] ?? false
{FEATURE_PREVIEWS.length > 0 ? (
<div className="flex">
<div>
<ScrollArea className="h-[550px] w-[240px] border-r">
{FEATURE_PREVIEWS.map((feature) => {
const isEnabled = flags[feature.key] ?? false

return (
<div
key={feature.key}
onClick={() => setSelectedFeatureKey(feature.key)}
className={cn(
'flex items-center space-x-3 p-4 border-b cursor-pointer bg transition',
selectedFeatureKey === feature.key ? 'bg-surface-200' : ''
)}
>
{isEnabled ? (
<IconEye size={14} strokeWidth={2} className="text-brand" />
) : (
<IconEyeOff size={14} strokeWidth={1.5} className="text-foreground-light" />
)}
<p className="text-sm">{feature.name}</p>
</div>
)
})}
</ScrollArea>
</div>
<div className="flex-grow max-h-[550px] p-4 space-y-3 overflow-y-auto">
<div className="flex items-center justify-between">
<p>{selectedFeature?.name}</p>
<div className="flex items-center space-x-2">
{selectedFeature?.discussionsUrl !== undefined && (
<Button asChild type="default" icon={<IconExternalLink strokeWidth={1.5} />}>
<Link href={selectedFeature.discussionsUrl} target="_blank" rel="noreferrer">
Give feedback
</Link>
return (
<div
key={feature.key}
onClick={() => setSelectedFeatureKey(feature.key)}
className={cn(
'flex items-center space-x-3 p-4 border-b cursor-pointer bg transition',
selectedFeatureKey === feature.key ? 'bg-surface-200' : ''
)}
>
{isEnabled ? (
<IconEye size={14} strokeWidth={2} className="text-brand" />
) : (
<IconEyeOff size={14} strokeWidth={1.5} className="text-foreground-light" />
)}
<p className="text-sm">{feature.name}</p>
</div>
)
})}
</ScrollArea>
</div>
<div className="flex-grow max-h-[550px] p-4 space-y-3 overflow-y-auto">
<div className="flex items-center justify-between">
<p>{selectedFeature?.name}</p>
<div className="flex items-center space-x-2">
{selectedFeature?.discussionsUrl !== undefined && (
<Button asChild type="default" icon={<IconExternalLink strokeWidth={1.5} />}>
<Link href={selectedFeature.discussionsUrl} target="_blank" rel="noreferrer">
Give feedback
</Link>
</Button>
)}
<Button type="default" onClick={() => toggleFeature()}>
{isSelectedFeatureEnabled ? 'Disable' : 'Enable'} feature
</Button>
)}
<Button type="default" onClick={() => toggleFeature()}>
{isSelectedFeatureEnabled ? 'Disable' : 'Enable'} feature
</Button>
</div>
</div>
{selectedFeature?.content}
</div>
</div>
) : (
<div className="h-[550px] flex flex-col items-center justify-center">
<FlaskConical size={30} strokeWidth={1.5} className="text-foreground-light" />
<div className="mt-1 mb-3 flex flex-col items-center gap-y-0.5">
<p className="text-sm">No feature previews available</p>
<p className="text-sm text-foreground-light">
Have an idea for the dashboard? Let us know via Github Discussions!
</p>
</div>
{selectedFeature?.content}
<Button asChild type="default" icon={<IconExternalLink strokeWidth={1.5} />}>
<Link
href="https://github.com/orgs/supabase/discussions/categories/feature-requests"
target="_blank"
rel="noreferrer"
>
Github Discussions
</Link>
</Button>
</div>
</div>
)}
</Modal>
)
}
Expand Down
21 changes: 3 additions & 18 deletions studio/components/interfaces/Auth/Users/Users.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import { useParams } from 'common'
import { useState } from 'react'
import { Button, IconCode, IconRefreshCw, IconSearch, IconX, Input, Listbox } from 'ui'
import { Button, IconRefreshCw, IconSearch, IconX, Input, Listbox } from 'ui'

import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import APIDocsButton from 'components/ui/APIDocsButton'
import { useUsersQuery } from 'data/auth/users-query'
import AddUserDropdown from './AddUserDropdown'
import UsersList from './UsersList'
import { useAppStateSnapshot } from 'state/app-state'
import { useIsAPIDocsSidePanelEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'

const Users = () => {
const { project } = useProjectContext()
const { ref: projectRef } = useParams()
const snap = useAppStateSnapshot()
const isNewAPIDocsEnabled = useIsAPIDocsSidePanelEnabled()

const [page, setPage] = useState(1)
const [search, setSearch] = useState('')
Expand Down Expand Up @@ -84,19 +81,7 @@ const Users = () => {
</Listbox>
</div>
<div className="mt-4 flex items-center gap-2 md:mt-0">
{isNewAPIDocsEnabled && (
<Button
size="tiny"
type="default"
icon={<IconCode size={14} strokeWidth={2} />}
onClick={() => {
snap.setActiveDocsSection(['user-management'])
snap.setShowProjectApiDocs(true)
}}
>
API
</Button>
)}
<APIDocsButton section={['user-management']} />
<Button
size="tiny"
icon={<IconRefreshCw />}
Expand Down
Loading

0 comments on commit 9bc6b8e

Please sign in to comment.