Skip to content

Commit

Permalink
Improve tab bar (#10333)
Browse files Browse the repository at this point in the history
- Add close button to Editor tab
- Convert Settings page into a modal (not guaranteed to be the final design, but it makes sense to change it to a modal for now at least)

# Important Notes
None
  • Loading branch information
somebody1234 authored Jun 24, 2024
1 parent e6c8ec7 commit b52e8eb
Show file tree
Hide file tree
Showing 28 changed files with 407 additions and 462 deletions.
7 changes: 7 additions & 0 deletions app/ide-desktop/lib/dashboard/e2e/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ export function locateStopProjectButton(page: test.Locator | test.Page) {
return page.getByLabel('Stop execution')
}

/** Close a modal. */
export function closeModal(page: test.Page) {
return test.test.step('Close modal', async () => {
await page.getByLabel('Close').click()
})
}

/** Find all labels in the labels panel (if any) on the current page. */
export function locateLabelsPanelLabels(page: test.Page, name?: string) {
return (
Expand Down
10 changes: 5 additions & 5 deletions app/ide-desktop/lib/dashboard/e2e/actions/BaseActions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/** @file The base class from which all `Actions` classes are derived. */

import * as test from '@playwright/test'

// ====================
Expand Down Expand Up @@ -78,10 +77,11 @@ export default class BaseActions implements PromiseLike<void> {
}

/** Return a {@link BaseActions} with the same {@link Promise} but a different type. */
into<T extends new (page: test.Page, promise: Promise<void>) => InstanceType<T>>(
clazz: T
): InstanceType<T> {
return new clazz(this.page, this.promise)
into<
T extends new (page: test.Page, promise: Promise<void>, ...args: Args) => InstanceType<T>,
Args extends readonly unknown[],
>(clazz: T, ...args: Args): InstanceType<T> {
return new clazz(this.page, this.promise, ...args)
}

/** Perform an action on the current page. This should generally be avoided in favor of using
Expand Down
16 changes: 2 additions & 14 deletions app/ide-desktop/lib/dashboard/e2e/actions/DrivePageActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,24 @@ import * as test from 'playwright/test'

import * as actions from '../actions'
import type * as baseActions from './BaseActions'
import BaseActions from './BaseActions'
import * as contextMenuActions from './contextMenuActions'
import EditorPageActions from './EditorPageActions'
import * as goToPageActions from './goToPageActions'
import NewDataLinkModalActions from './NewDataLinkModalActions'
import * as openUserMenuAction from './openUserMenuAction'
import PageActions from './PageActions'
import StartModalActions from './StartModalActions'
import * as userMenuActions from './userMenuActions'

// ========================
// === DrivePageActions ===
// ========================

/** Actions for the "drive" page. */
export default class DrivePageActions extends BaseActions {
export default class DrivePageActions extends PageActions {
/** Actions for navigating to another page. */
get goToPage(): Omit<goToPageActions.GoToPageActions, 'drive'> {
return goToPageActions.goToPageActions(this.step.bind(this))
}

/** Actions related to the User Menu. */
get userMenu() {
return userMenuActions.userMenuActions(this.step.bind(this))
}

/** Actions related to context menus. */
get contextMenu() {
return contextMenuActions.contextMenuActions(this.step.bind(this))
Expand Down Expand Up @@ -145,11 +138,6 @@ export default class DrivePageActions extends BaseActions {
).into(EditorPageActions)
}

/** Open the User Menu. */
openUserMenu() {
return openUserMenuAction.openUserMenuAction(this.step.bind(this))
}

/** Interact with the drive view (the main container of this page). */
withDriveView(callback: baseActions.LocatorCallback) {
return this.step('Interact with drive view', page => callback(actions.locateDriveView(page)))
Expand Down
17 changes: 2 additions & 15 deletions app/ide-desktop/lib/dashboard/e2e/actions/EditorPageActions.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,15 @@
/** @file Actions for the "editor" page. */

import BaseActions from './BaseActions'
import * as goToPageActions from './goToPageActions'
import * as openUserMenuAction from './openUserMenuAction'
import * as userMenuActions from './userMenuActions'
import PageActions from './PageActions'

// =========================
// === EditorPageActions ===
// =========================

/** Actions for the "editor" page. */
export default class EditorPageActions extends BaseActions {
export default class EditorPageActions extends PageActions {
/** Actions for navigating to another page. */
get goToPage(): Omit<goToPageActions.GoToPageActions, 'editor'> {
return goToPageActions.goToPageActions(this.step.bind(this))
}

/** Actions related to the User Menu. */
get userMenu() {
return userMenuActions.userMenuActions(this.step.bind(this))
}

/** Open the User Menu. */
openUserMenu() {
return openUserMenuAction.openUserMenuAction(this.step.bind(this))
}
}
21 changes: 21 additions & 0 deletions app/ide-desktop/lib/dashboard/e2e/actions/PageActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/** @file Actions common to all pages. */
import BaseActions from './BaseActions'
import * as openUserMenuAction from './openUserMenuAction'
import * as userMenuActions from './userMenuActions'

// ===================
// === PageActions ===
// ===================

/** Actions common to all pages. */
export default class PageActions extends BaseActions {
/** Actions related to the User Menu. */
get userMenu() {
return userMenuActions.userMenuActions(this.step.bind(this))
}

/** Open the User Menu. */
openUserMenu() {
return openUserMenuAction.openUserMenuAction(this.step.bind(this))
}
}
18 changes: 3 additions & 15 deletions app/ide-desktop/lib/dashboard/e2e/actions/SettingsPageActions.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,16 @@
/** @file Actions for the "settings" page. */
import BaseActions from './BaseActions'
import * as goToPageActions from './goToPageActions'
import * as openUserMenuAction from './openUserMenuAction'
import * as userMenuActions from './userMenuActions'
import PageActions from './PageActions'

// ===========================
// === SettingsPageActions ===
// ===========================

// TODO: split settings page actions into different classes for each settings tab.
/** Actions for the "settings" page. */
export default class SettingsPageActions extends BaseActions {
export default class SettingsPageActions extends PageActions {
/** Actions for navigating to another page. */
get goToPage(): Omit<goToPageActions.GoToPageActions, 'settings'> {
get goToPage(): Omit<goToPageActions.GoToPageActions, 'drive'> {
return goToPageActions.goToPageActions(this.step.bind(this))
}

/** Actions related to the User Menu. */
get userMenu() {
return userMenuActions.userMenuActions(this.step.bind(this))
}

/** Open the User Menu. */
openUserMenu() {
return openUserMenuAction.openUserMenuAction(this.step.bind(this))
}
}
5 changes: 1 addition & 4 deletions app/ide-desktop/lib/dashboard/e2e/actions/goToPageActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ export function goToPageActions(
).into(DrivePageActions),
editor: () =>
step('Go to "Spatial Analysis" page', page =>
page
.getByRole('button')
.filter({ has: page.getByText('Spatial Analysis') })
.click()
page.getByRole('button').and(page.getByLabel('Spatial Analysis')).click()
).into(EditorPageActions),
settings: () =>
step('Go to "settings" page', page => BaseActions.press(page, 'Mod+,')).into(
Expand Down
6 changes: 0 additions & 6 deletions app/ide-desktop/lib/dashboard/e2e/actions/userMenuActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type * as test from 'playwright/test'
import type * as baseActions from './BaseActions'
import type BaseActions from './BaseActions'
import LoginPageActions from './LoginPageActions'
import SettingsPageActions from './SettingsPageActions'

// =======================
// === UserMenuActions ===
Expand All @@ -13,7 +12,6 @@ import SettingsPageActions from './SettingsPageActions'
/** Actions for the user menu. */
export interface UserMenuActions<T extends BaseActions> {
readonly downloadApp: (callback: (download: test.Download) => Promise<void> | void) => T
readonly goToSettingsPage: () => SettingsPageActions
readonly logout: () => LoginPageActions
readonly goToLoginPage: () => LoginPageActions
}
Expand All @@ -34,10 +32,6 @@ export function userMenuActions<T extends BaseActions>(
await callback(await downloadPromise)
})
},
goToSettingsPage: () =>
step('Go to Settings (user menu)', page =>
page.getByRole('button', { name: 'Settings' }).getByText('Settings').click()
).into(SettingsPageActions),
logout: () =>
step('Logout (user menu)', page =>
page.getByRole('button', { name: 'Logout' }).getByText('Logout').click()
Expand Down
2 changes: 2 additions & 0 deletions app/ide-desktop/lib/dashboard/e2e/membersSettings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ test.test('members settings', async ({ page }) => {

const otherUserName = 'second.user_'
const otherUser = api.addUser(otherUserName)
// await actions.closeModal(page)
await actions.relog({ page })
await localActions.go(page)
await test
.expect(localActions.locateMembersRows(page).locator('> :nth-child(1) > :nth-child(2)'))
.toHaveText([api.currentUser()?.name ?? '', otherUserName])

api.deleteUser(otherUser.userId)
// await actions.closeModal(page)
await actions.relog({ page })
await localActions.go(page)
await test
Expand Down
15 changes: 11 additions & 4 deletions app/ide-desktop/lib/dashboard/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ appConfig.loadTestEnvironmentVariables()

/* eslint-disable @typescript-eslint/no-magic-numbers, @typescript-eslint/strict-boolean-expressions */

const DEBUG = process.env.PWDEBUG === '1'
const TIMEOUT_MS = DEBUG ? 100_000_000 : 30_000

export default test.defineConfig({
testDir: './e2e',
fullyParallel: true,
Expand All @@ -20,18 +23,22 @@ export default test.defineConfig({
repeatEach: process.env.CI ? 3 : 1,
expect: {
toHaveScreenshot: { threshold: 0 },
timeout: 30_000,
timeout: TIMEOUT_MS,
},
timeout: 30_000,
timeout: TIMEOUT_MS,
reporter: 'html',
use: {
baseURL: 'http://localhost:8080',
trace: 'retain-on-failure',
launchOptions: {
ignoreDefaultArgs: ['--headless'],
args: [
// Much closer to headful Chromium than classic headless.
'--headless=new',
...(DEBUG
? []
: [
// Much closer to headful Chromium than classic headless.
'--headless=new',
]),
// Required for `backdrop-filter: blur` to work.
'--use-angle=swiftshader',
// FIXME: `--disable-gpu` disables `backdrop-filter: blur`, which is not handled by
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const DIALOG_STYLES = twv.tv({
header:
'sticky grid grid-cols-[1fr_auto_1fr] items-center border-b border-primary/10 transition-[border-color] duration-150',
closeButton: 'col-start-1 col-end-1 mr-auto',
heading: 'col-start-2 col-end-2 my-0',
heading: 'col-start-2 col-end-2 my-0 text-center',
content: 'relative flex-auto overflow-y-auto p-3.5',
},
})
Expand Down
9 changes: 7 additions & 2 deletions app/ide-desktop/lib/dashboard/src/components/DateInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,13 @@ export default function DateInput(props: DateInputProps) {
</div>
</FocusRing>
{isPickerVisible && (
<div className="absolute left-1/2 top-text-h mt-date-input-gap">
<div className="relative -translate-x-1/2 rounded-2xl border border-primary/10 p-date-input shadow-soft before:absolute before:inset-0 before:rounded-2xl before:backdrop-blur-3xl">
<div className="absolute left-1/2 top-text-h z-1 mt-date-input-gap">
<div
className={ariaComponents.DIALOG_BACKGROUND({
className:
'relative -translate-x-1/2 rounded-2xl border border-primary/10 p-date-input shadow-soft',
})}
>
<div className="relative mb-date-input-gap">
<div className="flex items-center">
<ariaComponents.Button
Expand Down
14 changes: 0 additions & 14 deletions app/ide-desktop/lib/dashboard/src/components/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import * as React from 'react'

import * as authProvider from '#/providers/AuthProvider'
import * as modalProvider from '#/providers/ModalProvider'

import Chat from '#/layouts/Chat'
import ChatPlaceholder from '#/layouts/ChatPlaceholder'
Expand All @@ -25,25 +24,12 @@ export interface PageProps extends Readonly<React.PropsWithChildren> {
export default function Page(props: PageProps) {
const { hideInfoBar = false, children, hideChat = false } = props
const [isHelpChatOpen, setIsHelpChatOpen] = React.useState(false)
const { unsetModal } = modalProvider.useSetModal()
const session = authProvider.useUserSession()

const doCloseChat = () => {
setIsHelpChatOpen(false)
}

React.useEffect(() => {
const onClick = () => {
if (getSelection()?.type !== 'Range') {
unsetModal()
}
}
document.addEventListener('click', onClick)
return () => {
document.removeEventListener('click', onClick)
}
}, [unsetModal])

return (
<>
{children}
Expand Down
Loading

0 comments on commit b52e8eb

Please sign in to comment.