mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
fix: remove API Docs nav item after transition period (#44637)
## Summary - Removes the "API Docs" navigation item from the sidebar and mobile menu - Removes the `UI_PREVIEW_API_SIDE_PANEL` feature preview flag since the feature is fully rolled out - Makes API docs buttons unconditionally visible across Auth Users, Storage, Edge Functions, and SecondLevelNav ## Test plan - [x] `NavigationBar.utils` tests pass (26 tests) - [x] `FileExplorerHeader` tests pass (6 tests) - [x] TypeScript compiles with no errors - [ ] Verify sidebar no longer shows "API Docs" nav item - [ ] Verify API docs buttons still appear in Auth Users, Storage, and Edge Functions pages - [ ] Verify feature preview modal no longer lists "Project API documentation" Resolves FE-2759 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * APIDocs button can optionally display a label and use a custom tooltip. * **Chores** * Removed the API docs side-panel feature flag and its localStorage key. * “API Docs” navigation entry removed; sidebar no longer special-cases that route. * Back links and API Docs buttons now render consistently across the app (no flag gating). * **Tests** * Tests updated to stop depending on the removed feature-flag behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
69b6a4b273
commit
26b3db8302
14 files changed
+17
-145
No files matched your search
@@ -70,11 +70,6 @@ export const FeaturePreviewContextProvider = ({ children }: PropsWithChildren<{}
|
||||
|
||||
// Helpers
|
||||
|
||||
export const useIsAPIDocsSidePanelEnabled = () => {
|
||||
const { flags } = useFeaturePreviewContext()
|
||||
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL]
|
||||
}
|
||||
|
||||
export const useIsColumnLevelPrivilegesEnabled = () => {
|
||||
const { flags } = useFeaturePreviewContext()
|
||||
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_CLS]
|
||||
|
||||
@@ -77,15 +77,6 @@ export const useFeaturePreviews = (): FeaturePreview[] => {
|
||||
isDefaultOptIn: false,
|
||||
enabled: jitDbAccessEnabled,
|
||||
},
|
||||
{
|
||||
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL,
|
||||
name: 'Project API documentation',
|
||||
discussionsUrl: 'https://github.com/orgs/supabase/discussions/18038',
|
||||
enabled: true,
|
||||
isNew: false,
|
||||
isPlatformOnly: false,
|
||||
isDefaultOptIn: false,
|
||||
},
|
||||
{
|
||||
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_CLS,
|
||||
name: 'Column-level privileges',
|
||||
|
||||
@@ -54,9 +54,7 @@ import {
|
||||
import { formatUserColumns, formatUsersData } from './Users.utils'
|
||||
import { UsersFooter } from './UsersFooter'
|
||||
import { UsersSearch } from './UsersSearch'
|
||||
import { useIsAPIDocsSidePanelEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
|
||||
import { AlertError } from '@/components/ui/AlertError'
|
||||
import { APIDocsButton } from '@/components/ui/APIDocsButton'
|
||||
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
|
||||
import { FilterPopover } from '@/components/ui/FilterPopover'
|
||||
import { FormHeader } from '@/components/ui/Forms/FormHeader'
|
||||
@@ -99,7 +97,6 @@ export const UsersV2 = () => {
|
||||
const { data: selectedOrg } = useSelectedOrganizationQuery()
|
||||
const gridRef = useRef<DataGridHandle>(null)
|
||||
const xScroll = useRef<number>(0)
|
||||
const isNewAPIDocsEnabled = useIsAPIDocsSidePanelEnabled()
|
||||
const { mutate: sendEvent } = useSendEventMutation()
|
||||
|
||||
const {
|
||||
@@ -722,9 +719,6 @@ export const UsersV2 = () => {
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-x-2">
|
||||
{isNewAPIDocsEnabled && (
|
||||
<APIDocsButton section={['user-management']} source="auth-users" />
|
||||
)}
|
||||
<ButtonTooltip
|
||||
size="tiny"
|
||||
icon={<RefreshCw />}
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
PopoverTrigger_Shadcn_,
|
||||
} from 'ui'
|
||||
|
||||
import { useIsAPIDocsSidePanelEnabled } from '../App/FeaturePreview/FeaturePreviewContext'
|
||||
import { navigateToSection } from './Content/Content.utils'
|
||||
import { DOCS_RESOURCE_CONTENT } from './ProjectAPIDocs.constants'
|
||||
import { DocsButton } from '@/components/ui/DocsButton'
|
||||
@@ -90,8 +89,6 @@ type NavTitleProps = {
|
||||
}
|
||||
|
||||
const NavTitle = ({ title, category }: NavTitleProps) => {
|
||||
const isNewAPIDocsEnabled = useIsAPIDocsSidePanelEnabled()
|
||||
|
||||
const snap = useAppStateSnapshot()
|
||||
const handleBack = () => {
|
||||
snap.setActiveDocsSection([category])
|
||||
@@ -99,9 +96,7 @@ const NavTitle = ({ title, category }: NavTitleProps) => {
|
||||
|
||||
return (
|
||||
<div className="flex items-center space-x-2 mb-2">
|
||||
{isNewAPIDocsEnabled && (
|
||||
<Button type="text" icon={<ChevronLeft />} className="px-1" onClick={handleBack} />
|
||||
)}
|
||||
<Button type="text" icon={<ChevronLeft />} className="px-1" onClick={handleBack} />
|
||||
<p className="text-sm text-foreground-light capitalize">{title}</p>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -29,7 +29,6 @@ import {
|
||||
|
||||
import { Route } from '../ui/ui.types'
|
||||
import {
|
||||
useIsAPIDocsSidePanelEnabled,
|
||||
useIsPlatformWebhooksEnabled,
|
||||
useUnifiedLogsPreview,
|
||||
} from './App/FeaturePreview/FeaturePreviewContext'
|
||||
@@ -225,7 +224,6 @@ const ProjectLinks = () => {
|
||||
const showReports = useIsFeatureEnabled('reports:all')
|
||||
const { mutate: sendEvent } = useSendEventMutation()
|
||||
|
||||
const isNewAPIDocsEnabled = useIsAPIDocsSidePanelEnabled()
|
||||
const platformWebhooksEnabled = useIsPlatformWebhooksEnabled()
|
||||
const { isEnabled: isUnifiedLogsEnabled } = useUnifiedLogsPreview()
|
||||
|
||||
@@ -256,7 +254,6 @@ const ProjectLinks = () => {
|
||||
const otherRoutes = generateOtherRoutes(ref, project, {
|
||||
unifiedLogs: isUnifiedLogsEnabled,
|
||||
showReports,
|
||||
apiDocsSidePanel: isNewAPIDocsEnabled,
|
||||
})
|
||||
const settingsRoutes = generateSettingsRoutes(ref)
|
||||
|
||||
@@ -295,41 +292,7 @@ const ProjectLinks = () => {
|
||||
<Separator className="w-[calc(100%-1rem)] mx-auto" />
|
||||
<SidebarGroup className="gap-0.5">
|
||||
{otherRoutes.map((route, i) => {
|
||||
if (route.key === 'api') {
|
||||
const handleApiClick = () => {
|
||||
if (isNewAPIDocsEnabled) {
|
||||
snap.setShowProjectApiDocs(true)
|
||||
}
|
||||
sendEvent({
|
||||
action: 'api_docs_opened',
|
||||
properties: {
|
||||
source: 'sidebar',
|
||||
},
|
||||
groups: {
|
||||
project: ref ?? 'Unknown',
|
||||
organization: org?.slug ?? 'Unknown',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<SideBarNavLink
|
||||
key={route.key}
|
||||
route={
|
||||
isNewAPIDocsEnabled
|
||||
? {
|
||||
label: route.label,
|
||||
icon: route.icon,
|
||||
key: route.key,
|
||||
disabled: route.disabled,
|
||||
}
|
||||
: route
|
||||
}
|
||||
active={activeRoute === route.key}
|
||||
onClick={handleApiClick}
|
||||
/>
|
||||
)
|
||||
} else if (route.key === 'advisors') {
|
||||
if (route.key === 'advisors') {
|
||||
return (
|
||||
<div className="relative" key={route.key}>
|
||||
{!route.disabled && (
|
||||
|
||||
+1
-10
@@ -10,13 +10,11 @@ const {
|
||||
mockTrack,
|
||||
mockUseStorageExplorerStateSnapshot,
|
||||
mockUseAsyncCheckPermissions,
|
||||
mockIsAPIDocsSidePanelEnabled,
|
||||
mockUseStoragePreference,
|
||||
} = vi.hoisted(() => ({
|
||||
mockTrack: vi.fn(),
|
||||
mockUseStorageExplorerStateSnapshot: vi.fn(),
|
||||
mockUseAsyncCheckPermissions: vi.fn(),
|
||||
mockIsAPIDocsSidePanelEnabled: vi.fn(),
|
||||
mockUseStoragePreference: vi.fn(),
|
||||
}))
|
||||
|
||||
@@ -27,12 +25,7 @@ vi.mock('@/state/storage-explorer', () => ({
|
||||
vi.mock('@/hooks/misc/useCheckPermissions', () => ({
|
||||
useAsyncCheckPermissions: () => mockUseAsyncCheckPermissions(),
|
||||
}))
|
||||
vi.mock('@/components/interfaces/App/FeaturePreview/FeaturePreviewContext', () => ({
|
||||
useIsAPIDocsSidePanelEnabled: () => mockIsAPIDocsSidePanelEnabled(),
|
||||
}))
|
||||
vi.mock('@/components/ui/APIDocsButton', () => ({
|
||||
APIDocsButton: () => null,
|
||||
}))
|
||||
|
||||
vi.mock('./useStoragePreference', () => ({
|
||||
useStoragePreference: (...args: any[]) => mockUseStoragePreference(...args),
|
||||
}))
|
||||
@@ -83,13 +76,11 @@ describe('FileExplorerHeader', () => {
|
||||
mockTrack.mockReset()
|
||||
mockUseStorageExplorerStateSnapshot.mockReset()
|
||||
mockUseAsyncCheckPermissions.mockReset()
|
||||
mockIsAPIDocsSidePanelEnabled.mockReset()
|
||||
mockUseStoragePreference.mockReset()
|
||||
|
||||
mockUseStorageExplorerStateSnapshot.mockReturnValue(createSnapshot())
|
||||
mockUseStoragePreference.mockReturnValue(createPreference())
|
||||
mockUseAsyncCheckPermissions.mockReturnValue({ can: true })
|
||||
mockIsAPIDocsSidePanelEnabled.mockReturnValue(false)
|
||||
})
|
||||
|
||||
it('renders full breadcrumbs in column view and places Navigate before Reload', () => {
|
||||
|
||||
@@ -47,8 +47,6 @@ import { Input } from 'ui-patterns/DataInputs/Input'
|
||||
|
||||
import { STORAGE_SORT_BY, STORAGE_SORT_BY_ORDER, STORAGE_VIEWS } from '../Storage.constants'
|
||||
import { useStoragePreference } from './useStoragePreference'
|
||||
import { useIsAPIDocsSidePanelEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
|
||||
import { APIDocsButton } from '@/components/ui/APIDocsButton'
|
||||
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useTrack } from '@/lib/telemetry/track'
|
||||
@@ -208,7 +206,6 @@ export const FileExplorerHeader = ({
|
||||
onFilesUpload = noop,
|
||||
}: FileExplorerHeader) => {
|
||||
const snap = useStorageExplorerStateSnapshot()
|
||||
const isNewAPIDocsEnabled = useIsAPIDocsSidePanelEnabled()
|
||||
const track = useTrack()
|
||||
|
||||
const [pathString, setPathString] = useState('')
|
||||
@@ -545,15 +542,6 @@ export const FileExplorerHeader = ({
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{isNewAPIDocsEnabled && (
|
||||
<>
|
||||
<div className="h-6 shrink-0 border-r border-control" />
|
||||
<div className="mx-2 shrink-0">
|
||||
<APIDocsButton section={['storage', selectedBucket.name]} source="storage" />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { ReactElement } from 'react'
|
||||
|
||||
import { ProjectLayout } from '../ProjectLayout'
|
||||
import { generateDocsMenu, getActivePage } from './DocsLayout.utils'
|
||||
import { useIsAPIDocsSidePanelEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
|
||||
import Error from '@/components/ui/Error'
|
||||
import { ProductMenu } from '@/components/ui/ProductMenu'
|
||||
import { useOpenAPISpecQuery } from '@/data/open-api/api-spec-query'
|
||||
@@ -25,8 +24,7 @@ function DocsLayout({ title, children }: { title: string; children: ReactElement
|
||||
error,
|
||||
} = useOpenAPISpecQuery({ projectRef: ref }, { enabled: !isPaused })
|
||||
|
||||
const isNewAPIDocsEnabled = useIsAPIDocsSidePanelEnabled()
|
||||
const hideMenu = isNewAPIDocsEnabled && router.pathname.endsWith('/graphiql')
|
||||
const hideMenu = router.pathname.endsWith('/graphiql')
|
||||
|
||||
const { projectAuthAll: authEnabled } = useIsFeatureEnabled(['project_auth:all'])
|
||||
|
||||
|
||||
@@ -39,9 +39,7 @@ import {
|
||||
|
||||
import { ProjectLayout } from '../ProjectLayout'
|
||||
import EdgeFunctionsLayout from './EdgeFunctionsLayout'
|
||||
import { useIsAPIDocsSidePanelEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
|
||||
import { EdgeFunctionTesterSheet } from '@/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionTesterSheet'
|
||||
import { APIDocsButton } from '@/components/ui/APIDocsButton'
|
||||
import CopyButton from '@/components/ui/CopyButton'
|
||||
import { DocsButton } from '@/components/ui/DocsButton'
|
||||
import NoPermission from '@/components/ui/NoPermission'
|
||||
@@ -69,7 +67,6 @@ const EdgeFunctionDetailsLayout = ({
|
||||
const { functionSlug, ref } = useParams()
|
||||
const { mutate: sendEvent } = useSendEventMutation()
|
||||
|
||||
const isNewAPIDocsEnabled = useIsAPIDocsSidePanelEnabled()
|
||||
const { isLoading, can: canReadFunctions } = useAsyncCheckPermissions(
|
||||
PermissionAction.FUNCTIONS_READ,
|
||||
'*'
|
||||
@@ -332,16 +329,6 @@ const EdgeFunctionDetailsLayout = ({
|
||||
|
||||
<PageHeaderAside>
|
||||
<div className="flex items-center space-x-2">
|
||||
{isNewAPIDocsEnabled && (
|
||||
<APIDocsButton
|
||||
section={
|
||||
functionSlug !== undefined
|
||||
? ['edge-functions', functionSlug]
|
||||
: ['edge-functions']
|
||||
}
|
||||
source="edge-functions"
|
||||
/>
|
||||
)}
|
||||
<DocsButton href={`${DOCS_URL}/guides/functions`} />
|
||||
<Popover_Shadcn_>
|
||||
<PopoverTrigger_Shadcn_ asChild>
|
||||
|
||||
+2
-13
@@ -140,19 +140,8 @@ describe('generateOtherRoutes', () => {
|
||||
expect(keys(routes)).not.toContain('observability')
|
||||
})
|
||||
|
||||
it('includes API Docs when apiDocsSidePanel is enabled', () => {
|
||||
const routes = generateOtherRoutes(REF, activeProject, {
|
||||
isPlatform: true,
|
||||
apiDocsSidePanel: true,
|
||||
})
|
||||
expect(keys(routes)).toContain('api')
|
||||
})
|
||||
|
||||
it('excludes API Docs when apiDocsSidePanel is disabled', () => {
|
||||
const routes = generateOtherRoutes(REF, activeProject, {
|
||||
isPlatform: true,
|
||||
apiDocsSidePanel: false,
|
||||
})
|
||||
it('does not include API Docs nav item', () => {
|
||||
const routes = generateOtherRoutes(REF, activeProject, { isPlatform: true })
|
||||
expect(keys(routes)).not.toContain('api')
|
||||
})
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Auth, Database, EdgeFunctions, Realtime, SqlEditor, Storage, TableEditor } from 'icons'
|
||||
import { Blocks, FileText, Lightbulb, List, Settings, Telescope } from 'lucide-react'
|
||||
import { Blocks, Lightbulb, List, Settings, Telescope } from 'lucide-react'
|
||||
|
||||
import { ICON_SIZE, ICON_STROKE_WIDTH } from '@/components/interfaces/Sidebar'
|
||||
import type { Route } from '@/components/ui/ui.types'
|
||||
@@ -26,7 +26,6 @@ interface OtherFeatures {
|
||||
isPlatform?: boolean
|
||||
unifiedLogs?: boolean
|
||||
showReports?: boolean
|
||||
apiDocsSidePanel?: boolean
|
||||
}
|
||||
|
||||
interface SettingsFeatures {
|
||||
@@ -154,8 +153,6 @@ export const generateOtherRoutes = (
|
||||
const isPlatform = features?.isPlatform ?? IS_PLATFORM
|
||||
const unifiedLogsEnabled = features?.unifiedLogs ?? false
|
||||
const reportsEnabled = features?.showReports ?? true
|
||||
const apiDocsSidePanelEnabled = features?.apiDocsSidePanel ?? false
|
||||
|
||||
return [
|
||||
{
|
||||
key: 'advisors',
|
||||
@@ -183,19 +180,6 @@ export const generateOtherRoutes = (
|
||||
icon: <List size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
|
||||
link: ref && (unifiedLogsEnabled ? `/project/${ref}/logs` : `/project/${ref}/logs/explorer`),
|
||||
},
|
||||
...(apiDocsSidePanelEnabled
|
||||
? [
|
||||
{
|
||||
key: 'api',
|
||||
label: 'API Docs',
|
||||
disabled: !isProjectActive,
|
||||
icon: <FileText size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
|
||||
link:
|
||||
ref &&
|
||||
(isProjectBuilding ? buildingUrl : `/project/${ref}/integrations/data_api/docs`),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
key: 'integrations',
|
||||
label: 'Integrations',
|
||||
|
||||
+2
-7
@@ -12,10 +12,7 @@ import { resolveSectionDisplay } from './MobileMenuContent.utils'
|
||||
import { getProductMenuComponent } from './mobileProductMenuRegistry'
|
||||
import { TopLevelRouteItem } from './TopLevelRouteItem'
|
||||
import { routeHasSubmenu, useMobileMenuNavigation } from './useMobileMenuNavigation'
|
||||
import {
|
||||
useIsAPIDocsSidePanelEnabled,
|
||||
useUnifiedLogsPreview,
|
||||
} from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
|
||||
import { useUnifiedLogsPreview } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
|
||||
import { ICON_SIZE, ICON_STROKE_WIDTH } from '@/components/interfaces/Sidebar'
|
||||
import {
|
||||
generateOtherRoutes,
|
||||
@@ -67,7 +64,6 @@ export function MobileMenuContent({
|
||||
])
|
||||
const authOverviewPageEnabled = useFlag('authOverviewPage')
|
||||
const showReports = useIsFeatureEnabled('reports:all')
|
||||
const isNewAPIDocsEnabled = useIsAPIDocsSidePanelEnabled()
|
||||
const { isEnabled: isUnifiedLogsEnabled } = useUnifiedLogsPreview()
|
||||
|
||||
const toolRoutes = useMemo(() => generateToolRoutes(ref, project), [ref, project])
|
||||
@@ -95,9 +91,8 @@ export function MobileMenuContent({
|
||||
generateOtherRoutes(ref, project, {
|
||||
unifiedLogs: isUnifiedLogsEnabled,
|
||||
showReports,
|
||||
apiDocsSidePanel: isNewAPIDocsEnabled,
|
||||
}),
|
||||
[ref, project, isUnifiedLogsEnabled, showReports, isNewAPIDocsEnabled]
|
||||
[ref, project, isUnifiedLogsEnabled, showReports]
|
||||
)
|
||||
const settingsRoutes = useMemo(() => generateSettingsRoutes(ref), [ref])
|
||||
|
||||
|
||||
@@ -9,9 +9,11 @@ import { useAppStateSnapshot } from '@/state/app-state'
|
||||
interface APIDocsButtonProps {
|
||||
section?: string[]
|
||||
source: string
|
||||
label?: string
|
||||
tooltip?: string
|
||||
}
|
||||
|
||||
export const APIDocsButton = ({ section, source }: APIDocsButtonProps) => {
|
||||
export const APIDocsButton = ({ section, source, label, tooltip }: APIDocsButtonProps) => {
|
||||
const snap = useAppStateSnapshot()
|
||||
const { ref } = useParams()
|
||||
const { data: org } = useSelectedOrganizationQuery()
|
||||
@@ -37,13 +39,15 @@ export const APIDocsButton = ({ section, source }: APIDocsButtonProps) => {
|
||||
})
|
||||
}}
|
||||
icon={<BookOpenText />}
|
||||
className="w-7"
|
||||
className={label ? undefined : 'w-7'}
|
||||
tooltip={{
|
||||
content: {
|
||||
side: 'bottom',
|
||||
text: 'API Docs',
|
||||
text: tooltip ?? 'API Docs',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
>
|
||||
{label}
|
||||
</ButtonTooltip>
|
||||
)
|
||||
}
|
||||
@@ -15,7 +15,6 @@ export const LOCAL_STORAGE_KEYS = {
|
||||
MAINTENANCE_BANNER_DISMISSED: (id: string) => `maintenance-banner-dismissed-${id}`,
|
||||
DASHBOARD_PREFERENCES: (ref: string) => `dashboard-preferences-${ref}`,
|
||||
|
||||
UI_PREVIEW_API_SIDE_PANEL: 'supabase-ui-api-side-panel',
|
||||
UI_PREVIEW_CLS: 'supabase-ui-cls',
|
||||
UI_PREVIEW_INLINE_EDITOR: 'supabase-ui-preview-inline-editor',
|
||||
UI_PREVIEW_UNIFIED_LOGS: 'supabase-ui-preview-unified-logs',
|
||||
@@ -153,7 +152,6 @@ const LOCAL_STORAGE_KEYS_ALLOWLIST = [
|
||||
'supabase.dashboard.auth.debug',
|
||||
'supabase.dashboard.auth.navigatorLock.disabled',
|
||||
LOCAL_STORAGE_KEYS.TELEMETRY_CONSENT,
|
||||
LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL,
|
||||
LOCAL_STORAGE_KEYS.UI_PREVIEW_INLINE_EDITOR,
|
||||
LOCAL_STORAGE_KEYS.UI_PREVIEW_QUEUE_OPERATIONS,
|
||||
LOCAL_STORAGE_KEYS.UI_PREVIEW_CLS,
|
||||
|
||||
Reference in new issue
Block a user