Skip to content

Commit

Permalink
Merge branch 'main' into improve-external-ips-row
Browse files Browse the repository at this point in the history
  • Loading branch information
charliepark committed Jan 10, 2025
2 parents 1f49abe + a629300 commit 731d43b
Show file tree
Hide file tree
Showing 31 changed files with 501 additions and 516 deletions.
13 changes: 11 additions & 2 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ module.exports = {
'import/no-default-export': 'error',
'import/no-unresolved': 'off', // plugin doesn't know anything
'jsx-a11y/label-has-associated-control': [2, { controlComponents: ['button'] }],
// only worry about console.log
'no-console': ['error', { allow: ['warn', 'error', 'info', 'table'] }],
'no-param-reassign': 'error',
'no-restricted-imports': [
'error',
Expand Down Expand Up @@ -112,11 +114,18 @@ module.exports = {
},
{
files: ['*.e2e.ts'],
extends: ['plugin:playwright/playwright-test'],
extends: ['plugin:playwright/recommended'],
rules: {
'playwright/expect-expect': [
'warn',
{ assertFunctionNames: ['expectVisible', 'expectRowVisible', 'expectOptions'] },
{
assertFunctionNames: [
'expectVisible',
'expectRowVisible',
'expectOptions',
'expectRowMenuStaysOpen',
],
},
],
'playwright/no-force-option': 'off',
},
Expand Down
30 changes: 0 additions & 30 deletions .github/workflows/reformatter.yaml

This file was deleted.

5 changes: 4 additions & 1 deletion .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"plugins": ["react", "react-hooks", "unicorn", "typescript", "oxc"],
"rules": {
"react-hooks/exhaustive-deps": "error",
// only worry about console.log
"no-console": ["error", { "allow": ["warn", "error", "info", "table"] }],
// turning this off because it's more sensitive than eslint currently
// "react-hooks/rules-of-hooks": "error",
"no-unused-vars": [
Expand All @@ -13,5 +15,6 @@
"caughtErrorsIgnorePattern": "^_"
}
]
}
},
"ignorePatterns": ["dist/", "node_modules/"]
}
2 changes: 1 addition & 1 deletion app/api/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ export const wrapQueryClient = <A extends ApiClient>(api: A, queryClient: QueryC
// directly without further processing
throw data
}
console.log(options.explanation)
console.info(options.explanation)
return { type: 'error' as const, data }
}),
...options,
Expand Down
2 changes: 1 addition & 1 deletion app/api/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function handleResult<T>(result: ApiResult<T>): T {
}

function logHeading(s: string) {
console.log(`%c${s}`, 'font-size: 16px; font-weight: bold;')
console.info(`%c${s}`, 'font-size: 16px; font-weight: bold;')
}

if (typeof window !== 'undefined') {
Expand Down
3 changes: 1 addition & 2 deletions app/components/RoundedSector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
*
* Copyright Oxide Computer Company
*/
import { useReducedMotion } from 'motion/react'
import { useEffect, useMemo, useState } from 'react'

import { useReducedMotion } from '~/hooks/use-reduce-motion'

export function RoundedSector({
angle,
size,
Expand Down
48 changes: 21 additions & 27 deletions app/components/ToastStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,39 @@
*
* Copyright Oxide Computer Company
*/
import { animated, useTransition } from '@react-spring/web'
import { AnimatePresence } from 'motion/react'
import * as m from 'motion/react-m'

import { removeToast, useToastStore } from '~/stores/toast'
import { Toast } from '~/ui/lib/Toast'

export function ToastStack() {
const toasts = useToastStore((state) => state.toasts)

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 (
<div
className="pointer-events-auto fixed bottom-4 left-4 z-toast flex flex-col items-end space-y-2"
data-testid="Toasts"
>
{transition((style, item) => (
<animated.div
style={{
opacity: style.opacity,
y: style.y,
transform: style.scale.to((val) => `scale(${val}%, ${val}%)`),
}}
>
<Toast
key={item.id}
{...item.options}
onClose={() => {
removeToast(item.id)
item.options.onClose?.()
}}
/>
</animated.div>
))}
<AnimatePresence>
{toasts.map((toast) => (
<m.div
key={toast.id}
initial={{ opacity: 0, y: 20, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, y: 20, scale: 0.95 }}
transition={{ type: 'spring', duration: 0.2, bounce: 0 }}
>
<Toast
{...toast.options}
onClose={() => {
removeToast(toast.id)
toast.options.onClose?.()
}}
/>
</m.div>
))}
</AnimatePresence>
</div>
)
}
2 changes: 1 addition & 1 deletion app/forms/image-upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ export function Component() {
.catch((e) => {
// eat a 404 since that's what we want. anything else should still blow up
if (e.statusCode === 404) {
console.log(
console.info(
'/v1/images 404 is expected. It means the image name is not taken.'
)
return null
Expand Down
38 changes: 0 additions & 38 deletions app/hooks/use-reduce-motion.tsx

This file was deleted.

19 changes: 12 additions & 7 deletions app/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Copyright Oxide Computer Company
*/
import { QueryClientProvider } from '@tanstack/react-query'
import { LazyMotion, MotionConfig } from 'motion/react'
// import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
Expand All @@ -16,7 +17,6 @@ import { queryClient } from '@oxide/api'

import { ConfirmActionModal } from './components/ConfirmActionModal'
import { ErrorBoundary } from './components/ErrorBoundary'
import { ReduceMotion } from './hooks/use-reduce-motion'
// stripped out by rollup in production
import { startMockAPI } from './msw-mock-api'
import { routes } from './routes'
Expand All @@ -33,6 +33,8 @@ if (process.env.SHA) {
)
}

const loadFeatures = () => import('./util/motion-features').then((res) => res.domAnimation)

const root = createRoot(document.getElementById('root')!)

function render() {
Expand All @@ -46,12 +48,15 @@ function render() {
root.render(
<StrictMode>
<QueryClientProvider client={queryClient}>
<ErrorBoundary>
<ConfirmActionModal />
<SkipLink id="skip-nav" />
<ReduceMotion />
<RouterProvider router={router} />
</ErrorBoundary>
<LazyMotion strict features={loadFeatures}>
<MotionConfig reducedMotion="user">
<ErrorBoundary>
<ConfirmActionModal />
<SkipLink id="skip-nav" />
<RouterProvider router={router} />
</ErrorBoundary>
</MotionConfig>
</LazyMotion>
{/* <ReactQueryDevtools initialIsOpen={false} /> */}
</QueryClientProvider>
</StrictMode>
Expand Down
4 changes: 2 additions & 2 deletions app/msw-mock-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function getChaos() {
const chaos = getChaos()

if (process.env.NODE_ENV !== 'production' && chaos) {
console.log(`
console.info(`
▄████████ ▄█ █▄ ▄████████ ▄██████▄ ▄████████
███ ███ ███ ███ ███ ███ ███ ███ ███ ███
███ █▀ ███ ███ ███ ███ ███ ███ ███ █▀
Expand All @@ -34,7 +34,7 @@ if (process.env.NODE_ENV !== 'production' && chaos) {
███ ███ ███ ███ ███ ███ ▄███ ███ ███
▀█ ███ █▀ ▀██████▀ ████████▀ ██████████
`)
console.log(`Running MSW in CHAOS MODE with ${chaos}% likelihood of random failure`)
console.info(`Running MSW in CHAOS MODE with ${chaos}% likelihood of random failure`)
}

/** Return true for failure with a given likelihood */
Expand Down
45 changes: 21 additions & 24 deletions app/table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,27 @@ export const Table = <TData,>({
}: TableProps<TData>) => (
<UITable {...tableProps}>
<UITable.Header>
{table.getHeaderGroups().map((headerGroup) => {
console.log(headerGroup)
return (
<UITable.HeaderRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<UITable.HeadCell
key={header.id}
className={header.column.columnDef.meta?.thClassName}
colSpan={header.colSpan}
>
{
// Placeholder concept is for when grouped columns are
// combined with regular columns. The regular column only
// needs one entry in the stack of header cells, so the others
// have isPlacholder=true. See sleds table for an example.
header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())
}
</UITable.HeadCell>
))}
</UITable.HeaderRow>
)
})}
{table.getHeaderGroups().map((headerGroup) => (
<UITable.HeaderRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<UITable.HeadCell
key={header.id}
className={header.column.columnDef.meta?.thClassName}
colSpan={header.colSpan}
>
{
// Placeholder concept is for when grouped columns are
// combined with regular columns. The regular column only
// needs one entry in the stack of header cells, so the others
// have isPlacholder=true. See sleds table for an example.
header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())
}
</UITable.HeadCell>
))}
</UITable.HeaderRow>
))}
</UITable.Header>
<UITable.Body>
{table.getRowModel().rows.map((row) => {
Expand Down
34 changes: 28 additions & 6 deletions app/ui/lib/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Copyright Oxide Computer Company
*/
import cn from 'classnames'
import * as m from 'motion/react-m'
import { forwardRef, type MouseEventHandler, type ReactNode } from 'react'

import { Spinner } from '~/ui/lib/Spinner'
Expand Down Expand Up @@ -90,9 +91,14 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
with={<Tooltip content={disabledReason} ref={ref} placement="bottom" />}
>
<button
className={cn(buttonStyle({ size, variant }), className, {
'visually-disabled': isDisabled,
})}
className={cn(
buttonStyle({ size, variant }),
className,
{
'visually-disabled': isDisabled,
},
'overflow-hidden'
)}
ref={ref}
/* eslint-disable-next-line react/button-has-type */
type={type}
Expand All @@ -101,10 +107,26 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
aria-disabled={isDisabled}
{...rest}
>
{loading && <Spinner className="absolute" variant={variant} />}
<span className={cn('flex items-center', innerClassName, { invisible: loading })}>
{loading && (
<m.span
animate={{ opacity: 1, y: '-50%', x: '-50%' }}
initial={{ opacity: 0, y: 'calc(-50% - 25px)', x: '-50%' }}
transition={{ type: 'spring', duration: 0.3, bounce: 0 }}
className="absolute left-1/2 top-1/2"
>
<Spinner variant={variant} />
</m.span>
)}
<m.span
className={cn('flex items-center', innerClassName)}
animate={{
opacity: loading ? 0 : 1,
y: loading ? 25 : 0,
}}
transition={{ type: 'spring', duration: 0.3, bounce: 0 }}
>
{children}
</span>
</m.span>
</button>
</Wrap>
)
Expand Down
Loading

0 comments on commit 731d43b

Please sign in to comment.