Skip to content

Commit

Permalink
Adjust Refresh Interval in Assets table (#10775)
Browse files Browse the repository at this point in the history
(cherry picked from commit 77183e5)
  • Loading branch information
MrFlashAccount authored and jdunkerley committed Sep 10, 2024
1 parent 2dfd523 commit 1b95ea4
Show file tree
Hide file tree
Showing 45 changed files with 1,689 additions and 1,838 deletions.
47 changes: 27 additions & 20 deletions app/dashboard/e2e/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,24 +504,21 @@ async function mockApiInternal({ page, setupAPI }: MockParams) {
(a, b) => backend.ASSET_TYPE_ORDER[a.type] - backend.ASSET_TYPE_ORDER[b.type],
)
const json: remoteBackend.ListDirectoryResponseBody = { assets: filteredAssets }

return json
})
await get(
remoteBackendPaths.LIST_FILES_PATH + '*',
() => ({ files: [] }) satisfies remoteBackend.ListFilesResponseBody,
)
await get(
remoteBackendPaths.LIST_PROJECTS_PATH + '*',
() => ({ projects: [] }) satisfies remoteBackend.ListProjectsResponseBody,
)
await get(
remoteBackendPaths.LIST_SECRETS_PATH + '*',
() => ({ secrets: [] }) satisfies remoteBackend.ListSecretsResponseBody,
)
await get(
remoteBackendPaths.LIST_TAGS_PATH + '*',
() => ({ tags: labels }) satisfies remoteBackend.ListTagsResponseBody,
)
await get(remoteBackendPaths.LIST_FILES_PATH + '*', () => {
return { files: [] } satisfies remoteBackend.ListFilesResponseBody
})
await get(remoteBackendPaths.LIST_PROJECTS_PATH + '*', () => {
return { projects: [] } satisfies remoteBackend.ListProjectsResponseBody
})
await get(remoteBackendPaths.LIST_SECRETS_PATH + '*', () => {
return { secrets: [] } satisfies remoteBackend.ListSecretsResponseBody
})
await get(remoteBackendPaths.LIST_TAGS_PATH + '*', () => {
return { tags: labels } satisfies remoteBackend.ListTagsResponseBody
})
await get(remoteBackendPaths.LIST_USERS_PATH + '*', async (route) => {
if (currentUser != null) {
return { users } satisfies remoteBackend.ListUsersResponseBody
Expand Down Expand Up @@ -584,6 +581,7 @@ async function mockApiInternal({ page, setupAPI }: MockParams) {
interface Body {
readonly parentDirectoryId: backend.DirectoryId
}

const assetId = request.url().match(/[/]assets[/]([^?/]+)/)?.[1]
// eslint-disable-next-line no-restricted-syntax
const asset = assetId != null ? assetMap.get(assetId as backend.AssetId) : null
Expand All @@ -605,7 +603,7 @@ async function mockApiInternal({ page, setupAPI }: MockParams) {
const body: Body = await request.postDataJSON()
const parentId = body.parentDirectoryId
// Can be any asset ID.
const id = backend.DirectoryId(uniqueString.uniqueString())
const id = backend.DirectoryId(`directory-${uniqueString.uniqueString()}`)
const json: backend.CopyAssetResponse = {
asset: {
id,
Expand All @@ -621,6 +619,7 @@ async function mockApiInternal({ page, setupAPI }: MockParams) {
await route.fulfill({ json })
}
})

await get(remoteBackendPaths.INVITATION_PATH + '*', async (route) => {
await route.fulfill({
json: { invitations: [] } satisfies backend.ListInvitationsResponseBody,
Expand Down Expand Up @@ -695,15 +694,17 @@ async function mockApiInternal({ page, setupAPI }: MockParams) {
const searchParams: SearchParams = Object.fromEntries(
new URL(request.url()).searchParams.entries(),
) as never
const file = createFile(searchParams.file_name)

const file = addFile(searchParams.file_name)

return { path: '', id: file.id, project: null } satisfies backend.FileInfo
})

await post(remoteBackendPaths.CREATE_SECRET_PATH + '*', async (_route, request) => {
// The type of the body sent by this app is statically known.
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const body: backend.CreateSecretRequestBody = await request.postDataJSON()
const secret = createSecret(body.name)
const secret = addSecret(body.name)
return secret.id
})

Expand All @@ -721,6 +722,10 @@ async function mockApiInternal({ page, setupAPI }: MockParams) {
if (body.description != null) {
object.unsafeMutable(asset).description = body.description
}

if (body.parentDirectoryId != null) {
object.unsafeMutable(asset).parentId = body.parentDirectoryId
}
}
})
await patch(remoteBackendPaths.associateTagPath(GLOB_ASSET_ID), async (_route, request) => {
Expand Down Expand Up @@ -813,7 +818,9 @@ async function mockApiInternal({ page, setupAPI }: MockParams) {
currentUser = { ...currentUser, name: body.username }
}
})
await get(remoteBackendPaths.USERS_ME_PATH + '*', () => currentUser)
await get(remoteBackendPaths.USERS_ME_PATH + '*', () => {
return currentUser
})
await patch(remoteBackendPaths.UPDATE_ORGANIZATION_PATH + '*', async (route, request) => {
// The type of the body sent by this app is statically known.
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
Expand Down
20 changes: 10 additions & 10 deletions app/dashboard/e2e/copy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ test.test('copy', ({ page }) =>
.driveTable.withRows(async (rows) => {
await test.expect(rows).toHaveCount(3)
await test.expect(rows.nth(2)).toBeVisible()
await test.expect(rows.nth(2)).toHaveText(/^New Folder 2 [(]copy[)]/)
await test.expect(rows.nth(2)).toHaveText(/^New Folder 1 [(]copy[)]*/)
const parentLeft = await actions.getAssetRowLeftPx(rows.nth(1))
const childLeft = await actions.getAssetRowLeftPx(rows.nth(2))
test.expect(childLeft, 'child is indented further than parent').toBeGreaterThan(parentLeft)
Expand All @@ -46,7 +46,7 @@ test.test('copy (keyboard)', ({ page }) =>
.driveTable.withRows(async (rows) => {
await test.expect(rows).toHaveCount(3)
await test.expect(rows.nth(2)).toBeVisible()
await test.expect(rows.nth(2)).toHaveText(/^New Folder 2 [(]copy[)]/)
await test.expect(rows.nth(2)).toHaveText(/^New Folder 1 [(]copy[)]*/)
const parentLeft = await actions.getAssetRowLeftPx(rows.nth(1))
const childLeft = await actions.getAssetRowLeftPx(rows.nth(2))
test.expect(childLeft, 'child is indented further than parent').toBeGreaterThan(parentLeft)
Expand All @@ -69,7 +69,7 @@ test.test('move', ({ page }) =>
.driveTable.withRows(async (rows) => {
await test.expect(rows).toHaveCount(2)
await test.expect(rows.nth(1)).toBeVisible()
await test.expect(rows.nth(1)).toHaveText(/^New Folder 2/)
await test.expect(rows.nth(1)).toHaveText(/^New Folder 1/)
const parentLeft = await actions.getAssetRowLeftPx(rows.nth(0))
const childLeft = await actions.getAssetRowLeftPx(rows.nth(1))
test.expect(childLeft, 'child is indented further than parent').toBeGreaterThan(parentLeft)
Expand All @@ -88,7 +88,7 @@ test.test('move (drag)', ({ page }) =>
.driveTable.withRows(async (rows) => {
await test.expect(rows).toHaveCount(2)
await test.expect(rows.nth(1)).toBeVisible()
await test.expect(rows.nth(1)).toHaveText(/^New Folder 2/)
await test.expect(rows.nth(1)).toHaveText(/^New Folder 1/)
const parentLeft = await actions.getAssetRowLeftPx(rows.nth(0))
const childLeft = await actions.getAssetRowLeftPx(rows.nth(1))
test.expect(childLeft, 'child is indented further than parent').toBeGreaterThan(parentLeft)
Expand Down Expand Up @@ -129,7 +129,7 @@ test.test('move (keyboard)', ({ page }) =>
.driveTable.withRows(async (rows) => {
await test.expect(rows).toHaveCount(2)
await test.expect(rows.nth(1)).toBeVisible()
await test.expect(rows.nth(1)).toHaveText(/^New Folder 2/)
await test.expect(rows.nth(1)).toHaveText(/^New Folder 1/)
const parentLeft = await actions.getAssetRowLeftPx(rows.nth(0))
const childLeft = await actions.getAssetRowLeftPx(rows.nth(1))
test.expect(childLeft, 'child is indented further than parent').toBeGreaterThan(parentLeft)
Expand Down Expand Up @@ -164,11 +164,11 @@ test.test('duplicate', ({ page }) =>
.driveTable.rightClickRow(0)
.contextMenu.duplicate()
.driveTable.withRows(async (rows) => {
// Assets: [0: New Project 1 (copy), 1: New Project 1]
// Assets: [0: New Project 1, 1: New Project 1 (copy)]
await test.expect(rows).toHaveCount(2)
await test.expect(actions.locateContextMenus(page)).not.toBeVisible()
await test.expect(rows.nth(0)).toBeVisible()
await test.expect(rows.nth(0)).toHaveText(/^New Project 1 [(]copy[)]/)
await test.expect(rows.nth(1)).toBeVisible()
await test.expect(rows.nth(1)).toHaveText(/^New Project 1 [(]copy[)]/)
}),
)

Expand All @@ -184,7 +184,7 @@ test.test('duplicate (keyboard)', ({ page }) =>
.driveTable.withRows(async (rows) => {
// Assets: [0: New Project 1 (copy), 1: New Project 1]
await test.expect(rows).toHaveCount(2)
await test.expect(rows.nth(0)).toBeVisible()
await test.expect(rows.nth(0)).toHaveText(/^New Project 1 [(]copy[)]/)
await test.expect(rows.nth(1)).toBeVisible()
await test.expect(rows.nth(1)).toHaveText(/^New Project 1 [(]copy[)]/)
}),
)
2 changes: 1 addition & 1 deletion app/dashboard/e2e/driveView.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ test.test('drive view', ({ page }) =>
// user that project creation may take a while. Previously opened projects are stopped when the
// new project is created.
.driveTable.withRows(async (rows) => {
await actions.locateStopProjectButton(rows.nth(0)).click()
await actions.locateStopProjectButton(rows.nth(1)).click()
})
// Project context menu
.driveTable.rightClickRow(0)
Expand Down
12 changes: 7 additions & 5 deletions app/dashboard/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import * as inputBindingsModule from '#/configurations/inputBindings'
import AuthProvider, * as authProvider from '#/providers/AuthProvider'
import BackendProvider, { useLocalBackend } from '#/providers/BackendProvider'
import DriveProvider from '#/providers/DriveProvider'
import DevtoolsProvider from '#/providers/EnsoDevtoolsProvider'
import { useHttpClient } from '#/providers/HttpClientProvider'
import InputBindingsProvider from '#/providers/InputBindingsProvider'
import LocalStorageProvider, * as localStorageProvider from '#/providers/LocalStorageProvider'
Expand Down Expand Up @@ -91,10 +90,11 @@ import * as appBaseUrl from '#/utilities/appBaseUrl'
import * as eventModule from '#/utilities/event'
import LocalStorage from '#/utilities/LocalStorage'
import * as object from '#/utilities/object'
import { Path } from '#/utilities/path'

import { useInitAuthService } from '#/authentication/service'
import { InvitedToOrganizationModal } from '#/modals/InvitedToOrganizationModal'
import { Path } from '#/utilities/path'
import { FeatureFlagsProvider } from '#/providers/FeatureFlagsProvider'

// ============================
// === Global configuration ===
Expand Down Expand Up @@ -492,7 +492,7 @@ function AppRouter(props: AppRouterProps) {
)

return (
<DevtoolsProvider>
<FeatureFlagsProvider>
<RouterProvider navigate={navigate}>
<SessionProvider
saveAccessToken={authService?.cognito.saveAccessToken.bind(authService.cognito) ?? null}
Expand All @@ -517,7 +517,9 @@ function AppRouter(props: AppRouterProps) {
{routes}
{detect.IS_DEV_MODE && (
<suspense.Suspense>
<devtools.EnsoDevtools />
<errorBoundary.ErrorBoundary>
<devtools.EnsoDevtools />
</errorBoundary.ErrorBoundary>
</suspense.Suspense>
)}
</errorBoundary.ErrorBoundary>
Expand All @@ -527,7 +529,7 @@ function AppRouter(props: AppRouterProps) {
</BackendProvider>
</SessionProvider>
</RouterProvider>
</DevtoolsProvider>
</FeatureFlagsProvider>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,76 @@ import * as modalProvider from '#/providers/ModalProvider'

import * as aria from '#/components/aria'

import type * as types from './types'
import { AnimatePresence, motion } from 'framer-motion'

const PLACEHOLDER = <div />

/**
* Props passed to the render function of a {@link DialogTrigger}.
*/
export interface DialogTriggerRenderProps {
readonly isOpened: boolean
}
/**
* Props for a {@link DialogTrigger}.
*/
export interface DialogTriggerProps extends types.DialogTriggerProps {}
export interface DialogTriggerProps extends Omit<aria.DialogTriggerProps, 'children'> {
/**
* The trigger element.
*/
readonly children: [
React.ReactElement,
React.ReactElement | ((props: DialogTriggerRenderProps) => React.ReactElement),
]
}

/** A DialogTrigger opens a dialog when a trigger element is pressed. */
export function DialogTrigger(props: DialogTriggerProps) {
const { children, onOpenChange, ...triggerProps } = props

const [isOpened, setIsOpened] = React.useState(false)
const { setModal, unsetModal } = modalProvider.useSetModal()

const onOpenChangeInternal = React.useCallback(
(isOpened: boolean) => {
if (isOpened) {
(opened: boolean) => {
if (opened) {
// We're using a placeholder here just to let the rest of the code know that the modal
// is open.
setModal(PLACEHOLDER)
} else {
unsetModal()
}

onOpenChange?.(isOpened)
setIsOpened(opened)
onOpenChange?.(opened)
},
[setModal, unsetModal, onOpenChange],
)

const renderProps = {
isOpened,
} satisfies DialogTriggerRenderProps

const [trigger, dialog] = children

return (
<aria.DialogTrigger onOpenChange={onOpenChangeInternal} {...triggerProps}>
{children}
{trigger}

{/* We're using AnimatePresence here to animate the dialog in and out. */}
<AnimatePresence>
{isOpened && (
<motion.div
style={{ display: 'none' }}
initial={{ opacity: 1 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 1 }}
>
{typeof dialog === 'function' ? dialog(renderProps) : dialog}
</motion.div>
)}
</AnimatePresence>
</aria.DialogTrigger>
)
}
3 changes: 0 additions & 3 deletions app/dashboard/src/components/AriaComponents/Dialog/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,3 @@ export interface DialogProps extends aria.DialogProps {
readonly modalProps?: Pick<aria.ModalOverlayProps, 'className' | 'defaultOpen' | 'isOpen'>
readonly testId?: string
}

/** The props for the DialogTrigger component. */
export interface DialogTriggerProps extends aria.DialogTriggerProps {}
Loading

0 comments on commit 1b95ea4

Please sign in to comment.