Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/hooks/use-quick-actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const removeByValue = (items: Items, toRemove: Items) => {
return items.filter((i) => !valuesToRemove.has(i.value))
}

const useStore = create<StoreState>((set) => ({
const useStore = create<StoreState>()((set) => ({
items: [],
add: (toAdd) =>
set(({ items }) => ({ items: removeByValue(items, toAdd).concat(toAdd) })),
Expand Down
13 changes: 6 additions & 7 deletions app/hooks/use-toast/ToastStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@ import { animated, useTransition } from '@react-spring/web'

import { Toast } from '@oxide/ui'

import type { Toast as ToastModel } from './types'
import { useToastStore } from './index'

interface ToastStackProps {
toasts: ToastModel[]
onRemoveToast: (id: string) => void
}
export function ToastStack() {
const toasts = useToastStore((state) => state.toasts)
const remove = useToastStore((state) => state.remove)

export const ToastStack = ({ toasts, onRemoveToast }: ToastStackProps) => {
const transition = useTransition(toasts, {
keys: (toast) => toast.id,
from: { opacity: 0, y: 10, scale: 95 },
enter: { opacity: 1, y: 0, scale: 100 },
leave: { opacity: 0, y: 10, scale: 95 },
config: { duration: 100 },
})

return (
Expand All @@ -31,7 +30,7 @@ export const ToastStack = ({ toasts, onRemoveToast }: ToastStackProps) => {
key={item.id}
{...item.options}
onClose={() => {
onRemoveToast(item.id)
remove(item.id)
item.options.onClose?.()
}}
/>
Expand Down
42 changes: 17 additions & 25 deletions app/hooks/use-toast/index.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,23 @@
import type { FC } from 'react'
import { createContext, useContext, useState } from 'react'
import { v4 as uuid } from 'uuid'
import create from 'zustand'

import { ToastStack } from './ToastStack'
import type { Toast } from './types'
import type { ToastProps } from '@oxide/ui'

type AddToast = (options: Toast['options']) => void

const ToastContext = createContext<AddToast>(() => {})

export const useToast = () => useContext(ToastContext)

export const ToastProvider: FC = ({ children }) => {
const [toasts, setToasts] = useState<Toast[]>([])
type Toast = {
id: string
options: Optional<ToastProps, 'onClose'>
}

const addToast: AddToast = (options) => {
setToasts((toasts) => [...toasts, { id: uuid(), options }])
}
type StoreState = {
toasts: Toast[]
add: (options: Toast['options']) => void
remove: (id: Toast['id']) => void
}

const removeToast = (id: string) => {
setToasts((toasts) => toasts.filter((t) => t.id !== id))
}
export const useToastStore = create<StoreState>()((set) => ({
toasts: [],
add: (options) => set(({ toasts }) => ({ toasts: [...toasts, { id: uuid(), options }] })),
remove: (id) => set(({ toasts }) => ({ toasts: toasts.filter((t) => t.id !== id) })),
}))

return (
<ToastContext.Provider value={addToast}>
{children}
<ToastStack toasts={toasts} onRemoveToast={removeToast} />
</ToastContext.Provider>
)
}
export const useToast = () => useToastStore(({ add }) => add)
6 changes: 0 additions & 6 deletions app/hooks/use-toast/types.ts

This file was deleted.

22 changes: 11 additions & 11 deletions app/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import ReactDOM from 'react-dom'
import { SkipLink } from '@oxide/ui'

import { ErrorBoundary } from './components/ErrorBoundary'
import { QuickActions, ReduceMotion, ToastProvider } from './hooks'
import { QuickActions, ReduceMotion } from './hooks'
import { ToastStack } from './hooks/use-toast/ToastStack'
import { Router } from './routes'

if (process.env.SHA) {
Expand All @@ -28,16 +29,15 @@ const queryClient = new QueryClient({
function render() {
ReactDOM.render(
<StrictMode>
<ToastProvider>
<QueryClientProvider client={queryClient}>
<ErrorBoundary>
<QuickActions />
<SkipLink id="skip-nav" />
<ReduceMotion />
<Router />
</ErrorBoundary>
</QueryClientProvider>
</ToastProvider>
<QueryClientProvider client={queryClient}>
<ErrorBoundary>
<QuickActions />
<SkipLink id="skip-nav" />
<ReduceMotion />
<Router />
</ErrorBoundary>
</QueryClientProvider>
<ToastStack />
</StrictMode>,
document.getElementById('root')
)
Expand Down
2 changes: 0 additions & 2 deletions app/pages/__tests__/instance/networking.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,5 @@ test('Instance networking tab', async ({ page }) => {
.locator('role=button[name="Row actions"]')
.click()
await page.click('role=menuitem[name="Delete"]')
// Close toast, it holds up the test for some reason
await page.click('role=button[name="Dismiss notification"]')
await expectNotVisible(page, ['role=cell[name="nic-3"]'])
})
2 changes: 0 additions & 2 deletions app/pages/__tests__/instance/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,4 @@ import type { Page } from '@playwright/test'
export async function stopInstance(page: Page) {
await page.click('role=button[name="Instance actions"]')
await page.click('role=menuitem[name="Stop"]')
// Close toast, it holds up the test for some reason
await page.click('role=button[name="Dismiss notification"]')
}
6 changes: 1 addition & 5 deletions app/pages/project/disks/DisksPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,7 @@ export function DisksPage({ modal }: DisksPageProps) {

const queryClient = useApiQueryClient()
const { orgName, projectName } = useParams('orgName', 'projectName')
const { Table, Column } = useQueryTable(
'diskList',
{ orgName, projectName },
{ refetchInterval: 5000 }
)
const { Table, Column } = useQueryTable('diskList', { orgName, projectName })

const deleteDisk = useApiMutation('diskDelete', {
onSuccess() {
Expand Down
4 changes: 1 addition & 3 deletions app/pages/project/instances/instance/InstancePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ export const InstancePage = () => {
onDelete: () => navigate('..'),
})

const { data: instance } = useApiQuery('instanceView', instanceParams, {
refetchInterval: 5000,
})
const { data: instance } = useApiQuery('instanceView', instanceParams)
const actions = useMemo(
() => (instance ? makeActions(instance) : []),
[instance, makeActions]
Expand Down
4 changes: 1 addition & 3 deletions app/pages/project/instances/instance/tabs/StorageTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ export function StorageTab() {
const queryClient = useApiQueryClient()
const instanceParams = useParams('orgName', 'projectName', 'instanceName')

const { data } = useApiQuery('instanceDiskList', instanceParams, {
refetchInterval: 5000,
})
const { data } = useApiQuery('instanceDiskList', instanceParams)

const detachDisk = useApiMutation('instanceDiskDetach', {})

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"xterm": "^4.18.0",
"xterm-addon-fit": "^0.5.0",
"yup": "^0.32.11",
"zustand": "^3.7.1"
"zustand": "^4.0.0"
},
"devDependencies": {
"@babel/core": "^7.18.9",
Expand Down
1 change: 0 additions & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const config: PlaywrightTestConfig = {
workers: process.env.CI ? 1 : undefined,
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 10000,
baseURL: 'http://localhost:4009',
trace: 'on-first-retry',
},
Expand Down
11 changes: 9 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15249,7 +15249,7 @@ use-sidecar@^1.0.1, use-sidecar@^1.0.5:
detect-node-es "^1.1.0"
tslib "^1.9.3"

use-sync-external-store@^1.2.0:
use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
Expand Down Expand Up @@ -15948,11 +15948,18 @@ yup@^0.32.11:
property-expr "^2.0.4"
toposort "^2.0.2"

zustand@^3.6.9, zustand@^3.7.1:
zustand@^3.6.9:
version "3.7.1"
resolved "https://registry.yarnpkg.com/zustand/-/zustand-3.7.1.tgz#7388f0a7175a6c2fd9a2880b383a4bf6cdf6b7c6"
integrity sha512-wHBCZlKj+bg03/hP+Tzv24YhnqqP8MCeN9ECPDXoF01062SIbnfl3j9O0znkDw1lNTY0a8WN3F///a0UhhaEqg==

zustand@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.0.0.tgz#739cba69209ffe67b31e7d6741c25b51496114a7"
integrity sha512-OrsfQTnRXF1LZ9/vR/IqN9ws5EXUhb149xmPjErZnUrkgxS/gAHGy2dPNIVkVvoxrVe1sIydn4JjF0dYHmGeeQ==
dependencies:
use-sync-external-store "1.2.0"

zwitch@^1.0.0:
version "1.0.5"
resolved "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz"
Expand Down