Expose Shadcnui toast components from UI and partially implement in storage explorer (#21308)

* Expose Shadcnui toast components from UI and partially implement in storage explorer

* Fix
This commit is contained in:
Joshen Lim authored and GitHub committed 2024-02-26 16:59:49 +08:00
1 parent d8ae6de7a8
commit 72d00070f3
6 files changed
+31 -40

No files matched your search

@@ -6,9 +6,13 @@ import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuSeparator,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
IconCheck,
IconChevronLeft,
IconChevronRight,
IconColumns,
@@ -21,18 +25,14 @@ import {
IconUpload,
IconX,
Input,
IconCheck,
DropdownMenuSub,
DropdownMenuSubTrigger,
DropdownMenuSubContent,
} from 'ui'
import { useIsAPIDocsSidePanelEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import APIDocsButton from 'components/ui/APIDocsButton'
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 APIDocsButton from 'components/ui/APIDocsButton'
import { useIsAPIDocsSidePanelEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
const VIEW_OPTIONS = [
{ key: STORAGE_VIEWS.COLUMNS, name: 'As columns' },
@@ -5,6 +5,7 @@ import { BlobReader, BlobWriter, ZipWriter } from '@zip.js/zip.js'
import { chunk, compact, find, findIndex, has, isEqual, some, uniq, uniqBy } from 'lodash'
import { makeAutoObservable } from 'mobx'
import toast from 'react-hot-toast'
import { toast as UiToast } from 'ui'
import {
STORAGE_ROW_STATUS,
@@ -283,22 +284,13 @@ class StorageExplorerStore {
if (formattedName === null) return
if (!/^[a-zA-Z0-9_-\s]*$/.test(formattedName)) {
return this.ui.setNotification({
message: 'Folder name contains invalid special characters',
category: 'error',
duration: 8000,
})
}
/**
* todo: move this to a util file, as renameFolder() uses same logic
*/
if (formattedName.includes('/') || formattedName.includes('\\')) {
return this.ui.setNotification({
message: 'Folder names should not have forward or back slashes.',
category: 'error',
duration: 8000,
return UiToast({
variant: 'destructive',
description: 'Folder name contains invalid special characters',
duration: 6000,
})
}
if (formattedName.length === 0) {
return this.removeTempRows(columnIndex)
}
@@ -425,10 +417,7 @@ class StorageExplorerStore {
// https://stackoverflow.com/a/53058574
getFilesDataTransferItems = async (items) => {
const toastId = this.ui.setNotification({
category: 'loading',
message: 'Retrieving items to upload...',
})
const { dismiss } = UiToast({ description: 'Retrieving items to upload...' })
const files = []
const queue = []
for (const item of items) {
@@ -446,7 +435,7 @@ class StorageExplorerStore {
queue.push(...(await this.readAllDirectoryEntries(entry.createReader())))
}
}
toast.dismiss(toastId)
dismiss()
return files
}
@@ -663,7 +652,8 @@ class StorageExplorerStore {
let numberOfFilesMovedFail = 0
this.clearSelectedItems()
const infoToastId = toast('Please do not close the browser until the move is completed', {
const { dismiss } = UiToast({
description: 'Please do not close the browser until the move is completed',
duration: Infinity,
})
@@ -690,20 +680,16 @@ class StorageExplorerStore {
)
if (numberOfFilesMovedFail === this.selectedItemsToMove.length) {
this.ui.setNotification({
message: 'Failed to move files',
category: 'error',
})
UiToast({ variant: 'destructive', description: 'Failed to move files' })
} else {
this.ui.setNotification({
message: `Successfully moved ${
UiToast({
description: `Successfully moved ${
this.selectedItemsToMove.length - numberOfFilesMovedFail
} to ${formattedNewPathToFile}`,
category: 'success',
} files to ${formattedNewPathToFile.length > 0 ? formattedNewPathToFile : 'the root of your bucket'}`,
})
}
toast.dismiss(infoToastId)
dismiss()
// Clear file preview cache if moved files exist in cache
const idsOfItemsToMove = this.selectedItemsToMove.map((item) => item.id)
+2
View File
@@ -59,6 +59,7 @@ import { useAppStateSnapshot } from 'state/app-state'
import { RootStore } from 'stores'
import HCaptchaLoadedStore from 'stores/hcaptcha-loaded-store'
import { AppPropsWithLayout } from 'types'
import { Toaster } from 'ui'
dayjs.extend(customParseFormat)
dayjs.extend(utc)
@@ -182,6 +183,7 @@ function CustomApp({ Component, pageProps }: AppPropsWithLayout) {
</PageTelemetry>
<HCaptchaLoadedStore />
<Toaster />
<PortalToast />
{!isTestEnv && <ReactQueryDevtools initialIsOpen={false} position="bottom-right" />}
</FlagProvider>
+3
View File
@@ -81,6 +81,9 @@ export * from './src/components/ThemeProvider/prefixedThemes'
// shadcn
export * from './src/components/shadcn/ui/dropdown-menu'
export * from './src/components/shadcn/ui/use-toast'
export * from './src/components/shadcn/ui/toast'
export * from './src/components/shadcn/ui/toaster'
export {
Command as Command_Shadcn_,
@@ -14,7 +14,7 @@ const ToastViewport = React.forwardRef<
<ToastPrimitives.Viewport
ref={ref}
className={cn(
'fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]',
'fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse gap-y-2 p-4 sm:right-0 sm:flex-col md:max-w-[420px]',
className
)}
{...props}
@@ -23,13 +23,13 @@ const ToastViewport = React.forwardRef<
ToastViewport.displayName = ToastPrimitives.Viewport.displayName
const toastVariants = cva(
'data-[swipe=move]:transition-none group relative pointer-events-auto flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full data-[state=closed]:slide-out-to-right-full',
'data-[swipe=move]:transition-none group relative pointer-events-auto flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-top-full data-[state=closed]:slide-out-to-right-full',
{
variants: {
variant: {
default: 'bg-background border',
destructive:
'group destructive border-destructive bg-destructive text-destructive-foreground',
'group destructive border-destructive-400 bg-destructive-300 text-destructive-foreground',
},
},
defaultVariants: {
@@ -3,7 +3,7 @@ import * as React from 'react'
import { ToastActionElement, ToastProps } from './toast'
const TOAST_LIMIT = 1
const TOAST_LIMIT = 4
const TOAST_REMOVE_DELAY = 1000000
type ToasterToast = ToastProps & {