mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 02:21:54 +03:00
New user menu (#7581)
- Closes https://github.com/enso-org/cloud-v2/issues/610 - New user menu - Remove "go to profile" action that does not currently have an action, and does not exist in new design - Add placeholder icons for existing actions - Re-style "change password" modal to fit in with the design # Important Notes There are many differences from the design - none are visual differences though: - The list of actions is completely different - there are no menu entries in common between the design and the current - This also means that *all* current icons are placeholders. There are no appropriate icons in the "icons" Figma tab either. - The user icon is still a placeholder, as there is no backend support for user icons yet. - The user menu entries are highlighted on hover (not specified in the design), but to make this look nice, some of the padding has been moved from the outer container to the individual menu entries. - The menu entries use the same component as the context menu, so they *do* support shortcuts, and adding shortcuts to them will be very easy, *however* no shortcuts have been set for the new actions, because they are different from the actions in the Figma design (and so they don't have an official default shortcut)
This commit is contained in:
parent
e224eb350a
commit
06b2280ee6
9
app/ide-desktop/lib/assets/change_password.svg
Normal file
9
app/ide-desktop/lib/assets/change_password.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect opacity="0.2" y="3" width="16" height="10" rx="2" fill="black" />
|
||||
<path d="M10 0H12V16H10V0Z" fill="black" />
|
||||
<path d="M8 0H14V2H8V0Z" fill="black" />
|
||||
<path d="M8 14H14V16H8V14Z" fill="black" />
|
||||
<path d="M2 8L8 8" stroke="black" />
|
||||
<path d="M6.5 10.6L3.5 5.4" stroke="black" />
|
||||
<path d="M3.5 10.6L6.5 5.4" stroke="black" />
|
||||
</svg>
|
After Width: | Height: | Size: 460 B |
4
app/ide-desktop/lib/assets/sign_in.svg
Normal file
4
app/ide-desktop/lib/assets/sign_in.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect opacity="0.25" x="6" width="10" height="16" rx="2" fill="black" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 8L7.36364 5V7L1 7L1 9H7.36364V11L11 8Z" fill="black" />
|
||||
</svg>
|
After Width: | Height: | Size: 292 B |
5
app/ide-desktop/lib/assets/sign_out.svg
Normal file
5
app/ide-desktop/lib/assets/sign_out.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect opacity="0.25" x="6" width="10" height="16" rx="2" fill="black" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M-9.53674e-07 8L3.63636 5V7L10 7V9H3.63636V11L-9.53674e-07 8Z"
|
||||
fill="black" />
|
||||
</svg>
|
After Width: | Height: | Size: 319 B |
@ -19,11 +19,11 @@ import * as assetsTable from './assetsTable'
|
||||
import * as tableRow from './tableRow'
|
||||
import ConfirmDeleteModal from './confirmDeleteModal'
|
||||
import ContextMenu from './contextMenu'
|
||||
import ContextMenuEntry from './contextMenuEntry'
|
||||
import ContextMenuSeparator from './contextMenuSeparator'
|
||||
import ContextMenus from './contextMenus'
|
||||
import GlobalContextMenu from './globalContextMenu'
|
||||
import ManagePermissionsModal from './managePermissionsModal'
|
||||
import MenuEntry from './menuEntry'
|
||||
|
||||
// ========================
|
||||
// === AssetContextMenu ===
|
||||
@ -85,7 +85,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
<ContextMenus hidden={hidden} key={asset.id} event={event}>
|
||||
<ContextMenu hidden={hidden}>
|
||||
{asset.type === backendModule.AssetType.project && (
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
action={shortcuts.KeyboardAction.open}
|
||||
doAction={() => {
|
||||
@ -99,7 +99,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
)}
|
||||
{asset.type === backendModule.AssetType.project &&
|
||||
backend.type === backendModule.BackendType.local && (
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
action={shortcuts.KeyboardAction.uploadToCloud}
|
||||
doAction={async () => {
|
||||
@ -145,7 +145,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
disabled={
|
||||
asset.type !== backendModule.AssetType.project &&
|
||||
@ -160,7 +160,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
unsetModal()
|
||||
}}
|
||||
/>
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
disabled
|
||||
action={shortcuts.KeyboardAction.snapshot}
|
||||
@ -168,7 +168,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
// No backend support yet.
|
||||
}}
|
||||
/>
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
action={shortcuts.KeyboardAction.moveToTrash}
|
||||
doAction={() => {
|
||||
@ -182,7 +182,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
/>
|
||||
<ContextMenuSeparator hidden={hidden} />
|
||||
{managesThisAsset && (
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
action={shortcuts.KeyboardAction.share}
|
||||
doAction={() => {
|
||||
@ -203,7 +203,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
disabled
|
||||
action={shortcuts.KeyboardAction.label}
|
||||
@ -212,7 +212,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
}}
|
||||
/>
|
||||
<ContextMenuSeparator hidden={hidden} />
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
disabled
|
||||
action={shortcuts.KeyboardAction.duplicate}
|
||||
@ -220,7 +220,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
// No backend support yet.
|
||||
}}
|
||||
/>
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
disabled
|
||||
action={shortcuts.KeyboardAction.copy}
|
||||
@ -228,7 +228,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
// No backend support yet.
|
||||
}}
|
||||
/>
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
disabled
|
||||
action={shortcuts.KeyboardAction.cut}
|
||||
@ -236,7 +236,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
// No backend support yet.
|
||||
}}
|
||||
/>
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
disabled
|
||||
action={shortcuts.KeyboardAction.download}
|
||||
|
@ -28,9 +28,9 @@ import AssetRow from './assetRow'
|
||||
import Button from './button'
|
||||
import ConfirmDeleteModal from './confirmDeleteModal'
|
||||
import ContextMenu from './contextMenu'
|
||||
import ContextMenuEntry from './contextMenuEntry'
|
||||
import ContextMenus from './contextMenus'
|
||||
import GlobalContextMenu from './globalContextMenu'
|
||||
import MenuEntry from './menuEntry'
|
||||
import Table from './table'
|
||||
|
||||
// =================
|
||||
@ -775,7 +775,7 @@ export default function AssetsTable(props: AssetsTableProps) {
|
||||
<ContextMenus key={uniqueString.uniqueString()} event={event}>
|
||||
{innerSelectedKeys.size !== 0 && (
|
||||
<ContextMenu>
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
action={shortcuts.KeyboardAction.moveAllToTrash}
|
||||
doAction={doDeleteAll}
|
||||
/>
|
||||
|
@ -34,13 +34,12 @@ export default function ChangePasswordModal() {
|
||||
onClick={event => {
|
||||
event.stopPropagation()
|
||||
}}
|
||||
className="flex flex-col bg-white shadow-md px-4 sm:px-6 md:px-8 lg:px-10 py-8 rounded-md w-full max-w-md"
|
||||
className="flex flex-col bg-frame-selected backdrop-blur-3xl rounded-2xl px-4 py-8 w-full max-w-md"
|
||||
>
|
||||
<div className="font-medium self-center text-xl sm:text-2xl uppercase text-gray-800">
|
||||
Change Your Password
|
||||
</div>
|
||||
<div className="self-center text-xl">Change Your Password</div>
|
||||
<div className="mt-10">
|
||||
<form
|
||||
className="flex flex-col gap-6"
|
||||
onSubmit={async event => {
|
||||
event.preventDefault()
|
||||
setIsSubmitting(true)
|
||||
@ -51,13 +50,8 @@ export default function ChangePasswordModal() {
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-col mb-6">
|
||||
<label
|
||||
htmlFor="old_password"
|
||||
className="mb-1 text-xs sm:text-sm tracking-wide text-gray-600"
|
||||
>
|
||||
Old Password:
|
||||
</label>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label htmlFor="old_password">Old Password:</label>
|
||||
<div className="relative">
|
||||
<SvgIcon>
|
||||
<SvgMask src={LockIcon} />
|
||||
@ -74,17 +68,12 @@ export default function ChangePasswordModal() {
|
||||
error={validation.PASSWORD_ERROR}
|
||||
value={oldPassword}
|
||||
setValue={setOldPassword}
|
||||
className="text-sm sm:text-base placeholder-gray-500 pl-10 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400"
|
||||
className="text-sm sm:text-base placeholder-gray-500 pl-10 pr-4 rounded-2xl w-full py-2 focus:outline-none focus:border-blue-400"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col mb-6">
|
||||
<label
|
||||
htmlFor="new_password"
|
||||
className="mb-1 text-xs sm:text-sm tracking-wide text-gray-600"
|
||||
>
|
||||
New Password:
|
||||
</label>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label htmlFor="new_password">New Password:</label>
|
||||
<div className="relative">
|
||||
<SvgIcon>
|
||||
<SvgMask src={LockIcon} />
|
||||
@ -100,17 +89,12 @@ export default function ChangePasswordModal() {
|
||||
error={validation.PASSWORD_ERROR}
|
||||
value={newPassword}
|
||||
setValue={setNewPassword}
|
||||
className="text-sm sm:text-base placeholder-gray-500 pl-10 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400"
|
||||
className="text-sm placeholder-gray-500 pl-10 pr-4 rounded-full w-full py-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col mb-6">
|
||||
<label
|
||||
htmlFor="new_password_confirm"
|
||||
className="mb-1 text-xs sm:text-sm tracking-wide text-gray-600"
|
||||
>
|
||||
Confirm New Password:
|
||||
</label>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label htmlFor="new_password_confirm">Confirm New Password:</label>
|
||||
<div className="relative">
|
||||
<SvgIcon>
|
||||
<SvgMask src={LockIcon} />
|
||||
@ -126,22 +110,18 @@ export default function ChangePasswordModal() {
|
||||
error={validation.CONFIRM_PASSWORD_ERROR}
|
||||
value={confirmNewPassword}
|
||||
setValue={setConfirmNewPassword}
|
||||
className="text-sm sm:text-base placeholder-gray-500 pl-10 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400"
|
||||
className="text-sm placeholder-gray-500 pl-10 pr-4 rounded-full w-full py-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full">
|
||||
<button
|
||||
disabled={isSubmitting}
|
||||
type="submit"
|
||||
className="flex items-center justify-center focus:outline-none text-white text-sm sm:text-base bg-blue-600 hover:bg-blue-700 rounded py-2 w-full transition duration-150 ease-in disabled:opacity-50"
|
||||
>
|
||||
<span className="mr-2 uppercase">Reset</span>
|
||||
<span>
|
||||
<SvgMask src={ArrowRightIcon} />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
disabled={isSubmitting}
|
||||
type="submit"
|
||||
className="flex items-center justify-center text-white text-sm bg-cloud rounded-full gap-2 h-10 disabled:opacity-50"
|
||||
>
|
||||
Reset
|
||||
<SvgMask src={ArrowRightIcon} />
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -8,7 +8,7 @@ import * as modalProvider from '../../providers/modal'
|
||||
import * as shortcuts from '../shortcuts'
|
||||
|
||||
import ContextMenu from './contextMenu'
|
||||
import ContextMenuEntry from './contextMenuEntry'
|
||||
import MenuEntry from './menuEntry'
|
||||
|
||||
/** Props for a {@link GlobalContextMenu}. */
|
||||
export interface GlobalContextMenuProps {
|
||||
@ -49,7 +49,7 @@ export default function GlobalContextMenu(props: GlobalContextMenuProps) {
|
||||
}}
|
||||
></input>
|
||||
)}
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
action={shortcuts.KeyboardAction.uploadFiles}
|
||||
doAction={() => {
|
||||
@ -76,7 +76,7 @@ export default function GlobalContextMenu(props: GlobalContextMenuProps) {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
action={shortcuts.KeyboardAction.newProject}
|
||||
doAction={() => {
|
||||
@ -91,7 +91,7 @@ export default function GlobalContextMenu(props: GlobalContextMenuProps) {
|
||||
}}
|
||||
/>
|
||||
{backend.type !== backendModule.BackendType.local && (
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
action={shortcuts.KeyboardAction.newFolder}
|
||||
doAction={() => {
|
||||
@ -105,7 +105,7 @@ export default function GlobalContextMenu(props: GlobalContextMenuProps) {
|
||||
/>
|
||||
)}
|
||||
{backend.type !== backendModule.BackendType.local && (
|
||||
<ContextMenuEntry
|
||||
<MenuEntry
|
||||
hidden={hidden}
|
||||
disabled
|
||||
action={shortcuts.KeyboardAction.newDataConnector}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/** @file An entry in a context menu. */
|
||||
/** @file An entry in a menu. */
|
||||
import * as React from 'react'
|
||||
|
||||
import * as shortcutsModule from '../shortcuts'
|
||||
@ -7,22 +7,23 @@ import * as shortcutsProvider from '../../providers/shortcuts'
|
||||
import KeyboardShortcut from './keyboardShortcut'
|
||||
import SvgMask from '../../authentication/components/svgMask'
|
||||
|
||||
// ========================
|
||||
// === ContextMenuEntry ===
|
||||
// ========================
|
||||
// =================
|
||||
// === MenuEntry ===
|
||||
// =================
|
||||
|
||||
/** Props for a {@link ContextMenuEntry}. */
|
||||
export interface ContextMenuEntryProps {
|
||||
/** Props for a {@link MenuEntry}. */
|
||||
export interface MenuEntryProps {
|
||||
hidden?: boolean
|
||||
action: shortcutsModule.KeyboardAction
|
||||
disabled?: boolean
|
||||
title?: string
|
||||
paddingClassName?: string
|
||||
doAction: () => void
|
||||
}
|
||||
|
||||
/** An item in a `ContextMenu`. */
|
||||
export default function ContextMenuEntry(props: ContextMenuEntryProps) {
|
||||
const { hidden = false, action, disabled = false, title, doAction } = props
|
||||
/** An item in a menu. */
|
||||
export default function MenuEntry(props: MenuEntryProps) {
|
||||
const { hidden = false, action, disabled = false, title, paddingClassName, doAction } = props
|
||||
const { shortcuts } = shortcutsProvider.useShortcuts()
|
||||
const info = shortcuts.keyboardShortcutInfo[action]
|
||||
React.useEffect(() => {
|
||||
@ -39,7 +40,9 @@ export default function ContextMenuEntry(props: ContextMenuEntryProps) {
|
||||
<button
|
||||
disabled={disabled}
|
||||
title={title}
|
||||
className="flex items-center place-content-between h-8 px-3 py-1 hover:bg-black-a10 disabled:bg-transparent rounded-lg text-left disabled:opacity-50"
|
||||
className={`flex items-center place-content-between h-8 disabled:bg-transparent rounded-lg text-left disabled:opacity-50 hover:bg-black-a10 ${
|
||||
paddingClassName ?? 'px-3 py-1'
|
||||
}`}
|
||||
onClick={event => {
|
||||
event.stopPropagation()
|
||||
doAction()
|
@ -1,42 +1,22 @@
|
||||
/** @file The UserMenu component provides a dropdown menu of user actions and settings. */
|
||||
import * as React from 'react'
|
||||
|
||||
import DefaultUserIcon from 'enso-assets/default_user.svg'
|
||||
|
||||
import * as app from '../../components/app'
|
||||
import * as auth from '../../authentication/providers/auth'
|
||||
import * as hooks from '../../hooks'
|
||||
import * as modalProvider from '../../providers/modal'
|
||||
import * as shortcuts from '../shortcuts'
|
||||
|
||||
import ChangePasswordModal from './changePasswordModal'
|
||||
import MenuEntry from './menuEntry'
|
||||
import Modal from './modal'
|
||||
|
||||
// ================
|
||||
// === UserMenu ===
|
||||
// ================
|
||||
|
||||
/** This is the UI component for a `UserMenu` list item.
|
||||
* The main interaction logic is in the `onClick` injected by `UserMenu`. */
|
||||
export interface UserMenuItemProps {
|
||||
disabled?: boolean
|
||||
onClick?: React.MouseEventHandler<HTMLDivElement>
|
||||
}
|
||||
|
||||
/** User menu item. */
|
||||
function UserMenuItem(props: React.PropsWithChildren<UserMenuItemProps>) {
|
||||
const { children, disabled = false, onClick } = props
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`whitespace-nowrap first:rounded-t-2xl last:rounded-b-2xl px-4 py-2 ${
|
||||
disabled ? 'opacity-50' : ''
|
||||
} ${onClick && !disabled ? 'hover:bg-black-a10' : ''} ${
|
||||
onClick != null && !disabled ? 'cursor-pointer' : ''
|
||||
}`}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/** Props for a {@link UserMenu}. */
|
||||
export interface UserMenuProps {
|
||||
onSignOut: () => void
|
||||
@ -45,20 +25,11 @@ export interface UserMenuProps {
|
||||
/** Handling the UserMenuItem click event logic and displaying its content. */
|
||||
export default function UserMenu(props: UserMenuProps) {
|
||||
const { onSignOut } = props
|
||||
const navigate = hooks.useNavigate()
|
||||
const { signOut } = auth.useAuth()
|
||||
const { accessToken, organization } = auth.useNonPartialUserSession()
|
||||
const navigate = hooks.useNavigate()
|
||||
|
||||
const { setModal } = modalProvider.useSetModal()
|
||||
|
||||
const goToProfile = () => {
|
||||
// TODO: Implement this when the backend endpoints are implemented.
|
||||
}
|
||||
|
||||
const goToLoginPage = () => {
|
||||
navigate(app.LOGIN_PATH)
|
||||
}
|
||||
|
||||
// The shape of the JWT payload is statically known.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const username: string | null =
|
||||
@ -67,47 +38,59 @@ export default function UserMenu(props: UserMenuProps) {
|
||||
const canChangePassword = username != null ? !/^Github_|^Google_/.test(username) : false
|
||||
|
||||
return (
|
||||
<div
|
||||
className="absolute bg-frame-selected backdrop-blur-3xl right-2.25 top-11 z-1 flex flex-col rounded-2xl"
|
||||
onClick={event => {
|
||||
event.stopPropagation()
|
||||
}}
|
||||
>
|
||||
{organization != null ? (
|
||||
<>
|
||||
<UserMenuItem>
|
||||
Signed in as <span className="font-bold">{organization.name}</span>
|
||||
</UserMenuItem>
|
||||
<UserMenuItem disabled onClick={goToProfile}>
|
||||
Your profile
|
||||
</UserMenuItem>
|
||||
{canChangePassword && (
|
||||
<UserMenuItem
|
||||
onClick={() => {
|
||||
setModal(<ChangePasswordModal />)
|
||||
}}
|
||||
>
|
||||
Change your password
|
||||
</UserMenuItem>
|
||||
)}
|
||||
<UserMenuItem
|
||||
onClick={() => {
|
||||
onSignOut()
|
||||
// Wait until React has switched back to drive view, before signing out.
|
||||
window.setTimeout(() => {
|
||||
void signOut()
|
||||
}, 0)
|
||||
}}
|
||||
>
|
||||
Sign out
|
||||
</UserMenuItem>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<UserMenuItem>You are not signed in.</UserMenuItem>
|
||||
<UserMenuItem onClick={goToLoginPage}>Login</UserMenuItem>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<Modal className="absolute overflow-hidden bg-dim w-full h-full z-10">
|
||||
<div
|
||||
className="absolute flex flex-col bg-frame-selected backdrop-blur-3xl rounded-2xl gap-3 right-2.25 top-2.25 w-51.5 px-2 py-2.25"
|
||||
onClick={event => {
|
||||
event.stopPropagation()
|
||||
}}
|
||||
>
|
||||
{organization != null ? (
|
||||
<>
|
||||
<div className="flex items-center gap-3 px-1">
|
||||
<img src={DefaultUserIcon} height={28} width={28} />
|
||||
<span className="leading-170 h-6 py-px">{organization.name}</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
{canChangePassword && (
|
||||
<MenuEntry
|
||||
action={shortcuts.KeyboardAction.changeYourPassword}
|
||||
paddingClassName="p-1"
|
||||
doAction={() => {
|
||||
setModal(<ChangePasswordModal />)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<MenuEntry
|
||||
action={shortcuts.KeyboardAction.signOut}
|
||||
paddingClassName="p-1"
|
||||
doAction={() => {
|
||||
onSignOut()
|
||||
// Wait until React has switched back to drive view, before signing out.
|
||||
window.setTimeout(() => {
|
||||
void signOut()
|
||||
}, 0)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="flex items-center h-7">
|
||||
<span className="leading-170 h-6 py-px">You are not signed in.</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<MenuEntry
|
||||
action={shortcuts.KeyboardAction.signIn}
|
||||
paddingClassName="py-1"
|
||||
doAction={() => {
|
||||
navigate(app.LOGIN_PATH)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import AddFolderIcon from 'enso-assets/add_folder.svg'
|
||||
import AddNetworkIcon from 'enso-assets/add_network.svg'
|
||||
import BlankIcon from 'enso-assets/blank_16.svg'
|
||||
import CameraIcon from 'enso-assets/camera.svg'
|
||||
import ChangePasswordIcon from 'enso-assets/change_password.svg'
|
||||
import CloudToIcon from 'enso-assets/cloud_to.svg'
|
||||
import CopyIcon from 'enso-assets/copy.svg'
|
||||
import DataDownloadIcon from 'enso-assets/data_download.svg'
|
||||
@ -15,6 +16,8 @@ import OpenIcon from 'enso-assets/open.svg'
|
||||
import PenIcon from 'enso-assets/pen.svg'
|
||||
import PeopleIcon from 'enso-assets/people.svg'
|
||||
import ScissorsIcon from 'enso-assets/scissors.svg'
|
||||
import SignInIcon from 'enso-assets/sign_in.svg'
|
||||
import SignOutIcon from 'enso-assets/sign_out.svg'
|
||||
import TagIcon from 'enso-assets/tag.svg'
|
||||
import TrashIcon from 'enso-assets/trash.svg'
|
||||
|
||||
@ -61,6 +64,9 @@ export enum KeyboardAction {
|
||||
newDataConnector = 'new-data-connector',
|
||||
closeModal = 'close-modal',
|
||||
cancelEditName = 'cancel-edit-name',
|
||||
changeYourPassword = 'change-your-password',
|
||||
signIn = 'sign-in',
|
||||
signOut = 'sign-out',
|
||||
}
|
||||
|
||||
/** Valid mouse buttons. The values of each enum member is its corresponding value of
|
||||
@ -155,6 +161,9 @@ function makeKeyboardActionMap<T>(make: () => T): Record<KeyboardAction, T> {
|
||||
[KeyboardAction.newDataConnector]: make(),
|
||||
[KeyboardAction.closeModal]: make(),
|
||||
[KeyboardAction.cancelEditName]: make(),
|
||||
[KeyboardAction.changeYourPassword]: make(),
|
||||
[KeyboardAction.signIn]: make(),
|
||||
[KeyboardAction.signOut]: make(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,6 +428,9 @@ const DEFAULT_KEYBOARD_SHORTCUTS: Record<KeyboardAction, KeyboardShortcut[]> = {
|
||||
],
|
||||
[KeyboardAction.closeModal]: [keybind(KeyboardAction.closeModal, [], 'Escape')],
|
||||
[KeyboardAction.cancelEditName]: [keybind(KeyboardAction.cancelEditName, [], 'Escape')],
|
||||
[KeyboardAction.changeYourPassword]: [],
|
||||
[KeyboardAction.signIn]: [],
|
||||
[KeyboardAction.signOut]: [],
|
||||
}
|
||||
|
||||
/** The default UI data for every keyboard shortcut. */
|
||||
@ -450,6 +462,9 @@ const DEFAULT_KEYBOARD_SHORTCUT_INFO: Record<KeyboardAction, ShortcutInfo> = {
|
||||
// These should not appear in any context menus.
|
||||
[KeyboardAction.closeModal]: { name: 'Close', icon: BlankIcon },
|
||||
[KeyboardAction.cancelEditName]: { name: 'Cancel Editing', icon: BlankIcon },
|
||||
[KeyboardAction.changeYourPassword]: { name: 'Change Your Password', icon: ChangePasswordIcon },
|
||||
[KeyboardAction.signIn]: { name: 'Sign In', icon: SignInIcon },
|
||||
[KeyboardAction.signOut]: { name: 'Sign Out', icon: SignOutIcon, colorClass: 'text-delete' },
|
||||
}
|
||||
|
||||
/** The default mouse shortcuts. */
|
||||
|
@ -76,6 +76,7 @@ export const theme = {
|
||||
'30': '7.5rem',
|
||||
'30.25': '7.5625rem',
|
||||
'42': '10.5rem',
|
||||
'51.5': '12.875rem',
|
||||
'54': '13.5rem',
|
||||
'57.5': '14.375rem',
|
||||
'62': '15.5rem',
|
||||
|
Loading…
Reference in New Issue
Block a user