diff --git a/package.json b/package.json index a1e604a38a..55a4e21365 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "cozy-devtools": "^1.2.1", "cozy-doctypes": "1.85.4", "cozy-flags": "^4.6.1", - "cozy-harvest-lib": "^30.0.0", + "cozy-harvest-lib": "^30.6.4", "cozy-intent": "^2.29.1", "cozy-keys-lib": "6.0.0", "cozy-logger": "1.9.1", @@ -97,7 +97,8 @@ "cozy-scripts": "^8.3.0", "cozy-sharing": "^16.0.0", "cozy-stack-client": "^49.8.0", - "cozy-ui": "^111.21.0", + "cozy-ui": "^113.3.0", + "cozy-viewer": "^2.9.0", "date-fns": "1.30.1", "diacritics": "1.3.0", "filesize": "10.1.6", diff --git a/src/locales/fr.json b/src/locales/fr.json index d00cf144ab..e2f32cf661 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -58,7 +58,7 @@ "menu_create_shortcut": "Raccourci", "share": "Partager", "trash": "Supprimer", - "leave": "Quitter le dossier partagé et le supprimer", + "leave": "Quitter le partage et supprimer le dossier", "menu_add": "Ajouter", "menu_add_item": "Ajouter un élément", "menu_onlyOffice": { diff --git a/src/modules/actionmenu/ActionMenuWithHeader.jsx b/src/modules/actionmenu/ActionMenuWithHeader.jsx index 5b5882e772..883d1b24a3 100644 --- a/src/modules/actionmenu/ActionMenuWithHeader.jsx +++ b/src/modules/actionmenu/ActionMenuWithHeader.jsx @@ -26,7 +26,6 @@ export const ActionMenuWithHeader = ({ actions={actions} docs={[file]} anchorOrigin={{ - strategy: 'fixed', vertical: 'bottom', horizontal: 'right' }} diff --git a/src/modules/actions/index.jsx b/src/modules/actions/index.jsx index 5e82c8a7e9..f9df0890d7 100644 --- a/src/modules/actions/index.jsx +++ b/src/modules/actions/index.jsx @@ -17,6 +17,7 @@ import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { downloadFiles, restoreFiles } from './utils' +import { HOME_LINK_HREF } from 'constants/config' import { isEncryptedFolder, isEncryptedFile } from 'lib/encryption' import { navigateToModal } from 'modules/actions/helpers' import DeleteConfirm from 'modules/drive/DeleteConfirm' @@ -37,6 +38,7 @@ export const download = ({ client, t, vaultClient, showAlert }) => { // Then, we do not display the download button when the selection // includes an encrypted folder or several encrypted files return ( + files.length > 0 && !files.some(file => isEncryptedFolder(file)) && !(files.length > 1 && files.some(file => isEncryptedFile(file))) ) @@ -67,15 +69,21 @@ export const hr = () => { } } -export const trash = ({ t, pushModal, popModal, hasWriteAccess, refresh }) => { - const label = t('SelectionBar.trash') +export const trash = ({ + t, + pushModal, + popModal, + hasWriteAccess, + refresh, + byDocId, + isOwner +}) => { const icon = TrashIcon return { name: 'trash', - label, icon, - displayCondition: () => hasWriteAccess, + displayCondition: files => files.length > 0 && hasWriteAccess, action: files => pushModal( { /> ), Component: forwardRef(function Trash(props, ref) { + const sharedWithMe = + byDocId !== undefined && + byDocId[props.docs[0].id] && + !isOwner(props.docs[0].id) + const label = sharedWithMe ? t('toolbar.leave') : t('SelectionBar.trash') + return ( @@ -209,3 +223,35 @@ export const restore = ({ t, refresh, client }) => { }) } } + +export const openExternalLink = ({ t, isSharingShortcutCreated, link }) => { + const label = + link === HOME_LINK_HREF + ? t('Share.create-cozy') + : isSharingShortcutCreated + ? t('toolbar.menu_sync_cozy') + : t('toolbar.add_to_mine') + const icon = + !isSharingShortcutCreated || link === HOME_LINK_HREF + ? 'to-the-cloud' + : 'sync' + + return { + name: 'openExternalLink', + label, + icon, + action: () => { + openExternalLink(link) + }, + Component: forwardRef(function OpenExternalLink(props, ref) { + return ( + + + + + + + ) + }) + } +} diff --git a/src/modules/breadcrumb/components/DesktopBreadcrumb.jsx b/src/modules/breadcrumb/components/DesktopBreadcrumb.jsx index e61b01a035..5eb37d305b 100644 --- a/src/modules/breadcrumb/components/DesktopBreadcrumb.jsx +++ b/src/modules/breadcrumb/components/DesktopBreadcrumb.jsx @@ -1,12 +1,12 @@ import React, { useEffect, useMemo, useState } from 'react' +import ActionsMenu from 'cozy-ui/transpiled/react/ActionsMenu' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import BreadcrumbMui from 'cozy-ui/transpiled/react/Breadcrumbs' import Icon from 'cozy-ui/transpiled/react/Icon' import FolderIcon from 'cozy-ui/transpiled/react/Icons/Folder' import RightIcon from 'cozy-ui/transpiled/react/Icons/Right' -import ActionMenu, { - ActionMenuItem -} from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import IconServer from 'assets/icons/icon-server.svg' @@ -28,13 +28,15 @@ const DesktopBreadcrumb = ({ onBreadcrumbClick, path }) => { ) const [menuDisplayed, setMenuDisplayed] = useState(false) + const closeMenu = () => setMenuDisplayed(false) + const handleDropdownTriggerClick = e => { e.stopPropagation() setMenuDisplayed(true) } useEffect(() => { - setMenuDisplayed(false) + closeMenu() setDropdownTrigger(document.querySelector(`[aria-label="${expandText}"]`)) }, [path]) // eslint-disable-line react-hooks/exhaustive-deps @@ -43,7 +45,7 @@ const DesktopBreadcrumb = ({ onBreadcrumbClick, path }) => { if (trigger) { trigger.addEventListener('click', handleDropdownTriggerClick) return () => { - setMenuDisplayed(false) + closeMenu() trigger.removeEventListener('click', handleDropdownTriggerClick) } } @@ -115,36 +117,29 @@ const DesktopBreadcrumb = ({ onBreadcrumbClick, path }) => { {menuDisplayed && ( - { - setMenuDisplayed(false) - }} - popperOptions={{ - placement: 'bottom-end', - modifiers: [ - { - name: 'offset', - options: { - offset: [0, 10] - } - } - ] + {path.slice(1, -2).map(breadcrumbPath => ( - { e.stopPropagation() onBreadcrumbClick(breadcrumbPath) }} > - {breadcrumbPath.name} - + + ))} - + )} ) diff --git a/src/modules/breadcrumb/components/DesktopBreadcrumb.spec.jsx b/src/modules/breadcrumb/components/DesktopBreadcrumb.spec.jsx index 3e6deda6e6..faf160e7e0 100644 --- a/src/modules/breadcrumb/components/DesktopBreadcrumb.spec.jsx +++ b/src/modules/breadcrumb/components/DesktopBreadcrumb.spec.jsx @@ -7,15 +7,15 @@ import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import DesktopBreadcrumb from './DesktopBreadcrumb' import { dummyBreadcrumbPath } from 'test/dummies/dummyBreadcrumbPath' -jest.mock('cozy-ui/transpiled/react/deprecated/ActionMenu', () => ({ - __esModule: true, - // eslint-disable-next-line react/display-name - default: ({ children }) =>
{children}
, - // eslint-disable-next-line react/display-name - ActionMenuItem: ({ children }) => ( -
{children}
- ) -})) +jest.mock('cozy-ui/transpiled/react/ActionsMenu', () => ({ children }) => ( +
{children}
+)) +jest.mock( + 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem', + () => + ({ children }) => +
{children}
+) jest.mock('cozy-ui/transpiled/react/providers/I18n') describe('DesktopBreadcrumb', () => { @@ -53,6 +53,12 @@ describe('DesktopBreadcrumb', () => { }) describe('mount', () => { + beforeEach(() => { + jest.spyOn(console, 'error').mockImplementation(() => {}) + }) + afterEach(() => { + console.error.mockRestore() + }) it('should hide menu displayed while navigating', async () => { // Given const { container, queryByTestId, rerender } = await render( diff --git a/src/modules/drive/AddMenu/AddMenu.jsx b/src/modules/drive/AddMenu/AddMenu.jsx index 3196259719..8bedf602c8 100644 --- a/src/modules/drive/AddMenu/AddMenu.jsx +++ b/src/modules/drive/AddMenu/AddMenu.jsx @@ -1,8 +1,10 @@ import React from 'react' import flag from 'cozy-flags' -import Typography from 'cozy-ui/transpiled/react/Typography' -import ActionMenu from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ActionsMenu from 'cozy-ui/transpiled/react/ActionsMenu' +import ActionsMenuMobileHeader from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuMobileHeader' +import Divider from 'cozy-ui/transpiled/react/Divider' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' @@ -23,25 +25,27 @@ export const ActionMenuContent = ({ refreshFolderContent, isPublic, isEncryptedFolder, - displayedFolder + displayedFolder, + onClick }) => { const { t } = useI18n() - const { isMobile, isDesktop } = useBreakpoints() + const { isDesktop } = useBreakpoints() const { hasScanner } = useScannerContext() return ( <> - {isMobile && ( - <> - - {t('toolbar.menu_add')} - -
- + + + + + {canCreateFolder && !isEncryptedFolder && ( + )} - {canCreateFolder && !isEncryptedFolder && } {canCreateFolder && !isPublic && flag('drive.enable-encryption') && ( - + )} {!isPublic && !isEncryptedFolder && ( @@ -54,17 +58,18 @@ export const ActionMenuContent = ({ )} {!isEncryptedFolder && ( - + )} - {canUpload &&
} + {canUpload && } {canUpload && ( )} - {hasScanner && } + {hasScanner && } ) } @@ -82,13 +87,12 @@ const AddMenu = ({ ...actionMenuProps }) => { return ( - - + ) } diff --git a/src/modules/drive/Toolbar/components/AddEncryptedFolderItem.jsx b/src/modules/drive/Toolbar/components/AddEncryptedFolderItem.jsx index 546a935e52..b546c4806d 100644 --- a/src/modules/drive/Toolbar/components/AddEncryptedFolderItem.jsx +++ b/src/modules/drive/Toolbar/components/AddEncryptedFolderItem.jsx @@ -2,24 +2,33 @@ import React from 'react' import { connect } from 'react-redux' import { useVaultUnlockContext } from 'cozy-keys-lib' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import { showNewFolderInput, encryptedFolder } from 'modules/filelist/duck' import EncryptedFolderIcon from 'modules/views/Folder/EncryptedFolderIcon' -const AddEncryptedFolderItem = ({ addEncryptedFolder }) => { +const AddEncryptedFolderItem = ({ addEncryptedFolder, onClick }) => { const { t } = useI18n() const { showUnlockForm } = useVaultUnlockContext() + const handleClick = () => { + showUnlockForm({ onUnlock: addEncryptedFolder }) + onClick() + } + return ( - showUnlockForm({ onUnlock: addEncryptedFolder })} - left={} + onClick={handleClick} > - {t('toolbar.menu_new_encrypted_folder')} - + + + + + ) } diff --git a/src/modules/drive/Toolbar/components/AddFolderItem.jsx b/src/modules/drive/Toolbar/components/AddFolderItem.jsx index 27e1f1ea1c..08ca823bcc 100644 --- a/src/modules/drive/Toolbar/components/AddFolderItem.jsx +++ b/src/modules/drive/Toolbar/components/AddFolderItem.jsx @@ -1,22 +1,28 @@ import React from 'react' import { connect } from 'react-redux' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import Icon from 'cozy-ui/transpiled/react/Icon' import IconFolder from 'cozy-ui/transpiled/react/Icons/FileTypeFolder' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { translate } from 'cozy-ui/transpiled/react/providers/I18n' import { showNewFolderInput } from 'modules/filelist/duck' -const AddFolderItem = translate()(({ t, addFolder }) => { +const AddFolderItem = translate()(({ t, addFolder, onClick }) => { + const handleClick = () => { + addFolder() + onClick() + } + return ( - } - > - {t('toolbar.menu_new_folder')} - + + + + + + ) }) const mapDispatchToProps = dispatch => ({ diff --git a/src/modules/drive/Toolbar/components/AddMenuItem.jsx b/src/modules/drive/Toolbar/components/AddMenuItem.jsx index 5aeb82f241..fa3e0916ae 100644 --- a/src/modules/drive/Toolbar/components/AddMenuItem.jsx +++ b/src/modules/drive/Toolbar/components/AddMenuItem.jsx @@ -1,13 +1,15 @@ import React, { useContext } from 'react' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import Icon from 'cozy-ui/transpiled/react/Icon' import PlusIcon from 'cozy-ui/transpiled/react/Icons/Plus' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import { AddMenuContext } from 'modules/drive/AddMenu/AddMenuProvider' -const AddMenuItem = () => { +const AddMenuItem = ({ onClick }) => { const { t } = useI18n() const { @@ -19,18 +21,24 @@ const AddMenuItem = () => { a11y } = useContext(AddMenuContext) + const handleClick = () => { + isOffline ? handleOfflineClick() : handleToggle() + onClick() + } + return ( -
- } - disabled={isDisabled || isOffline} - icon={PlusIcon} - onClick={handleToggle} - {...a11y} - > - {t('toolbar.menu_add_item')} - -
+ + + } /> + + + ) } diff --git a/src/modules/drive/Toolbar/components/CreateNoteItem.jsx b/src/modules/drive/Toolbar/components/CreateNoteItem.jsx index aea07179c5..0529b6d756 100644 --- a/src/modules/drive/Toolbar/components/CreateNoteItem.jsx +++ b/src/modules/drive/Toolbar/components/CreateNoteItem.jsx @@ -10,10 +10,12 @@ import { } from 'cozy-client' import { isFlagshipApp } from 'cozy-device-helper' import { useWebviewIntent } from 'cozy-intent' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import { generateUniversalLink } from 'cozy-ui/transpiled/react/AppLinker/native' import Icon from 'cozy-ui/transpiled/react/Icon' import IconNote from 'cozy-ui/transpiled/react/Icons/FileTypeNote' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { translate } from 'cozy-ui/transpiled/react/providers/I18n' const CreateNoteItem = ({ client, t, displayedFolder }) => { @@ -53,38 +55,39 @@ const CreateNoteItem = ({ client, t, displayedFolder }) => { } } - return ( - } - onClick={async () => { - if (notesAppUrl === undefined) return - if (notesAppIsInstalled) { - const { data: file } = await client.create('io.cozy.notes', { - dir_id: displayedFolder.id - }) + const handleClick = async () => { + if (notesAppUrl === undefined) return + if (notesAppIsInstalled) { + const { data: file } = await client.create('io.cozy.notes', { + dir_id: displayedFolder.id + }) - const privateUrl = await models.note.generatePrivateUrl( - notesAppUrl, - file, - { returnUrl } - ) + const privateUrl = await models.note.generatePrivateUrl( + notesAppUrl, + file, + { returnUrl } + ) - /** - * Not using AppLinker here because it would require too much refactoring and would be risky - * Instead we use the webviewIntent programmatically to open the cozy-note app on the note href - */ - if (isFlagshipApp() && webviewIntent) - return webviewIntent.call('openApp', privateUrl, { slug: 'notes' }) + /** + * Not using AppLinker here because it would require too much refactoring and would be risky + * Instead we use the webviewIntent programmatically to open the cozy-note app on the note href + */ + if (isFlagshipApp() && webviewIntent) + return webviewIntent.call('openApp', privateUrl, { slug: 'notes' }) - window.location.href = privateUrl - } else { - window.location.href = notesAppUrl - } - }} - > - {t('toolbar.menu_create_note')} - + window.location.href = privateUrl + } else { + window.location.href = notesAppUrl + } + } + + return ( + + + + + + ) } diff --git a/src/modules/drive/Toolbar/components/CreateOnlyOfficeItem.jsx b/src/modules/drive/Toolbar/components/CreateOnlyOfficeItem.jsx index 1b96fc6ca1..bf59e68f02 100644 --- a/src/modules/drive/Toolbar/components/CreateOnlyOfficeItem.jsx +++ b/src/modules/drive/Toolbar/components/CreateOnlyOfficeItem.jsx @@ -1,8 +1,10 @@ import React, { useCallback, useMemo } from 'react' import { useParams, useNavigate } from 'react-router-dom' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import Icon from 'cozy-ui/transpiled/react/Icon' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import { ROOT_DIR_ID } from 'constants/config' @@ -30,9 +32,12 @@ const CreateOnlyOfficeItem = ({ fileClass }) => { ) return ( - }> - {t(`toolbar.menu_onlyOffice.${fileClass}`)} - + + + + + + ) } diff --git a/src/modules/drive/Toolbar/components/CreateShortcut.jsx b/src/modules/drive/Toolbar/components/CreateShortcut.jsx index 4406511251..77e9834c0a 100644 --- a/src/modules/drive/Toolbar/components/CreateShortcut.jsx +++ b/src/modules/drive/Toolbar/components/CreateShortcut.jsx @@ -2,24 +2,30 @@ import React from 'react' import { showModal } from 'react-cozy-helpers' import { connect } from 'react-redux' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import Icon from 'cozy-ui/transpiled/react/Icon' import DeviceBrowserIcon from 'cozy-ui/transpiled/react/Icons/DeviceBrowser' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import ShortcutCreationModal from './ShortcutCreationModal' -const CreateShortcutWrapper = ({ openModal }) => { +const CreateShortcutWrapper = ({ openModal, onClick }) => { const { t } = useI18n() + const handleClick = () => { + openModal() + onClick() + } + return ( - } - onClick={openModal} - > - {t('toolbar.menu_create_shortcut')} - + + + + + + ) } diff --git a/src/modules/drive/Toolbar/components/DownloadButtonItem.jsx b/src/modules/drive/Toolbar/components/DownloadButtonItem.jsx index d70eba678e..c15b0d6cbe 100644 --- a/src/modules/drive/Toolbar/components/DownloadButtonItem.jsx +++ b/src/modules/drive/Toolbar/components/DownloadButtonItem.jsx @@ -3,9 +3,11 @@ import React from 'react' import { connect } from 'react-redux' import { withClient } from 'cozy-client' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import Icon from 'cozy-ui/transpiled/react/Icon' import DownloadIcon from 'cozy-ui/transpiled/react/Icons/Download' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert' import { translate } from 'cozy-ui/transpiled/react/providers/I18n' @@ -15,12 +17,15 @@ const DownloadButtonItem = ({ t, downloadAll, displayedFolder }) => { const { showAlert } = useAlert() return ( - } + downloadAll([displayedFolder], showAlert, t)} > - {t('toolbar.menu_download_folder')} - + + + + + ) } diff --git a/src/modules/drive/Toolbar/components/MoreMenu.jsx b/src/modules/drive/Toolbar/components/MoreMenu.jsx index c4227d8a63..e21a18e328 100644 --- a/src/modules/drive/Toolbar/components/MoreMenu.jsx +++ b/src/modules/drive/Toolbar/components/MoreMenu.jsx @@ -1,8 +1,9 @@ -import React, { useState, useCallback } from 'react' +import React, { useState, useCallback, useRef } from 'react' import { isIOSApp } from 'cozy-device-helper' import { useSharingContext } from 'cozy-sharing' -import ActionMenu from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ActionsMenu from 'cozy-ui/transpiled/react/ActionsMenu' +import Divider from 'cozy-ui/transpiled/react/Divider' import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints' import { MoreButton } from 'components/Button' @@ -41,10 +42,11 @@ const MoreMenu = ({ displayedFolder, folderId, showSelectionBar, - isSelectionBarVisible + isSelectionBarVisible, + isSharedWithMe }) => { const [menuIsVisible, setMenuVisible] = useState(false) - const anchorRef = React.createRef() + const anchorRef = useRef() const { isMobile } = useBreakpoints() const { allLoaded } = useSharingContext() // We need to wait for the sharing context to be completely loaded to avoid race conditions @@ -70,12 +72,15 @@ const MoreMenu = ({ isSelectionBarVisible={isSelectionBarVisible} > {menuIsVisible && ( - {isMobile && allLoaded && ( @@ -93,18 +98,20 @@ const MoreMenu = ({ {isMobile && hasWriteAccess && } - + {hasWriteAccess && ( -
- {/* TODO DeleteItem needs props */} - + +
)} -
+ )} diff --git a/src/modules/drive/Toolbar/components/Scanner/Scanner.spec.tsx b/src/modules/drive/Toolbar/components/Scanner/Scanner.spec.tsx index ea6c6111ec..8e117908a8 100644 --- a/src/modules/drive/Toolbar/components/Scanner/Scanner.spec.tsx +++ b/src/modules/drive/Toolbar/components/Scanner/Scanner.spec.tsx @@ -10,10 +10,10 @@ import { uploadFiles } from 'modules/navigation/duck' // @ts-expect-error Component is not typed import AppLike from 'test/components/AppLike' -const MockApp = ({ id = 'test' }): JSX.Element => ( +const MockApp = ({ id = 'test', onClick = jest.fn() }): JSX.Element => ( - + ) @@ -94,9 +94,10 @@ describe('Scanner', () => { return Promise.resolve(false) }) }) + const onClickMock = jest.fn() // Render the component under test - const { queryByTestId } = render() + const { queryByTestId } = render() // Wait for the scan-doc element to be clickable and then simulate a click event await waitFor(() => { @@ -114,6 +115,7 @@ describe('Scanner', () => { const calls = mockUploadFiles.mock.calls as unknown[][] + expect(onClickMock).toBeCalledTimes(1) expect(calls[0][0]).toEqual([mockFile]) // File expect(calls[0][1]).toBe('test') // Directory ID expect(calls[0][2]).toEqual({ isScanned: true }) // Upload options diff --git a/src/modules/drive/Toolbar/components/Scanner/ScannerMenuItem.tsx b/src/modules/drive/Toolbar/components/Scanner/ScannerMenuItem.tsx index cc990d1679..db554a891b 100644 --- a/src/modules/drive/Toolbar/components/Scanner/ScannerMenuItem.tsx +++ b/src/modules/drive/Toolbar/components/Scanner/ScannerMenuItem.tsx @@ -1,29 +1,46 @@ import React from 'react' +import logger from 'cozy-logger' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import Icon from 'cozy-ui/transpiled/react/Icon' import CameraIcon from 'cozy-ui/transpiled/react/Icons/Camera' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import { useScannerContext } from 'modules/drive/Toolbar/components/Scanner/ScannerProvider' +const log = logger.namespace('Toolbar/components/Scanner/ScannerMenuItem') + /** * Renders a scanner menu item. * @returns The JSX element representing the scanner menu item. */ -export const ScannerMenuItem = (): JSX.Element | null => { +interface ScannerMenuItemProps { + onClick: () => void +} + +export const ScannerMenuItem = ({ + onClick +}: ScannerMenuItemProps): JSX.Element | null => { const { t } = useI18n() const { hasScanner, startScanner } = useScannerContext() + const handleClick = (): void => { + if (startScanner) { + startScanner().catch((error: Error) => { + log('error', `Failed to start scanner: ${error.message}`) + }) + } + onClick() + } + return hasScanner ? ( -
- } - data-testid="scan-doc" - > - {t('Scan.scan_a_doc')} - -
+ + + + + + ) : null } diff --git a/src/modules/drive/Toolbar/components/UploadItem.jsx b/src/modules/drive/Toolbar/components/UploadItem.jsx index 9117669337..9d9c0e8482 100644 --- a/src/modules/drive/Toolbar/components/UploadItem.jsx +++ b/src/modules/drive/Toolbar/components/UploadItem.jsx @@ -5,39 +5,47 @@ import { compose } from 'redux' import { useClient } from 'cozy-client' import { useVaultClient } from 'cozy-keys-lib' import withSharingState from 'cozy-sharing/dist/hoc/withSharingState' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import FileInput from 'cozy-ui/transpiled/react/FileInput' import Icon from 'cozy-ui/transpiled/react/Icon' import UploadIcon from 'cozy-ui/transpiled/react/Icons/Upload' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert' import { translate } from 'cozy-ui/transpiled/react/providers/I18n' import { uploadFiles } from 'modules/navigation/duck' -const UploadItem = ({ t, isDisabled, onUpload, displayedFolder }) => { +const UploadItem = ({ t, isDisabled, onUpload, displayedFolder, onClick }) => { const client = useClient() const vaultClient = useVaultClient() const { showAlert } = useAlert() + const handleClick = evt => { + evt.stopPropagation() + } + const handleChange = files => { + onUpload(client, vaultClient, files, displayedFolder, showAlert) + onClick() + } + return ( - onUpload(client, vaultClient, files, displayedFolder, showAlert) - } + onChange={handleChange} data-testid="upload-btn" value={[]} // FileInput needs to stay rendered until the onChange event, so we prevent the event from bubbling - onClick={e => e.stopPropagation()} + onClick={handleClick} > - } - onClick={e => e.stopPropagation()} - > - {t('toolbar.menu_upload')} - + + + + + + ) } diff --git a/src/modules/drive/Toolbar/delete/DeleteItem.jsx b/src/modules/drive/Toolbar/delete/DeleteItem.jsx index 5d6f5e23a7..0dc4ca50d3 100644 --- a/src/modules/drive/Toolbar/delete/DeleteItem.jsx +++ b/src/modules/drive/Toolbar/delete/DeleteItem.jsx @@ -2,40 +2,33 @@ import compose from 'lodash/flowRight' import PropTypes from 'prop-types' import React from 'react' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import Icon from 'cozy-ui/transpiled/react/Icon' import TrashIcon from 'cozy-ui/transpiled/react/Icons/Trash' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { translate } from 'cozy-ui/transpiled/react/providers/I18n' import deleteContainer from './delete' -const DeleteItem = ({ - t, - isSharedWithMe, - trashFolder, - onLeave, - displayedFolder -}) => { - return isSharedWithMe ? ( - } - onClick={() => - onLeave(displayedFolder).then(() => trashFolder(displayedFolder)) - } - > - {t('toolbar.leave')} - - ) : ( - { + const handleClick = () => { + trashFolder(displayedFolder) + } + + const label = isSharedWithMe ? t('toolbar.leave') : t('toolbar.trash') + + return ( + } - onClick={() => { - trashFolder(displayedFolder) - }} + isListItem + onClick={handleClick} > - {t('toolbar.trash')} - + + + + + ) } @@ -43,7 +36,6 @@ DeleteItem.propTypes = { t: PropTypes.func.isRequired, isSharedWithMe: PropTypes.bool.isRequired, trashFolder: PropTypes.func.isRequired, - onLeave: PropTypes.func.isRequired, displayedFolder: PropTypes.object.isRequired } diff --git a/src/modules/drive/Toolbar/index.jsx b/src/modules/drive/Toolbar/index.jsx index 18e1f8de14..8b81f609e9 100644 --- a/src/modules/drive/Toolbar/index.jsx +++ b/src/modules/drive/Toolbar/index.jsx @@ -23,7 +23,8 @@ const Toolbar = ({ disabled, canUpload, canCreateFolder, - hasWriteAccess + hasWriteAccess, + isSharedWithMe }) => { const { displayedFolder } = useDisplayedFolder() const { isMobile } = useBreakpoints() @@ -73,6 +74,7 @@ const Toolbar = ({ { ) : ( {sharingProps => { - const { hasWriteAccess } = sharingProps + const { hasWriteAccess, isSharedWithMe } = sharingProps return ( diff --git a/src/modules/drive/Toolbar/selectable/SelectableItem.jsx b/src/modules/drive/Toolbar/selectable/SelectableItem.jsx index b110d45dd1..4f12684e1b 100644 --- a/src/modules/drive/Toolbar/selectable/SelectableItem.jsx +++ b/src/modules/drive/Toolbar/selectable/SelectableItem.jsx @@ -1,30 +1,31 @@ import PropTypes from 'prop-types' import React from 'react' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import Icon from 'cozy-ui/transpiled/react/Icon' import CheckSquareIcon from 'cozy-ui/transpiled/react/Icons/CheckSquare' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' /** * Action to show the selection bar */ -const SelectableItem = ({ showSelectionBar }) => { +const SelectableItem = ({ onClick }) => { const { t } = useI18n() return ( - } - onClick={showSelectionBar} - > - {t('toolbar.menu_select')} - + + + + + + ) } SelectableItem.propTypes = { - /** Function to show the selection bar coming from SelectionBar */ - showSelectionBar: PropTypes.func.isRequired + onClick: PropTypes.func.isRequired } export default SelectableItem diff --git a/src/modules/drive/Toolbar/share/ShareItem.jsx b/src/modules/drive/Toolbar/share/ShareItem.jsx index e73c55e1b1..cb240b536d 100644 --- a/src/modules/drive/Toolbar/share/ShareItem.jsx +++ b/src/modules/drive/Toolbar/share/ShareItem.jsx @@ -3,15 +3,15 @@ import { useNavigate, useLocation } from 'react-router-dom' import { SharedDocument } from 'cozy-sharing' import { AvatarList } from 'cozy-sharing/dist/components/Avatar/AvatarList' +import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem' import Icon from 'cozy-ui/transpiled/react/Icon' import ShareIcon from 'cozy-ui/transpiled/react/Icons/Share' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' +import ListItemText from 'cozy-ui/transpiled/react/ListItemText' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import { getPathToShareDisplayedFolder } from 'modules/drive/Toolbar/share/helpers' -import styles from 'styles/toolbar.styl' - const ShareItem = ({ displayedFolder }) => { const { t } = useI18n() const navigate = useNavigate() @@ -24,26 +24,19 @@ const ShareItem = ({ displayedFolder }) => { return ( {({ isSharedWithMe, recipients, link }) => ( - } - right={ -
- -
- } - > - {t( - isSharedWithMe - ? 'Files.share.sharedWithMe' - : 'toolbar.menu_share_folder' - )} -
+ + + + + + + )}
) diff --git a/src/modules/public/LightFileViewer.jsx b/src/modules/public/LightFileViewer.jsx index 5a4af961ba..e7590ddcca 100644 --- a/src/modules/public/LightFileViewer.jsx +++ b/src/modules/public/LightFileViewer.jsx @@ -7,9 +7,8 @@ import { BarCenter } from 'cozy-bar' import { SharingBannerPlugin, useSharingInfos } from 'cozy-sharing' import MidEllipsis from 'cozy-ui/transpiled/react/MidEllipsis' import Typography from 'cozy-ui/transpiled/react/Typography' -import FooterActionButtons from 'cozy-ui/transpiled/react/Viewer/Footer/FooterActionButtons' -import ForwardOrDownloadButton from 'cozy-ui/transpiled/react/Viewer/Footer/ForwardOrDownloadButton' import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints' +import { FooterActionButtons, ForwardOrDownloadButton } from 'cozy-viewer' import PublicToolbar from 'modules/public/PublicToolbar' import PublicViewer from 'modules/viewer/PublicViewer' diff --git a/src/modules/public/PublicToolbarByLink.jsx b/src/modules/public/PublicToolbarByLink.jsx index 6ef8f6e586..6063d8d2a2 100644 --- a/src/modules/public/PublicToolbarByLink.jsx +++ b/src/modules/public/PublicToolbarByLink.jsx @@ -1,18 +1,21 @@ import { useDisplayedFolder } from 'hooks' import React from 'react' -import Icon from 'cozy-ui/transpiled/react/Icon' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import { useClient } from 'cozy-client' +import { makeActions } from 'cozy-ui/transpiled/react/ActionsMenu/Actions' +import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert' import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import { BarRightOnMobile } from 'components/Bar' import { HOME_LINK_HREF } from 'constants/config' +import { download, openExternalLink } from 'modules/actions' import AddMenuProvider from 'modules/drive/AddMenu/AddMenuProvider' import AddButton from 'modules/drive/Toolbar/components/AddButton' +import AddMenuItem from 'modules/drive/Toolbar/components/AddMenuItem' +import SelectableItem from 'modules/drive/Toolbar/selectable/SelectableItem' import { DownloadFilesButton } from 'modules/public/DownloadButton' import PublicToolbarMoreMenu from 'modules/public/PublicToolbarMoreMenu' -import { isFilesIsFile, openExternalLink } from 'modules/public/helpers' import { useSelectionContext } from 'modules/selection/SelectionProvider' const PublicToolbarByLink = ({ @@ -20,52 +23,54 @@ const PublicToolbarByLink = ({ hasWriteAccess, refreshFolderContent }) => { - const isFile = isFilesIsFile(files) const { isMobile } = useBreakpoints() + const client = useClient() + const { showAlert } = useAlert() const { t } = useI18n() const { displayedFolder } = useDisplayedFolder() const { showSelectionBar, isSelectionBarVisible } = useSelectionContext() - const shouldDisplayMoreMenu = isMobile || (!isFile && files.length > 0) + const actionOptions = { + client, + t, + showAlert, + isPublic: true, + link: HOME_LINK_HREF + } + const actions = makeActions( + [isMobile && files.length > 0 && download, isMobile && openExternalLink], + actionOptions + ) return ( - <> - - + + {!isMobile && ( + <> + {hasWriteAccess && } + {files.length > 0 && ( + + )} + + )} + - {!isMobile && ( - <> - {hasWriteAccess && } - {files.length > 0 && ( - - )} - - )} - {shouldDisplayMoreMenu && ( - - {isMobile && ( - openExternalLink(HOME_LINK_HREF)} - left={} - > - {t('Share.create-cozy')} - - )} - - )} - - - + {isMobile && hasWriteAccess && } + {files.length > 1 && } + + + ) } diff --git a/src/modules/public/PublicToolbarCozyToCozy.jsx b/src/modules/public/PublicToolbarCozyToCozy.jsx index a4ca744818..e94c73ebad 100644 --- a/src/modules/public/PublicToolbarCozyToCozy.jsx +++ b/src/modules/public/PublicToolbarCozyToCozy.jsx @@ -1,14 +1,16 @@ import React from 'react' -import Icon from 'cozy-ui/transpiled/react/Icon' -import { ActionMenuItem } from 'cozy-ui/transpiled/react/deprecated/ActionMenu' +import { useClient } from 'cozy-client' +import { makeActions } from 'cozy-ui/transpiled/react/ActionsMenu/Actions' +import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert' import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import { BarRightOnMobile } from 'components/Bar' +import { download, openExternalLink } from 'modules/actions' +import SelectableItem from 'modules/drive/Toolbar/selectable/SelectableItem' import { DownloadFilesButton } from 'modules/public/DownloadButton' import PublicToolbarMoreMenu from 'modules/public/PublicToolbarMoreMenu' -import { isFilesIsFile, openExternalLink } from 'modules/public/helpers' import { useSelectionContext } from 'modules/selection/SelectionProvider' const PublicToolbarCozyToCozy = ({ @@ -16,33 +18,35 @@ const PublicToolbarCozyToCozy = ({ discoveryLink, files }) => { - const isFile = isFilesIsFile(files) const { isMobile } = useBreakpoints() const { t } = useI18n() const { showSelectionBar } = useSelectionContext() + const client = useClient() + const { showAlert } = useAlert() - const shouldDisplayMoreMenu = isMobile || (!isFile && files.length > 0) + const actionOptions = { + client, + t, + showAlert, + isPublic: true, + isSharingShortcutCreated, + link: discoveryLink + } + const actions = makeActions( + [isMobile && files.length > 0 && download, openExternalLink], + actionOptions + ) return ( {!isMobile && files.length > 0 && } - {shouldDisplayMoreMenu && ( - - openExternalLink(discoveryLink)} - left={ - - } - > - {isSharingShortcutCreated - ? t('toolbar.menu_sync_cozy') - : t('toolbar.add_to_mine')} - - - )} + + {files.length > 1 && } + ) } diff --git a/src/modules/public/PublicToolbarMoreMenu.jsx b/src/modules/public/PublicToolbarMoreMenu.jsx index 2c098dac55..ce94483c84 100644 --- a/src/modules/public/PublicToolbarMoreMenu.jsx +++ b/src/modules/public/PublicToolbarMoreMenu.jsx @@ -1,30 +1,14 @@ +import cx from 'classnames' import React, { useState, useCallback, useRef } from 'react' -import { useClient } from 'cozy-client' -import Icon from 'cozy-ui/transpiled/react/Icon' -import ActionMenu, { - ActionMenuItem -} from 'cozy-ui/transpiled/react/deprecated/ActionMenu' -import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert' +import ActionsMenu from 'cozy-ui/transpiled/react/ActionsMenu' import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints' -import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' import { MoreButton } from 'components/Button' -import { downloadFiles } from 'modules/actions/utils' -import AddMenuItem from 'modules/drive/Toolbar/components/AddMenuItem' -import SelectableItem from 'modules/drive/Toolbar/selectable/SelectableItem' -const PublicToolbarMoreMenu = ({ - files, - hasWriteAccess, - children, - showSelectionBar -}) => { - const anchorRef = useRef() - const { t } = useI18n() - const client = useClient() +const PublicToolbarMoreMenu = ({ files, actions, children }) => { + const moreButtonRef = useRef() const { isMobile } = useBreakpoints() - const { showAlert } = useAlert() const [menuIsVisible, setMenuVisible] = useState(false) @@ -37,25 +21,33 @@ const PublicToolbarMoreMenu = ({ return ( <> -
+
{menuIsVisible && ( - - {children} - {isMobile && files.length > 0 && ( - downloadFiles(client, files, { showAlert, t })} - left={} - > - {t('toolbar.menu_download')} - - )} - {isMobile && hasWriteAccess && } - {files.length > 1 && ( - - )} - + + {React.Children.map(children, child => { + if (React.isValidElement(child)) { + return React.cloneElement(child, { + onClick: () => { + child.props.onClick?.() + closeMenu() + } + }) + } + })} + )} ) diff --git a/src/modules/viewer/FileOpenerExternal.jsx b/src/modules/viewer/FileOpenerExternal.jsx index e604157c82..71cf1b1ad5 100644 --- a/src/modules/viewer/FileOpenerExternal.jsx +++ b/src/modules/viewer/FileOpenerExternal.jsx @@ -12,14 +12,15 @@ import { RemoveScroll } from 'react-remove-scroll' import { useNavigate, useParams } from 'react-router-dom' import Spinner from 'cozy-ui/transpiled/react/Spinner' -import Viewer from 'cozy-ui/transpiled/react/Viewer' -import FooterActionButtons from 'cozy-ui/transpiled/react/Viewer/Footer/FooterActionButtons' -import ForwardOrDownloadButton from 'cozy-ui/transpiled/react/Viewer/Footer/ForwardOrDownloadButton' -import SharingButton from 'cozy-ui/transpiled/react/Viewer/Footer/Sharing' -import ToolbarButtons from 'cozy-ui/transpiled/react/Viewer/components/ToolbarButtons' import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert' import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints' import { translate, useI18n } from 'cozy-ui/transpiled/react/providers/I18n' +import Viewer, { + FooterActionButtons, + ForwardOrDownloadButton, + ToolbarButtons, + SharingButton +} from 'cozy-viewer' import Fallback from 'modules/viewer/Fallback' import { diff --git a/src/modules/viewer/FilesViewer.jsx b/src/modules/viewer/FilesViewer.jsx index 37a9c19222..7e27e3bf52 100644 --- a/src/modules/viewer/FilesViewer.jsx +++ b/src/modules/viewer/FilesViewer.jsx @@ -6,13 +6,14 @@ import { useNavigate } from 'react-router-dom' import { Q, useClient } from 'cozy-client' import { isIOSApp } from 'cozy-device-helper' import { useVaultClient } from 'cozy-keys-lib' -import Viewer from 'cozy-ui/transpiled/react/Viewer' -import FooterActionButtons from 'cozy-ui/transpiled/react/Viewer/Footer/FooterActionButtons' -import ForwardOrDownloadButton from 'cozy-ui/transpiled/react/Viewer/Footer/ForwardOrDownloadButton' -import SharingButton from 'cozy-ui/transpiled/react/Viewer/Footer/Sharing' -import ToolbarButtons from 'cozy-ui/transpiled/react/Viewer/components/ToolbarButtons' import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' +import Viewer, { + FooterActionButtons, + ForwardOrDownloadButton, + ToolbarButtons, + SharingButton +} from 'cozy-viewer' import { FilesViewerLoading } from 'components/FilesViewerLoading' import { diff --git a/src/modules/viewer/FilesViewer.spec.jsx b/src/modules/viewer/FilesViewer.spec.jsx index 8513b48e9d..bb2cf4f77b 100644 --- a/src/modules/viewer/FilesViewer.spec.jsx +++ b/src/modules/viewer/FilesViewer.spec.jsx @@ -22,7 +22,11 @@ jest.mock('lib/encryption', () => ({ jest.mock('hooks') -jest.mock('cozy-ui/transpiled/react/Viewer', () => () =>
Viewer
) +jest.mock('cozy-viewer', () => ({ + ...jest.requireActual('cozy-viewer'), + __esModule: true, + default: () =>
Viewer
+})) const sleep = duration => new Promise(resolve => setTimeout(resolve, duration)) diff --git a/src/modules/viewer/PublicViewer.jsx b/src/modules/viewer/PublicViewer.jsx index 987f3697a8..bb5308bbee 100644 --- a/src/modules/viewer/PublicViewer.jsx +++ b/src/modules/viewer/PublicViewer.jsx @@ -2,7 +2,7 @@ import { pdfjs } from 'react-pdf' import createWorker from 'react-pdf/dist/esm/pdf.worker.entry' -import Viewer from 'cozy-ui/transpiled/react/Viewer' +import Viewer from 'cozy-viewer' pdfjs.GlobalWorkerOptions.workerPort = createWorker() diff --git a/src/modules/views/Drive/DriveFolderView.jsx b/src/modules/views/Drive/DriveFolderView.jsx index 4de6b77ab9..71d8a896fb 100644 --- a/src/modules/views/Drive/DriveFolderView.jsx +++ b/src/modules/views/Drive/DriveFolderView.jsx @@ -63,7 +63,8 @@ const DriveFolderView = () => { const { isMobile } = useBreakpoints() const { t, lang } = useI18n() const { isFabDisplayed, setIsFabDisplayed } = useContext(FabContext) - const { allLoaded, hasWriteAccess, refresh } = useSharingContext() + const { allLoaded, hasWriteAccess, refresh, isOwner, byDocId } = + useSharingContext() const client = useClient() const vaultClient = useVaultClient() const { pushModal, popModal } = useModalContext() @@ -156,7 +157,9 @@ const DriveFolderView = () => { canMove: true, isPublic: false, allLoaded, - showAlert + showAlert, + isOwner, + byDocId } const actions = makeActions( [ diff --git a/src/modules/views/OnlyOffice/Editor.spec.jsx b/src/modules/views/OnlyOffice/Editor.spec.jsx index c4625513bc..97fd6a6235 100644 --- a/src/modules/views/OnlyOffice/Editor.spec.jsx +++ b/src/modules/views/OnlyOffice/Editor.spec.jsx @@ -37,9 +37,11 @@ jest.mock('cozy-client/dist/hooks/useQuery', () => jest.fn()) jest.mock('cozy-flags') jest.mock('modules/views/OnlyOffice/Toolbar', () => () =>
Toolbar
) -jest.mock('cozy-ui/transpiled/react/Viewer', () => () => ( -
-)) +jest.mock('cozy-viewer', () => ({ + ...jest.requireActual('cozy-viewer'), + __esModule: true, + default: () =>
+})) const client = createMockClient({}) client.plugins = { diff --git a/src/modules/views/OnlyOffice/Error.jsx b/src/modules/views/OnlyOffice/Error.jsx index feb43c9b2b..fe0c0e79bd 100644 --- a/src/modules/views/OnlyOffice/Error.jsx +++ b/src/modules/views/OnlyOffice/Error.jsx @@ -3,12 +3,13 @@ import { RemoveScroll } from 'react-remove-scroll' import { isQueryLoading, useQuery } from 'cozy-client' import Spinner from 'cozy-ui/transpiled/react/Spinner' -import Viewer from 'cozy-ui/transpiled/react/Viewer' -import FooterActionButtons from 'cozy-ui/transpiled/react/Viewer/Footer/FooterActionButtons' -import ForwardOrDownloadButton from 'cozy-ui/transpiled/react/Viewer/Footer/ForwardOrDownloadButton' -import SharingButton from 'cozy-ui/transpiled/react/Viewer/Footer/Sharing' -import ToolbarButtons from 'cozy-ui/transpiled/react/Viewer/components/ToolbarButtons' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' +import Viewer, { + FooterActionButtons, + ForwardOrDownloadButton, + ToolbarButtons, + SharingButton +} from 'cozy-viewer' import Oops from 'components/Error/Oops' import { useOnlyOfficeContext } from 'modules/views/OnlyOffice/OnlyOfficeProvider' diff --git a/src/modules/views/Public/PublicFileViewer.jsx b/src/modules/views/Public/PublicFileViewer.jsx index 75f99bb2a9..f6be655295 100644 --- a/src/modules/views/Public/PublicFileViewer.jsx +++ b/src/modules/views/Public/PublicFileViewer.jsx @@ -2,8 +2,7 @@ import { useCurrentFolderId } from 'hooks' import React, { useMemo, useEffect, useState } from 'react' import { useParams, useNavigate } from 'react-router-dom' -import FooterActionButtons from 'cozy-ui/transpiled/react/Viewer/Footer/FooterActionButtons' -import ForwardOrDownloadButton from 'cozy-ui/transpiled/react/Viewer/Footer/ForwardOrDownloadButton' +import { FooterActionButtons, ForwardOrDownloadButton } from 'cozy-viewer' import { FilesViewerLoading } from 'components/FilesViewerLoading' import PublicViewer from 'modules/viewer/PublicViewer' diff --git a/src/modules/views/Public/PublicFolderView.jsx b/src/modules/views/Public/PublicFolderView.jsx index 4e86d591d3..19315cf0ee 100644 --- a/src/modules/views/Public/PublicFolderView.jsx +++ b/src/modules/views/Public/PublicFolderView.jsx @@ -15,7 +15,10 @@ import { useSharingInfos } from 'cozy-sharing' import { Content } from 'cozy-ui/transpiled/react' -import { makeActions } from 'cozy-ui/transpiled/react/ActionsMenu/Actions' +import { + divider, + makeActions +} from 'cozy-ui/transpiled/react/ActionsMenu/Actions' import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert' import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints' import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' @@ -76,7 +79,7 @@ const PublicFolderView = () => { const { isSelectionBarVisible } = useSelectionContext() const { hasWritePermissions } = usePublicWritePermissions() const { pushModal, popModal } = useModalContext() - const { refresh } = useSharingContext() + const { refresh, isOwner, byDocId } = useSharingContext() const dispatch = useDispatch() const sharingInfos = useSharingInfos() const { showAlert } = useAlert() @@ -117,10 +120,12 @@ const PublicFolderView = () => { pathname, hasWriteAccess: hasWritePermissions, canMove: false, - isPublic: true + isPublic: true, + isOwner, + byDocId } const actions = makeActions( - [download, trash, rename, versions], + [download, rename, versions, divider, trash], actionOptions ) diff --git a/src/modules/views/Recent/index.jsx b/src/modules/views/Recent/index.jsx index d38b931c9d..ef1a7eab39 100644 --- a/src/modules/views/Recent/index.jsx +++ b/src/modules/views/Recent/index.jsx @@ -46,7 +46,7 @@ export const RecentView = () => { const { isMobile } = useBreakpoints() const client = useClient() const { pushModal, popModal } = useModalContext() - const { allLoaded, refresh } = useSharingContext() + const { allLoaded, refresh, isOwner, byDocId } = useSharingContext() const dispatch = useDispatch() useHead() const { showAlert } = useAlert() @@ -79,7 +79,9 @@ export const RecentView = () => { canMove: true, isPublic: false, allLoaded, - showAlert + showAlert, + isOwner, + byDocId } const actions = makeActions( diff --git a/src/modules/views/Sharings/SharingsFolderView.jsx b/src/modules/views/Sharings/SharingsFolderView.jsx index 7618b1b3ac..56b41f7620 100644 --- a/src/modules/views/Sharings/SharingsFolderView.jsx +++ b/src/modules/views/Sharings/SharingsFolderView.jsx @@ -47,7 +47,8 @@ const SharingsFolderView = ({ sharedDocumentIds }) => { const { t } = useI18n() const { showAlert } = useAlert() const client = useClient() - const { allLoaded, hasWriteAccess, refresh } = useSharingContext() + const { allLoaded, hasWriteAccess, refresh, isOwner, byDocId } = + useSharingContext() const { pushModal, popModal } = useModalContext() const dispatch = useDispatch() const { displayedFolder, isNotFound } = useDisplayedFolder() @@ -96,7 +97,9 @@ const SharingsFolderView = ({ sharedDocumentIds }) => { pathname, hasWriteAccess: hasWrite, canMove: true, - allLoaded + allLoaded, + isOwner, + byDocId } const actions = makeActions( [share, download, trash, rename, moveTo, qualify, versions], diff --git a/src/styles/toolbar.styl b/src/styles/toolbar.styl index 789ee98603..b745f8518d 100644 --- a/src/styles/toolbar.styl +++ b/src/styles/toolbar.styl @@ -23,12 +23,3 @@ .fil-toolbar-trash margin-left auto display flex - -.menu-recipients-wrapper - position relative - -.menu-recipients - position absolute - right 0 - top -.5rem - diff --git a/src/targets/browser/index.jsx b/src/targets/browser/index.jsx index a6cf56d058..24c239eb6c 100644 --- a/src/targets/browser/index.jsx +++ b/src/targets/browser/index.jsx @@ -5,6 +5,7 @@ // otherwise the themes will not be supplied and the app crashes import 'cozy-ui/transpiled/react/stylesheet.css' import 'cozy-ui/dist/cozy-ui.utils.min.css' +import 'cozy-viewer/dist/stylesheet.css' import 'cozy-bar/dist/stylesheet.css' import 'cozy-sharing/dist/stylesheet.css' diff --git a/src/targets/intents/index.jsx b/src/targets/intents/index.jsx index c2a81990b7..745cb8e17f 100644 --- a/src/targets/intents/index.jsx +++ b/src/targets/intents/index.jsx @@ -3,6 +3,7 @@ import 'cozy-ui/transpiled/react/stylesheet.css' import 'cozy-ui/dist/cozy-ui.utils.min.css' +import 'cozy-viewer/dist/stylesheet.css' import 'cozy-sharing/dist/stylesheet.css' import 'whatwg-fetch' diff --git a/src/targets/public/index.jsx b/src/targets/public/index.jsx index b7c907d651..5f59a2086f 100644 --- a/src/targets/public/index.jsx +++ b/src/targets/public/index.jsx @@ -5,6 +5,7 @@ // otherwise the themes will not be supplied and the app crashes import 'cozy-ui/transpiled/react/stylesheet.css' import 'cozy-ui/dist/cozy-ui.utils.min.css' +import 'cozy-viewer/dist/stylesheet.css' import 'cozy-bar/dist/stylesheet.css' import 'cozy-sharing/dist/stylesheet.css' diff --git a/yarn.lock b/yarn.lock index 96a77f134e..2d6d9bc01f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3692,11 +3692,6 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - "@types/prettier@^2.0.0": version "2.4.4" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17" @@ -4647,13 +4642,6 @@ axios-retry@^4.5.0: dependencies: is-retry-allowed "^2.2.0" -axios@^0.21.1: - version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" - integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== - dependencies: - follow-redirects "^1.14.0" - axios@^1.7.5: version "1.7.7" resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" @@ -5289,13 +5277,6 @@ builtins@^1.0.3: resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= -bundlemon-utils@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/bundlemon-utils/-/bundlemon-utils-0.4.0.tgz#52220218faf11f985cce0951ecbd158969d54fec" - integrity sha512-BqYhoCgkPNgdN3ORpj2Xqphj+OQ4iHGBqq9KfM2aQpj+RAauVS2F0EAe77ZXpme2JLbLJq6MyrUOHoeXvB2lGA== - dependencies: - bytes "^3.1.0" - bundlemon-utils@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/bundlemon-utils/-/bundlemon-utils-2.0.1.tgz#c1c31365432da9ab1f6b703e1f486d3d989cb283" @@ -5320,22 +5301,6 @@ bundlemon@3.1.0: micromatch "^4.0.8" yup "^0.32.11" -bundlemon@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/bundlemon/-/bundlemon-1.3.2.tgz#164a038b1f4e8f520119367d3ba3b11a2372d19d" - integrity sha512-Mc2OWqZK2rJge6htxeFtK6imjgyOPn8mniH7RcqUv4GLeNG7LWbu+p9QNbW2tEWtuk+AKhkBZdlNCdo1KP4v8Q== - dependencies: - axios "^0.21.1" - brotli-size "^4.0.0" - bundlemon-utils "^0.4.0" - bytes "^3.1.0" - chalk "^4.1.1" - commander "^8.0.0" - cosmiconfig "^7.0.0" - gzip-size "^6.0.0" - micromatch "^4.0.4" - yup "^0.32.11" - bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -5526,7 +5491,7 @@ chalk@3, chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: +chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -5953,11 +5918,6 @@ commander@^2.18.0, commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^8.0.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -6167,17 +6127,6 @@ cosmiconfig@^5.0.0: js-yaml "^3.13.1" parse-json "^4.0.0" -cosmiconfig@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" - integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - cosmiconfig@^8.3.6: version "8.3.6" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" @@ -6374,6 +6323,17 @@ cozy-doctypes@^1.91.1: lodash "^4.17.19" prop-types "^15.7.2" +cozy-doctypes@^1.97.1: + version "1.97.1" + resolved "https://registry.yarnpkg.com/cozy-doctypes/-/cozy-doctypes-1.97.1.tgz#115b0ad53c0135f4bce7b23a7107d884b9961161" + integrity sha512-8E9fn6U+IabV6vdsbBHbe09px+PV/utMvfmSheWCYt7nekAyTawiUZk0/kYXf1rRu0Hl7gaP6QfycccZDte4iQ== + dependencies: + cozy-logger "^1.16.1" + date-fns "^1.30.1" + es6-promise-pool "^2.5.0" + lodash "^4.17.19" + prop-types "^15.7.2" + cozy-flags@^2.8.7: version "2.12.0" resolved "https://registry.yarnpkg.com/cozy-flags/-/cozy-flags-2.12.0.tgz#bc3d689db9c91389c28f053223142d4684573ef1" @@ -6388,16 +6348,16 @@ cozy-flags@^4.6.1: dependencies: microee "^0.0.6" -cozy-harvest-lib@^30.0.0: - version "30.0.0" - resolved "https://registry.yarnpkg.com/cozy-harvest-lib/-/cozy-harvest-lib-30.0.0.tgz#2966a120d7177acc8cd9c8127a4581d1ec131031" - integrity sha512-hnlY/7ZZrEeY7tyIjBro2yU78zhRCW3sPqmJKBMkjvamyd3iu6NZqweUv/zsqhtgUAbf0b317LpRuCPnaaglYA== +cozy-harvest-lib@^30.6.4: + version "30.6.4" + resolved "https://registry.yarnpkg.com/cozy-harvest-lib/-/cozy-harvest-lib-30.6.4.tgz#fbe4850614a6e6af53ef100eec10e0e95ef6baec" + integrity sha512-kNKzCAdltHfXZAOeUX09pEufMXIC5J7WBl2u0pwlYSvlBRoZJvE24dGDuCQhmIeCqtB3RXVWokhIERG6IQ+f8A== dependencies: "@cozy/minilog" "^1.0.0" classnames "^2.3.1" cozy-bi-auth "0.0.25" - cozy-doctypes "^1.91.1" - cozy-logger "^1.10.4" + cozy-doctypes "^1.97.1" + cozy-logger "^1.16.1" date-fns "^1.30.1" final-form "^4.18.5" lodash "^4.17.19" @@ -6534,6 +6494,14 @@ cozy-logger@^1.10.4: chalk "^2.4.2" json-stringify-safe "5.0.1" +cozy-logger@^1.16.1: + version "1.16.1" + resolved "https://registry.yarnpkg.com/cozy-logger/-/cozy-logger-1.16.1.tgz#f2ce38711ce71287908fb1efaae3c7274bf6c7fa" + integrity sha512-ntzxu3vEwwSZqgGG3d6EnFoG8nfL4+dzCYOspmgg+S1BvHk9+nctq2SybOk5eB9P4ccrBNYQNJ4WtrZuCJRUVw== + dependencies: + chalk "^2.4.2" + json-stringify-safe "5.0.1" + cozy-logger@^1.3.0: version "1.7.0" resolved "https://registry.yarnpkg.com/cozy-logger/-/cozy-logger-1.7.0.tgz#945ff84df66f7e7e9640db00f8c632d4ff776fc8" @@ -6677,16 +6645,15 @@ cozy-tsconfig@1.2.0: resolved "https://registry.yarnpkg.com/cozy-tsconfig/-/cozy-tsconfig-1.2.0.tgz#17e61f960f139fae4d26cbac2254b9ab632b269e" integrity sha512-TRHnY9goF3FzVlUbP7BcHxuN2XAA4AmppT4fHHZmTKaSwYTByVR1Al+riFMDbce94kJZ1wzl9WNLWQuqzGZ6Cw== -cozy-ui@^111.21.0: - version "111.21.0" - resolved "https://registry.yarnpkg.com/cozy-ui/-/cozy-ui-111.21.0.tgz#ecac0c446d65f87c07ffa24e245ab30dfcc130b3" - integrity sha512-mAFWSCVba18GBHe70Piij3RYr1hhdOpURD7Si1YyfiMJS9hlxZXJerzlJF6JWKq3CsNcKJAfYT4NiULyfp8y4g== +cozy-ui@^113.3.0: + version "113.3.0" + resolved "https://registry.yarnpkg.com/cozy-ui/-/cozy-ui-113.3.0.tgz#2acd1818a329ec4b8288ca7d603db8580f4ce249" + integrity sha512-D3SMBVBCIA4FFyoiqYeduJtRASlKaLgHAFJ0dSZ4mTc1GcBX++86Y2fU5WcohAtmLtdDoWPD2J4GdhcrzEvYdw== dependencies: "@babel/runtime" "^7.3.4" "@material-ui/core" "4.12.3" "@material-ui/lab" "^4.0.0-alpha.61" "@popperjs/core" "^2.4.4" - bundlemon "^1.3.2" chart.js "3.7.1" classnames "^2.2.5" cozy-interapp "^0.5.4" @@ -6702,13 +6669,23 @@ cozy-ui@^111.21.0: piwik-react-router "0.12.1" react-chartjs-2 "4.1.0" react-markdown "^4.0.8" - react-pdf "^5.7.2" react-popper "^2.2.3" react-remove-scroll "^2.4.0" react-select "^4.3.0" react-swipeable-views "^0.13.3" rooks "^5.11.2" +cozy-viewer@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/cozy-viewer/-/cozy-viewer-2.9.0.tgz#6b847c4d794172778cc1994b3ff12787a5f1bbef" + integrity sha512-P1RkMz39EsVXH8CH2cb+ovEziZM5RlNkZhHLTqeyvHma5Nh01djcAwhbHo7/Sv1NB+aUsgl9bt+PlrYPMoPfnA== + dependencies: + classnames "^2.2.5" + hammerjs "^2.0.8" + lodash "4.17.21" + react-markdown "^4.0.8" + react-pdf "^5.7.2" + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -9043,7 +9020,7 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" -follow-redirects@^1.0.0, follow-redirects@^1.14.0: +follow-redirects@^1.0.0: version "1.14.8" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== @@ -18681,11 +18658,6 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - yargs-parser@^11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"