Remove edit name on mod+click (#11058)

Closes: enso-org/cloud-v2#1476

(cherry picked from commit 3c1db7dbc1)
This commit is contained in:
Sergei Garin 2024-09-13 15:51:35 +03:00 committed by James Dunkerley
parent 9d581d039b
commit 3e43d62eaa
9 changed files with 18 additions and 76 deletions

View File

@ -62,7 +62,7 @@ export default class DrivePageActions extends PageActions {
cloud() {
return self.step('Go to "Cloud" category', (page) =>
page
.getByRole('button', { name: TEXT.cloudCategory })
.getByRole('button', { name: TEXT.cloudCategory, exact: true })
.getByText(TEXT.cloudCategory)
.click(),
)
@ -71,7 +71,7 @@ export default class DrivePageActions extends PageActions {
local() {
return self.step('Go to "Local" category', (page) =>
page
.getByRole('button', { name: TEXT.localCategory })
.getByRole('button', { name: TEXT.localCategory, exact: true })
.getByText(TEXT.localCategory)
.click(),
)
@ -80,7 +80,7 @@ export default class DrivePageActions extends PageActions {
recent() {
return self.step('Go to "Recent" category', (page) =>
page
.getByRole('button', { name: TEXT.recentCategory })
.getByRole('button', { name: TEXT.recentCategory, exact: true })
.getByText(TEXT.recentCategory)
.click(),
)
@ -88,10 +88,7 @@ export default class DrivePageActions extends PageActions {
/** Switch to the "trash" category. */
trash() {
return self.step('Go to "Trash" category', (page) =>
page
.getByRole('button', { name: TEXT.trashCategory })
.getByText(TEXT.trashCategory)
.click(),
page.getByRole('button', { name: TEXT.trashCategory, exact: true }).click(),
)
},
}

View File

@ -7,12 +7,12 @@ test.test.beforeEach(({ page }) => actions.mockAllAndLogin({ page }))
test.test('edit name', async ({ page }) => {
const assetRows = actions.locateAssetRows(page)
const mod = await actions.modModifier(page)
const row = assetRows.nth(0)
const newName = 'foo bar baz'
await actions.locateNewFolderIcon(page).click()
await actions.locateAssetRowName(row).click({ modifiers: [mod] })
await actions.locateAssetRowName(row).click()
await actions.locateAssetRowName(row).click()
await actions.locateAssetRowName(row).fill(newName)
await actions.locateEditingTick(row).click()
await test.expect(row).toHaveText(new RegExp('^' + newName))
@ -33,13 +33,14 @@ test.test('edit name (keyboard)', async ({ page }) => {
test.test('cancel editing name', async ({ page }) => {
const assetRows = actions.locateAssetRows(page)
const mod = await actions.modModifier(page)
const row = assetRows.nth(0)
const newName = 'foo bar baz'
await actions.locateNewFolderIcon(page).click()
const oldName = (await actions.locateAssetRowName(row).textContent()) ?? ''
await actions.locateAssetRowName(row).click({ modifiers: [mod] })
await actions.locateAssetRowName(row).click()
await actions.locateAssetRowName(row).click()
await actions.locateAssetRowName(row).fill(newName)
await actions.locateEditingCross(row).click()
await test.expect(row).toHaveText(new RegExp('^' + oldName))
@ -61,12 +62,12 @@ test.test('cancel editing name (keyboard)', async ({ page }) => {
test.test('change to blank name', async ({ page }) => {
const assetRows = actions.locateAssetRows(page)
const mod = await actions.modModifier(page)
const row = assetRows.nth(0)
await actions.locateNewFolderIcon(page).click()
const oldName = (await actions.locateAssetRowName(row).textContent()) ?? ''
await actions.locateAssetRowName(row).click({ modifiers: [mod] })
await actions.locateAssetRowName(row).click()
await actions.locateAssetRowName(row).click()
await actions.locateAssetRowName(row).fill('')
await test.expect(actions.locateEditingTick(row)).not.toBeVisible()
await actions.locateEditingCross(row).click()

View File

@ -75,7 +75,6 @@ export const ACTION_TO_TEXT_ID: Readonly<
signOut: 'signOutShortcut',
downloadApp: 'downloadAppShortcut',
cancelCut: 'cancelCutShortcut',
editName: 'editNameShortcut',
selectAdditional: 'selectAdditionalShortcut',
selectRange: 'selectRangeShortcut',
selectAdditionalRange: 'selectAdditionalRangeShortcut',

View File

@ -3,8 +3,6 @@ import DatalinkIcon from '#/assets/datalink.svg'
import * as setAssetHooks from '#/hooks/setAssetHooks'
import * as inputBindingsProvider from '#/providers/InputBindingsProvider'
import type * as column from '#/components/dashboard/column'
import EditableSpan from '#/components/EditableSpan'
@ -15,7 +13,6 @@ import * as eventModule from '#/utilities/event'
import * as indent from '#/utilities/indent'
import * as object from '#/utilities/object'
import * as tailwindMerge from '#/utilities/tailwindMerge'
import { isOnMacOS } from 'enso-common/src/detect'
// ====================
// === DatalinkName ===
@ -30,7 +27,7 @@ export interface DatalinkNameColumnProps extends column.AssetColumnProps {}
export default function DatalinkNameColumn(props: DatalinkNameColumnProps) {
const { item, setItem, selected, rowState, setRowState, isEditable } = props
const setIsAssetPanelTemporarilyVisible = useSetIsAssetPanelTemporarilyVisible()
const inputBindings = inputBindingsProvider.useInputBindings()
if (item.type !== backendModule.AssetType.datalink) {
// eslint-disable-next-line no-restricted-syntax
throw new Error('`DatalinkNameColumn` can only display Datalinks.')
@ -49,12 +46,6 @@ export default function DatalinkNameColumn(props: DatalinkNameColumnProps) {
// Backend implementation is tracked here: https://github.com/enso-org/cloud-v2/issues/505.
const doRename = () => Promise.resolve(null)
const handleClick = inputBindings.handler({
editName: () => {
setIsEditing(true)
},
})
return (
<div
className={tailwindMerge.twMerge(
@ -67,9 +58,7 @@ export default function DatalinkNameColumn(props: DatalinkNameColumnProps) {
}
}}
onClick={(event) => {
if (handleClick(event)) {
// Already handled.
} else if (eventModule.isSingleClick(event) && isOnMacOS() && selected) {
if (eventModule.isSingleClick(event) && selected) {
setIsEditing(true)
} else if (eventModule.isDoubleClick(event)) {
event.stopPropagation()

View File

@ -9,7 +9,6 @@ import * as setAssetHooks from '#/hooks/setAssetHooks'
import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
import { useDriveStore } from '#/providers/DriveProvider'
import * as inputBindingsProvider from '#/providers/InputBindingsProvider'
import * as textProvider from '#/providers/TextProvider'
import * as ariaComponents from '#/components/AriaComponents'
@ -25,7 +24,6 @@ import * as object from '#/utilities/object'
import * as string from '#/utilities/string'
import * as tailwindMerge from '#/utilities/tailwindMerge'
import * as validation from '#/utilities/validation'
import { isOnMacOS } from 'enso-common/src/detect'
// =====================
// === DirectoryName ===
@ -43,7 +41,6 @@ export default function DirectoryNameColumn(props: DirectoryNameColumnProps) {
const { doToggleDirectoryExpansion, expandedDirectoryIds } = state
const toastAndLog = toastAndLogHooks.useToastAndLog()
const { getText } = textProvider.useText()
const inputBindings = inputBindingsProvider.useInputBindings()
const driveStore = useDriveStore()
if (item.type !== backendModule.AssetType.directory) {
@ -87,12 +84,6 @@ export default function DirectoryNameColumn(props: DirectoryNameColumnProps) {
}
}
const handleClick = inputBindings.handler({
editName: () => {
setIsEditing(true)
},
})
return (
<div
className={tailwindMerge.twMerge(
@ -105,11 +96,8 @@ export default function DirectoryNameColumn(props: DirectoryNameColumnProps) {
}
}}
onClick={(event) => {
if (handleClick(event)) {
// Already handled.
} else if (
if (
eventModule.isSingleClick(event) &&
isOnMacOS() &&
selected &&
driveStore.getState().selectedKeys.size === 1
) {

View File

@ -5,8 +5,6 @@ import { backendMutationOptions } from '#/hooks/backendHooks'
import * as setAssetHooks from '#/hooks/setAssetHooks'
import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
import * as inputBindingsProvider from '#/providers/InputBindingsProvider'
import type * as column from '#/components/dashboard/column'
import EditableSpan from '#/components/EditableSpan'
import SvgMask from '#/components/SvgMask'
@ -19,7 +17,6 @@ import * as indent from '#/utilities/indent'
import * as object from '#/utilities/object'
import * as string from '#/utilities/string'
import * as tailwindMerge from '#/utilities/tailwindMerge'
import { isOnMacOS } from 'enso-common/src/detect'
// ================
// === FileName ===
@ -35,7 +32,6 @@ export default function FileNameColumn(props: FileNameColumnProps) {
const { item, setItem, selected, state, rowState, setRowState, isEditable } = props
const { backend, nodeMap } = state
const toastAndLog = toastAndLogHooks.useToastAndLog()
const inputBindings = inputBindingsProvider.useInputBindings()
if (item.type !== backendModule.AssetType.file) {
// eslint-disable-next-line no-restricted-syntax
@ -74,12 +70,6 @@ export default function FileNameColumn(props: FileNameColumnProps) {
}
}
const handleClick = inputBindings.handler({
editName: () => {
setIsEditing(true)
},
})
return (
<div
className={tailwindMerge.twMerge(
@ -92,9 +82,7 @@ export default function FileNameColumn(props: FileNameColumnProps) {
}
}}
onClick={(event) => {
if (handleClick(event)) {
// Already handled.
} else if (eventModule.isSingleClick(event) && isOnMacOS() && selected) {
if (eventModule.isSingleClick(event) && selected) {
if (!isCloud) {
setIsEditing(true)
}

View File

@ -10,7 +10,6 @@ import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
import * as authProvider from '#/providers/AuthProvider'
import { useDriveStore } from '#/providers/DriveProvider'
import * as inputBindingsProvider from '#/providers/InputBindingsProvider'
import * as textProvider from '#/providers/TextProvider'
import type * as column from '#/components/dashboard/column'
@ -56,7 +55,6 @@ export default function ProjectNameColumn(props: ProjectNameColumnProps) {
const toastAndLog = toastAndLogHooks.useToastAndLog()
const { user } = authProvider.useFullUserSession()
const { getText } = textProvider.useText()
const inputBindings = inputBindingsProvider.useInputBindings()
const driveStore = useDriveStore()
const doOpenProject = projectHooks.useOpenProject()
@ -116,12 +114,6 @@ export default function ProjectNameColumn(props: ProjectNameColumnProps) {
}
}
const handleClick = inputBindings.handler({
editName: () => {
setIsEditing(true)
},
})
return (
<div
className={tailwindMerge.twMerge(
@ -136,8 +128,6 @@ export default function ProjectNameColumn(props: ProjectNameColumnProps) {
onClick={(event) => {
if (rowState.isEditingName || isOtherUserUsingProject) {
// The project should neither be edited nor opened in these cases.
} else if (handleClick(event)) {
// Already handled.
} else if (
!isRunning &&
eventModule.isSingleClick(event) &&

View File

@ -6,7 +6,6 @@ import KeyIcon from '#/assets/key.svg'
import { backendMutationOptions } from '#/hooks/backendHooks'
import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
import * as inputBindingsProvider from '#/providers/InputBindingsProvider'
import * as modalProvider from '#/providers/ModalProvider'
import * as ariaComponents from '#/components/AriaComponents'
@ -21,7 +20,6 @@ import * as eventModule from '#/utilities/event'
import * as indent from '#/utilities/indent'
import * as object from '#/utilities/object'
import * as tailwindMerge from '#/utilities/tailwindMerge'
import { isOnMacOS } from 'enso-common/src/detect'
// =====================
// === ConnectorName ===
@ -38,11 +36,12 @@ export default function SecretNameColumn(props: SecretNameColumnProps) {
const { backend } = state
const toastAndLog = toastAndLogHooks.useToastAndLog()
const { setModal } = modalProvider.useSetModal()
const inputBindings = inputBindingsProvider.useInputBindings()
if (item.type !== backendModule.AssetType.secret) {
// eslint-disable-next-line no-restricted-syntax
throw new Error('`SecretNameColumn` can only display secrets.')
}
const asset = item.item
const updateSecretMutation = useMutation(backendMutationOptions(backend, 'updateSecret'))
@ -53,12 +52,6 @@ export default function SecretNameColumn(props: SecretNameColumnProps) {
}
}
const handleClick = inputBindings.handler({
editName: () => {
setIsEditing(true)
},
})
return (
<div
className={tailwindMerge.twMerge(
@ -71,9 +64,7 @@ export default function SecretNameColumn(props: SecretNameColumnProps) {
}
}}
onClick={(event) => {
if (handleClick(event)) {
// Already handled.
} else if (eventModule.isSingleClick(event) && isOnMacOS() && selected) {
if (eventModule.isSingleClick(event) && selected) {
setIsEditing(true)
} else if (eventModule.isDoubleClick(event) && isEditable) {
event.stopPropagation()

View File

@ -108,7 +108,6 @@ export const BINDINGS = inputBindings.defineBindings({
// TODO: support handlers for double click; make single click handlers not work on double click events
// [MouseAction.open]: [mousebind(MouseAction.open, [], MouseButton.left, 2)],
// [MouseAction.run]: [mousebind(MouseAction.run, ['Shift'], MouseButton.left, 2)],
editName: { name: 'Edit Name', bindings: ['Mod+PointerMain'], rebindable: false },
selectAdditional: { name: 'Select Additional', bindings: ['Mod+PointerMain'], rebindable: false },
selectRange: { name: 'Select Range', bindings: ['Shift+PointerMain'], rebindable: false },
selectAdditionalRange: {