From 391a8e6578f1e7a936d0edfaad8f21644118aab2 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Tue, 3 Aug 2021 15:35:30 +0200 Subject: [PATCH 01/31] fix reloading the loader and other components (#1391) --- .../FileBrowsers/CopyToSharedFolderModal.tsx | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CopyToSharedFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/CopyToSharedFolderModal.tsx index cd27e20620..6bde63894f 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CopyToSharedFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/CopyToSharedFolderModal.tsx @@ -197,13 +197,7 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => const classes = useStyles() const { isCreatingSharedFolder, handleCreateSharedFolder } = useCreateOrEditSharedFolder() const [sharedFolderName, setSharedFolderName] = useState("") - const { - sharedFolderReaders, - sharedFolderWriters, - handleLookupUser, - onNewUsers, - usersError - } = useLookupSharedFolderUser() + const { sharedFolderReaders, sharedFolderWriters, handleLookupUser, onNewUsers, usersError } = useLookupSharedFolderUser() const [isUsingCurrentBucket, setIsUsingCurrentBucket] = useState(true) const [currentStep, setCurrentStep] = useState("1_SHARED_FOLDER_SELECTION_CREATION") const [destinationBucket, setDestinationBucket] = useState() @@ -285,7 +279,6 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => let fileContent: Blob | undefined try { - console.log("filePath", filePath) fileContent = await getFile({ file, filePath }) } catch(e) { setError(t`Error while downloading ${file.name}`) @@ -334,7 +327,7 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => } }, [close, currentStep]) - const Loader = () => ( + const Loader = useCallback(() => (
{isUploading && Encrypting and uploading…}
- ) + ), [classes.loadingContainer, isDownloading, isUploading]) - const Step1CreateSharedFolder = () => ( + const Step1CreateSharedFolder = useCallback(() => ( <>
}}/>
- ) + ), [ + classes.inputLabel, + classes.modalFlexItem, + classes.shareFolderNameInput, + handleLookupUser, + onNewUsers, + sharedFolderName, + sharedFolderReaders, + sharedFolderWriters + ]) - const Step1ExistingSharedFolder = () => ( + const Step1ExistingSharedFolder = useCallback(() => (
onChange={(val: string) => setDestinationBucket(buckets.find((bu) => bu.id === val))} />
- ) + ), [buckets, bucketsOptions, classes.inputLabel, classes.inputWrapper, classes.modalFlexItem, destinationBucket]) return ( Date: Tue, 3 Aug 2021 17:54:35 +0200 Subject: [PATCH 02/31] Fix test with onboard bump (#1395) * fix test with onboard bump * align versions * lint * for storage --- packages/files-ui/cypress/support/commands.ts | 3 ++- .../cypress/support/page-objects/authenticationPage.ts | 3 ++- packages/files-ui/package.json | 2 +- packages/files-ui/src/App.tsx | 3 ++- packages/gaming-ui/package.json | 2 +- packages/storage-ui/cypress/support/commands.ts | 6 ++++-- .../cypress/support/page-objects/authenticationPage.ts | 3 ++- packages/storage-ui/package.json | 2 +- packages/storage-ui/src/App.tsx | 3 ++- yarn.lock | 4 ++-- 10 files changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/files-ui/cypress/support/commands.ts b/packages/files-ui/cypress/support/commands.ts index 99c0f37aaa..ba719f728f 100644 --- a/packages/files-ui/cypress/support/commands.ts +++ b/packages/files-ui/cypress/support/commands.ts @@ -144,7 +144,8 @@ Cypress.Commands.add( if (local.length === 0) { cy.log("nothing in session storage, --> click on web3 button") authenticationPage.web3Button().click() - authenticationPage.metaMaskButton().click() + authenticationPage.showMoreButton().click() + authenticationPage.detectedWallet().click() authenticationPage.web3SignInButton().click() authenticationPage.loginPasswordButton().click() authenticationPage.loginPasswordInput().type(`${testAccountPassword}{enter}`) diff --git a/packages/files-ui/cypress/support/page-objects/authenticationPage.ts b/packages/files-ui/cypress/support/page-objects/authenticationPage.ts index ddce450bab..2c408c7cd3 100644 --- a/packages/files-ui/cypress/support/page-objects/authenticationPage.ts +++ b/packages/files-ui/cypress/support/page-objects/authenticationPage.ts @@ -5,7 +5,8 @@ export const authenticationPage = { // get started section elements web3Button: () => cy.get("[data-cy=web3]"), - metaMaskButton: () => cy.get(".bn-onboard-modal-select-wallets > :nth-child(1) > .bn-onboard-custom"), + showMoreButton: () => cy.get("div.svelte-q1527 > .bn-onboard-custom"), + detectedWallet: () => cy.get(":nth-child(3) > .bn-onboard-custom > span.svelte-1799bj2"), web3SignInButton: () => cy.get("[data-cy=sign-in-with-web3-button]"), // sign in section elements diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index 9a03b8f223..29949ef7c3 100644 --- a/packages/files-ui/package.json +++ b/packages/files-ui/package.json @@ -25,7 +25,7 @@ "clsx": "^1.1.1", "dayjs": "^1.9.7", "eth-crypto": "^1.8.0", - "ethers": "^5.1.4", + "ethers": "^5.4.3", "formik": "^2.2.5", "mime-matcher": "^1.0.5", "react": "^16.14.0", diff --git a/packages/files-ui/src/App.tsx b/packages/files-ui/src/App.tsx index 8e6035e525..636ba61141 100644 --- a/packages/files-ui/src/App.tsx +++ b/packages/files-ui/src/App.tsx @@ -55,7 +55,8 @@ const onboardConfig = { walletName: "walletConnect", infuraKey: "a7e16429d2254d488d396710084e2cd3", preferred: true - } + }, + { walletName: "detectedwallet" } ] } } diff --git a/packages/gaming-ui/package.json b/packages/gaming-ui/package.json index a05cd49f52..fe1ede2968 100644 --- a/packages/gaming-ui/package.json +++ b/packages/gaming-ui/package.json @@ -22,7 +22,7 @@ "clsx": "^1.1.1", "dayjs": "^1.9.7", "eth-crypto": "^1.8.0", - "ethers": "^5.1.4", + "ethers": "^5.4.3", "formik": "^2.2.5", "mime-matcher": "^1.0.5", "react": "^16.14.0", diff --git a/packages/storage-ui/cypress/support/commands.ts b/packages/storage-ui/cypress/support/commands.ts index 4c49fa4b5f..a248d2b293 100644 --- a/packages/storage-ui/cypress/support/commands.ts +++ b/packages/storage-ui/cypress/support/commands.ts @@ -137,7 +137,8 @@ Cypress.Commands.add( if (local.length === 0) { cy.log("nothing in local storage, --> click on web3 button") authenticationPage.web3Button().click() - authenticationPage.metaMaskButton().click() + authenticationPage.showMoreButton().click() + authenticationPage.detectedWallet().click() // eslint-disable-next-line cypress/no-unnecessary-waiting cy.wait(1000) authenticationPage.web3SignInButton().click() @@ -156,7 +157,8 @@ Cypress.Commands.add( // Temp work around for local storage being cleared after the reload cy.log("nothing in local storage after reload, --> click on web3 button") authenticationPage.web3Button().click() - authenticationPage.metaMaskButton().click() + authenticationPage.showMoreButton().click() + authenticationPage.detectedWallet().click() // eslint-disable-next-line cypress/no-unnecessary-waiting cy.wait(1000) authenticationPage.web3SignInButton().click() diff --git a/packages/storage-ui/cypress/support/page-objects/authenticationPage.ts b/packages/storage-ui/cypress/support/page-objects/authenticationPage.ts index ccd7a616d2..ef5dc889ad 100644 --- a/packages/storage-ui/cypress/support/page-objects/authenticationPage.ts +++ b/packages/storage-ui/cypress/support/page-objects/authenticationPage.ts @@ -5,6 +5,7 @@ export const authenticationPage = { // get started section elements web3Button: () => cy.get("[data-cy=web3]", { timeout: 120000 }), - metaMaskButton: () => cy.get(".bn-onboard-modal-select-wallets > :nth-child(1) > .bn-onboard-custom"), + showMoreButton: () => cy.get("div.svelte-q1527 > .bn-onboard-custom"), + detectedWallet: () => cy.get(":nth-child(3) > .bn-onboard-custom > span.svelte-1799bj2"), web3SignInButton: () => cy.get("[data-cy=sign-in-with-web3-button]") } diff --git a/packages/storage-ui/package.json b/packages/storage-ui/package.json index a35d981d24..ab7e7b4467 100644 --- a/packages/storage-ui/package.json +++ b/packages/storage-ui/package.json @@ -22,7 +22,7 @@ "clsx": "^1.1.1", "dayjs": "^1.9.7", "eth-crypto": "^1.8.0", - "ethers": "^5.1.4", + "ethers": "^5.4.3", "formik": "^2.2.5", "is-ipfs": "^6.0.1", "mime-matcher": "^1.0.5", diff --git a/packages/storage-ui/src/App.tsx b/packages/storage-ui/src/App.tsx index 4c2f3c3da5..4e8a7fca4f 100644 --- a/packages/storage-ui/src/App.tsx +++ b/packages/storage-ui/src/App.tsx @@ -50,7 +50,8 @@ const onboardConfig = { walletName: "walletConnect", infuraKey: "a7e16429d2254d488d396710084e2cd3", preferred: true - } + }, + { walletName: "detectedwallet" } ] } } diff --git a/yarn.lock b/yarn.lock index 1f26e97730..c8ac4ec39c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12010,7 +12010,7 @@ ethers@5.0.13: "@ethersproject/web" "^5.0.6" "@ethersproject/wordlists" "^5.0.4" -ethers@^5.0.13: +ethers@^5.0.13, ethers@^5.4.3: version "5.4.3" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.4.3.tgz#9469e7f353285caac4114467eb2618f755a3f7d0" integrity sha512-esWqdrFZObpyZyhH6VLHCz5vRA/YJrEmQO77sALWSWFjFtJr5ITIRwJ448N+mxIrvnqjZGQ2Jx2zC3xt5lc64g== @@ -12046,7 +12046,7 @@ ethers@^5.0.13: "@ethersproject/web" "5.4.0" "@ethersproject/wordlists" "5.4.0" -ethers@^5.1.0, ethers@^5.1.4: +ethers@^5.1.0: version "5.1.4" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.1.4.tgz#8ae973705ed962f8f41dc59693704002a38dd18b" integrity sha512-EAPQ/fgGRu0PoR/VNFnHTMOtG/IZ0AItdW55C9T8ffmVu0rnyllZL404eBF66elJehOLz2kxnUrhXpE7TCpW7g== From fccae7d12e501eab97042ecd65a9fc00b108a406 Mon Sep 17 00:00:00 2001 From: Ryan Noble Date: Tue, 3 Aug 2021 21:45:10 +0200 Subject: [PATCH 03/31] Adding buckets user logic (#1394) * Init * Sharing user names * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Updated for feedback * Apply suggestions from code review Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> --- packages/files-ui/package.json | 2 +- .../CreateOrEditSharedFolderModal.tsx | 5 +++-- .../views/FileSystemItem/SharedFolderRow.tsx | 17 +++++++++++++---- packages/files-ui/src/Contexts/FilesContext.tsx | 14 +++++++++++--- packages/storage-ui/package.json | 2 +- yarn.lock | 13 ++++--------- 6 files changed, 33 insertions(+), 20 deletions(-) diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index 29949ef7c3..7367de5ef6 100644 --- a/packages/files-ui/package.json +++ b/packages/files-ui/package.json @@ -6,7 +6,7 @@ "@babel/core": "^7.12.10", "@babel/runtime": "^7.0.0", "@chainsafe/browser-storage-hooks": "^1.0.1", - "@chainsafe/files-api-client": "1.17.7", + "@chainsafe/files-api-client": "1.17.9", "@chainsafe/web3-context": "1.1.4", "@lingui/core": "^3.7.2", "@lingui/react": "^3.7.2", diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx index d01c8f90d5..3764d7f086 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx @@ -21,6 +21,7 @@ import { useEffect } from "react" import { SharedFolderModalMode } from "./types" import { useCreateOrEditSharedFolder } from "./hooks/useCreateOrEditSharedFolder" import { useLookupSharedFolderUser } from "./hooks/useLookupUser" +import { centerEllipsis } from "../../../Utils/Helpers" const useStyles = makeStyles( ({ breakpoints, constants, typography, zIndex, palette }: CSFTheme) => { @@ -136,14 +137,14 @@ const CreateOrEditSharedFolderModal = ({ mode, isModalOpen, onClose, bucketToEdi if (!bucketToEdit) return const newWriters = bucketToEdit.writers.map((writer) => ({ - label: writer.uuid || "", + label: writer.username || centerEllipsis(writer.public_address.toLowerCase(), 6) || writer.uuid, value: writer.uuid || "", data: writer }) ) || [] const newReaders = bucketToEdit.readers.map((reader) => ({ - label: reader.uuid || "", + label: reader.username || centerEllipsis(reader.public_address.toLowerCase(), 6) || reader.uuid, value: reader.uuid || "", data: reader }) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx index b87d09ba08..9f68bf5bcf 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx @@ -16,7 +16,7 @@ import { UserShareSvg } from "@chainsafe/common-components" import { CSFTheme } from "../../../../../Themes/types" -import { BucketUser } from "@chainsafe/files-api-client" +import { LookupUser } from "@chainsafe/files-api-client" import { desktopSharedGridSettings, mobileSharedGridSettings } from "../../SharedFoldersOverview" import SharedUsers from "../../../../Elements/SharedUser" import { t, Trans } from "@lingui/macro" @@ -25,6 +25,7 @@ import clsx from "clsx" import { BucketKeyPermission } from "../../../../../Contexts/FilesContext" import UserBubble from "../../../../Elements/UserBubble" import { renameSchema } from "../../../../../Utils/validationSchema" +import { centerEllipsis } from "../../../../../Utils/Helpers" const useStyles = makeStyles(({ breakpoints, constants, palette }: CSFTheme) => { @@ -200,13 +201,21 @@ const SharedFolderRow = ({ bucket, handleRename, openSharedFolder, handleDeleteS click(e) } - const getUserIds = (users: BucketUser[]): string[] => { + const getUserLabels = (users: LookupUser[]): string[] => { return users.reduce((acc: string[], user): string[] => { + if (user.username !== "") { + return user.username ? [...acc, user.username] : acc + } + + if (user.public_address !== "") { + return user.public_address ? [...acc, centerEllipsis(user.public_address.toLowerCase(), 6)] : acc + } + return user.uuid ? [...acc, user.uuid] : acc }, [] as string[]) } - const userIds = [...getUserIds(bucket.owners), ...getUserIds(bucket.readers), ...getUserIds(bucket.writers)] + const userLabels = [...getUserLabels(bucket.owners), ...getUserLabels(bucket.readers), ...getUserLabels(bucket.writers)] const formik = useFormik({ initialValues:{ @@ -284,7 +293,7 @@ const SharedFolderRow = ({ bucket, handleRename, openSharedFolder, handleDeleteS align="left" className={classes.sharedUser} > - + {desktop && diff --git a/packages/files-ui/src/Contexts/FilesContext.tsx b/packages/files-ui/src/Contexts/FilesContext.tsx index e157c2ddad..faf7153a2a 100644 --- a/packages/files-ui/src/Contexts/FilesContext.tsx +++ b/packages/files-ui/src/Contexts/FilesContext.tsx @@ -5,7 +5,8 @@ import { Bucket as FilesBucket, SearchEntry, BucketFileFullInfoResponse, - BucketSummaryResponse + BucketSummaryResponse, + LookupUser } from "@chainsafe/files-api-client" import React, { useCallback, useEffect, useReducer } from "react" import { useState } from "react" @@ -67,9 +68,12 @@ interface GetFileContentParams { export type BucketPermission = "writer" | "owner" | "reader" -export type BucketKeyPermission = FilesBucket & { +export type BucketKeyPermission = Omit & { encryptionKey: string permission?: BucketPermission + owners: LookupUser[] + writers: LookupUser[] + readers: LookupUser[] } type FilesContext = { @@ -187,10 +191,14 @@ const FilesProvider = ({ children }: FilesContextProps) => { const bucketsWithKeys: BucketKeyPermission[] = await Promise.all( result.map(async (b) => { + const userData = await filesApiClient.getBucketUsers(b.id) return { ...b, encryptionKey: await getKeyForBucket(b) || "", - permission: getPermissionForBucket(b) + permission: getPermissionForBucket(b), + owners: userData.owners || [], + writers: userData.writers || [], + readers: userData.readers || [] } }) ) diff --git a/packages/storage-ui/package.json b/packages/storage-ui/package.json index ab7e7b4467..2c0e66d5f8 100644 --- a/packages/storage-ui/package.json +++ b/packages/storage-ui/package.json @@ -6,7 +6,7 @@ "@babel/core": "^7.12.10", "@babel/runtime": "^7.0.0", "@chainsafe/browser-storage-hooks": "^1.0.1", - "@chainsafe/files-api-client": "1.17.8", + "@chainsafe/files-api-client": "1.17.9", "@chainsafe/web3-context": "1.1.4", "@lingui/core": "^3.7.2", "@lingui/react": "^3.7.2", diff --git a/yarn.lock b/yarn.lock index c8ac4ec39c..3716259ee0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1662,15 +1662,10 @@ resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.17.5.tgz#35dd9c4baf0833ee9b654495979ed1a66fb02f8d" integrity sha512-5L7bAJr3siPgadDkGwhfo31MCkda01v/rTkLxUta13g6QG+pu0oKDoug+dtm8f9EPoH/rI89L2JHFM7XFrYveQ== -"@chainsafe/files-api-client@1.17.7": - version "1.17.7" - resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.17.7.tgz#aa8618eab659f9fc5baeef1134bdfcddba6dfc28" - integrity sha512-xqqSNlFqhx1UkgxSKzwB9KKvWztI0+WlRgLw4vikwEjQojSbX4ygrq5QfkDovi+lGAPGpeNTKaHlDMZZPyjx2A== - -"@chainsafe/files-api-client@1.17.8": - version "1.17.8" - resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.17.8.tgz#0c52924cce276fc0e54b75c677e1d68e21d9cb5d" - integrity sha512-EJLGuDAPBsWfOe5CJ7SRpR2iywUEY0/iVO4tYvnWoT0j5ik100RNPQzVClD4B7yO8qPBneMtMBVldD0gNkqBWQ== +"@chainsafe/files-api-client@1.17.9": + version "1.17.9" + resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.17.9.tgz#8c608db1a07dc8bbdb10a1cd21fad00d091deed3" + integrity sha512-5XUs/KlNfAIVbqKCxtVEbUyWneTn0/kp70blbyCqVwaX1X3e7D2aXX0gy7zR5kMM7yjGsZE7vwA/0oVCaemfig== "@chainsafe/web3-context@1.1.4": version "1.1.4" From a1fd4ca8d1b1486cc5e9e2ef34f67c5396058f55 Mon Sep 17 00:00:00 2001 From: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Date: Wed, 4 Aug 2021 12:25:49 +0300 Subject: [PATCH 04/31] fix preview in search results (#1403) --- .../Modules/FileBrowsers/hooks/useGetFile.tsx | 10 +++++++--- .../src/Components/Modules/FilePreviewModal.tsx | 14 +++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useGetFile.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useGetFile.tsx index 71580b6049..65c34c5221 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useGetFile.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useGetFile.tsx @@ -7,6 +7,7 @@ import { useFileBrowser } from "../../../../Contexts/FileBrowserContext" interface getFilesParams { file: IFileSystemItem filePath: string + bucketId?: string } export const useGetFile = () => { const [isDownloading, setIsDownloading] = useState(false) @@ -16,9 +17,11 @@ export const useGetFile = () => { const source = useRef(null) const { bucket } = useFileBrowser() - const getFile = useCallback(async ({ file, filePath }: getFilesParams) => { + const getFile = useCallback(async ({ file, filePath, bucketId }: getFilesParams) => { const { cid, size } = file - if(!bucket) return + + const id = bucket?.id || bucketId + if (!id) return if (source.current) { source.current.cancel("Cancelling previous request") @@ -37,8 +40,9 @@ export const useGetFile = () => { setError("") try { + const content = await getFileContent( - bucket?.id, + id, { cid, cancelToken, diff --git a/packages/files-ui/src/Components/Modules/FilePreviewModal.tsx b/packages/files-ui/src/Components/Modules/FilePreviewModal.tsx index f8d8beb40d..a1f5783a94 100644 --- a/packages/files-ui/src/Components/Modules/FilePreviewModal.tsx +++ b/packages/files-ui/src/Components/Modules/FilePreviewModal.tsx @@ -160,6 +160,7 @@ const FilePreviewModal = ({ file, nextFile, previousFile, closePreview, filePath const { downloadFile } = useFiles() const [fileContent, setFileContent] = useState() const { bucket } = useFileBrowser() + const { buckets } = useFiles() const { desktop } = useThemeSwitcher() const { cid, content_type, name } = file || {} const { isDownloading, downloadProgress, getFile, error } = useGetFile() @@ -171,11 +172,18 @@ const FilePreviewModal = ({ file, nextFile, previousFile, closePreview, filePath }) useEffect(() => { - - getFile({ file, filePath }) + let bucketId + // Handle preview in Search where a Bucket is not available, but can be assumed to be a `CSF` bucket + // as search results can only currently come from there. + if (!bucket) { + bucketId = buckets.find(b => b.type === "csf")?.id + } else { + bucketId = bucket.id + } + getFile({ file, filePath, bucketId }) .then(setFileContent) .catch(console.error) - }, [file, filePath, getFile]) + }, [file, filePath, getFile, bucket, buckets]) const validRendererMimeType = content_type && From d276d8fe6fe6b90b5254d0d8f2c6af14f7e00bf9 Mon Sep 17 00:00:00 2001 From: Tanmoy Basak Anjan Date: Wed, 4 Aug 2021 15:28:49 +0600 Subject: [PATCH 05/31] breadcrumbs removed (#1400) Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> --- .../src/Components/Pages/SettingsPage.tsx | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/storage-ui/src/Components/Pages/SettingsPage.tsx b/packages/storage-ui/src/Components/Pages/SettingsPage.tsx index 3f82c6e24e..78f89a1910 100644 --- a/packages/storage-ui/src/Components/Pages/SettingsPage.tsx +++ b/packages/storage-ui/src/Components/Pages/SettingsPage.tsx @@ -1,9 +1,7 @@ -import React, { useCallback, useMemo } from "react" +import React, { useCallback } from "react" import { Tabs, TabPane as TabPaneOrigin, Typography, Divider, - Breadcrumb, - Crumb, useParams, useHistory, ITabPaneProps, @@ -137,19 +135,9 @@ const SettingsPage: React.FC = () => { (path: string) => redirect(ROUTE_LINKS.Settings(path as SettingsPath)) , [redirect]) - const crumbs: Crumb[] = useMemo(() => [ - { - text: t`Settings` - } - ], []) - return (
- redirect(ROUTE_LINKS.Cids)} - /> Date: Wed, 4 Aug 2021 15:31:22 +0600 Subject: [PATCH 06/31] Summary size on base 2 (#1398) * using base 2 * update all format bytes Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> --- packages/files-ui/src/Components/Layouts/AppNav.tsx | 4 ++-- .../src/Components/Modules/FileBrowsers/FileInfoModal.tsx | 2 +- .../FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx | 2 +- .../FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx | 2 +- packages/files-ui/src/Components/Modules/Settings/Plan.tsx | 4 ++-- packages/gaming-ui/src/Components/Layouts/AppNav.tsx | 4 ++-- packages/storage-ui/src/Components/Elements/BucketRow.tsx | 2 +- packages/storage-ui/src/Components/Elements/CidRow.tsx | 2 +- .../Components/Modules/FileSystemItem/FileSystemTableItem.tsx | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/files-ui/src/Components/Layouts/AppNav.tsx b/packages/files-ui/src/Components/Layouts/AppNav.tsx index 97da6f94f0..9ccdb21a5d 100644 --- a/packages/files-ui/src/Components/Layouts/AppNav.tsx +++ b/packages/files-ui/src/Components/Layouts/AppNav.tsx @@ -356,8 +356,8 @@ const AppNav: React.FC = ({ navOpen, setNavOpen }: IAppNav) => { variant="body2" className={classes.spaceUsedMargin} component="p" - >{`${formatBytes(storageSummary.used_storage)} of ${formatBytes( - storageSummary.total_storage + >{`${formatBytes(storageSummary.used_storage, 2)} of ${formatBytes( + storageSummary.total_storage, 2 )} used`} { variant="body2" component="p" > - {formatBytes(fullFileInfo.content?.size)} + {formatBytes(fullFileInfo.content?.size, 2)}
)} diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx index 422975d93f..7bdf9e9d28 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx @@ -227,7 +227,7 @@ const FileSystemTableItem = React.forwardRef( } - {!isFolder && formatBytes(size)} + {!isFolder && formatBytes(size, 2)} )} diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx index 9f68bf5bcf..bd88884ba8 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx @@ -297,7 +297,7 @@ const SharedFolderRow = ({ bucket, handleRename, openSharedFolder, handleDeleteS {desktop && - {formatBytes(size)} + {formatBytes(size, 2)} } diff --git a/packages/files-ui/src/Components/Modules/Settings/Plan.tsx b/packages/files-ui/src/Components/Modules/Settings/Plan.tsx index 698f75febb..2302e20a3f 100644 --- a/packages/files-ui/src/Components/Modules/Settings/Plan.tsx +++ b/packages/files-ui/src/Components/Modules/Settings/Plan.tsx @@ -123,8 +123,8 @@ const PlanView: React.FC = () => { variant="body2" className={classes.spaceUsedMargin} component="p" - >{`${formatBytes(storageSummary.used_storage)} of ${formatBytes( - storageSummary.total_storage + >{`${formatBytes(storageSummary.used_storage, 2)} of ${formatBytes( + storageSummary.total_storage, 2 )} used`} = ({ navOpen, setNavOpen }: IAppNav) => { variant="body2" className={classes.spaceUsedMargin} component="p" - >{`${formatBytes(spaceUsed)} of ${formatBytes( - FREE_PLAN_LIMIT + >{`${formatBytes(spaceUsed, 2)} of ${formatBytes( + FREE_PLAN_LIMIT, 2 )} used`} { {bucket.name || bucket.id} - {formatBytes(bucket.size)} + {formatBytes(bucket.size, 2)} { {dayjs(pinStatus.created).format("DD MMM YYYY h:mm a")} - {pinStatus.info?.size ? formatBytes(pinStatus.info?.size) : "-"} + {pinStatus.info?.size ? formatBytes(pinStatus.info?.size, 2) : "-"} {pinStatus.status} diff --git a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx index e641d82ce5..a7ce472ba8 100644 --- a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx +++ b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx @@ -237,7 +237,7 @@ const FileSystemTableItem = React.forwardRef( } - {!isFolder && formatBytes(size)} + {!isFolder && formatBytes(size, 2)} )} From 6dc0c95605a8162590b36bc078b3c0db89e716be Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Wed, 4 Aug 2021 12:20:47 +0200 Subject: [PATCH 07/31] Show users at the top of shared folders browser (#1388) * show users at the top of shared folders browser * rename * fix tooltip position * with helper for display name * lingui extract * ellipsis for uuid Co-authored-by: GitHub Actions --- .../src/Components/Elements/SharedUser.tsx | 53 ------------- .../src/Components/Elements/SharedUsers.tsx | 75 +++++++++++++++++++ .../src/Components/Elements/UserBubble.tsx | 4 +- .../CreateOrEditSharedFolderModal.tsx | 6 +- .../views/FileSystemItem/SharedFolderRow.tsx | 22 +----- .../Modules/FileBrowsers/views/FilesList.tsx | 12 ++- .../files-ui/src/Utils/getUserDisplayName.ts | 6 ++ packages/files-ui/src/locales/de/messages.po | 3 + packages/files-ui/src/locales/en/messages.po | 3 + packages/files-ui/src/locales/es/messages.po | 3 + packages/files-ui/src/locales/fr/messages.po | 3 + packages/files-ui/src/locales/no/messages.po | 3 + 12 files changed, 113 insertions(+), 80 deletions(-) delete mode 100644 packages/files-ui/src/Components/Elements/SharedUser.tsx create mode 100644 packages/files-ui/src/Components/Elements/SharedUsers.tsx create mode 100644 packages/files-ui/src/Utils/getUserDisplayName.ts diff --git a/packages/files-ui/src/Components/Elements/SharedUser.tsx b/packages/files-ui/src/Components/Elements/SharedUser.tsx deleted file mode 100644 index 26126f2ff0..0000000000 --- a/packages/files-ui/src/Components/Elements/SharedUser.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from "react" -import { makeStyles, createStyles, useThemeSwitcher } from "@chainsafe/common-theme" -import UserBubble from "./UserBubble" - -const useStyles = makeStyles(() => { - return createStyles({ - root: { - display: "flex" - } - }) -}) -interface Props { - sharedUsers: string[] -} - -const SharedUsers = ({ sharedUsers }: Props) => { - const classes = useStyles() - const { desktop } = useThemeSwitcher() - - if (!sharedUsers.length) { - return null - } - - if (!desktop) { - return
- -
- } - - return ( -
- - {sharedUsers.length > 2 && ( - - )} - {sharedUsers.length === 2 && ( - - )} -
- ) -} - -export default SharedUsers \ No newline at end of file diff --git a/packages/files-ui/src/Components/Elements/SharedUsers.tsx b/packages/files-ui/src/Components/Elements/SharedUsers.tsx new file mode 100644 index 0000000000..ff39669ea7 --- /dev/null +++ b/packages/files-ui/src/Components/Elements/SharedUsers.tsx @@ -0,0 +1,75 @@ +import React, { useCallback, useMemo } from "react" +import { makeStyles, createStyles, useThemeSwitcher } from "@chainsafe/common-theme" +import UserBubble from "./UserBubble" +import { LookupUser } from "@chainsafe/files-api-client" +import { BucketKeyPermission } from "../../Contexts/FilesContext" +import { getUserDisplayName } from "../../Utils/getUserDisplayName" + +const useStyles = makeStyles(() => { + return createStyles({ + root: { + display: "flex" + } + }) +}) +interface Props { + bucket: BucketKeyPermission +} + +const SharedUsers = ({ bucket }: Props) => { + const classes = useStyles() + const { desktop } = useThemeSwitcher() + const { owners, readers, writers } = bucket + + const getUserLabels = useCallback((users: LookupUser[]): string[] => { + return users.reduce((acc: string[], user): string[] => { + const displayName = getUserDisplayName(user) + + return [...acc, displayName] + }, [] as string[]) + }, []) + + const userLabels = useMemo(() => + [ + ...getUserLabels(owners), + ...getUserLabels(readers), + ...getUserLabels(writers) + ], + [owners, readers, writers, getUserLabels]) + + if (!userLabels.length) { + return null + } + + if (!desktop) { + return ( +
+ +
+ ) + } + + return ( +
+ + {userLabels.length > 2 && ( + + )} + {userLabels.length === 2 && ( + + )} +
+ ) +} + +export default SharedUsers \ No newline at end of file diff --git a/packages/files-ui/src/Components/Elements/UserBubble.tsx b/packages/files-ui/src/Components/Elements/UserBubble.tsx index f5a5384e3b..6579d44d53 100644 --- a/packages/files-ui/src/Components/Elements/UserBubble.tsx +++ b/packages/files-ui/src/Components/Elements/UserBubble.tsx @@ -32,10 +32,8 @@ const useStyles = makeStyles(({ zIndex, animation, constants, palette }: CSFThem flexDirection: "column", alignItems: "center", justifyContent: "center", - left: "50%", - top: "-20px", + bottom: constants.generalUnit * 5 + 5, //bubble height + the 5 from the triangle in &:after position: "absolute", - transform: "translate(-50%, -50%)", zIndex: zIndex?.layer1, transitionDuration: `${animation.transform}ms`, opacity: 0, diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx index 3764d7f086..bb01b8f3d9 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx @@ -21,7 +21,7 @@ import { useEffect } from "react" import { SharedFolderModalMode } from "./types" import { useCreateOrEditSharedFolder } from "./hooks/useCreateOrEditSharedFolder" import { useLookupSharedFolderUser } from "./hooks/useLookupUser" -import { centerEllipsis } from "../../../Utils/Helpers" +import { getUserDisplayName } from "../../../Utils/getUserDisplayName" const useStyles = makeStyles( ({ breakpoints, constants, typography, zIndex, palette }: CSFTheme) => { @@ -137,14 +137,14 @@ const CreateOrEditSharedFolderModal = ({ mode, isModalOpen, onClose, bucketToEdi if (!bucketToEdit) return const newWriters = bucketToEdit.writers.map((writer) => ({ - label: writer.username || centerEllipsis(writer.public_address.toLowerCase(), 6) || writer.uuid, + label: getUserDisplayName(writer), value: writer.uuid || "", data: writer }) ) || [] const newReaders = bucketToEdit.readers.map((reader) => ({ - label: reader.username || centerEllipsis(reader.public_address.toLowerCase(), 6) || reader.uuid, + label: getUserDisplayName(reader), value: reader.uuid || "", data: reader }) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx index bd88884ba8..8a10c026bd 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx @@ -16,16 +16,14 @@ import { UserShareSvg } from "@chainsafe/common-components" import { CSFTheme } from "../../../../../Themes/types" -import { LookupUser } from "@chainsafe/files-api-client" import { desktopSharedGridSettings, mobileSharedGridSettings } from "../../SharedFoldersOverview" -import SharedUsers from "../../../../Elements/SharedUser" +import SharedUsers from "../../../../Elements/SharedUsers" import { t, Trans } from "@lingui/macro" import { Form, FormikProvider, useFormik } from "formik" import clsx from "clsx" import { BucketKeyPermission } from "../../../../../Contexts/FilesContext" import UserBubble from "../../../../Elements/UserBubble" import { renameSchema } from "../../../../../Utils/validationSchema" -import { centerEllipsis } from "../../../../../Utils/Helpers" const useStyles = makeStyles(({ breakpoints, constants, palette }: CSFTheme) => { @@ -201,22 +199,6 @@ const SharedFolderRow = ({ bucket, handleRename, openSharedFolder, handleDeleteS click(e) } - const getUserLabels = (users: LookupUser[]): string[] => { - return users.reduce((acc: string[], user): string[] => { - if (user.username !== "") { - return user.username ? [...acc, user.username] : acc - } - - if (user.public_address !== "") { - return user.public_address ? [...acc, centerEllipsis(user.public_address.toLowerCase(), 6)] : acc - } - - return user.uuid ? [...acc, user.uuid] : acc - }, [] as string[]) - } - - const userLabels = [...getUserLabels(bucket.owners), ...getUserLabels(bucket.readers), ...getUserLabels(bucket.writers)] - const formik = useFormik({ initialValues:{ fileName: name @@ -293,7 +275,7 @@ const SharedFolderRow = ({ bucket, handleRename, openSharedFolder, handleDeleteS align="left" className={classes.sharedUser} > - + {desktop && diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx index 2f758074ba..56a8665bf9 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx @@ -51,6 +51,7 @@ import { DragPreviewLayer } from "./DragPreviewLayer" import { useFileBrowser } from "../../../../Contexts/FileBrowserContext" import ReportFileModal from "../ReportFileModal" import CopyToSharedFolderModal from "../CopyToSharedFolderModal" +import SharedUsers from "../../../Elements/SharedUsers" const baseOperations: FileOperation[] = ["download", "info", "preview"] const readerOperations: FileOperation[] = [...baseOperations, "report"] @@ -82,7 +83,6 @@ const useStyles = makeStyles( borderColor: palette.primary.main } } - // transitionDuration: `${animation.transform}ms`, }, header: { display: "flex", @@ -276,6 +276,11 @@ const useStyles = makeStyles( width: "20px", height: "20px" } + }, + users: { + flex: 1, + display: "flex", + justifyContent: "flex-end" } }) } @@ -632,6 +637,11 @@ const FilesList = ({ isShared = false }: Props) => { > {heading} + {isShared && bucket && ( +
+ +
+ )}
{controls && desktop ? ( <> diff --git a/packages/files-ui/src/Utils/getUserDisplayName.ts b/packages/files-ui/src/Utils/getUserDisplayName.ts new file mode 100644 index 0000000000..1f4b85aa49 --- /dev/null +++ b/packages/files-ui/src/Utils/getUserDisplayName.ts @@ -0,0 +1,6 @@ +import { LookupUser } from "@chainsafe/files-api-client" +import { t } from "@lingui/macro" +import { centerEllipsis } from "./Helpers" + +export const getUserDisplayName = (user: LookupUser) => + user.username || centerEllipsis(user.public_address.toLowerCase()) || centerEllipsis(user.uuid) || t`unknown` \ No newline at end of file diff --git a/packages/files-ui/src/locales/de/messages.po b/packages/files-ui/src/locales/de/messages.po index 3d194e1bfd..b41da2ba01 100644 --- a/packages/files-ui/src/locales/de/messages.po +++ b/packages/files-ui/src/locales/de/messages.po @@ -853,6 +853,9 @@ msgstr "am" msgid "recovered successfully" msgstr "erfolgreich wiederhergestellt" +msgid "unknown" +msgstr "" + msgid "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" msgstr "" diff --git a/packages/files-ui/src/locales/en/messages.po b/packages/files-ui/src/locales/en/messages.po index c3767ccf2a..c281c12c34 100644 --- a/packages/files-ui/src/locales/en/messages.po +++ b/packages/files-ui/src/locales/en/messages.po @@ -856,6 +856,9 @@ msgstr "on" msgid "recovered successfully" msgstr "recovered successfully" +msgid "unknown" +msgstr "unknown" + msgid "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" msgstr "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" diff --git a/packages/files-ui/src/locales/es/messages.po b/packages/files-ui/src/locales/es/messages.po index abe7ed2d48..b9a9b149ed 100644 --- a/packages/files-ui/src/locales/es/messages.po +++ b/packages/files-ui/src/locales/es/messages.po @@ -857,6 +857,9 @@ msgstr "en" msgid "recovered successfully" msgstr "recuperado con éxito" +msgid "unknown" +msgstr "" + msgid "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" msgstr "" diff --git a/packages/files-ui/src/locales/fr/messages.po b/packages/files-ui/src/locales/fr/messages.po index dec4d408dc..cb31246825 100644 --- a/packages/files-ui/src/locales/fr/messages.po +++ b/packages/files-ui/src/locales/fr/messages.po @@ -857,6 +857,9 @@ msgstr "le" msgid "recovered successfully" msgstr "récupéré avec succès" +msgid "unknown" +msgstr "" + msgid "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" msgstr "{0, plural, one {Vous êtes sur le point de supprimer {1} élément.} other {Vous êtes sur le point de supprimer {2} éléments.}}" diff --git a/packages/files-ui/src/locales/no/messages.po b/packages/files-ui/src/locales/no/messages.po index 7a983c49eb..38639b2c3d 100644 --- a/packages/files-ui/src/locales/no/messages.po +++ b/packages/files-ui/src/locales/no/messages.po @@ -853,6 +853,9 @@ msgstr "" msgid "recovered successfully" msgstr "gjenopprettet" +msgid "unknown" +msgstr "" + msgid "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" msgstr "" From 8aca03ab6d651cc430104ac38f227cc183deb2f1 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Wed, 4 Aug 2021 12:37:31 +0200 Subject: [PATCH 08/31] add headless (#1402) --- packages/files-ui/package.json | 2 +- packages/gaming-ui/package.json | 2 +- packages/storage-ui/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index 7367de5ef6..3279958a81 100644 --- a/packages/files-ui/package.json +++ b/packages/files-ui/package.json @@ -76,7 +76,7 @@ "sentry": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); node scripts/sentry.js)", "release": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); yarn compile && yarn build && node scripts/sentry.js)", "test": "yarn test:clean && cypress open", - "test:ci": "yarn test:clean && cypress run", + "test:ci": "yarn test:clean && cypress run --browser chrome --headless", "test:clean": "rimraf cypress/fixtures/storage", "analyze": "source-map-explorer 'build/static/js/*.js'", "extract": "lingui extract", diff --git a/packages/gaming-ui/package.json b/packages/gaming-ui/package.json index fe1ede2968..5a7c530936 100644 --- a/packages/gaming-ui/package.json +++ b/packages/gaming-ui/package.json @@ -73,7 +73,7 @@ "sentry": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); node scripts/sentry.js)", "release": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); yarn compile && yarn build && node scripts/sentry.js)", "test": "yarn test:clean && cypress open", - "test:ci": "yarn test:clean && cypress run --browser chrome", + "test:ci": "yarn test:clean && cypress run --browser chrome --headless", "test:clean": "rimraf cypress/fixtures/storage", "analyze": "source-map-explorer 'build/static/js/*.js'", "extract": "lingui extract", diff --git a/packages/storage-ui/package.json b/packages/storage-ui/package.json index 2c0e66d5f8..6e9593b947 100644 --- a/packages/storage-ui/package.json +++ b/packages/storage-ui/package.json @@ -74,7 +74,7 @@ "sentry": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); node scripts/sentry.js)", "release": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); yarn compile && yarn build && node scripts/sentry.js)", "test": "yarn test:clean && cypress open", - "test:ci": "yarn test:clean && cypress run", + "test:ci": "yarn test:clean && cypress run --browser chrome --headless", "test:clean": "rimraf cypress/fixtures/storage", "analyze": "source-map-explorer 'build/static/js/*.js'", "extract": "lingui extract", From 09b2c3b426578203b079e3747a44a0a59b2078ae Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:29:18 +0200 Subject: [PATCH 09/31] New auth flow (#1401) * new flow * lingui extract * Update packages/files-ui/src/Components/Modules/Settings/Security/index.tsx Co-authored-by: GitHub Actions --- .../LoginModule/AuthenticationFactors.tsx | 306 ------------------ .../Modules/LoginModule/Complete.tsx | 178 ---------- .../Modules/LoginModule/ConfirmSkip.tsx | 120 ------- .../Modules/LoginModule/InitializeAccount.tsx | 47 +-- .../Modules/LoginModule/MigrateAccount.tsx | 145 +++++---- .../Modules/LoginModule/SaveBackupPhrase.tsx | 91 ------ .../Modules/Settings/Security/index.tsx | 122 ++----- .../src/Components/Pages/LoginPage.tsx | 1 - packages/files-ui/src/locales/de/messages.po | 57 +--- packages/files-ui/src/locales/en/messages.po | 57 +--- packages/files-ui/src/locales/es/messages.po | 57 +--- packages/files-ui/src/locales/fr/messages.po | 57 +--- packages/files-ui/src/locales/no/messages.po | 57 +--- 13 files changed, 127 insertions(+), 1168 deletions(-) delete mode 100644 packages/files-ui/src/Components/Modules/LoginModule/AuthenticationFactors.tsx delete mode 100644 packages/files-ui/src/Components/Modules/LoginModule/Complete.tsx delete mode 100644 packages/files-ui/src/Components/Modules/LoginModule/ConfirmSkip.tsx delete mode 100644 packages/files-ui/src/Components/Modules/LoginModule/SaveBackupPhrase.tsx diff --git a/packages/files-ui/src/Components/Modules/LoginModule/AuthenticationFactors.tsx b/packages/files-ui/src/Components/Modules/LoginModule/AuthenticationFactors.tsx deleted file mode 100644 index be4ce5620a..0000000000 --- a/packages/files-ui/src/Components/Modules/LoginModule/AuthenticationFactors.tsx +++ /dev/null @@ -1,306 +0,0 @@ -import React from "react" -import { createStyles, makeStyles, useThemeSwitcher } from "@chainsafe/common-theme" -import { CheckCircleSvg, CrossOutlinedSvg, Typography, WarningSvg } from "@chainsafe/common-components" -import { Trans } from "@lingui/macro" -import { useThresholdKey } from "../../../Contexts/ThresholdKeyContext" -import { CSFTheme } from "../../../Themes/types" -import clsx from "clsx" -import { ROUTE_LINKS } from "../../FilesRoutes" - -const useStyles = makeStyles(({ breakpoints, constants, typography, palette, zIndex }: CSFTheme) => - createStyles({ - root:{ - zIndex: zIndex?.layer1, - backgroundColor: constants.loginModule.background, - color: constants.loginModule.textColor, - width: "100vw", - [breakpoints.up("md")]: { - maxWidth: 580, - padding: `${constants.generalUnit * 6.5}px ${constants.generalUnit * 5}px` - }, - [breakpoints.down("md")]: { - height: "100vh", - padding: `${constants.generalUnit * 2.5}px ${constants.generalUnit * 2}px` - } - }, - setOption: { - width: "100%", - backgroundColor: constants.loginModule.itemBackground, - color: constants.loginModule.textColor, - padding: constants.generalUnit * 1.5, - borderRadius: 4, - marginTop: constants.generalUnit * 1.5, - "&.clickable": { - cursor: "pointer" - }, - "& > div": { - display: "flex", - alignItems: "center", - "& > span": { - display: "block", - lineHeight: "16px", - fontWeight: typography.fontWeight.regular, - "&:first-child": { - flex: "1 1 0" - } - } - }, - "& svg": { - width: 21, - height: 21, - marginLeft: constants.generalUnit * 1 - } - }, - checkIcon: { - stroke: palette.additional.green[6], - fill: palette.additional.green[6] - }, - errorIcon: { - stroke: palette.error.main, - fill: palette.error.main, - marginLeft: constants.generalUnit * 1 - }, - subText: { - color: constants.loginModule.subText, - display: "block", - marginTop: constants.generalUnit * 2, - "& a": { - color: constants.loginModule.subText - } - }, - ctaText: { - fontWeight: typography.fontWeight.bold, - textDecoration: "underline", - [breakpoints.down("md")]: { - display: "block", - marginTop: constants.generalUnit * 2 - } - }, - continue: { - display: "block", - textAlign: "right", - textDecoration: "underline", - cursor: "pointer", - color: palette.additional.gray[6], - [breakpoints.up("md")]: { - marginTop: constants.generalUnit * 6 - }, - [breakpoints.down("md")]: { - marginTop: constants.generalUnit * 3 - } - }, - title: { - fontWeight: 400, - marginBottom: constants.generalUnit * 2.5, - [breakpoints.down("md")]: { - ...typography.h4 - } - } - }) -) - -interface IAuthenticationFactors { - goToPassword: () => void - goToMnemonic: () => void - goToSkip: () => void - goToComplete: () => void - className?: string -} - -const AuthenticationFactors = ({ goToComplete, goToMnemonic, goToPassword, goToSkip, className }: IAuthenticationFactors) => { - const classes = useStyles() - const { desktop } = useThemeSwitcher() - const { keyDetails, loggedinAs, hasMnemonicShare, hasPasswordShare, browserShares } = useThresholdKey() - - return ( -
- - - Your Authentication Factors - - - - { - !!loggedinAs && ( -
-
- - - Social Sign-in or Wallet - - - { - desktop && ( - - { loggedinAs } - - ) - } - -
-
- ) - } - -
-
- {browserShares.length > 0 && - - Saved Browser - - } - { - desktop && ( - - Saved{" "} - {browserShares.length > 0 && `${browserShares[0].browser.name} ${browserShares[0].browser.version}`} - - ) - } - { - browserShares.length > 0 - ? - : - } -
- { - desktop && ( - - Files uses device backups to save your browser.{" "} - Learn more - - ) - } -
-
!hasPasswordShare && goToPassword()} - className={clsx(classes.setOption, { "clickable": !hasPasswordShare })} - > -
- - - Password - - - { - !hasPasswordShare ? ( - <> - { - desktop && ( - - - Set it up now - - - ) - } - - - ) : ( - - ) - } -
- { - !desktop && ( - - - Set it up now - - - ) - } -
-
!hasMnemonicShare && goToMnemonic()} - className={clsx(classes.setOption, { "clickable": !hasMnemonicShare })} - > -
- - - Backup secret phrase - - - { - !hasMnemonicShare ? ( - <> - { - desktop && ( - - - Set it up now - - - ) - } - - - ) : ( - - ) - } -
- { - !desktop && ( - - - Set it up now - - - ) - } -
- { - keyDetails && ( - keyDetails.totalShares > keyDetails.threshold ? ( - - - Complete - - - ) : ( - - - Remind me later - - - ) - ) - } -
- ) -} - -export default AuthenticationFactors diff --git a/packages/files-ui/src/Components/Modules/LoginModule/Complete.tsx b/packages/files-ui/src/Components/Modules/LoginModule/Complete.tsx deleted file mode 100644 index db59fe7b49..0000000000 --- a/packages/files-ui/src/Components/Modules/LoginModule/Complete.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import React from "react" -import { createStyles, makeStyles } from "@chainsafe/common-theme" -import { Button, CheckSvg, CloseSvg, Typography } from "@chainsafe/common-components" -import { Trans } from "@lingui/macro" -import clsx from "clsx" -import { CSFTheme } from "../../../Themes/types" -import CompleteSVG from "../../../Media/svgs/complete.svg" -import { useThresholdKey } from "../../../Contexts/ThresholdKeyContext" - -const useStyles = makeStyles(({ breakpoints, constants, palette, zIndex }: CSFTheme) => - createStyles({ - root:{ - backgroundColor: `${constants.loginModule.completeBg} !important`, - color: constants.loginModule.completeText, - display: "flex", - flexDirection: "column", - alignItems: "center", - position: "relative", - justifyContent: "center !important", - height: "100vh", - width: "100vw", - overflow: "hidden", - [breakpoints.up("md")]: { - maxWidth: 550, - maxHeight: 640 - }, - "& p": { - margin: `${constants.generalUnit * 1.5}px 0` - }, - "& h2": { - textAlign: "center" - } - }, - background: { - position: "absolute", - top: "50%", - left: "50%", - transform: "translate(-50%, -50%)", - zIndex: zIndex?.background - }, - option: { - display: "flex", - flexDirection: "row", - alignItems: "center", - justifyContent: "space-between", - padding: `${constants.generalUnit}px ${constants.generalUnit * 3}px`, - "& svg": { - height: 15, - width: 15, - marginLeft: constants.generalUnit * 3, - marginRight: 2.5, - stroke: palette.error.main, - fill: palette.error.main - }, - "&.active svg": { - height: 20, - width: 20, - marginRight: 0, - fill: palette.success.main, - stroke: palette.success.main, - marginLeft: constants.generalUnit * 3 - } - }, - cta: { - marginTop : constants.generalUnit * 3, - maxWidth: 270, - color: constants.loginModule.completeBg, - backgroundColor: constants.loginModule.completeText, - "&:hover": { - backgroundColor: palette.primary.main, - color: palette.common.white.main - } - } - }) -) - -interface IComplete { - className?: string -} - -const Complete = ({ className }: IComplete) => { - const classes = useStyles() - const { userInfo, resetShouldInitialize, hasPasswordShare, hasMnemonicShare, browserShares } = useThresholdKey() - - const hasSocial = !!userInfo?.userInfo - - return ( -
- complete slide background - - - Great! You’re all done. - - - - - Thanks for taking care of that. You can adjust these anytime in security settings. - - -
-
- - - Social sign in or wallet - - - { - hasSocial ? ( - - ) : ( - - ) - } -
-
0 - } - )}> - - - Saved browser - - - { - browserShares.length > 0 ? ( - - ) : ( - - ) - } -
- {hasPasswordShare && -
- - - Password setup - - - -
} - {hasMnemonicShare &&
- - - Backup secret phrase - - - -
} -
- -
- ) -} - -export default Complete diff --git a/packages/files-ui/src/Components/Modules/LoginModule/ConfirmSkip.tsx b/packages/files-ui/src/Components/Modules/LoginModule/ConfirmSkip.tsx deleted file mode 100644 index 547230a9f7..0000000000 --- a/packages/files-ui/src/Components/Modules/LoginModule/ConfirmSkip.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import React from "react" -import { createStyles, makeStyles, useThemeSwitcher } from "@chainsafe/common-theme" -import { Button, Typography } from "@chainsafe/common-components" -import { Trans } from "@lingui/macro" -import clsx from "clsx" -import { CSFTheme } from "../../../Themes/types" - -const useStyles = makeStyles(({ breakpoints, constants, typography }: CSFTheme) => - createStyles({ - root: { - width: "100vw", - [breakpoints.up("md")]:{ - maxWidth: 570, - padding: `${constants.generalUnit * 13.5}px ${constants.generalUnit * 9.5}px` - }, - [breakpoints.down("md")]: { - padding: `${constants.generalUnit * 2}px ${constants.generalUnit * 2}px` - } - }, - title: { - fontWeight: typography.fontWeight.regular, - [breakpoints.down("md")]: { - textAlign: "center" - } - }, - warning: { - fontSize: 16, - lineHeight: "24px", - [breakpoints.up("md")]: { - marginTop: constants.generalUnit * 2.5, - marginBottom: constants.generalUnit * 14.5 - }, - [breakpoints.down("md")]: { - marginTop: constants.generalUnit * 2.5, - marginBottom: constants.generalUnit * 5.5 - } - }, - buttons: { - display: "flex", - flexDirection: "row", - justifyContent: "space-between", - "& > *": { - [breakpoints.up("md")]: { - maxWidth: `calc(50% - ${constants.generalUnit}px)` - }, - [breakpoints.down("md")]: { - maxWidth: `calc(50% - ${constants.generalUnit / 2}px)` - } - }, - [breakpoints.down("md")]: { - width: `calc(100% + ${constants.generalUnit * 2}px)`, - position: "relative", - left: -constants.generalUnit - } - }, - importantText:{ - textDecorationLine: "underline" - } - }) -) - -interface IConfirmSkip { - cancel: () => void - confirm: () => void - className?: string -} - -const ConfirmSkip = ({ cancel, confirm, className }: IConfirmSkip) => { - const classes = useStyles() - const { desktop } = useThemeSwitcher() - - return ( -
- - - Setup incomplete - - - - - - You’re at risk of getting locked out of your account - because you only have two auth factors set up. Add at least one more to ensure account recovery. - - - -
- - -
-
- ) -} - -export default ConfirmSkip diff --git a/packages/files-ui/src/Components/Modules/LoginModule/InitializeAccount.tsx b/packages/files-ui/src/Components/Modules/LoginModule/InitializeAccount.tsx index eb8458f605..f9aa2c18f4 100644 --- a/packages/files-ui/src/Components/Modules/LoginModule/InitializeAccount.tsx +++ b/packages/files-ui/src/Components/Modules/LoginModule/InitializeAccount.tsx @@ -1,76 +1,41 @@ import React, { useState, useCallback } from "react" import { useThresholdKey } from "../../../Contexts/ThresholdKeyContext" import ConciseExplainer from "./ConciseExplainer" -import Complete from "./Complete" -import AuthenticationFactors from "./AuthenticationFactors" import PasswordSetup from "./PasswordSetup" -import ConfirmSkip from "./ConfirmSkip" -import SaveBackupPhrase from "./SaveBackupPhrase" interface IInitializeAccount { className?: string } -type InitializeState = "explainer" | -"authenticationFactors" | -"setUpPassword" | -"skip" | -"backup" | -"complete" +type InitializeState = "explainer" | "setUpPassword" | "complete" -const Content = ({ className }: { - className?: string -}) => { +const InitializeAccount = ({ className }: IInitializeAccount) => { const { addPasswordShare, resetShouldInitialize } = useThresholdKey() - const [initializeState, setInitializeState] = useState("explainer") const onSetPassword = useCallback((password: string) => addPasswordShare(password) .then(() => { - setInitializeState("authenticationFactors") + resetShouldInitialize() }) .catch(console.error) - , [addPasswordShare]) + , [addPasswordShare, resetShouldInitialize]) switch (initializeState) { case "explainer": return setInitializeState("authenticationFactors")} - /> - case "authenticationFactors": - return setInitializeState("setUpPassword")} - goToMnemonic={() => setInitializeState("backup")} - goToSkip={() => setInitializeState("skip")} - goToComplete={() => setInitializeState("complete")} + onContinue={() => setInitializeState("setUpPassword")} /> case "setUpPassword": return setInitializeState("authenticationFactors")} + cancel={() => setInitializeState("explainer")} setPassword={onSetPassword} /> - case "skip": - return resetShouldInitialize()} - cancel={() => setInitializeState("authenticationFactors")} - /> - case "backup": - return setInitializeState("authenticationFactors")} - complete={() => setInitializeState("authenticationFactors")} - /> - case "complete": - return default: return null } } -const InitializeAccount = ({ className }: IInitializeAccount) => export default InitializeAccount diff --git a/packages/files-ui/src/Components/Modules/LoginModule/MigrateAccount.tsx b/packages/files-ui/src/Components/Modules/LoginModule/MigrateAccount.tsx index 0902367008..7b2be49ed0 100644 --- a/packages/files-ui/src/Components/Modules/LoginModule/MigrateAccount.tsx +++ b/packages/files-ui/src/Components/Modules/LoginModule/MigrateAccount.tsx @@ -12,7 +12,6 @@ import { useThresholdKey } from "../../../Contexts/ThresholdKeyContext" import ConciseExplainer from "./ConciseExplainer" import { CSFTheme } from "../../../Themes/types" import { t, Trans } from "@lingui/macro" -import Complete from "./Complete" const useStyles = makeStyles( ({ constants, breakpoints, palette, typography }: CSFTheme) => @@ -90,14 +89,12 @@ interface IMigrateAccount { className?: string } -const MigrateAccount: React.FC = ({ - className -}: IMigrateAccount) => { +const MigrateAccount = ({ className }: IMigrateAccount) => { const classes = useStyles() const { validateMasterPassword } = useFilesApi() const { secureAccountWithMasterPassword } = useFiles() - const { addPasswordShare, logout } = useThresholdKey() - const [migrateState, setMigrateState] = useState<"migrate"|"explainer"|"complete">("migrate") + const { addPasswordShare, logout, resetShouldInitialize } = useThresholdKey() + const [migrateState, setMigrateState] = useState<"migrate"|"explainer">("migrate") const [masterPassword, setMasterPassword] = useState("") const [error, setError] = useState("") const [isLoading, setIsLoading] = useState(false) @@ -107,7 +104,7 @@ const MigrateAccount: React.FC = ({ setMasterPassword(password?.toString() || "") }, []) - const handleSecureAccountWithMasterPassword = async (e: SyntheticEvent) => { + const handleSecureAccountWithMasterPassword = useCallback(async (e: SyntheticEvent) => { e.preventDefault() if (!masterPassword) return @@ -128,79 +125,81 @@ const MigrateAccount: React.FC = ({ setError(t`Failed to migrate account, please try again.`) setIsLoading(false) } - } + }, + [addPasswordShare, masterPassword, secureAccountWithMasterPassword, validateMasterPassword]) - const onLogout = () => { - logout() - } - - return ( - (migrateState === "migrate") - ?
-
+
+ + - - Hello again! - - + Hello again! + + + + We’ve got a new authentication system in place. All you need to do is enter + your password again to migrate your credentials over to the new system. + + + + Password + + + + + {error} + + +
+
+ - We’ve got a new authentication system in place. All you need to do is enter - your password again to migrate your credentials over to the new system. + Sign in with a different account - - Password - - - - - {error} - - -
-
- - - Sign in with a different account - - -
-
-
- : (migrateState === "explainer") - ? + +
+ , [className, classes, error, handleSecureAccountWithMasterPassword, isLoading, masterPassword, logout, onPasswordChange]) + + return ( + <> + {migrateState === "migrate" && } + {migrateState === "explainer" && ( + setMigrateState("complete")} + onContinue={resetShouldInitialize} /> - : + )} + ) } diff --git a/packages/files-ui/src/Components/Modules/LoginModule/SaveBackupPhrase.tsx b/packages/files-ui/src/Components/Modules/LoginModule/SaveBackupPhrase.tsx deleted file mode 100644 index 4cb66d9b65..0000000000 --- a/packages/files-ui/src/Components/Modules/LoginModule/SaveBackupPhrase.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import React from "react" -import { createStyles, makeStyles, useThemeSwitcher } from "@chainsafe/common-theme" -import { CloseSvg, Typography } from "@chainsafe/common-components" -import clsx from "clsx" -import { CSFTheme } from "../../../Themes/types" -import { t, Trans } from "@lingui/macro" -import MnemonicForm from "../../Elements/MnemonicForm" - -const useStyles = makeStyles(({ breakpoints, constants, typography }: CSFTheme) => - createStyles({ - root: { - color: constants.loginModule.textColor, - width: "100vw", - "& h1": { - fontWeight: typography.fontWeight.regular, - marginBottom: constants.generalUnit, - color: constants.loginModule.textColor, - [breakpoints.down("md")]: { - textAlign: "center", - marginBottom: constants.generalUnit * 2 - } - }, - [breakpoints.up("md")]: { - padding: `${constants.generalUnit * 13.5}px ${constants.generalUnit * 9.5}px`, - maxWidth: 580 - }, - [breakpoints.down("md")]: { - padding: constants.generalUnit * 2 - } - }, - close: { - position: "absolute", - cursor: "pointer", - "& svg": { - width: 15, - height: 15, - stroke: constants.loginModule.textColor - }, - [breakpoints.up("md")]: { - top: constants.generalUnit * 3, - right: constants.generalUnit * 3 - }, - [breakpoints.down("md")]: { - top: constants.generalUnit * 1.5, - right: constants.generalUnit * 1.5 - } - } - }) -) - -interface ISaveBackupPhrase { - className?: string - complete: () => void - cancel: () => void -} - -const SaveBackupPhrase = ({ className, complete, cancel }: ISaveBackupPhrase) => { - const classes = useStyles() - const { desktop } = useThemeSwitcher() - - return ( -
-
- -
- - - Generate backup secret phrase - - - - - A backup secret phrase will be generated and used for your account.
- We do not store it and it can only be displayed once. Save it somewhere safe! -
-
- -
- ) -} - -export default SaveBackupPhrase diff --git a/packages/files-ui/src/Components/Modules/Settings/Security/index.tsx b/packages/files-ui/src/Components/Modules/Settings/Security/index.tsx index 116810ab8b..d751598441 100644 --- a/packages/files-ui/src/Components/Modules/Settings/Security/index.tsx +++ b/packages/files-ui/src/Components/Modules/Settings/Security/index.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useMemo, useState } from "react" -import { CheckCircleSvg, CloseSvg, CrossOutlinedSvg, Divider, Typography } from "@chainsafe/common-components" +import { CloseSvg, Divider, Typography } from "@chainsafe/common-components" import { makeStyles, createStyles, useThemeSwitcher } from "@chainsafe/common-theme" import { CSFTheme } from "../../../../Themes/types" import { t, Trans } from "@lingui/macro" @@ -48,14 +48,6 @@ const useStyles = makeStyles(({ constants, breakpoints, palette, typography, zIn height: 21, marginLeft: constants.generalUnit * 1 }, - green: { - stroke: palette.additional.green[6], - fill: palette.additional.green[6] - }, - red: { - stroke: palette.additional.red[6], - fill: palette.additional.red[6] - }, buttonLink: { outline: "none", textDecoration: "underline", @@ -136,17 +128,8 @@ interface SecurityProps { } const Security = ({ className }: SecurityProps) => { - const { keyDetails, - addPasswordShare, - changePasswordShare, - loggedinAs, - hasPasswordShare, - hasMnemonicShare, - browserShares, - refreshTKeyMeta - } = useThresholdKey() + const { keyDetails, changePasswordShare, loggedinAs, hasMnemonicShare, browserShares, refreshTKeyMeta } = useThresholdKey() const classes = useStyles() - const [isSettingPassword, setIsSettingPassword] = useState(false) const [isChangingPassword, setIsChangingPassword] = useState(false) const [isSettingBackupPhrase, setIsSettingBackupPhrase] = useState(false) const { desktop } = useThemeSwitcher() @@ -155,21 +138,13 @@ const Security = ({ className }: SecurityProps) => { const onResetPasswordForm = useCallback(() => { setIsChangingPassword(false) - setIsSettingPassword(false) }, []) - const onSetPassword = useCallback(async (password: string) => { - if (isSettingPassword) { - await addPasswordShare(password) - setIsSettingPassword(false) - } - - if (isChangingPassword) { - console.log("settingUpPassword", password) - await changePasswordShare(password) - setIsChangingPassword(false) - } - }, [addPasswordShare, changePasswordShare, isChangingPassword, isSettingPassword]) + const onSetPassword = useCallback((password: string) => { + return changePasswordShare(password) + .then(() => setIsChangingPassword(false)) + .catch(console.error) + }, [changePasswordShare]) useEffect(() => { setIsRefreshingMetadata(true) @@ -217,7 +192,6 @@ const Security = ({ className }: SecurityProps) => { ) } -
) @@ -232,10 +206,6 @@ const Security = ({ className }: SecurityProps) => { {browserShares.length} Saved{" "} - { browserShares.length - ? - : - }
{showWarning && ( @@ -251,46 +221,8 @@ const Security = ({ className }: SecurityProps) => { )} - { !isSettingPassword && !isChangingPassword + { isChangingPassword ? ( -
-
- - - Password - - - - { !hasPasswordShare - ? ( - - {setIsSettingPassword(true)}} - > - Set up password - - - - ) - : ( - - Set up - {setIsChangingPassword(true)}} - > - (Change) - - - - ) - } - -
-
- ) - : (
{ variant="h4" component="h2" > - {isChangingPassword - ? - Change password - - : - Set up a password - - } + + Change password +
+ ) + : ( +
+
+ + + Password + + + + { + {setIsChangingPassword(true)}} + > + Change Password + + } + +
+
)} { isSettingBackupPhrase ? ( @@ -355,13 +303,11 @@ const Security = ({ className }: SecurityProps) => { > Generate backup secret phrase - ) : ( - Set up - + Generated ) } diff --git a/packages/files-ui/src/Components/Pages/LoginPage.tsx b/packages/files-ui/src/Components/Pages/LoginPage.tsx index 1a98585007..00b9a6e09b 100644 --- a/packages/files-ui/src/Components/Pages/LoginPage.tsx +++ b/packages/files-ui/src/Components/Pages/LoginPage.tsx @@ -179,7 +179,6 @@ const LoginPage = () => { } - {/* */} You’re at risk of getting locked out of your account because you only have two auth factors set up. Add at least one more to ensure account recovery." -msgstr "<0>Sie laufen Gefahr, aus Ihrem Konto gesperrt zu werden, weil Sie nur zwei Autorisierungsfaktoren eingerichtet haben. Fügen Sie mindestens einen weiteren hinzu, um die Wiederherstellung des Kontos sicherzustellen." - msgid "A backup secret phrase will be generated and used for your account.<0/>We do not store it and <1>it can only be displayed once. Save it somewhere safe!" msgstr "Es wird ein Sicherungsgeheimsatz generiert und für Ihr Konto verwendet.<0/>Wir speichern ihn nicht und <1>er kann nur einmal angezeigt werden. Speichern Sie ihn an einem sicheren Ort!" @@ -94,9 +88,6 @@ msgstr "Klicken oder ziehen, um Dateien hochzuladen" msgid "Close" msgstr "Schließen" -msgid "Complete" -msgstr "Vollständig" - msgid "Confirm" msgstr "Bestätigen" @@ -268,9 +259,6 @@ msgstr "Dateien" msgid "Files sharing key" msgstr "Dateifreigabeschlüssel" -msgid "Files uses device backups to save your browser." -msgstr "Dateien verwendet Gerätesicherungen, um Ihren Browser zu speichern." - msgid "First name" msgstr "Vorname" @@ -298,6 +286,9 @@ msgstr "Allgemein" msgid "Generate backup secret phrase" msgstr "Sicherungsgeheimsatz generieren" +msgid "Generated" +msgstr "" + msgid "Generating…" msgstr "Wird generiert …" @@ -313,9 +304,6 @@ msgstr "" msgid "Go back" msgstr "Zurück" -msgid "Great! You’re all done." -msgstr "Super! Sie sind fertig." - msgid "Hello again!" msgstr "Hallo nochmal!" @@ -328,9 +316,6 @@ msgstr "" msgid "Home" msgstr "Startseite" -msgid "I understand the risk" -msgstr "Ich gehe das Risiko ein" - msgid "If you think this file does not comply with our <0>Terms of Service, please send the following information to report@files.chainsafe.io. Beware that by sending the file's decryption key, an admin can then decrypt any file in this shared folder." msgstr "" @@ -457,9 +442,6 @@ msgstr "Das Passwort stimmt nicht mit dem Benutzerkonto überein, bitte überpr msgid "Password needs to be more complex" msgstr "Das Passwort muss komplexer sein" -msgid "Password setup" -msgstr "Passworteinrichtung" - msgid "Password:" msgstr "Passwort:" @@ -517,9 +499,6 @@ msgstr "Ablehnen" msgid "Reject all" msgstr "Alle ablehnen" -msgid "Remind me later" -msgstr "Später erinnern" - msgid "Rename" msgstr "Umbenennen" @@ -559,9 +538,6 @@ msgstr "Browser gespeichert" msgid "Saved Browsers" msgstr "Gespeicherte Browser" -msgid "Saved browser" -msgstr "Browser gespeichert" - msgid "Saved on:" msgstr "Gesichert am:" @@ -592,30 +568,15 @@ msgstr "Passwort festlegen" msgid "Set Username" msgstr "Benutzername festlegen" -msgid "Set it up now" -msgstr "Jetzt einrichten" - -msgid "Set up" -msgstr "Einrichten" - msgid "Set up a password" msgstr "Eine Passwort einrichten" -msgid "Set up auth factors" -msgstr "Authentifizierungsfaktoren einrichten" - -msgid "Set up password" -msgstr "Passwort einrichten" - msgid "Setting Username" msgstr "Benutzername wird eingestellt" msgid "Settings" msgstr "Einstellungen" -msgid "Setup incomplete" -msgstr "Einrichtung unvollständig" - msgid "Shared" msgstr "Geteilt" @@ -652,12 +613,6 @@ msgstr "Größe" msgid "Social Sign-in Wallet" msgstr "" -msgid "Social Sign-in or Wallet" -msgstr "" - -msgid "Social sign in or wallet" -msgstr "" - msgid "Something went wrong with email login! Please try again." msgstr "" @@ -682,9 +637,6 @@ msgstr "Technisch" msgid "Terms and Conditions" msgstr "Bedingungen" -msgid "Thanks for taking care of that. You can adjust these anytime in security settings." -msgstr "Danke, dass Sie sich darum gekümmert haben. Sie können diese jederzeit in den Sicherheitseinstellungen anpassen." - msgid "The authentication popup was closed" msgstr "" @@ -826,9 +778,6 @@ msgstr "Sie haben noch keinen Benutzernamen festgelegt." msgid "You will need to sign a message in your wallet to complete sign in." msgstr "" -msgid "Your Authentication Factors" -msgstr "Ihre Authentifizierungsfaktoren" - msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "Ihr Wiederherstellungsschlüssel kann zur Wiederherstellung Ihres Kontos anstelle Ihres Sicherungsgeheimsatz verwendet werden." diff --git a/packages/files-ui/src/locales/en/messages.po b/packages/files-ui/src/locales/en/messages.po index c281c12c34..b35cf0668d 100644 --- a/packages/files-ui/src/locales/en/messages.po +++ b/packages/files-ui/src/locales/en/messages.po @@ -13,12 +13,6 @@ msgstr "" "Language-Team: \n" "Plural-Forms: \n" -msgid "(Change)" -msgstr "(Change)" - -msgid "<0>You’re at risk of getting locked out of your account because you only have two auth factors set up. Add at least one more to ensure account recovery." -msgstr "<0>You’re at risk of getting locked out of your account because you only have two auth factors set up. Add at least one more to ensure account recovery." - msgid "A backup secret phrase will be generated and used for your account.<0/>We do not store it and <1>it can only be displayed once. Save it somewhere safe!" msgstr "A backup secret phrase will be generated and used for your account.<0/>We do not store it and <1>it can only be displayed once. Save it somewhere safe!" @@ -94,9 +88,6 @@ msgstr "Click or drag to upload files" msgid "Close" msgstr "Close" -msgid "Complete" -msgstr "Complete" - msgid "Confirm" msgstr "Confirm" @@ -271,9 +262,6 @@ msgstr "Files" msgid "Files sharing key" msgstr "Files sharing key" -msgid "Files uses device backups to save your browser." -msgstr "Files uses device backups to save your browser." - msgid "First name" msgstr "First name" @@ -301,6 +289,9 @@ msgstr "General" msgid "Generate backup secret phrase" msgstr "Generate backup secret phrase" +msgid "Generated" +msgstr "Generated" + msgid "Generating…" msgstr "Generating…" @@ -316,9 +307,6 @@ msgstr "Give view-only permission to:" msgid "Go back" msgstr "Go back" -msgid "Great! You’re all done." -msgstr "Great! You’re all done." - msgid "Hello again!" msgstr "Hello again!" @@ -331,9 +319,6 @@ msgstr "Hold on, we are logging you in…" msgid "Home" msgstr "Home" -msgid "I understand the risk" -msgstr "I understand the risk" - msgid "If you think this file does not comply with our <0>Terms of Service, please send the following information to report@files.chainsafe.io. Beware that by sending the file's decryption key, an admin can then decrypt any file in this shared folder." msgstr "If you think this file does not comply with our <0>Terms of Service, please send the following information to report@files.chainsafe.io. Beware that by sending the file's decryption key, an admin can then decrypt any file in this shared folder." @@ -460,9 +445,6 @@ msgstr "Password does not match user account, please double-check and try again. msgid "Password needs to be more complex" msgstr "Password needs to be more complex" -msgid "Password setup" -msgstr "Password setup" - msgid "Password:" msgstr "Password:" @@ -520,9 +502,6 @@ msgstr "Reject" msgid "Reject all" msgstr "Reject all" -msgid "Remind me later" -msgstr "Remind me later" - msgid "Rename" msgstr "Rename" @@ -562,9 +541,6 @@ msgstr "Saved Browser" msgid "Saved Browsers" msgstr "Saved Browsers" -msgid "Saved browser" -msgstr "Saved browser" - msgid "Saved on:" msgstr "Saved on:" @@ -595,30 +571,15 @@ msgstr "Set Password" msgid "Set Username" msgstr "Set Username" -msgid "Set it up now" -msgstr "Set it up now" - -msgid "Set up" -msgstr "Set up" - msgid "Set up a password" msgstr "Set up a password" -msgid "Set up auth factors" -msgstr "Set up auth factors" - -msgid "Set up password" -msgstr "Set up password" - msgid "Setting Username" msgstr "Setting Username" msgid "Settings" msgstr "Settings" -msgid "Setup incomplete" -msgstr "Setup incomplete" - msgid "Shared" msgstr "Shared" @@ -655,12 +616,6 @@ msgstr "Size" msgid "Social Sign-in Wallet" msgstr "Social Sign-in Wallet" -msgid "Social Sign-in or Wallet" -msgstr "Social Sign-in or Wallet" - -msgid "Social sign in or wallet" -msgstr "Social sign in or wallet" - msgid "Something went wrong with email login! Please try again." msgstr "Something went wrong with email login! Please try again." @@ -685,9 +640,6 @@ msgstr "Technical" msgid "Terms and Conditions" msgstr "Terms and Conditions" -msgid "Thanks for taking care of that. You can adjust these anytime in security settings." -msgstr "Thanks for taking care of that. You can adjust these anytime in security settings." - msgid "The authentication popup was closed" msgstr "The authentication popup was closed" @@ -829,9 +781,6 @@ msgstr "You haven't set a username yet." msgid "You will need to sign a message in your wallet to complete sign in." msgstr "You will need to sign a message in your wallet to complete sign in." -msgid "Your Authentication Factors" -msgstr "Your Authentication Factors" - msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "Your recovery key can be used to restore your account in place of your backup secret phrase." diff --git a/packages/files-ui/src/locales/es/messages.po b/packages/files-ui/src/locales/es/messages.po index b9a9b149ed..fb01b89dea 100644 --- a/packages/files-ui/src/locales/es/messages.po +++ b/packages/files-ui/src/locales/es/messages.po @@ -14,12 +14,6 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "Plural-Forms: \n" -msgid "(Change)" -msgstr "" - -msgid "<0>You’re at risk of getting locked out of your account because you only have two auth factors set up. Add at least one more to ensure account recovery." -msgstr "<0>Corres el riesgo de quedar bloqueado fuera de tu cuenta porque solo tienes dos factores de autenticación configurados. Agregue al menos uno más para garantizar la recuperación de la cuenta." - msgid "A backup secret phrase will be generated and used for your account.<0/>We do not store it and <1>it can only be displayed once. Save it somewhere safe!" msgstr "" @@ -95,9 +89,6 @@ msgstr "Haga clic o arrastre para cargar archivos" msgid "Close" msgstr "Cerrar" -msgid "Complete" -msgstr "Completar" - msgid "Confirm" msgstr "Confirmar" @@ -272,9 +263,6 @@ msgstr "Archivos" msgid "Files sharing key" msgstr "" -msgid "Files uses device backups to save your browser." -msgstr "Archivos utiliza copias de seguridad del dispositivo para guardar su navegador." - msgid "First name" msgstr "Primer Nombre" @@ -302,6 +290,9 @@ msgstr "General" msgid "Generate backup secret phrase" msgstr "" +msgid "Generated" +msgstr "" + msgid "Generating…" msgstr "" @@ -317,9 +308,6 @@ msgstr "" msgid "Go back" msgstr "Regresar" -msgid "Great! You’re all done." -msgstr "Estupendo! Todo ha terminado." - msgid "Hello again!" msgstr "Hola de nuevo!" @@ -332,9 +320,6 @@ msgstr "" msgid "Home" msgstr "Casa" -msgid "I understand the risk" -msgstr "Entiendo el riesgo" - msgid "If you think this file does not comply with our <0>Terms of Service, please send the following information to report@files.chainsafe.io. Beware that by sending the file's decryption key, an admin can then decrypt any file in this shared folder." msgstr "" @@ -461,9 +446,6 @@ msgstr "La contraseña no coincide con la cuenta de usuario, vuelva a verificar msgid "Password needs to be more complex" msgstr "La contraseña debe ser más compleja" -msgid "Password setup" -msgstr "Configuración de contraseña" - msgid "Password:" msgstr "Contraseña:" @@ -521,9 +503,6 @@ msgstr "Rechazar" msgid "Reject all" msgstr "Rechazar todo" -msgid "Remind me later" -msgstr "Recuérdame más tarde" - msgid "Rename" msgstr "Renombrar" @@ -563,9 +542,6 @@ msgstr "Navegador guardado" msgid "Saved Browsers" msgstr "Navegadores guardados" -msgid "Saved browser" -msgstr "Navegador guardado" - msgid "Saved on:" msgstr "Guardado el:" @@ -596,30 +572,15 @@ msgstr "Configurar la clave" msgid "Set Username" msgstr "" -msgid "Set it up now" -msgstr "Configúralo ahora" - -msgid "Set up" -msgstr "Configurar" - msgid "Set up a password" msgstr "Configurar una contraseña" -msgid "Set up auth factors" -msgstr "Configurar factores de autenticación" - -msgid "Set up password" -msgstr "Configurar contraseña" - msgid "Setting Username" msgstr "" msgid "Settings" msgstr "Ajustes" -msgid "Setup incomplete" -msgstr "Configuración incompleta" - msgid "Shared" msgstr "" @@ -656,12 +617,6 @@ msgstr "Tamaño" msgid "Social Sign-in Wallet" msgstr "Cartera de inicio de sesión social" -msgid "Social Sign-in or Wallet" -msgstr "Inicio de sesión social o billetera" - -msgid "Social sign in or wallet" -msgstr "Inicio de sesión social o billetera" - msgid "Something went wrong with email login! Please try again." msgstr "" @@ -686,9 +641,6 @@ msgstr "Técnico" msgid "Terms and Conditions" msgstr "Términos y condiciones" -msgid "Thanks for taking care of that. You can adjust these anytime in security settings." -msgstr "Gracias por encargarte de eso. Puede ajustarlos en cualquier momento en la configuración de seguridad." - msgid "The authentication popup was closed" msgstr "Se cerró la ventana emergente de autenticación" @@ -830,9 +782,6 @@ msgstr "" msgid "You will need to sign a message in your wallet to complete sign in." msgstr "Deberá firmar un mensaje en su billetera para completar el inicio de sesión." -msgid "Your Authentication Factors" -msgstr "Sus factores de autenticación" - msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "" diff --git a/packages/files-ui/src/locales/fr/messages.po b/packages/files-ui/src/locales/fr/messages.po index cb31246825..97a7a4b941 100644 --- a/packages/files-ui/src/locales/fr/messages.po +++ b/packages/files-ui/src/locales/fr/messages.po @@ -14,12 +14,6 @@ msgstr "" "X-Generator: Weblate 4.8-dev\n" "Mime-Version: 1.0\n" -msgid "(Change)" -msgstr "(Changer)" - -msgid "<0>You’re at risk of getting locked out of your account because you only have two auth factors set up. Add at least one more to ensure account recovery." -msgstr "<0>Vous risquez de ne plus avoir accès à votre compte car vous n’avez configuré que deux facteurs d’authentification. Ajoutez-en au moins un autre pour garantir la récupération du compte." - msgid "A backup secret phrase will be generated and used for your account.<0/>We do not store it and <1>it can only be displayed once. Save it somewhere safe!" msgstr "Une phrase secrète de sauvegarde sera générée et utilisé pour ce compte.<0/>Nous ne la sauvergardons pas <1>elle ne peut être affichée qu’une seule fois. Gardez-la dans un endroit sûr !" @@ -95,9 +89,6 @@ msgstr "Cliquer ou faire glisser un ficher pour le téléverser" msgid "Close" msgstr "Fermer" -msgid "Complete" -msgstr "Terminé" - msgid "Confirm" msgstr "Confirmer" @@ -272,9 +263,6 @@ msgstr "Fichiers" msgid "Files sharing key" msgstr "Clé de partage des fichiers" -msgid "Files uses device backups to save your browser." -msgstr "Files enregistre ce navigateur." - msgid "First name" msgstr "Prénom" @@ -302,6 +290,9 @@ msgstr "Général" msgid "Generate backup secret phrase" msgstr "Créer une phrase de sauvegarde secrète" +msgid "Generated" +msgstr "" + msgid "Generating…" msgstr "Génération…" @@ -317,9 +308,6 @@ msgstr "Donner l’accès en lecture seule à :" msgid "Go back" msgstr "Retour" -msgid "Great! You’re all done." -msgstr "Génial ! Vous avez terminé." - msgid "Hello again!" msgstr "Ravis de vous revoir !" @@ -332,9 +320,6 @@ msgstr "Un instant, nous te connectons…" msgid "Home" msgstr "Accueil" -msgid "I understand the risk" -msgstr "Je prends le risque" - msgid "If you think this file does not comply with our <0>Terms of Service, please send the following information to report@files.chainsafe.io. Beware that by sending the file's decryption key, an admin can then decrypt any file in this shared folder." msgstr "Si vous pensez que ce fichier n'est pas conforme à nos <0>Conditions de service, veuillez envoyer les informations suivantes à report@files.chainsafe.io. Attention, en envoyant la clé de déchiffrement du fichier, un administrateur peut ensuite déchiffrer n'importe quel fichier de ce dossier partagé." @@ -461,9 +446,6 @@ msgstr "Le mot de passe ne correspond pas au compte, merci de vérifier et rées msgid "Password needs to be more complex" msgstr "Le mot de passe doit être plus complexe" -msgid "Password setup" -msgstr "Configuration du mot de passe" - msgid "Password:" msgstr "Mot de passe :" @@ -521,9 +503,6 @@ msgstr "Refuser" msgid "Reject all" msgstr "Refuser tous" -msgid "Remind me later" -msgstr "Plus tard" - msgid "Rename" msgstr "Renommer" @@ -563,9 +542,6 @@ msgstr "Navigateur enregistré" msgid "Saved Browsers" msgstr "Navigateurs enregistrés" -msgid "Saved browser" -msgstr "Navigateur enregistré" - msgid "Saved on:" msgstr "Enregistré sur :" @@ -596,30 +572,15 @@ msgstr "Définir un mot de passe" msgid "Set Username" msgstr "Définir le nom d’utilisateur" -msgid "Set it up now" -msgstr "Le définir maintenant" - -msgid "Set up" -msgstr "Définir" - msgid "Set up a password" msgstr "Définir un mot de passe" -msgid "Set up auth factors" -msgstr "Configurer les facteurs" - -msgid "Set up password" -msgstr "Définir un mot de passe" - msgid "Setting Username" msgstr "Définition du nom d’utilisateur" msgid "Settings" msgstr "Paramètres" -msgid "Setup incomplete" -msgstr "Configuration incomplète" - msgid "Shared" msgstr "Partagé" @@ -656,12 +617,6 @@ msgstr "Taille" msgid "Social Sign-in Wallet" msgstr "Connecté avec un réseau social ou wallet" -msgid "Social Sign-in or Wallet" -msgstr "Connecté avec un réseau social ou wallet" - -msgid "Social sign in or wallet" -msgstr "Connecté avec un réseau social ou wallet" - msgid "Something went wrong with email login! Please try again." msgstr "Un problème est survenu lors de la connexion avec courriel ! Veuillez réessayer." @@ -686,9 +641,6 @@ msgstr "Technique" msgid "Terms and Conditions" msgstr "Termes et conditions" -msgid "Thanks for taking care of that. You can adjust these anytime in security settings." -msgstr "Vous pouvez les changer à tout moment dans les paramètres de sécurité." - msgid "The authentication popup was closed" msgstr "Le popup d’authentification a été fermé" @@ -830,9 +782,6 @@ msgstr "Vous n’avez pas encore défini de nom d’utilisateur." msgid "You will need to sign a message in your wallet to complete sign in." msgstr "Vous devrez signer un message avec votre wallet pour terminer la procédure connexion." -msgid "Your Authentication Factors" -msgstr "Vos facteurs d’authentification" - msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "Votre clé de récupération peut être utilisée pour restaurer votre compte à la place de votre phrase de sauvegarde secrète." diff --git a/packages/files-ui/src/locales/no/messages.po b/packages/files-ui/src/locales/no/messages.po index 38639b2c3d..edde230a24 100644 --- a/packages/files-ui/src/locales/no/messages.po +++ b/packages/files-ui/src/locales/no/messages.po @@ -13,12 +13,6 @@ msgstr "" "X-Generator: Weblate 4.7.2-dev\n" "Mime-Version: 1.0\n" -msgid "(Change)" -msgstr "(Endre)" - -msgid "<0>You’re at risk of getting locked out of your account because you only have two auth factors set up. Add at least one more to ensure account recovery." -msgstr "" - msgid "A backup secret phrase will be generated and used for your account.<0/>We do not store it and <1>it can only be displayed once. Save it somewhere safe!" msgstr "" @@ -94,9 +88,6 @@ msgstr "" msgid "Close" msgstr "Lukk" -msgid "Complete" -msgstr "" - msgid "Confirm" msgstr "Bekreft" @@ -268,9 +259,6 @@ msgstr "Filer" msgid "Files sharing key" msgstr "" -msgid "Files uses device backups to save your browser." -msgstr "" - msgid "First name" msgstr "Fornavn" @@ -298,6 +286,9 @@ msgstr "" msgid "Generate backup secret phrase" msgstr "" +msgid "Generated" +msgstr "" + msgid "Generating…" msgstr "" @@ -313,9 +304,6 @@ msgstr "" msgid "Go back" msgstr "Tilbake" -msgid "Great! You’re all done." -msgstr "" - msgid "Hello again!" msgstr "Hei igjen." @@ -328,9 +316,6 @@ msgstr "" msgid "Home" msgstr "Hjem" -msgid "I understand the risk" -msgstr "Jeg forstår risikoen" - msgid "If you think this file does not comply with our <0>Terms of Service, please send the following information to report@files.chainsafe.io. Beware that by sending the file's decryption key, an admin can then decrypt any file in this shared folder." msgstr "" @@ -457,9 +442,6 @@ msgstr "" msgid "Password needs to be more complex" msgstr "" -msgid "Password setup" -msgstr "Passord-oppsett" - msgid "Password:" msgstr "Passord:" @@ -517,9 +499,6 @@ msgstr "Avslå" msgid "Reject all" msgstr "Avslå alle" -msgid "Remind me later" -msgstr "Minn meg på dette senere" - msgid "Rename" msgstr "Gi nytt navn" @@ -559,9 +538,6 @@ msgstr "" msgid "Saved Browsers" msgstr "" -msgid "Saved browser" -msgstr "" - msgid "Saved on:" msgstr "" @@ -592,30 +568,15 @@ msgstr "Sett passord" msgid "Set Username" msgstr "Sett brukernavn" -msgid "Set it up now" -msgstr "" - -msgid "Set up" -msgstr "Sett opp" - msgid "Set up a password" msgstr "Sett opp et passord" -msgid "Set up auth factors" -msgstr "" - -msgid "Set up password" -msgstr "Sett opp passord" - msgid "Setting Username" msgstr "" msgid "Settings" msgstr "Innstillinger" -msgid "Setup incomplete" -msgstr "" - msgid "Shared" msgstr "Delt" @@ -652,12 +613,6 @@ msgstr "Størrelse" msgid "Social Sign-in Wallet" msgstr "" -msgid "Social Sign-in or Wallet" -msgstr "" - -msgid "Social sign in or wallet" -msgstr "" - msgid "Something went wrong with email login! Please try again." msgstr "" @@ -682,9 +637,6 @@ msgstr "Teknisk" msgid "Terms and Conditions" msgstr "Vilkår og betingelser" -msgid "Thanks for taking care of that. You can adjust these anytime in security settings." -msgstr "" - msgid "The authentication popup was closed" msgstr "" @@ -826,9 +778,6 @@ msgstr "Du har ikke satt noe brukernavn enda." msgid "You will need to sign a message in your wallet to complete sign in." msgstr "" -msgid "Your Authentication Factors" -msgstr "" - msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "" From fbf4d297a0a20aaf2bbc79ad9f50864b62df2a17 Mon Sep 17 00:00:00 2001 From: Tanmoy Basak Anjan Date: Wed, 4 Aug 2021 18:00:41 +0600 Subject: [PATCH 10/31] Copy/Move to shared folder (#1396) * added checkbox * keep file checkbox ready * lingui extract * Update packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * lingui extract * circular dependency in components * lingui extract Co-authored-by: GitHub Actions Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> --- .../src/TagsInput/TagsInput.tsx | 2 +- .../Modules/FileBrowsers/CSFFileBrowser.tsx | 18 +++++----- ...Modal.tsx => ShareToSharedFolderModal.tsx} | 36 +++++++++++++++---- .../views/FileSystemItem/FileSystemItem.tsx | 2 +- .../Modules/FileBrowsers/views/FilesList.tsx | 4 +-- .../src/Contexts/FileBrowserContext.tsx | 2 +- packages/files-ui/src/locales/de/messages.po | 21 +++++++---- packages/files-ui/src/locales/en/messages.po | 21 +++++++---- packages/files-ui/src/locales/es/messages.po | 21 +++++++---- packages/files-ui/src/locales/fr/messages.po | 21 +++++++---- packages/files-ui/src/locales/no/messages.po | 21 +++++++---- 11 files changed, 120 insertions(+), 49 deletions(-) rename packages/files-ui/src/Components/Modules/FileBrowsers/{CopyToSharedFolderModal.tsx => ShareToSharedFolderModal.tsx} (94%) diff --git a/packages/common-components/src/TagsInput/TagsInput.tsx b/packages/common-components/src/TagsInput/TagsInput.tsx index 33789a39da..a7a4b06867 100644 --- a/packages/common-components/src/TagsInput/TagsInput.tsx +++ b/packages/common-components/src/TagsInput/TagsInput.tsx @@ -7,7 +7,7 @@ import { } from "@chainsafe/common-theme" import clsx from "clsx" import AsyncSelect from "react-select/async" -import { Typography } from ".." +import { Typography } from "../Typography" import { Styles, ValueType, ActionMeta, ActionTypes } from "react-select" const useStyles = makeStyles( diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CSFFileBrowser.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/CSFFileBrowser.tsx index b5fbbac8d5..c87cb38f2e 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CSFFileBrowser.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/CSFFileBrowser.tsx @@ -76,7 +76,7 @@ const CSFFileBrowser: React.FC = () => { refreshContents(true) }, [bucket, refreshContents]) - const moveItemsToBin = useCallback(async (cids: string[]) => { + const moveItemsToBin = useCallback(async (cids: string[], hideToast?: boolean) => { if (!bucket) return await Promise.all( cids.map(async (cid: string) => { @@ -92,13 +92,15 @@ const CSFFileBrowser: React.FC = () => { new_path: getPathWithFile("/", itemToDelete.name), destination: buckets.find(b => b.type === "trash")?.id }) - const message = `${ - itemToDelete.isFolder ? t`Folder` : t`File` - } ${t`deleted successfully`}` - addToastMessage({ - message: message, - appearance: "success" - }) + if (!hideToast) { + const message = `${ + itemToDelete.isFolder ? t`Folder` : t`File` + } ${t`deleted successfully`}` + addToastMessage({ + message: message, + appearance: "success" + }) + } return Promise.resolve() } catch (error) { const message = `${t`There was an error deleting this`} ${ diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CopyToSharedFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx similarity index 94% rename from packages/files-ui/src/Components/Modules/FileBrowsers/CopyToSharedFolderModal.tsx rename to packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx index 6bde63894f..d8eb8fa1c0 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CopyToSharedFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx @@ -4,6 +4,7 @@ import CustomModal from "../../Elements/CustomModal" import { t, Trans } from "@lingui/macro" import { Button, + CheckboxInput, CheckCircleIcon, Link, Loading, @@ -96,11 +97,16 @@ const useStyles = makeStyles( justifyContent: "center", flexDirection: "column" }, - buttonsContainer: { + checkboxContainer: { display: "flex", justifyContent: "center", marginTop: constants.generalUnit * 4 }, + buttonsContainer: { + display: "flex", + justifyContent: "center", + marginTop: constants.generalUnit * 2 + }, mainButton: { width: "100%" }, @@ -199,10 +205,11 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => const [sharedFolderName, setSharedFolderName] = useState("") const { sharedFolderReaders, sharedFolderWriters, handleLookupUser, onNewUsers, usersError } = useLookupSharedFolderUser() const [isUsingCurrentBucket, setIsUsingCurrentBucket] = useState(true) + const [keepOriginalFile, setKeepOriginalFile] = useState(true) const [currentStep, setCurrentStep] = useState("1_SHARED_FOLDER_SELECTION_CREATION") const [destinationBucket, setDestinationBucket] = useState() const { buckets, uploadFiles } = useFiles() - const { bucket } = useFileBrowser() + const { bucket, deleteItems } = useFileBrowser() const { profile } = useUser() const { getFile, error: downloadError, isDownloading } = useGetFile() const [error, setError] = useState("") @@ -294,6 +301,11 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => setIsUploading(true) uploadFiles(bucketToUpload.id, [new File([fileContent], file.name)], UPLOAD_PATH, bucketToUpload.encryptionKey) + .then(() => { + if (!keepOriginalFile) { + deleteItems && deleteItems([file.cid], true) + } + }) .catch((e) => { setError(t`Error while uploading ${file.name}`) console.error(e) @@ -315,7 +327,9 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => sharedFolderName, uploadFiles, sharedFolderReaders, - sharedFolderWriters + sharedFolderWriters, + deleteItems, + keepOriginalFile ]) @@ -432,7 +446,7 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) =>
- Copy to shared folder + Share file
{(error || downloadError) && ( @@ -477,6 +491,13 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => {usersError} )} +
+ setKeepOriginalFile(!keepOriginalFile)} + label={t`Keep original file`} + /> +
@@ -515,7 +539,7 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => variant="h4" component="p" > - File added successfully! + File shared successfully! diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemItem.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemItem.tsx index 40a43cc3d6..741ed2cf76 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemItem.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemItem.tsx @@ -233,7 +233,7 @@ const FileSystemItem = ({ <> - Copy to shared folder + Share ), diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx index 56a8665bf9..ed3e60ed27 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx @@ -50,7 +50,7 @@ import SurveyBanner from "../../../SurveyBanner" import { DragPreviewLayer } from "./DragPreviewLayer" import { useFileBrowser } from "../../../../Contexts/FileBrowserContext" import ReportFileModal from "../ReportFileModal" -import CopyToSharedFolderModal from "../CopyToSharedFolderModal" +import ShareToSharedFolderModal from "../ShareToSharedFolderModal" import SharedUsers from "../../../Elements/SharedUsers" const baseOperations: FileOperation[] = ["download", "info", "preview"] @@ -1097,7 +1097,7 @@ const FilesList = ({ isShared = false }: Props) => { /> } { isCopyToSharedFolerModalOpen && filePath && fileIndex !== undefined && - { setIsCopyToSharedFolerModalOpen(false) diff --git a/packages/files-ui/src/Contexts/FileBrowserContext.tsx b/packages/files-ui/src/Contexts/FileBrowserContext.tsx index b60005a501..4252705ebb 100644 --- a/packages/files-ui/src/Contexts/FileBrowserContext.tsx +++ b/packages/files-ui/src/Contexts/FileBrowserContext.tsx @@ -11,7 +11,7 @@ interface FileBrowserContext extends IFileBrowserModuleProps { renameItem?: (cid: string, newName: string) => Promise moveItems?: (cids: string[], newPath: string) => Promise downloadFile?: (cid: string) => Promise - deleteItems?: (cid: string[]) => Promise + deleteItems?: (cid: string[], hideToast?: boolean) => Promise recoverItems?: (cid: string[], newPath: string) => Promise viewFolder?: (cid: string) => void allowDropUpload?: boolean diff --git a/packages/files-ui/src/locales/de/messages.po b/packages/files-ui/src/locales/de/messages.po index d37caaa1e7..5805473843 100644 --- a/packages/files-ui/src/locales/de/messages.po +++ b/packages/files-ui/src/locales/de/messages.po @@ -130,9 +130,6 @@ msgstr "" msgid "Copy over" msgstr "" -msgid "Copy to shared folder" -msgstr "" - msgid "Create" msgstr "Erstellen" @@ -241,15 +238,15 @@ msgstr "Datei" msgid "File Info" msgstr "Dateiinfos" -msgid "File added successfully!" -msgstr "" - msgid "File format not supported." msgstr "Dateiformat wird nicht unterstützt." msgid "File path" msgstr "" +msgid "File shared successfully!" +msgstr "" + msgid "File size" msgstr "Dateigröße" @@ -325,6 +322,9 @@ msgstr "Infos" msgid "I’m done saving my backup secret phrase" msgstr "Ich bin fertig mit dem Speichern meines Sixherungsgeheimsatzes" +msgid "Keep original file" +msgstr "" + msgid "Language" msgstr "Sprache" @@ -364,6 +364,9 @@ msgstr "" msgid "Move" msgstr "Verschieben" +msgid "Move over" +msgstr "" + msgid "Move selected" msgstr "Ausgewählte verschieben" @@ -577,6 +580,12 @@ msgstr "Benutzername wird eingestellt" msgid "Settings" msgstr "Einstellungen" +msgid "Share" +msgstr "" + +msgid "Share file" +msgstr "" + msgid "Shared" msgstr "Geteilt" diff --git a/packages/files-ui/src/locales/en/messages.po b/packages/files-ui/src/locales/en/messages.po index b35cf0668d..93b23a2bae 100644 --- a/packages/files-ui/src/locales/en/messages.po +++ b/packages/files-ui/src/locales/en/messages.po @@ -130,9 +130,6 @@ msgstr "Copy info" msgid "Copy over" msgstr "Copy over" -msgid "Copy to shared folder" -msgstr "Copy to shared folder" - msgid "Create" msgstr "Create" @@ -244,15 +241,15 @@ msgstr "File" msgid "File Info" msgstr "File Info" -msgid "File added successfully!" -msgstr "File added successfully!" - msgid "File format not supported." msgstr "File format not supported." msgid "File path" msgstr "File path" +msgid "File shared successfully!" +msgstr "File shared successfully!" + msgid "File size" msgstr "File size" @@ -328,6 +325,9 @@ msgstr "Info" msgid "I’m done saving my backup secret phrase" msgstr "I’m done saving my backup secret phrase" +msgid "Keep original file" +msgstr "Keep original file" + msgid "Language" msgstr "Language" @@ -367,6 +367,9 @@ msgstr "Manage Access" msgid "Move" msgstr "Move" +msgid "Move over" +msgstr "Move over" + msgid "Move selected" msgstr "Move selected" @@ -580,6 +583,12 @@ msgstr "Setting Username" msgid "Settings" msgstr "Settings" +msgid "Share" +msgstr "Share" + +msgid "Share file" +msgstr "Share file" + msgid "Shared" msgstr "Shared" diff --git a/packages/files-ui/src/locales/es/messages.po b/packages/files-ui/src/locales/es/messages.po index fb01b89dea..3fcb73ad52 100644 --- a/packages/files-ui/src/locales/es/messages.po +++ b/packages/files-ui/src/locales/es/messages.po @@ -131,9 +131,6 @@ msgstr "" msgid "Copy over" msgstr "" -msgid "Copy to shared folder" -msgstr "" - msgid "Create" msgstr "Crear" @@ -245,15 +242,15 @@ msgstr "Archivo" msgid "File Info" msgstr "Información del archivo" -msgid "File added successfully!" -msgstr "" - msgid "File format not supported." msgstr "Formato de archivo no soportado." msgid "File path" msgstr "" +msgid "File shared successfully!" +msgstr "" + msgid "File size" msgstr "Tamaño del archivo" @@ -329,6 +326,9 @@ msgstr "Info" msgid "I’m done saving my backup secret phrase" msgstr "" +msgid "Keep original file" +msgstr "" + msgid "Language" msgstr "Idioma" @@ -368,6 +368,9 @@ msgstr "" msgid "Move" msgstr "Moverse" +msgid "Move over" +msgstr "" + msgid "Move selected" msgstr "Mover seleccionado" @@ -581,6 +584,12 @@ msgstr "" msgid "Settings" msgstr "Ajustes" +msgid "Share" +msgstr "" + +msgid "Share file" +msgstr "" + msgid "Shared" msgstr "" diff --git a/packages/files-ui/src/locales/fr/messages.po b/packages/files-ui/src/locales/fr/messages.po index 97a7a4b941..b79ae24995 100644 --- a/packages/files-ui/src/locales/fr/messages.po +++ b/packages/files-ui/src/locales/fr/messages.po @@ -131,9 +131,6 @@ msgstr "Copier les infos" msgid "Copy over" msgstr "Copier sur" -msgid "Copy to shared folder" -msgstr "Copier dans le dossier partagé" - msgid "Create" msgstr "Créer" @@ -245,15 +242,15 @@ msgstr "Fichier" msgid "File Info" msgstr "Infos du fichier" -msgid "File added successfully!" -msgstr "Fichier ajouté avec succès !" - msgid "File format not supported." msgstr "Format de fichier non pris en charge." msgid "File path" msgstr "Chemin du fichier" +msgid "File shared successfully!" +msgstr "" + msgid "File size" msgstr "Taille" @@ -329,6 +326,9 @@ msgstr "Infos" msgid "I’m done saving my backup secret phrase" msgstr "Phrase de sauvegarde secrète enregistrée" +msgid "Keep original file" +msgstr "" + msgid "Language" msgstr "Langue" @@ -368,6 +368,9 @@ msgstr "Gérer l’accès" msgid "Move" msgstr "Déplacer" +msgid "Move over" +msgstr "" + msgid "Move selected" msgstr "Déplacer la sélection" @@ -581,6 +584,12 @@ msgstr "Définition du nom d’utilisateur" msgid "Settings" msgstr "Paramètres" +msgid "Share" +msgstr "" + +msgid "Share file" +msgstr "" + msgid "Shared" msgstr "Partagé" diff --git a/packages/files-ui/src/locales/no/messages.po b/packages/files-ui/src/locales/no/messages.po index edde230a24..a26f15686d 100644 --- a/packages/files-ui/src/locales/no/messages.po +++ b/packages/files-ui/src/locales/no/messages.po @@ -130,9 +130,6 @@ msgstr "" msgid "Copy over" msgstr "" -msgid "Copy to shared folder" -msgstr "" - msgid "Create" msgstr "Opprett" @@ -241,15 +238,15 @@ msgstr "Fil" msgid "File Info" msgstr "Filinfo" -msgid "File added successfully!" -msgstr "" - msgid "File format not supported." msgstr "" msgid "File path" msgstr "" +msgid "File shared successfully!" +msgstr "" + msgid "File size" msgstr "Filstørrelse" @@ -325,6 +322,9 @@ msgstr "Info" msgid "I’m done saving my backup secret phrase" msgstr "" +msgid "Keep original file" +msgstr "" + msgid "Language" msgstr "Språk" @@ -364,6 +364,9 @@ msgstr "" msgid "Move" msgstr "Flytt" +msgid "Move over" +msgstr "" + msgid "Move selected" msgstr "Flytt valgte" @@ -577,6 +580,12 @@ msgstr "" msgid "Settings" msgstr "Innstillinger" +msgid "Share" +msgstr "" + +msgid "Share file" +msgstr "" + msgid "Shared" msgstr "Delt" From 2db0874d3d12967b37499b5680b0e78c89b87be4 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Wed, 4 Aug 2021 14:10:27 +0200 Subject: [PATCH 11/31] Add validation for new shared folder (#1390) * fix validation and refactor * lingui extract * lingui extract * validate creation on copy * trim on the last stage * with the right name * better button behavior shared folder validation * Update packages/files-ui/src/Components/Modules/FileBrowsers/CopyToSharedFolderModal.tsx Co-authored-by: GitHub Actions Co-authored-by: Ryan Noble Co-authored-by: Tanmoy Basak Anjan Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> --- .../FileBrowsers/CreateFolderModal.tsx | 4 +- .../CreateOrEditSharedFolderModal.tsx | 55 +++++++++----- .../FileBrowsers/ShareToSharedFolderModal.tsx | 71 ++++++++++++++----- .../FileBrowsers/SharedFileBrowser.tsx | 2 +- .../hooks/useCreateOrEditSharedFolder.tsx | 2 +- .../FileSystemItem/FileSystemGridItem.tsx | 14 ++-- .../views/FileSystemItem/FileSystemItem.tsx | 16 ++--- .../FileSystemItem/FileSystemTableItem.tsx | 14 ++-- .../views/FileSystemItem/SharedFolderRow.tsx | 10 +-- .../Modules/LoginModule/InitialScreen.tsx | 8 ++- .../Modules/LoginModule/PasswordlessEmail.tsx | 18 ----- .../files-ui/src/Utils/validationSchema.ts | 33 ++------- packages/files-ui/src/locales/de/messages.po | 12 ---- packages/files-ui/src/locales/en/messages.po | 12 ---- packages/files-ui/src/locales/es/messages.po | 12 ---- packages/files-ui/src/locales/fr/messages.po | 14 +--- packages/files-ui/src/locales/no/messages.po | 12 ---- .../Modules/LoginModule/PasswordlessEmail.tsx | 10 +-- .../src/Components/Modules/AddCIDModal.tsx | 2 +- .../CreateFolderModal/CreateFolderModal.tsx | 4 +- .../FileSystemItem/FileSystemGridItem.tsx | 4 +- .../Modules/FileSystemItem/FileSystemItem.tsx | 4 +- .../FileSystemItem/FileSystemTableItem.tsx | 4 +- .../Modules/LoginModule/PasswordlessEmail.tsx | 8 ++- .../storage-ui/src/Utils/validationSchema.ts | 40 ++--------- .../storage-ui/src/locales/en/messages.po | 21 +----- 26 files changed, 167 insertions(+), 239 deletions(-) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx index 308537133a..27195e4d30 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx @@ -17,7 +17,7 @@ import { t, Trans } from "@lingui/macro" import { CSFTheme } from "../../../Themes/types" import { useFileBrowser } from "../../../Contexts/FileBrowserContext" import { useFilesApi } from "../../../Contexts/FilesApiContext" -import { folderNameValidator } from "../../../Utils/validationSchema" +import { nameValidator } from "../../../Utils/validationSchema" import { getPathWithFile } from "../../../Utils/pathUtils" @@ -108,7 +108,7 @@ const CreateFolderModal: React.FC = ({ initialValues={{ name: "" }} - validationSchema={folderNameValidator} + validationSchema={nameValidator} validateOnChange={false} onSubmit={async (values, helpers) => { if (!bucket) return diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx index bb01b8f3d9..e9e1bbcd25 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx @@ -1,16 +1,5 @@ -import { - Button, - ShareAltSvg, - TagsInput, - Typography, - Grid, - TextInput -} from "@chainsafe/common-components" -import { - createStyles, - makeStyles, - useThemeSwitcher -} from "@chainsafe/common-theme" +import { Button, ShareAltSvg, TagsInput, Typography, Grid, TextInput } from "@chainsafe/common-components" +import { createStyles, makeStyles, useThemeSwitcher } from "@chainsafe/common-theme" import React, { useState, useCallback } from "react" import CustomModal from "../../Elements/CustomModal" import { CSFTheme } from "../../../Themes/types" @@ -21,6 +10,7 @@ import { useEffect } from "react" import { SharedFolderModalMode } from "./types" import { useCreateOrEditSharedFolder } from "./hooks/useCreateOrEditSharedFolder" import { useLookupSharedFolderUser } from "./hooks/useLookupUser" +import { nameValidator } from "../../../Utils/validationSchema" import { getUserDisplayName } from "../../../Utils/getUserDisplayName" const useStyles = makeStyles( @@ -109,6 +99,10 @@ const useStyles = makeStyles( footer: { width: "100%", padding: `${constants.generalUnit * 2}px ${constants.generalUnit}px` + }, + errorText: { + marginLeft: constants.generalUnit * 1.5, + color: palette.error.main } }) } @@ -128,6 +122,7 @@ const CreateOrEditSharedFolderModal = ({ mode, isModalOpen, onClose, bucketToEdi const [sharedFolderName, setSharedFolderName] = useState("") const { sharedFolderReaders, sharedFolderWriters, onNewUsers, handleLookupUser, usersError, setUsersError } = useLookupSharedFolderUser() const [hasPermissionsChanged, setHasPermissionsChanged] = useState(false) + const [nameError, setNameError] = useState("") useEffect(() => { setSharedFolderName("") @@ -167,6 +162,22 @@ const CreateOrEditSharedFolderModal = ({ mode, isModalOpen, onClose, bucketToEdi .finally(onClose) }, [handleEditSharedFolder, sharedFolderWriters, sharedFolderReaders, onClose, bucketToEdit]) + const onNameChange = useCallback((value?: string | number) => { + if (value === undefined) return + + const name = value.toString() + setSharedFolderName(name) + + nameValidator + .validate({ name }) + .then(() => { + setNameError("") + }) + .catch((e: Error) => { + setNameError(e.message) + }) + }, []) + return ( {setSharedFolderName(value?.toString() || "")}} + onChange={onNameChange} autoFocus + state={nameError ? "error" : "normal"} /> + {nameError && ( + + {nameError} + + )} }
@@ -219,7 +240,8 @@ const CreateOrEditSharedFolderModal = ({ mode, isModalOpen, onClose, bucketToEdi minHeight: 90, alignContent: "start" }) - }}/> + }} + />
{usersError} @@ -276,7 +299,7 @@ const CreateOrEditSharedFolderModal = ({ mode, isModalOpen, onClose, bucketToEdi className={classes.okButton} loading={isCreatingSharedFolder || isEditingSharedFolder} onClick={mode === "create" ? onCreateSharedFolder : onEditSharedFolder} - disabled={mode === "create" ? !!usersError : !hasPermissionsChanged || !!usersError} + disabled={mode === "create" ? (!!usersError || !!nameError) : !hasPermissionsChanged || !!usersError} > {mode === "create" ? Create diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx index d8eb8fa1c0..bca7cb8ed1 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx @@ -26,6 +26,7 @@ import { useFileBrowser } from "../../../Contexts/FileBrowserContext" import { ROUTE_LINKS } from "../../FilesRoutes" import clsx from "clsx" import { useEffect } from "react" +import { nameValidator } from "../../../Utils/validationSchema" const useStyles = makeStyles( ({ breakpoints, constants, palette, typography, zIndex }: CSFTheme) => { @@ -185,6 +186,13 @@ const useStyles = makeStyles( }, inputWrapper: { marginBottom: 0 + }, + errorText: { + marginLeft: constants.generalUnit * 2, + color: palette.error.main + }, + titleWrapper: { + padding: "0 5px" } }) } @@ -214,6 +222,7 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => const { getFile, error: downloadError, isDownloading } = useGetFile() const [error, setError] = useState("") const [isUploading, setIsUploading] = useState(false) + const [nameError, setNameError] = useState("") const isBusyWithSecondStep = useMemo( () => isCreatingSharedFolder || isDownloading || isUploading , [isCreatingSharedFolder, isDownloading, isUploading] @@ -244,6 +253,22 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => } }, [hasNoSharedBucket]) + const onNameChange = useCallback((value?: string | number) => { + if (value === undefined) return + + const name = value.toString() + setSharedFolderName(name) + + nameValidator + .validate({ name }) + .then(() => { + setNameError("") + }) + .catch((e: Error) => { + setNameError(e.message) + }) + }, []) + const onShare = useCallback(async () => { if(!bucket) { console.error("Bucket is undefined") @@ -332,7 +357,6 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => keepOriginalFile ]) - const onBackClick = useCallback(() => { if (currentStep === "1_SHARED_FOLDER_SELECTION_CREATION"){ close() @@ -365,15 +389,25 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => const Step1CreateSharedFolder = useCallback(() => ( <> -
+
{setSharedFolderName(value?.toString() || "")}} autoFocus + onChange={onNameChange} + state={nameError ? "error" : "normal"} /> + {nameError && ( + + {nameError} + + )}
}) }}/>
+ {!!usersError && ( + + {usersError} + + )} ), [ - classes.inputLabel, - classes.modalFlexItem, - classes.shareFolderNameInput, + classes, handleLookupUser, + nameError, + onNameChange, onNewUsers, sharedFolderName, sharedFolderReaders, - sharedFolderWriters + sharedFolderWriters, + usersError ]) const Step1ExistingSharedFolder = useCallback(() => ( @@ -483,14 +527,6 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) =>
)} - {!!usersError && ( - - {usersError} - - )}
variant="primary" onClick={onShare} className={classes.sideBySideButton} - disabled={currentStep === "1_SHARED_FOLDER_SELECTION_CREATION" ? !!usersError : false} + disabled={isUsingCurrentBucket + ? !destinationBucket?.id + : !sharedFolderName || !!usersError || !!nameError + } > {keepOriginalFile ? Copy over diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFileBrowser.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFileBrowser.tsx index ad07bf19b7..c42485184e 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFileBrowser.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFileBrowser.tsx @@ -251,7 +251,7 @@ const SharedFileBrowser = () => { deleteItems, downloadFile: handleDownload, moveItems, - renameItem: renameItem, + renameItem, viewFolder, loadingCurrentPath, showUploadsInTable: false, diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useCreateOrEditSharedFolder.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useCreateOrEditSharedFolder.tsx index 08e510e313..d3222536f7 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useCreateOrEditSharedFolder.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useCreateOrEditSharedFolder.tsx @@ -21,7 +21,7 @@ export const useCreateOrEditSharedFolder = () => { const readers = getSharedUsers(sharedFolderReaders) const writers = getSharedUsers(sharedFolderWriters) setIsCreatingSharedFolder(true) - return createSharedFolder(sharedFolderName, writers, readers) + return createSharedFolder(sharedFolderName.trim(), writers, readers) .then((bucket) => { setIsCreatingSharedFolder(false) return bucket diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemGridItem.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemGridItem.tsx index 7c70be06e8..b305989fb7 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemGridItem.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemGridItem.tsx @@ -12,7 +12,7 @@ import { CSFTheme } from "../../../../../Themes/types" import { FileSystemItem } from "../../../../../Contexts/FilesContext" import { ConnectDragPreview } from "react-dnd" import { Form, FormikProvider, useFormik } from "formik" -import { renameSchema } from "../../../../../Utils/validationSchema" +import { nameValidator } from "../../../../../Utils/validationSchema" const useStyles = makeStyles(({ breakpoints, constants, palette }: CSFTheme) => { return createStyles({ @@ -157,12 +157,12 @@ const FileSystemGridItem = React.forwardRef( const { desktop } = useThemeSwitcher() const formik = useFormik({ - initialValues:{ - fileName: name + initialValues: { + name }, - validationSchema: renameSchema, - onSubmit:(values) => { - const newName = values.fileName?.trim() + validationSchema: nameValidator, + onSubmit: (values: {name: string}) => { + const newName = values.name.trim() newName && handleRename && handleRename(file.cid, newName) }, @@ -229,7 +229,7 @@ const FileSystemGridItem = React.forwardRef( > { if (event.key === "Escape") { diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemItem.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemItem.tsx index 741ed2cf76..588e3ca608 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemItem.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemItem.tsx @@ -34,7 +34,7 @@ import { useFileBrowser } from "../../../../../Contexts/FileBrowserContext" import { getPathWithFile } from "../../../../../Utils/pathUtils" import { BucketUser } from "@chainsafe/files-api-client" import { useMemo } from "react" -import { renameSchema } from "../../../../../Utils/validationSchema" +import { nameValidator } from "../../../../../Utils/validationSchema" const useStyles = makeStyles(({ breakpoints, constants }: CSFTheme) => { return createStyles({ @@ -153,17 +153,18 @@ const FileSystemItem = ({ const { cid, name, isFolder, content_type } = file const formik = useFormik({ - initialValues:{ - fileName: name + initialValues: { + name }, - validationSchema:renameSchema, - onSubmit:(values) => { - const newName = values.fileName?.trim() + validationSchema: nameValidator, + onSubmit: (values: {name: string}) => { + const newName = values.name.trim() newName && handleRename && handleRename(file.cid, newName) }, enableReinitialize: true }) + let Icon if (isFolder) { Icon = FolderFilledSvg @@ -433,7 +434,6 @@ const FileSystemItem = ({ menuItems, onFolderOrFileClicks, preview, - renameSchema, selected, setEditing, resetSelectedFiles @@ -473,7 +473,7 @@ const FileSystemItem = ({ diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx index 7bdf9e9d28..54f34b528c 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx @@ -18,7 +18,7 @@ import dayjs from "dayjs" import { FileSystemItem } from "../../../../../Contexts/FilesContext" import { ConnectDragPreview } from "react-dnd" import { Form, FormikProvider, useFormik } from "formik" -import { renameSchema } from "../../../../../Utils/validationSchema" +import { nameValidator } from "../../../../../Utils/validationSchema" const useStyles = makeStyles(({ breakpoints, constants, palette }: CSFTheme) => { const desktopGridSettings = "50px 69px 3fr 190px 100px 45px !important" @@ -142,12 +142,12 @@ const FileSystemTableItem = React.forwardRef( const { desktop } = useThemeSwitcher() const formik = useFormik({ - initialValues:{ - fileName: name + initialValues: { + name }, - validationSchema: renameSchema, - onSubmit:(values) => { - const newName = values.fileName?.trim() + validationSchema: nameValidator, + onSubmit: (values: {name: string}) => { + const newName = values.name.trim() newName && handleRename && handleRename(file.cid, newName) }, @@ -201,7 +201,7 @@ const FileSystemTableItem = React.forwardRef( > { if (event.key === "Escape") { diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx index 8a10c026bd..d456bed699 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx @@ -23,7 +23,7 @@ import { Form, FormikProvider, useFormik } from "formik" import clsx from "clsx" import { BucketKeyPermission } from "../../../../../Contexts/FilesContext" import UserBubble from "../../../../Elements/UserBubble" -import { renameSchema } from "../../../../../Utils/validationSchema" +import { nameValidator } from "../../../../../Utils/validationSchema" const useStyles = makeStyles(({ breakpoints, constants, palette }: CSFTheme) => { @@ -201,12 +201,12 @@ const SharedFolderRow = ({ bucket, handleRename, openSharedFolder, handleDeleteS const formik = useFormik({ initialValues:{ - fileName: name + name }, enableReinitialize: true, - validationSchema: renameSchema, + validationSchema: nameValidator, onSubmit:(values, { resetForm }) => { - const newName = values.fileName?.trim() + const newName = values.name?.trim() newName && handleRename && handleRename(bucket, newName) setIsRenaming(false) @@ -249,7 +249,7 @@ const SharedFolderRow = ({ bucket, handleRename, openSharedFolder, handleDeleteS > { if (event.key === "Escape") { diff --git a/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx b/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx index f8d16a64aa..fe3499b564 100644 --- a/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx +++ b/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx @@ -230,13 +230,15 @@ const InitialScreen = ({ className }: IInitialScreen) => { setIsConnecting(false) } - const onSubmitEmail = useCallback((values) => { + const onSubmitEmail = useCallback((values: {email: string}) => { setIsConnecting(true) setErrorEmail("") + const trimmedEmail = values.email.trim() + filesApiClient - .getIdentityEmailToken({ email: values.email }) + .getIdentityEmailToken({ email: trimmedEmail }) .then(() => { - setEmail(values.email) + setEmail(trimmedEmail) setLoginMode("email") }) .catch((e) => { diff --git a/packages/files-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx b/packages/files-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx index 55bb7c146a..1d0fe08623 100644 --- a/packages/files-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx +++ b/packages/files-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx @@ -88,31 +88,13 @@ interface IPasswordlessEmail { const PasswordlessEmail = ({ resetLogin, email }: IPasswordlessEmail) => { const classes = useStyles() - // const [isSubmitEmailLoading, setIsSubmitEmailLoading] = useState(false) const [isSubmitResendEmailLoading, setIsSubmitResendEmailLoading] = useState(false) const [isSubmitNonceLoading, setIsSubmitNonceLoading] = useState(false) - // const [page, setPage] = useState<"confirmEmail" | "confirmVerificationCode">("confirmEmail") - // const [email, setEmail] = useState() const [hasEmailResent, setHasEmailResent] = useState(false) const { filesApiClient } = useFilesApi() const { login } = useThresholdKey() const [error, setError] = useState() - // const onSubmitEmail = useCallback((values) => { - // setIsSubmitEmailLoading(true) - // setError(undefined) - // filesApiClient.getIdentityEmailToken({ email: values.email }) - // .then(() => { - // setEmail(values.email) - // setPage("confirmVerificationCode") - // setIsSubmitEmailLoading(false) - // }).catch ((e) => { - // setError(t`Something went wrong!`) - // setIsSubmitEmailLoading(false) - // console.error(e) - // }) - // }, [filesApiClient]) - const onSubmitNonce = useCallback((values) => { if (!email) return setIsSubmitNonceLoading(true) diff --git a/packages/files-ui/src/Utils/validationSchema.ts b/packages/files-ui/src/Utils/validationSchema.ts index 05c7476651..fec4a7a9e3 100644 --- a/packages/files-ui/src/Utils/validationSchema.ts +++ b/packages/files-ui/src/Utils/validationSchema.ts @@ -1,49 +1,28 @@ import { t } from "@lingui/macro" import { object, string } from "yup" -const whitespaceOnlyRegex = new RegExp("^\\s+$") - -export const renameSchema = object().shape({ - fileName: string() - .min(1, t`Please enter a name`) - .max(65, t`Name too long`) - .required(t`A name is required`) - .test( - "Invalid character in name", - t`Name cannot contain '/' character`, - (val: string | null | undefined) => !val?.includes("/") - ) - .test( - "Only whitespace", - t`Name cannot only contain whitespace characters`, - (val) => !!val && !whitespaceOnlyRegex.test(val) - ) -}) - -export const folderNameValidator = object().shape({ +export const nameValidator = object().shape({ name: string() + .trim() .min(1, t`Please enter a name`) .max(65, t`Name too long`) - .required("Folder name is required") + .required("A name is required") .test( "Invalid name", - "Folder name cannot contain '/' character", + "A name cannot contain '/' character", (val: string | null | undefined) => !val?.includes("/") ) - .test( - "Only whitespace", - t`Folder name cannot only contain whitepsace characters`, - (val) => !!val && !whitespaceOnlyRegex.test(val) - ) }) export const emailValidation = object().shape({ email: string() + .trim() .email("Please enter a valid email") .required(t`Email is required`) }) export const nonceValidation = object().shape({ nonce: string() + .trim() .required(t`Verification code is required`) }) \ No newline at end of file diff --git a/packages/files-ui/src/locales/de/messages.po b/packages/files-ui/src/locales/de/messages.po index 5805473843..3091d1ef42 100644 --- a/packages/files-ui/src/locales/de/messages.po +++ b/packages/files-ui/src/locales/de/messages.po @@ -19,9 +19,6 @@ msgstr "Es wird ein Sicherungsgeheimsatz generiert und für Ihr Konto verwendet. msgid "A file with the same name already exists" msgstr "Es existiert bereits eine Datei mit demselben Namen" -msgid "A name is required" -msgstr "Ein Name ist erforderlich" - msgid "Account" msgstr "Konto" @@ -262,9 +259,6 @@ msgstr "Vorname" msgid "Folder" msgstr "Ordner" -msgid "Folder name cannot only contain whitepsace characters" -msgstr "" - msgid "Folder name is already in use" msgstr "" @@ -379,12 +373,6 @@ msgstr "Meine Dateien" msgid "Name" msgstr "Name" -msgid "Name cannot contain '/' character" -msgstr "Name darf kein /-Zeichen enthalten" - -msgid "Name cannot only contain whitespace characters" -msgstr "" - msgid "Name too long" msgstr "Name zu lang" diff --git a/packages/files-ui/src/locales/en/messages.po b/packages/files-ui/src/locales/en/messages.po index 93b23a2bae..cb6dc1791b 100644 --- a/packages/files-ui/src/locales/en/messages.po +++ b/packages/files-ui/src/locales/en/messages.po @@ -19,9 +19,6 @@ msgstr "A backup secret phrase will be generated and used for your account.<0/>W msgid "A file with the same name already exists" msgstr "A file with the same name already exists" -msgid "A name is required" -msgstr "A name is required" - msgid "Account" msgstr "Account" @@ -265,9 +262,6 @@ msgstr "First name" msgid "Folder" msgstr "Folder" -msgid "Folder name cannot only contain whitepsace characters" -msgstr "Folder name cannot only contain whitepsace characters" - msgid "Folder name is already in use" msgstr "Folder name is already in use" @@ -382,12 +376,6 @@ msgstr "My Files" msgid "Name" msgstr "Name" -msgid "Name cannot contain '/' character" -msgstr "Name cannot contain '/' character" - -msgid "Name cannot only contain whitespace characters" -msgstr "Name cannot only contain whitespace characters" - msgid "Name too long" msgstr "Name too long" diff --git a/packages/files-ui/src/locales/es/messages.po b/packages/files-ui/src/locales/es/messages.po index 3fcb73ad52..b8fa8e79a7 100644 --- a/packages/files-ui/src/locales/es/messages.po +++ b/packages/files-ui/src/locales/es/messages.po @@ -20,9 +20,6 @@ msgstr "" msgid "A file with the same name already exists" msgstr "Ya existe un archivo con el mismo nombre" -msgid "A name is required" -msgstr "" - msgid "Account" msgstr "Cuenta" @@ -266,9 +263,6 @@ msgstr "Primer Nombre" msgid "Folder" msgstr "Archivo" -msgid "Folder name cannot only contain whitepsace characters" -msgstr "" - msgid "Folder name is already in use" msgstr "" @@ -383,12 +377,6 @@ msgstr "Mis Archivos" msgid "Name" msgstr "Nombre" -msgid "Name cannot contain '/' character" -msgstr "" - -msgid "Name cannot only contain whitespace characters" -msgstr "" - msgid "Name too long" msgstr "" diff --git a/packages/files-ui/src/locales/fr/messages.po b/packages/files-ui/src/locales/fr/messages.po index b79ae24995..6e5afcacd7 100644 --- a/packages/files-ui/src/locales/fr/messages.po +++ b/packages/files-ui/src/locales/fr/messages.po @@ -20,9 +20,6 @@ msgstr "Une phrase secrète de sauvegarde sera générée et utilisé pour ce co msgid "A file with the same name already exists" msgstr "Un fichier avec ce nom existe déjà" -msgid "A name is required" -msgstr "Le nom ne peut être vide" - msgid "Account" msgstr "Compte" @@ -129,7 +126,7 @@ msgid "Copy info" msgstr "Copier les infos" msgid "Copy over" -msgstr "Copier sur" +msgstr "Copier" msgid "Create" msgstr "Créer" @@ -266,9 +263,6 @@ msgstr "Prénom" msgid "Folder" msgstr "Dossier" -msgid "Folder name cannot only contain whitepsace characters" -msgstr "Le nom du dossier ne peut pas seulement contenir des caractères blancs" - msgid "Folder name is already in use" msgstr "Le nom du dossier est déjà utilisé" @@ -383,12 +377,6 @@ msgstr "Mes Fichiers" msgid "Name" msgstr "Nom" -msgid "Name cannot contain '/' character" -msgstr "Le nom ne peut pas contenir le caractère /" - -msgid "Name cannot only contain whitespace characters" -msgstr "Le nom ne peut pas seulement contenir des espaces" - msgid "Name too long" msgstr "Le nom est trop long" diff --git a/packages/files-ui/src/locales/no/messages.po b/packages/files-ui/src/locales/no/messages.po index a26f15686d..249161d948 100644 --- a/packages/files-ui/src/locales/no/messages.po +++ b/packages/files-ui/src/locales/no/messages.po @@ -19,9 +19,6 @@ msgstr "" msgid "A file with the same name already exists" msgstr "" -msgid "A name is required" -msgstr "Navn kreves" - msgid "Account" msgstr "Konto" @@ -262,9 +259,6 @@ msgstr "Fornavn" msgid "Folder" msgstr "Mappe" -msgid "Folder name cannot only contain whitepsace characters" -msgstr "" - msgid "Folder name is already in use" msgstr "" @@ -379,12 +373,6 @@ msgstr "Mine filer" msgid "Name" msgstr "Navn" -msgid "Name cannot contain '/' character" -msgstr "" - -msgid "Name cannot only contain whitespace characters" -msgstr "" - msgid "Name too long" msgstr "Navnet er for langt" diff --git a/packages/gaming-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx b/packages/gaming-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx index 1324dd781f..cc753dd610 100644 --- a/packages/gaming-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx +++ b/packages/gaming-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx @@ -110,12 +110,14 @@ const PasswordlessEmail = ({ resetLogin }: IPasswordlessEmail) => { }) , []) - const onSubmitEmail = useCallback((values) => { + const onSubmitEmail = useCallback((values: {email: string}) => { + const trimmedEmail = values?.email?.trim() + setIsSubmitEmailLoading(true) setError(undefined) - gamingApiClient.getIdentityEmailToken({ email: values.email }) + gamingApiClient.getIdentityEmailToken({ email: trimmedEmail }) .then(() => { - setEmail(values.email) + setEmail(trimmedEmail) setPage("confirmVerificationCode") }).catch ((e) => { setError(t`Something went wrong! Please try again.`) @@ -123,7 +125,7 @@ const PasswordlessEmail = ({ resetLogin }: IPasswordlessEmail) => { }).finally (() => setIsSubmitEmailLoading(false)) }, [gamingApiClient]) - const onSubmitNonce = useCallback((values) => { + const onSubmitNonce = useCallback((values: {nonce: string}) => { if (!email) return setIsSubmitNonceLoading(true) setError(undefined) diff --git a/packages/storage-ui/src/Components/Modules/AddCIDModal.tsx b/packages/storage-ui/src/Components/Modules/AddCIDModal.tsx index 5e0593b735..3d3f7cb70d 100644 --- a/packages/storage-ui/src/Components/Modules/AddCIDModal.tsx +++ b/packages/storage-ui/src/Components/Modules/AddCIDModal.tsx @@ -70,7 +70,7 @@ const AddCIDModal = ({ modalOpen = false, close }: IAddCIDModuleProps) => { const onSubmit = useCallback((values, helpers) => { helpers.setSubmitting(true) setAccessingCID(true) - addPin(values.cid) + addPin(values.cid.trim()) .then(() => { helpers.resetForm() close() diff --git a/packages/storage-ui/src/Components/Modules/CreateFolderModal/CreateFolderModal.tsx b/packages/storage-ui/src/Components/Modules/CreateFolderModal/CreateFolderModal.tsx index 99cca04b6d..7eedf160c2 100644 --- a/packages/storage-ui/src/Components/Modules/CreateFolderModal/CreateFolderModal.tsx +++ b/packages/storage-ui/src/Components/Modules/CreateFolderModal/CreateFolderModal.tsx @@ -17,7 +17,7 @@ import { t, Trans } from "@lingui/macro" import { CSSTheme } from "../../../Themes/types" import { useFileBrowser } from "../../../Contexts/FileBrowserContext" import { useStorageApi } from "../../../Contexts/StorageApiContext" -import { folderNameValidator } from "../../../Utils/validationSchema" +import { nameValidator } from "../../../Utils/validationSchema" import { getPathWithFile } from "../../../Utils/pathUtils" @@ -108,7 +108,7 @@ const CreateFolderModal: React.FC = ({ initialValues={{ name: "" }} - validationSchema={folderNameValidator} + validationSchema={nameValidator} validateOnChange={false} onSubmit={async (values, helpers) => { if (!bucket) return diff --git a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemGridItem.tsx b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemGridItem.tsx index 9fc1ea310b..e0ebadaed7 100644 --- a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemGridItem.tsx +++ b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemGridItem.tsx @@ -12,7 +12,7 @@ import { CSSTheme } from "../../../Themes/types" import { FileSystemItem } from "../../../Contexts/StorageContext" import { ConnectDragPreview } from "react-dnd" import { Form, FormikProvider, useFormik } from "formik" -import { renameSchema } from "../../../Utils/validationSchema" +import { nameValidator } from "../../../Utils/validationSchema" import { ISelectedFile } from "../../../Contexts/FileBrowserContext" const useStyles = makeStyles(({ breakpoints, constants, palette }: CSSTheme) => { @@ -161,7 +161,7 @@ const FileSystemGridItem = React.forwardRef( initialValues: { fileName: name }, - validationSchema: renameSchema, + validationSchema: nameValidator, onSubmit: (values) => { const newName = values.fileName?.trim() diff --git a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemItem.tsx b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemItem.tsx index 9f2b042b8f..9c89001409 100644 --- a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemItem.tsx +++ b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemItem.tsx @@ -30,7 +30,7 @@ import { FileSystemItem as FileSystemItemType } from "../../../Contexts/StorageC import { ISelectedFile, useFileBrowser } from "../../../Contexts/FileBrowserContext" import { BrowserView, FileOperation } from "../../../Contexts/types" import { DragTypes } from "../FilesList/DragConstants" -import { renameSchema } from "../../../Utils/validationSchema" +import { nameValidator } from "../../../Utils/validationSchema" import { getPathWithFile } from "../../../Utils/pathUtils" const useStyles = makeStyles(({ breakpoints, constants }: CSSTheme) => { @@ -437,7 +437,7 @@ const FileSystemItem = ({ initialValues={{ fileName: name }} - validationSchema={renameSchema} + validationSchema={nameValidator} onSubmit={(values) => { const newName = values.fileName?.trim() diff --git a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx index a7ce472ba8..3dbb46378d 100644 --- a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx +++ b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx @@ -18,7 +18,7 @@ import { ConnectDragPreview } from "react-dnd" import { Form, FormikProvider, useFormik } from "formik" import { CSSTheme } from "../../../Themes/types" import { FileSystemItem } from "../../../Contexts/StorageContext" -import { renameSchema } from "../../../Utils/validationSchema" +import { nameValidator } from "../../../Utils/validationSchema" import { ISelectedFile, useFileBrowser } from "../../../Contexts/FileBrowserContext" const useStyles = makeStyles(({ breakpoints, constants, palette }: CSSTheme) => { @@ -147,7 +147,7 @@ const FileSystemTableItem = React.forwardRef( initialValues: { fileName: name }, - validationSchema: renameSchema, + validationSchema: nameValidator, onSubmit: (values) => { const newName = values.fileName?.trim() diff --git a/packages/storage-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx b/packages/storage-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx index c29439c881..f2aad86950 100644 --- a/packages/storage-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx +++ b/packages/storage-ui/src/Components/Modules/LoginModule/PasswordlessEmail.tsx @@ -110,12 +110,14 @@ const PasswordlessEmail = ({ resetLogin }: IPasswordlessEmail) => { }) , []) - const onSubmitEmail = useCallback((values) => { + const onSubmitEmail = useCallback((values: {email: string}) => { + const trimmedEmail = values.email.trim() + setIsSubmitEmailLoading(true) setError(undefined) - storageApiClient.getIdentityEmailToken({ email: values.email }) + storageApiClient.getIdentityEmailToken({ email: trimmedEmail }) .then(() => { - setEmail(values.email) + setEmail(trimmedEmail) setPage("confirmVerificationCode") }).catch ((e) => { setError(t`Something went wrong! Please try again.`) diff --git a/packages/storage-ui/src/Utils/validationSchema.ts b/packages/storage-ui/src/Utils/validationSchema.ts index 47359d3ec2..f7cbdf271c 100644 --- a/packages/storage-ui/src/Utils/validationSchema.ts +++ b/packages/storage-ui/src/Utils/validationSchema.ts @@ -2,57 +2,30 @@ import { t } from "@lingui/macro" import { object, string } from "yup" import { cid as isCid } from "is-ipfs" -const whitespaceOnlyRegex = new RegExp("^\\s+$") - -export const renameSchema = object().shape({ - fileName: string() - .min(1, t`Please enter a name`) - .max(65, t`Name too long`) - .test( - "Invalid character in name", - t`Name cannot contain '/' character`, - (val: string | null | undefined) => !val?.includes("/") - ) - .test( - "Only whitespace", - t`Name cannot only contain whitespace characters`, - (val) => !!val && !whitespaceOnlyRegex.test(val) - ) - .required(t`A name is required`) -}) - -export const folderNameValidator = object().shape({ +export const nameValidator = object().shape({ name: string() + .trim() .min(1, t`Please enter a name`) .max(65, t`Name too long`) - .required("Folder name is required") + .required("A name is required") .test( "Invalid name", - "Folder name cannot contain '/' character", + "The name cannot contain '/' character", (val: string | null | undefined) => !val?.includes("/") ) - .test( - "Only whitespace", - t`Folder name cannot only contain whitepsace characters`, - (val) => !!val && !whitespaceOnlyRegex.test(val) - ) }) export const bucketNameValidator = (bucketNames: Array) => object().shape({ name: string() + .trim() .min(1, t`Please enter a name`) .max(65, t`Name too long`) .required(t`Bucket name is required`) .test( "Invalid name", - t`Bucket name cannot contain '/' character`, + t`The name cannot contain '/' character`, (val: string | null | undefined) => !val?.includes("/") ) - .test( - "Only whitespace", - t`Bucket name cannot only contain whitepsace characters`, - (val) => !!val && !whitespaceOnlyRegex.test(val) - ) .test( "Unique name", t`A bucket with this name already exists`, @@ -62,6 +35,7 @@ export const bucketNameValidator = (bucketNames: Array) => o export const cidValidator = object().shape({ cid: string() + .trim() .required(t`CID is required`) .test( "Valid CID", diff --git a/packages/storage-ui/src/locales/en/messages.po b/packages/storage-ui/src/locales/en/messages.po index 38b8b0b339..86f7e31ed7 100644 --- a/packages/storage-ui/src/locales/en/messages.po +++ b/packages/storage-ui/src/locales/en/messages.po @@ -19,9 +19,6 @@ msgstr "A bucket with this name already exists" msgid "A file with the same name already exists" msgstr "A file with the same name already exists" -msgid "A name is required" -msgstr "A name is required" - msgid "API Keys" msgstr "API Keys" @@ -43,12 +40,6 @@ msgstr "Are we on the right track? Let us know in less than 1 minute." msgid "Bucket name" msgstr "Bucket name" -msgid "Bucket name cannot contain '/' character" -msgstr "Bucket name cannot contain '/' character" - -msgid "Bucket name cannot only contain whitepsace characters" -msgstr "Bucket name cannot only contain whitepsace characters" - msgid "Bucket name is required" msgstr "Bucket name is required" @@ -196,9 +187,6 @@ msgstr "Folder" msgid "Folder Name" msgstr "Folder Name" -msgid "Folder name cannot only contain whitepsace characters" -msgstr "Folder name cannot only contain whitepsace characters" - msgid "Folder name is already in use" msgstr "Folder name is already in use" @@ -241,12 +229,6 @@ msgstr "Move to..." msgid "Name" msgstr "Name" -msgid "Name cannot contain '/' character" -msgstr "Name cannot contain '/' character" - -msgid "Name cannot only contain whitespace characters" -msgstr "Name cannot only contain whitespace characters" - msgid "Name too long" msgstr "Name too long" @@ -364,6 +346,9 @@ msgstr "The authentication popup was closed" msgid "The files are already in this folder" msgstr "The files are already in this folder" +msgid "The name cannot contain '/' character" +msgstr "The name cannot contain '/' character" + msgid "The system is undergoing maintenance, thank you for being patient." msgstr "The system is undergoing maintenance, thank you for being patient." From bbb706537aa1d65ff7da00517db728d8e63521a8 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Wed, 4 Aug 2021 18:15:20 +0200 Subject: [PATCH 12/31] fix reload (#1406) --- .../FileBrowsers/ShareToSharedFolderModal.tsx | 166 ++++++++---------- 1 file changed, 76 insertions(+), 90 deletions(-) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx index bca7cb8ed1..5055e7b17f 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx @@ -387,94 +387,6 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) =>
), [classes.loadingContainer, isDownloading, isUploading]) - const Step1CreateSharedFolder = useCallback(() => ( - <> -
- - {nameError && ( - - {nameError} - - )} -
-
- onNewUsers(values, "read")} - label={t`Give view-only permission to:`} - labelClassName={classes.inputLabel} - value={sharedFolderReaders} - fetchTags={(inputVal) => handleLookupUser(inputVal, "read")} - placeholder={t`Add by sharing address, username or wallet address`} - styles={{ - control: (provided) => ({ - ...provided, - minHeight: 90, - alignContent: "start" - }) - }}/> -
-
- onNewUsers(values, "write")} - label={t`Give edit permission to:`} - labelClassName={classes.inputLabel} - value={sharedFolderWriters} - fetchTags={(inputVal) => handleLookupUser(inputVal, "write")} - placeholder={t`Add by sharing address, username or wallet address`} - styles={{ - control: (provided) => ({ - ...provided, - minHeight: 90, - alignContent: "start" - }) - }}/> -
- {!!usersError && ( - - {usersError} - - )} - - ), [ - classes, - handleLookupUser, - nameError, - onNameChange, - onNewUsers, - sharedFolderName, - sharedFolderReaders, - sharedFolderWriters, - usersError - ]) - - const Step1ExistingSharedFolder = useCallback(() => ( -
- setDestinationBucket(buckets.find((bu) => bu.id === val))} - /> -
- ), [buckets, bucketsOptions, classes.inputLabel, classes.inputWrapper, classes.modalFlexItem, destinationBucket]) - return (
{currentStep === "1_SHARED_FOLDER_SELECTION_CREATION" && ( isUsingCurrentBucket - ? - : + ? ( +
+ setDestinationBucket(buckets.find((bu) => bu.id === val))} + /> +
+ ) + : ( + <> +
+ + {nameError && ( + + {nameError} + + )} +
+
+ onNewUsers(values, "read")} + label={t`Give view-only permission to:`} + labelClassName={classes.inputLabel} + value={sharedFolderReaders} + fetchTags={(inputVal) => handleLookupUser(inputVal, "read")} + placeholder={t`Add by sharing address, username or wallet address`} + styles={{ + control: (provided) => ({ + ...provided, + minHeight: 90, + alignContent: "start" + }) + }}/> +
+
+ onNewUsers(values, "write")} + label={t`Give edit permission to:`} + labelClassName={classes.inputLabel} + value={sharedFolderWriters} + fetchTags={(inputVal) => handleLookupUser(inputVal, "write")} + placeholder={t`Add by sharing address, username or wallet address`} + styles={{ + control: (provided) => ({ + ...provided, + minHeight: 90, + alignContent: "start" + }) + }}/> +
+ {!!usersError && ( + + {usersError} + + )} + + ) )}
{currentStep === "1_SHARED_FOLDER_SELECTION_CREATION" && ( From d4207da85ceecbd735d83bd2f3739c1a1e1bc4ed Mon Sep 17 00:00:00 2001 From: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Date: Wed, 4 Aug 2021 19:16:56 +0300 Subject: [PATCH 13/31] [FILES] Ensure content type is retained when sharing (#1407) * fix lost content type * fix lint Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> --- .../Modules/FileBrowsers/ShareToSharedFolderModal.tsx | 7 ++++++- packages/files-ui/src/Utils/contentTypeGuesser.ts | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx index 5055e7b17f..0e34e357ea 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareToSharedFolderModal.tsx @@ -325,7 +325,12 @@ const CopyToSharedFolderModal = ({ close, file, filePath }: IShareFileProps) => setIsUploading(true) - uploadFiles(bucketToUpload.id, [new File([fileContent], file.name)], UPLOAD_PATH, bucketToUpload.encryptionKey) + uploadFiles( + bucketToUpload.id, + [new File([fileContent], file.name, { type: file.content_type })], + UPLOAD_PATH, + bucketToUpload.encryptionKey + ) .then(() => { if (!keepOriginalFile) { deleteItems && deleteItems([file.cid], true) diff --git a/packages/files-ui/src/Utils/contentTypeGuesser.ts b/packages/files-ui/src/Utils/contentTypeGuesser.ts index d65fb94191..6f7af8db43 100644 --- a/packages/files-ui/src/Utils/contentTypeGuesser.ts +++ b/packages/files-ui/src/Utils/contentTypeGuesser.ts @@ -5,6 +5,7 @@ const guessContentType = (fileName: string) => { case "pdf": return "application/pdf" case "jpg": + case "jpeg": case "png": case "gif": case "bmp": From d60b8b27dc09db9cec1af78780ea0ce3e8fd801f Mon Sep 17 00:00:00 2001 From: Andrew Snaith Date: Wed, 4 Aug 2021 09:39:02 -0700 Subject: [PATCH 14/31] Add new ui tests for folder creation and deletion (#1383) * Add new identifiers and element declarations for create folder modal * Add new tests for creating and deleting folders * Add temp workarounds for local session clearing issue * Add custom click command to help with detached from dom issues * Comment amendment * Minor amendments Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> --- .../cypress/fixtures/filesTestData.ts | 1 + packages/files-ui/cypress/support/commands.ts | 41 +++++++++++++++- .../cypress/support/page-objects/homePage.ts | 29 ++++++----- .../cypress/tests/file-management-spec.ts | 48 +++++++++++++++++-- .../FileBrowsers/CreateFolderModal.tsx | 8 +++- .../Modules/FileBrowsers/views/FilesList.tsx | 3 +- .../storage-ui/cypress/support/commands.ts | 2 +- 7 files changed, 111 insertions(+), 21 deletions(-) create mode 100644 packages/files-ui/cypress/fixtures/filesTestData.ts diff --git a/packages/files-ui/cypress/fixtures/filesTestData.ts b/packages/files-ui/cypress/fixtures/filesTestData.ts new file mode 100644 index 0000000000..792eecd885 --- /dev/null +++ b/packages/files-ui/cypress/fixtures/filesTestData.ts @@ -0,0 +1 @@ +export const folderName = "Testing" \ No newline at end of file diff --git a/packages/files-ui/cypress/support/commands.ts b/packages/files-ui/cypress/support/commands.ts index ba719f728f..74fd24c95a 100644 --- a/packages/files-ui/cypress/support/commands.ts +++ b/packages/files-ui/cypress/support/commands.ts @@ -32,6 +32,7 @@ import { homePage } from "./page-objects/homePage" import { testPrivateKey, testAccountPassword, localHost } from "../fixtures/loginData" import { CustomizedBridge } from "./utils/CustomBridge" import "cypress-file-upload" +import "cypress-pipe" export type Storage = Record[]; @@ -146,7 +147,7 @@ Cypress.Commands.add( authenticationPage.web3Button().click() authenticationPage.showMoreButton().click() authenticationPage.detectedWallet().click() - authenticationPage.web3SignInButton().click() + authenticationPage.web3SignInButton().safeClick() authenticationPage.loginPasswordButton().click() authenticationPage.loginPasswordInput().type(`${testAccountPassword}{enter}`) @@ -172,12 +173,33 @@ Cypress.Commands.add( } if(clearTrashBucket || clearCSFBucket){ - cy.reload() + cy.reload({ timeout: 50000 }).then(() => { + if (local.length === 0) { + // Temp work around for local storage being cleared after the reload. See issue in #1381 + cy.log("nothing in local storage after reload, --> click on web3 button") + authenticationPage.web3Button().click() + authenticationPage.showMoreButton().click() + authenticationPage.detectedWallet().click() + authenticationPage.web3SignInButton().safeClick() + authenticationPage.loginPasswordButton().click() + authenticationPage.loginPasswordInput().type(`${testAccountPassword}{enter}`) + authenticationPage.doNotSaveBrowserButton().click() + } + }) homePage.appHeaderLabel().should("be.visible") } } ) +Cypress.Commands.add("safeClick", { prevSubject: "element" }, $element => { + const click = ($el: JQuery) => $el.trigger("click") + return cy + .wrap($element) + .should("be.visible") + .pipe(click) + .should($el => expect($el).to.not.be.visible) +}) + // Must be declared global to be detected by typescript (allows import/export) // eslint-disable @typescript/interface-name declare global { @@ -207,6 +229,21 @@ declare global { * @example cy.saveLocalAndSession() */ saveLocalAndSession: () => Chainable + + /** + * Use this when encountering race condition issues resulting in + * cypress "detached from DOM" issues or clicking before an event + * listener has been registered + * + * Temporary solution until cypress improve this issue + * further info + * https://www.cypress.io/blog/2019/01/22/when-can-the-test-click/ + * https://github.com/testing-library/cypress-testing-library/issues/153#issuecomment-692386444 + * https://github.com/cypress-io/cypress/issues/7306 + * + */ + safeClick: () => Chainable + } } } diff --git a/packages/files-ui/cypress/support/page-objects/homePage.ts b/packages/files-ui/cypress/support/page-objects/homePage.ts index 6d5138f6f1..eb18cee55f 100644 --- a/packages/files-ui/cypress/support/page-objects/homePage.ts +++ b/packages/files-ui/cypress/support/page-objects/homePage.ts @@ -1,4 +1,5 @@ import { basePage } from "./basePage" +import { folderName } from "../../fixtures/filesTestData" export const click = ($el: JQuery) => $el.trigger("click") @@ -6,7 +7,8 @@ export const homePage = { ...basePage, // main file browser elements - uploadButton: () => cy.get("[data-cy=upload-modal-button]"), + newFolderButton: () => cy.get("[data-cy=button-new-folder]"), + uploadButton: () => cy.get("[data-cy=button-upload-file]"), uploadFileForm: () => cy.get("[data-cy=upload-file-form] input", { timeout: 20000 }), moveSelectedButton: () => cy.get("[data-testId=button-move-selected-file]"), deleteSelectedButton: () => cy.get("[data-testId=button-delete-selected-file]"), @@ -23,6 +25,12 @@ export const homePage = { fileRenameErrorLabel: () => cy.get("[data-cy=rename-form] span.minimal.error"), fileItemKebabButton: () => cy.get("[data-testid=dropdown-title-fileDropdown]"), + // create folder modal elements + createFolderModal: () => cy.get("[data-cy=modal-create-folder]", { timeout: 10000 }), + folderNameInput: () => cy.get("[data-cy=input-folder-name]"), + cancelButton: () => cy.get("[data-cy=button-cancel-create-folder]"), + createButton: () => cy.get("[data-cy=button-create-folder]"), + // upload modal elements startUploadButton: () => cy.get("[data-testId=button-start-upload]"), uploadCancelButton: () => cy.get("[data-testId=button-cancel-upload]"), @@ -38,26 +46,25 @@ export const homePage = { moveMenuOption: () => cy.get("[data-cy=menu-move]"), deleteMenuOption: () => cy.get("[data-cy=menu-delete]"), - clickUploadButton: () => homePage.startUploadButton() - .should("not.be.disabled") - // this pipe is needed to prevent https://github.com/ChainSafe/ui-monorepo/issues/1146 - // as described https://www.cypress.io/blog/2019/01/22/when-can-the-test-click/ - .pipe(click) - .should(($el: JQuery) => { - expect($el).to.not.be.visible - }), - // helpers and convenience functions uploadFile(filePath: string) { this.uploadButton().click() this.uploadFileForm().attachFile(filePath) this.fileUploadList().should("have.length", 1) this.fileListRemoveButton().should("be.visible") - this.clickUploadButton() + this.startUploadButton().safeClick() // ensure upload is complete before proceeding this.uploadFileForm().should("not.exist") this.uploadStatusToast().should("not.exist") + }, + + createFolder(name: string = folderName) { + this.newFolderButton().click() + this.folderNameInput().type(name) + this.createButton().safeClick() + this.createFolderModal().should("not.exist") + this.fileItemName().contains(name) } } diff --git a/packages/files-ui/cypress/tests/file-management-spec.ts b/packages/files-ui/cypress/tests/file-management-spec.ts index c08e2fb7e3..b55b2f6cdc 100644 --- a/packages/files-ui/cypress/tests/file-management-spec.ts +++ b/packages/files-ui/cypress/tests/file-management-spec.ts @@ -1,13 +1,30 @@ import { binPage } from "../support/page-objects/binPage" import { homePage } from "../support/page-objects/homePage" import { navigationMenu } from "../support/page-objects/navigationMenu" +import { folderName } from "../fixtures/filesTestData" import "cypress-pipe" describe("File management", () => { context("desktop", () => { - it("can add files and cancel", () => { + it("can create folders and cancel modal", () => { + cy.web3Login({ clearCSFBucket: true }) + + // create a folder and see it in the file list + homePage.newFolderButton().click() + homePage.folderNameInput().type(folderName) + homePage.createButton().safeClick() + homePage.createFolderModal().should("not.exist") + homePage.fileItemName().contains(folderName) + + // cancel and ensure that the create folder modal is dismissed + homePage.newFolderButton().click() + homePage.cancelButton().click() + homePage.createFolderModal().should("not.exist") + }) + + it("can add files and cancel modal", () => { cy.web3Login() // upload a file and see it in the file list @@ -39,7 +56,7 @@ describe("File management", () => { homePage.uploadFileForm().attachFile("../fixtures/uploadedFiles/text-file.txt") homePage.fileUploadList().should("have.length", 2) homePage.fileListRemoveButton().should("have.length", 2) - homePage.clickUploadButton() + homePage.startUploadButton().safeClick() homePage.uploadFileForm().should("not.exist") homePage.fileItemRow().should("have.length", 2) }) @@ -103,12 +120,33 @@ describe("File management", () => { homePage.fileItemRow().should("have.length", 1) // retrieve the deleted file's name, store as a cypress alias - binPage.fileItemName().invoke("text").as("deletedFile") + binPage.fileItemName().invoke("text").as("binFile") // ensure file in bin matches the name of the deleted file cy.get("@originalFile").then(($originalFile) => { - cy.get("@deletedFile").should("equals", $originalFile) + cy.get("@binFile").should("equals", $originalFile) }) }) + + it("can delete a folder", () => { + cy.web3Login({ clearCSFBucket: true, clearTrashBucket: true }) + + // create a folder + homePage.createFolder(folderName) + homePage.fileItemRow().should("have.length", 1) + + // delete the folder via the menu option + homePage.fileItemKebabButton().first().click() + homePage.deleteMenuOption().click() + homePage.deleteFileDialog().should("be.visible") + homePage.deleteFileConfirmButton().click() + homePage.deleteFileDialog().should("not.exist") + homePage.fileItemRow().should("not.exist") + + // confirm the deleted folder is moved to the bin + navigationMenu.binNavButton().click() + binPage.fileItemRow().should("have.length", 1) + binPage.fileItemName().should("have.text", folderName) + }) }) -}) +}) \ No newline at end of file diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx index 27195e4d30..64604d4404 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx @@ -132,7 +132,10 @@ const CreateFolderModal: React.FC = ({ }} >
-
+
{!desktop && ( = ({ className={classes.input} > = ({ justifyContent="flex-end" > close()} size="medium" className={classes.cancelButton} @@ -178,6 +183,7 @@ const CreateFolderModal: React.FC = ({ Cancel From 37fb6715d0ac2ff475f1147ae72f06790495cc1e Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Thu, 5 Aug 2021 15:05:37 +0200 Subject: [PATCH 16/31] bump cypress (#1417) --- packages/files-ui/package.json | 2 +- packages/gaming-ui/package.json | 2 +- packages/storage-ui/package.json | 2 +- yarn.lock | 55 +++----------------------------- 4 files changed, 7 insertions(+), 54 deletions(-) diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index 3279958a81..1404d69eb5 100644 --- a/packages/files-ui/package.json +++ b/packages/files-ui/package.json @@ -65,7 +65,7 @@ "@types/yup": "^0.29.9", "@types/zxcvbn": "^4.4.0", "babel-plugin-macros": "^2.8.0", - "cypress": "^8.1.0", + "cypress": "^8.2.0", "cypress-file-upload": "^5.0.8", "cypress-pipe": "^2.0.0" }, diff --git a/packages/gaming-ui/package.json b/packages/gaming-ui/package.json index 5a7c530936..ee76c7c359 100644 --- a/packages/gaming-ui/package.json +++ b/packages/gaming-ui/package.json @@ -63,7 +63,7 @@ "@types/yup": "^0.29.9", "@types/zxcvbn": "^4.4.0", "babel-plugin-macros": "^2.8.0", - "cypress": "^7.6.0", + "cypress": "^8.2.0", "cypress-file-upload": "^5.0.7" }, "scripts": { diff --git a/packages/storage-ui/package.json b/packages/storage-ui/package.json index 6e9593b947..3c4b29984b 100644 --- a/packages/storage-ui/package.json +++ b/packages/storage-ui/package.json @@ -64,7 +64,7 @@ "@types/yup": "^0.29.9", "@types/zxcvbn": "^4.4.0", "babel-plugin-macros": "^2.8.0", - "cypress": "^8.1.0", + "cypress": "^8.2.0", "cypress-file-upload": "^5.0.8" }, "scripts": { diff --git a/yarn.lock b/yarn.lock index 3716259ee0..90c34b32e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10123,57 +10123,10 @@ cypress-pipe@^2.0.0: resolved "https://registry.yarnpkg.com/cypress-pipe/-/cypress-pipe-2.0.0.tgz#577df7a70a8603d89a96dfe4092a605962181af8" integrity sha512-KW9s+bz4tFLucH3rBGfjW+Q12n7S4QpUSSyxiGrgPOfoHlbYWzAGB3H26MO0VTojqf9NVvfd5Kt0MH5XMgbfyg== -cypress@^7.6.0: - version "7.6.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-7.6.0.tgz#80fe7496cd4165a0fa06e25fc11413dda4544463" - integrity sha512-tTwQExY28CKt6cY85/2V1uLExcMfpBEBWXt/EcE2ht/Onl9k4lxUS7ul1UnUO5MrYwMIHMdGVh13DxdzXj4Z5w== - dependencies: - "@cypress/request" "^2.88.5" - "@cypress/xvfb" "^1.2.4" - "@types/node" "^14.14.31" - "@types/sinonjs__fake-timers" "^6.0.2" - "@types/sizzle" "^2.3.2" - arch "^2.2.0" - blob-util "^2.0.2" - bluebird "^3.7.2" - cachedir "^2.3.0" - chalk "^4.1.0" - check-more-types "^2.24.0" - cli-cursor "^3.1.0" - cli-table3 "~0.6.0" - commander "^5.1.0" - common-tags "^1.8.0" - dayjs "^1.10.4" - debug "^4.3.2" - enquirer "^2.3.6" - eventemitter2 "^6.4.3" - execa "4.1.0" - executable "^4.1.1" - extract-zip "2.0.1" - figures "^3.2.0" - fs-extra "^9.1.0" - getos "^3.2.1" - is-ci "^3.0.0" - is-installed-globally "~0.4.0" - lazy-ass "^1.6.0" - listr2 "^3.8.3" - lodash "^4.17.21" - log-symbols "^4.0.0" - minimist "^1.2.5" - ospath "^1.2.2" - pretty-bytes "^5.6.0" - ramda "~0.27.1" - request-progress "^3.0.0" - supports-color "^8.1.1" - tmp "~0.2.1" - untildify "^4.0.0" - url "^0.11.0" - yauzl "^2.10.0" - -cypress@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-8.1.0.tgz#9aaed7fb2a4d1876528b72d437f97bc824db0735" - integrity sha512-GXjlqPjY/6HPbQwAp3AvlA1Mk/NoJTAmqVSUhQsuM/1xDpd/FQHkxVuq5h6O6RrAoCXSgpZPXFsVtdqE+FwEJw== +cypress@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-8.2.0.tgz#1e4e9f6218324e82a95c1b9cad7f3965ba663d7f" + integrity sha512-jg7S5VxxslwsgEyAkCE9ZCkFADxOUY1bSWScp1cWnga88K0TZgFQ0zdxyG9Mw/4spLGuvkriIZ62am+TR6C04w== dependencies: "@cypress/request" "^2.88.5" "@cypress/xvfb" "^1.2.4" From 776111c31054c36da2a8972a7507690014e9c80c Mon Sep 17 00:00:00 2001 From: Andrew Snaith Date: Thu, 5 Aug 2021 07:35:15 -0700 Subject: [PATCH 17/31] Update the docker container used for tests to the latest version (#1413) * Update the docker container to the latest * Minor change to force tests to try and execute * Add env variable to disable HTTPS certificate checks * Revert "Add env variable to disable HTTPS certificate checks" This reverts commit 3a676343d69e8b9ebf64f66c12523a186f02b1bb. --- .github/workflows/test-files.yml | 2 +- packages/files-ui/cypress/tests/file-management-spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-files.yml b/.github/workflows/test-files.yml index 5e8e6d8fa7..75c2e7a3dd 100644 --- a/.github/workflows/test-files.yml +++ b/.github/workflows/test-files.yml @@ -11,7 +11,7 @@ on: jobs: cypress-run: runs-on: ubuntu-latest - container: cypress/browsers:node14.16.0-chrome90-ff88 + container: cypress/browsers:node14.17.0-chrome91-ff89 steps: - name: Checkout uses: actions/checkout@v2 diff --git a/packages/files-ui/cypress/tests/file-management-spec.ts b/packages/files-ui/cypress/tests/file-management-spec.ts index 390c51de0e..4a711c618f 100644 --- a/packages/files-ui/cypress/tests/file-management-spec.ts +++ b/packages/files-ui/cypress/tests/file-management-spec.ts @@ -182,4 +182,4 @@ describe("File management", () => { homePage.fileItemName().should("have.text", folderName) }) }) -}) \ No newline at end of file +}) From aa0b1a410da89c58e427b53e1e311f7bb5c26eac Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Thu, 5 Aug 2021 18:45:21 +0200 Subject: [PATCH 18/31] Folder creation validation and test (#1416) --- .../cypress/support/page-objects/homePage.ts | 1 + .../cypress/tests/file-management-spec.ts | 30 ++++++++ .../FileBrowsers/CreateFolderModal.tsx | 73 +++++++++---------- 3 files changed, 65 insertions(+), 39 deletions(-) diff --git a/packages/files-ui/cypress/support/page-objects/homePage.ts b/packages/files-ui/cypress/support/page-objects/homePage.ts index eb18cee55f..cda080fba6 100644 --- a/packages/files-ui/cypress/support/page-objects/homePage.ts +++ b/packages/files-ui/cypress/support/page-objects/homePage.ts @@ -30,6 +30,7 @@ export const homePage = { folderNameInput: () => cy.get("[data-cy=input-folder-name]"), cancelButton: () => cy.get("[data-cy=button-cancel-create-folder]"), createButton: () => cy.get("[data-cy=button-create-folder]"), + folderCreationErrorLabel: () => cy.get("[data-cy=folder-creation-form] span.default.error"), // upload modal elements startUploadButton: () => cy.get("[data-testId=button-start-upload]"), diff --git a/packages/files-ui/cypress/tests/file-management-spec.ts b/packages/files-ui/cypress/tests/file-management-spec.ts index 4a711c618f..7f2583bd00 100644 --- a/packages/files-ui/cypress/tests/file-management-spec.ts +++ b/packages/files-ui/cypress/tests/file-management-spec.ts @@ -181,5 +181,35 @@ describe("File management", () => { binPage.fileItemRow().should("have.length", 1) homePage.fileItemName().should("have.text", folderName) }) + + it("cannot create a folder with an invalid name", () => { + cy.web3Login({ clearCSFBucket: true, clearTrashBucket: true }) + homePage.newFolderButton().click() + + // ensure a folder can't be created without entering a name + homePage.createButton().should("have.attr", "disabled") + homePage.folderNameInput().type("a{selectall}{del}") + homePage.folderCreationErrorLabel().should("be.visible") + + // ensure a folder can't be created with "/" in the name + homePage.folderNameInput().type("/") + homePage.createButton().should("have.attr", "disabled") + homePage.folderCreationErrorLabel().should("be.visible") + homePage.createFolderModal().should("contain.text", "A name cannot contain '/' character") + + // ensure a folder can't be created with white space only in the name + homePage.folderNameInput().type("{selectall}{del}") + homePage.folderNameInput().type(" ") + homePage.createButton().should("have.attr", "disabled") + homePage.folderCreationErrorLabel().should("be.visible") + homePage.createFolderModal().should("contain.text", "Please enter a name") + + // ensure a folder can't be created if name exceeds 65 characters + homePage.folderNameInput().type("{selectall}{del}") + homePage.folderNameInput().type("cgsxffymqivoknhwhqvmnchvjngtwsriovhvkgzgmonmimctcrdytujbtkogngvext") + homePage.createButton().should("have.attr", "disabled") + homePage.folderCreationErrorLabel().should("be.visible") + homePage.createFolderModal().should("contain.text", "Name too long") + }) }) }) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx index 64604d4404..cad44f1d75 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateFolderModal.tsx @@ -9,8 +9,8 @@ import { makeStyles, useMediaQuery } from "@chainsafe/common-theme" -import React, { useRef, useEffect, useState } from "react" -import { Formik, Form } from "formik" +import React, { useState } from "react" +import { Form, FormikProvider, useFormik } from "formik" import CustomModal from "../../Elements/CustomModal" import CustomButton from "../../Elements/CustomButton" import { t, Trans } from "@lingui/macro" @@ -86,13 +86,33 @@ const CreateFolderModal: React.FC = ({ const { currentPath, refreshContents, bucket } = useFileBrowser() const [creatingFolder, setCreatingFolder] = useState(false) const desktop = useMediaQuery("md") - const inputRef = useRef(null) - - useEffect(() => { - if (modalOpen) { - setTimeout(() => inputRef.current?.focus(), 100) - } - }, [modalOpen]) + const formik = useFormik({ + initialValues: { + name: "" + }, + validationSchema: nameValidator, + onSubmit: async (values, helpers) => { + if (!bucket) return + helpers.setSubmitting(true) + try { + setCreatingFolder(true) + await filesApiClient.addBucketDirectory(bucket.id, { path: getPathWithFile(currentPath, values.name.trim()) }) + refreshContents && await refreshContents() + setCreatingFolder(false) + helpers.resetForm() + close() + } catch (errors) { + setCreatingFolder(false) + if (errors[0].message.includes("Entry with such name can")) { + helpers.setFieldError("name", t`Folder name is already in use`) + } else { + helpers.setFieldError("name", errors[0].message) + } + helpers.setSubmitting(false) + } + }, + enableReinitialize: true + }) return ( = ({ closePosition="none" maxWidth="sm" > - { - if (!bucket) return - helpers.setSubmitting(true) - try { - setCreatingFolder(true) - await filesApiClient.addBucketDirectory(bucket.id, { path: getPathWithFile(currentPath, values.name.trim()) }) - refreshContents && await refreshContents() - setCreatingFolder(false) - helpers.resetForm() - close() - } catch (errors) { - setCreatingFolder(false) - if (errors[0].message.includes("Entry with such name can")) { - helpers.setFieldError("name", t`Folder name is already in use`) - } else { - helpers.setFieldError("name", errors[0].message) - } - } - helpers.setSubmitting(false) - }} - > - + +
= ({ placeholder="Name" labelClassName={classes.label} label="Folder Name" - ref={inputRef} + autoFocus /> = ({ type="submit" className={classes.okButton} loading={creatingFolder} + disabled={!formik.dirty || !formik.isValid} > {desktop ? OK : Create}
-
+
) } From ea53022bd6986db595c0d9ce1c45293f8f430a04 Mon Sep 17 00:00:00 2001 From: ryry79261 Date: Fri, 6 Aug 2021 11:57:30 +0200 Subject: [PATCH 19/31] Added download in --- .../src/Components/Pages/BucketPage.tsx | 16 +-- .../src/Contexts/StorageContext.tsx | 98 ++++++++++++++++++- 2 files changed, 105 insertions(+), 9 deletions(-) diff --git a/packages/storage-ui/src/Components/Pages/BucketPage.tsx b/packages/storage-ui/src/Components/Pages/BucketPage.tsx index 246f451141..d579cc9010 100644 --- a/packages/storage-ui/src/Components/Pages/BucketPage.tsx +++ b/packages/storage-ui/src/Components/Pages/BucketPage.tsx @@ -21,7 +21,7 @@ import { useLocalStorage } from "@chainsafe/browser-storage-hooks" import { DISMISSED_SURVEY_KEY } from "../Modules/SurveyBanner" const BucketPage: React.FC = () => { - const { storageBuckets, uploadFiles, uploadsInProgress, getStorageSummary } = useStorage() + const { storageBuckets, uploadFiles, uploadsInProgress, getStorageSummary, downloadFile } = useStorage() const { storageApiClient } = useStorageApi() const { addToastMessage } = useToaster() const [loadingCurrentPath, setLoadingCurrentPath] = useState(false) @@ -137,15 +137,15 @@ const BucketPage: React.FC = () => { }, [addToastMessage, pathContents, refreshContents, storageApiClient, bucket, currentPath]) const handleDownload = useCallback(async ( - //cid: string + toDownload: ISelectedFile ) => { - throw new Error("Not implemented") - // const itemToDownload = pathContents.find(item => item.cid === cid) - // if (!itemToDownload || !bucket) return + // throw new Error("Not implemented") + const itemToDownload = pathContents.find(item => item.cid === toDownload.cid) + if (!itemToDownload || !bucket) return - // downloadFile(bucket.id, itemToDownload, currentPath) + downloadFile(bucket.id, itemToDownload, currentPath) }, [ - //pathContents, currentPath, bucket + pathContents, currentPath, bucket, downloadFile ]) // Breadcrumbs/paths @@ -198,7 +198,7 @@ const BucketPage: React.FC = () => { [CONTENT_TYPES.Image]: [], [CONTENT_TYPES.Pdf]: [], [CONTENT_TYPES.Text]: [], - [CONTENT_TYPES.File]: ["delete", "move"], + [CONTENT_TYPES.File]: ["delete", "move", "download"], [CONTENT_TYPES.Directory]: ["delete", "move"] }), []) diff --git a/packages/storage-ui/src/Contexts/StorageContext.tsx b/packages/storage-ui/src/Contexts/StorageContext.tsx index c8a1ca08b6..9dc6aaeef4 100644 --- a/packages/storage-ui/src/Contexts/StorageContext.tsx +++ b/packages/storage-ui/src/Contexts/StorageContext.tsx @@ -17,6 +17,8 @@ import { useStorageApi } from "./StorageApiContext" import { v4 as uuidv4 } from "uuid" import { t } from "@lingui/macro" import { readFileAsync } from "../Utils/Helpers" +import axios, { CancelToken } from "axios" +import { getPathWithFile } from "../Utils/pathUtils" type StorageContextProps = { children: React.ReactNode | React.ReactNode[] @@ -42,6 +44,14 @@ export type DownloadProgress = { complete: boolean } +interface GetFileContentParams { + cid: string + cancelToken?: CancelToken + onDownloadProgress?: (progressEvent: ProgressEvent) => void + file: FileSystemItem + path: string +} + type StorageContext = { pins: PinStatus[] uploadsInProgress: UploadProgress[] @@ -49,6 +59,7 @@ type StorageContext = { storageSummary: BucketSummaryResponse | undefined getStorageSummary: () => Promise uploadFiles: (bucketId: string, files: File[], path: string) => Promise + downloadFile: (bucketId: string, itemToDownload: FileSystemItem, path: string) => void addPin: (cid: string) => Promise refreshPins: () => void unpin: (requestId: string) => void @@ -132,7 +143,7 @@ const StorageProvider = ({ children }: StorageContextProps) => { [] ) - const [downloadsInProgress] = useReducer( + const [downloadsInProgress, dispatchDownloadsInProgress] = useReducer( downloadsInProgressReducer, [] ) @@ -257,6 +268,90 @@ const StorageProvider = ({ children }: StorageContextProps) => { } }, [storageBuckets, storageApiClient, getStorageSummary]) + const getFileContent = useCallback(async ( + bucketId: string, + { cid, cancelToken, onDownloadProgress, file, path }: GetFileContentParams + ) => { + + // when a file is accessed from the search page, a file and a path are passed in + // because the current path will not reflect the right state of the app + const fileToGet = file + + if (!fileToGet) { + console.error("No file passed, and no file found for cid:", cid, "in pathContents:", path) + throw new Error("No file found.") + } + + try { + const result = await storageApiClient.getBucketObjectContent( + bucketId, + { path: path }, + cancelToken, + onDownloadProgress + ) + + return result.data + + } catch (error) { + if (axios.isCancel(error)) { + return Promise.reject() + } else { + console.error(error) + return Promise.reject(error) + } + } + }, [storageApiClient]) + + const downloadFile = useCallback(async (bucketId: string, itemToDownload: FileSystemItem, path: string) => { + const toastId = uuidv4() + try { + const downloadProgress: DownloadProgress = { + id: toastId, + fileName: itemToDownload.name, + complete: false, + error: false, + progress: 0 + } + dispatchDownloadsInProgress({ type: "add", payload: downloadProgress }) + const result = await getFileContent(bucketId, { + cid: itemToDownload.cid, + file: itemToDownload, + path: getPathWithFile(path, itemToDownload.name), + onDownloadProgress: (progressEvent) => { + dispatchDownloadsInProgress({ + type: "progress", + payload: { + id: toastId, + progress: Math.ceil( + (progressEvent.loaded / itemToDownload.size) * 100 + ) + } + }) + } + }) + if (!result) return + const link = document.createElement("a") + link.href = URL.createObjectURL(result) + link.download = itemToDownload?.name || "file" + link.click() + dispatchDownloadsInProgress({ + type: "complete", + payload: { id: toastId } + }) + URL.revokeObjectURL(link.href) + setTimeout(() => { + dispatchDownloadsInProgress({ + type: "remove", + payload: { id: toastId } + }) + }, REMOVE_UPLOAD_PROGRESS_DELAY) + return Promise.resolve() + } catch (error) { + dispatchDownloadsInProgress({ type: "error", payload: { id: toastId } }) + return Promise.reject() + } + }, [getFileContent]) + return ( { refreshPins, unpin, storageBuckets, + downloadFile, createBucket, removeBucket, uploadFiles From 8dfea1f18a4367a54ae848c4f09391037c8ccc95 Mon Sep 17 00:00:00 2001 From: Ryan Noble Date: Fri, 6 Aug 2021 13:08:35 +0200 Subject: [PATCH 20/31] Update packages/storage-ui/src/Components/Pages/BucketPage.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> --- packages/storage-ui/src/Components/Pages/BucketPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/storage-ui/src/Components/Pages/BucketPage.tsx b/packages/storage-ui/src/Components/Pages/BucketPage.tsx index d579cc9010..3c611f0d17 100644 --- a/packages/storage-ui/src/Components/Pages/BucketPage.tsx +++ b/packages/storage-ui/src/Components/Pages/BucketPage.tsx @@ -139,7 +139,6 @@ const BucketPage: React.FC = () => { const handleDownload = useCallback(async ( toDownload: ISelectedFile ) => { - // throw new Error("Not implemented") const itemToDownload = pathContents.find(item => item.cid === toDownload.cid) if (!itemToDownload || !bucket) return From 22aaa7585bd457aab36a11bad4a3e720499f1a75 Mon Sep 17 00:00:00 2001 From: Ryan Noble Date: Fri, 6 Aug 2021 13:08:48 +0200 Subject: [PATCH 21/31] Update packages/storage-ui/src/Components/Pages/BucketPage.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> --- packages/storage-ui/src/Components/Pages/BucketPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-ui/src/Components/Pages/BucketPage.tsx b/packages/storage-ui/src/Components/Pages/BucketPage.tsx index 3c611f0d17..06b2a26f3b 100644 --- a/packages/storage-ui/src/Components/Pages/BucketPage.tsx +++ b/packages/storage-ui/src/Components/Pages/BucketPage.tsx @@ -197,7 +197,7 @@ const BucketPage: React.FC = () => { [CONTENT_TYPES.Image]: [], [CONTENT_TYPES.Pdf]: [], [CONTENT_TYPES.Text]: [], - [CONTENT_TYPES.File]: ["delete", "move", "download"], + [CONTENT_TYPES.File]: ["download", "move", "delete"], [CONTENT_TYPES.Directory]: ["delete", "move"] }), []) From 2c3c150b797796fd63c14877d6080825836b9797 Mon Sep 17 00:00:00 2001 From: Tanmoy Basak Anjan Date: Fri, 6 Aug 2021 17:09:29 +0600 Subject: [PATCH 22/31] Using default cursors (#1411) * moved to cursors * remove selectable * moved to props Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> --- .../Modules/FileBrowsers/SharedFoldersOverview.tsx | 6 ++++-- .../views/FileSystemItem/FileSystemGridItem.tsx | 3 +-- .../views/FileSystemItem/FileSystemTableItem.tsx | 1 - .../FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx | 1 - .../Modules/FileSystemItem/FileSystemGridItem.tsx | 3 +-- .../Modules/FileSystemItem/FileSystemTableItem.tsx | 1 - 6 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx index c5bd40fd88..feaccd411a 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx @@ -200,8 +200,10 @@ const SharedFolderOverview = () => { hover={true} > - + {desktop && {/* Icon */} diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemGridItem.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemGridItem.tsx index b305989fb7..18df535533 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemGridItem.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemGridItem.tsx @@ -107,8 +107,7 @@ const useStyles = makeStyles(({ breakpoints, constants, palette }: CSFTheme) => gridViewIconNameBox: { display: "flex", flexDirection: "column", - width: "100%", - cursor: "pointer" + width: "100%" }, menuTitleGrid: { padding: `0 ${constants.generalUnit * 0.5}px`, diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx index 54f34b528c..f0536f973a 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/FileSystemTableItem.tsx @@ -166,7 +166,6 @@ const FileSystemTableItem = React.forwardRef( droppable: isFolder && (isOverMove || isOverUpload) })} type="grid" - rowSelectable={true} ref={forwardedRef} selected={selected.includes(cid)} > diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx index d456bed699..fdcfda8c63 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FileSystemItem/SharedFolderRow.tsx @@ -31,7 +31,6 @@ const useStyles = makeStyles(({ breakpoints, constants, palette }: CSFTheme) => tableRow: { border: "2px solid transparent", [breakpoints.up("md")]: { - cursor: "pointer", gridTemplateColumns: desktopSharedGridSettings }, [breakpoints.down("md")]: { diff --git a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemGridItem.tsx b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemGridItem.tsx index e0ebadaed7..71beb08368 100644 --- a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemGridItem.tsx +++ b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemGridItem.tsx @@ -108,8 +108,7 @@ const useStyles = makeStyles(({ breakpoints, constants, palette }: CSSTheme) => gridViewIconNameBox: { display: "flex", flexDirection: "column", - width: "100%", - cursor: "pointer" + width: "100%" }, menuTitleGrid: { padding: `0 ${constants.generalUnit * 0.5}px`, diff --git a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx index 3dbb46378d..4a2de2329e 100644 --- a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx +++ b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx @@ -171,7 +171,6 @@ const FileSystemTableItem = React.forwardRef( droppable: isFolder && (isOverMove || isOverUpload) })} type="grid" - rowSelectable={true} ref={forwardedRef} selected={selected.findIndex(item => item.name === file.name && item.cid === file.cid) >= 0} > From 610c2b477fb873e9a523f1624d9cb6797612c9d4 Mon Sep 17 00:00:00 2001 From: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Date: Fri, 6 Aug 2021 14:43:29 +0300 Subject: [PATCH 23/31] [Storage] add CID to bucket item row (#1423) * add cid to bucket item row * revert fr change * Apply suggestions from code review Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> --- packages/storage-ui/src/Components/Elements/CidRow.tsx | 4 +++- .../Modules/FileSystemItem/FileSystemTableItem.tsx | 9 ++++++--- .../src/Components/Modules/FilesList/FilesList.tsx | 10 +++++++--- packages/storage-ui/src/Components/Pages/CidsPage.tsx | 4 ++-- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/storage-ui/src/Components/Elements/CidRow.tsx b/packages/storage-ui/src/Components/Elements/CidRow.tsx index e273abc9b6..74927f785d 100644 --- a/packages/storage-ui/src/Components/Elements/CidRow.tsx +++ b/packages/storage-ui/src/Components/Elements/CidRow.tsx @@ -71,7 +71,9 @@ const CidRow = ({ pinStatus }: Props) => { className={classes.tableRow} data-cy="row-cid-item" > - + {pinStatus.pin?.cid} diff --git a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx index 4a2de2329e..b590b4877d 100644 --- a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx +++ b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx @@ -20,11 +20,9 @@ import { CSSTheme } from "../../../Themes/types" import { FileSystemItem } from "../../../Contexts/StorageContext" import { nameValidator } from "../../../Utils/validationSchema" import { ISelectedFile, useFileBrowser } from "../../../Contexts/FileBrowserContext" +import { desktopGridSettings, mobileGridSettings } from "../FilesList/FilesList" const useStyles = makeStyles(({ breakpoints, constants, palette }: CSSTheme) => { - const desktopGridSettings = "50px 69px 3fr 190px 100px 45px !important" - const mobileGridSettings = "69px 3fr 45px !important" - return createStyles({ tableRow: { border: "2px solid transparent", @@ -235,6 +233,11 @@ const FileSystemTableItem = React.forwardRef( {!isFolder && !!created_at && dayjs.unix(created_at).format("DD MMM YYYY h:mm a")} } + { + + {!isFolder && cid} + + } {!isFolder && formatBytes(size, 2)} diff --git a/packages/storage-ui/src/Components/Modules/FilesList/FilesList.tsx b/packages/storage-ui/src/Components/Modules/FilesList/FilesList.tsx index 32de4b0437..34f08126a2 100644 --- a/packages/storage-ui/src/Components/Modules/FilesList/FilesList.tsx +++ b/packages/storage-ui/src/Components/Modules/FilesList/FilesList.tsx @@ -49,10 +49,12 @@ interface IStyleProps { themeKey: string } +export const desktopGridSettings = "50px 69px 3fr 3fr 100px 45px !important" +export const mobileGridSettings = "69px 3fr 45px !important" + const useStyles = makeStyles( ({ animation, breakpoints, constants, palette, zIndex }: CSSTheme) => { - const desktopGridSettings = "50px 69px 3fr 190px 100px 45px !important" - const mobileGridSettings = "69px 3fr 45px !important" + return createStyles({ root: { position: "relative", @@ -779,7 +781,6 @@ const FilesList = () => { handleSortToggle("name")} sortDirection={column === "name" ? direction : undefined} sortActive={column === "name"} @@ -799,6 +800,9 @@ const FilesList = () => { Date uploaded } + + CID + createStyles({ From f355a9eba64c8721c6d6c5fcc0a4e8df84c0bce9 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Fri, 6 Aug 2021 18:15:10 +0200 Subject: [PATCH 24/31] Use cypress session instead of locally stored files. (#1421) * Add ui tests for folder name validation * change implementation and tests * remove only * ci run failing sometimes * Extend timeouts, use safeClick on another dialog button * remove comments and video and now useless commands * remove .only Co-authored-by: Andrew Snaith Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> --- packages/files-ui/cypress.json | 3 +- packages/files-ui/cypress/plugins/index.ts | 11 -- packages/files-ui/cypress/support/commands.ts | 122 +++--------------- .../cypress/support/page-objects/homePage.ts | 6 +- .../cypress/tests/file-management-spec.ts | 4 +- .../cypress/tests/main-navigation-spec.ts | 4 +- .../files-ui/cypress/tests/settings-spec.ts | 4 +- 7 files changed, 26 insertions(+), 128 deletions(-) diff --git a/packages/files-ui/cypress.json b/packages/files-ui/cypress.json index fb59b54133..591ee687a6 100644 --- a/packages/files-ui/cypress.json +++ b/packages/files-ui/cypress.json @@ -1,4 +1,5 @@ { "integrationFolder": "cypress/tests", - "video": false + "video": false, + "experimentalSessionSupport": true } diff --git a/packages/files-ui/cypress/plugins/index.ts b/packages/files-ui/cypress/plugins/index.ts index 77ca4f8215..368e28954a 100644 --- a/packages/files-ui/cypress/plugins/index.ts +++ b/packages/files-ui/cypress/plugins/index.ts @@ -8,7 +8,6 @@ // You can read more here: // https://on.cypress.io/plugins-guide // *********************************************************** -import { existsSync, readFileSync } from "fs" // This function is called when a project is opened or re-opened (e.g. due to // the project's config changing) @@ -21,16 +20,6 @@ export default (on: any) => { // `on` is used to hook into various events Cypress emits // `config` is the resolved Cypress config - on("task", { - readFileMaybe(filename: string) { - if (existsSync(filename)) { - return readFileSync(filename, "utf8") - } - - return null - } - }) - on("before:browser:launch", (browser: Cypress.Browser, launchOptions: Cypress.BrowserLaunchOptions) => { if (browser.name === "chrome" && browser.isHeadless) { // fullPage screenshot size is 1280x720 on non-retina screens diff --git a/packages/files-ui/cypress/support/commands.ts b/packages/files-ui/cypress/support/commands.ts index 74fd24c95a..7920897bc1 100644 --- a/packages/files-ui/cypress/support/commands.ts +++ b/packages/files-ui/cypress/support/commands.ts @@ -45,9 +45,6 @@ export interface Web3LoginOptions { clearTrashBucket?: boolean } -const SESSION_FILE = "cypress/fixtures/storage/sessionStorage.json" -const LOCAL_FILE = "cypress/fixtures/storage/localStorage.json" - Cypress.Commands.add("clearCsfBucket", (apiUrlBase: string) => { apiTestHelper.clearBucket(apiUrlBase, "csf") }) @@ -56,52 +53,15 @@ Cypress.Commands.add("clearTrashBucket", (apiUrlBase: string) => { apiTestHelper.clearBucket(apiUrlBase, "trash") }) -Cypress.Commands.add("saveLocalAndSession", () => { - // save local and session storage in files - cy.window().then((win) => { - const newLocal: Storage = [] - const newSession: Storage = [] - - Object.keys(win.localStorage).forEach((key) => { - newLocal.push({ key, value: win.localStorage.getItem(key) || "" }) - }) - - Object.keys(win.sessionStorage).forEach((key) => { - newSession.push({ key, value: win.sessionStorage.getItem(key) || "" }) - }) - - const newLocalString = JSON.stringify(newLocal) - const newSessionString = JSON.stringify(newSession) - - cy.writeFile(SESSION_FILE, newSessionString) - cy.writeFile(LOCAL_FILE, newLocalString) - }) -}) - Cypress.Commands.add( "web3Login", ({ saveBrowser = false, url = localHost, apiUrlBase = "https://stage.imploy.site/api/v1", - useLocalAndSessionStorage = true, clearCSFBucket = false, clearTrashBucket = false }: Web3LoginOptions = {}) => { - let session: Storage = [] - let local: Storage = [] - - cy.task("readFileMaybe", SESSION_FILE).then( - (unparsedSession) => { - session = (unparsedSession && JSON.parse(unparsedSession)) || [] - } - ) - - cy.task("readFileMaybe", LOCAL_FILE).then( - (unparsedLocal) => { - local = (unparsedLocal && JSON.parse(unparsedLocal)) || [] - } - ) cy.on("window:before:load", (win) => { const provider = new ethers.providers.JsonRpcProvider( @@ -113,57 +73,29 @@ Cypress.Commands.add( Object.defineProperty(win, "ethereum", { get: () => new CustomizedBridge(signer as any, provider as any) }) - - // clear session storage in any case, if previous session storage should be - // kept will be decided after. - // Note that Cypress keep the session storage between test but clears localStorage - win.sessionStorage.clear() - win.localStorage.clear() - - if (useLocalAndSessionStorage) { - session.forEach(({ key, value }) => { - win.sessionStorage.setItem(key, value) - }) - - local.forEach(({ key, value }) => { - win.localStorage.setItem(key, value) - }) - } }) - cy.visit(url) - // with nothing in localstorage (and in session storage) // the whole login flow should kick in - cy.then(() => { - cy.log( - "Logging in", - local.length > 0 && - "there is something in session storage ---> direct login" - ) - - if (local.length === 0) { - cy.log("nothing in session storage, --> click on web3 button") - authenticationPage.web3Button().click() - authenticationPage.showMoreButton().click() - authenticationPage.detectedWallet().click() - authenticationPage.web3SignInButton().safeClick() - authenticationPage.loginPasswordButton().click() - authenticationPage.loginPasswordInput().type(`${testAccountPassword}{enter}`) - - if (saveBrowser) { - // this is taking forever for test accounts - authenticationPage.saveBrowserButton().click() - } else { - authenticationPage.doNotSaveBrowserButton().click() - } + cy.session("web3login", () => { + cy.visit(url) + authenticationPage.web3Button().click() + authenticationPage.showMoreButton().click() + authenticationPage.detectedWallet().click() + authenticationPage.web3SignInButton().safeClick() + authenticationPage.loginPasswordButton().click() + authenticationPage.loginPasswordInput().type(`${testAccountPassword}{enter}`) + + if (saveBrowser) { + // this is taking forever for test accounts + authenticationPage.saveBrowserButton().click() + } else { + authenticationPage.doNotSaveBrowserButton().click() } }) - + cy.visit(url) homePage.appHeaderLabel().should("be.visible") - cy.saveLocalAndSession() - if (clearCSFBucket) { cy.clearCsfBucket(apiUrlBase) } @@ -171,23 +103,6 @@ Cypress.Commands.add( if (clearTrashBucket) { cy.clearTrashBucket(apiUrlBase) } - - if(clearTrashBucket || clearCSFBucket){ - cy.reload({ timeout: 50000 }).then(() => { - if (local.length === 0) { - // Temp work around for local storage being cleared after the reload. See issue in #1381 - cy.log("nothing in local storage after reload, --> click on web3 button") - authenticationPage.web3Button().click() - authenticationPage.showMoreButton().click() - authenticationPage.detectedWallet().click() - authenticationPage.web3SignInButton().safeClick() - authenticationPage.loginPasswordButton().click() - authenticationPage.loginPasswordInput().type(`${testAccountPassword}{enter}`) - authenticationPage.doNotSaveBrowserButton().click() - } - }) - homePage.appHeaderLabel().should("be.visible") - } } ) @@ -210,7 +125,6 @@ declare global { * @param {String} options.url - (default: "http://localhost:3000") - what url to visit. * @param {String} apiUrlBase - (default: "https://stage.imploy.site/api/v1") - what url to call for the api. * @param {Boolean} options.saveBrowser - (default: false) - save the browser to localstorage. - * @param {Boolean} options.useLocalAndSessionStorage - (default: true) - use what could have been stored before to speedup login * @param {Boolean} options.clearCSFBucket - (default: false) - whether any file in the csf bucket should be deleted. * @example cy.web3Login({saveBrowser: true, url: 'http://localhost:8080'}) */ @@ -224,12 +138,6 @@ declare global { clearCsfBucket: (apiUrlBase: string) => Chainable clearTrashBucket: (apiUrlBase: string) => Chainable - /** - * Save local and session storage to local files - * @example cy.saveLocalAndSession() - */ - saveLocalAndSession: () => Chainable - /** * Use this when encountering race condition issues resulting in * cypress "detached from DOM" issues or clicking before an event diff --git a/packages/files-ui/cypress/support/page-objects/homePage.ts b/packages/files-ui/cypress/support/page-objects/homePage.ts index cda080fba6..ca624f4ec9 100644 --- a/packages/files-ui/cypress/support/page-objects/homePage.ts +++ b/packages/files-ui/cypress/support/page-objects/homePage.ts @@ -14,7 +14,7 @@ export const homePage = { deleteSelectedButton: () => cy.get("[data-testId=button-delete-selected-file]"), deleteFileDialog: () => cy.get("[data-testid=modal-container-file-deletion]"), deleteFileCancelButton: () => cy.get("[data-testid=button-cancel-deletion]"), - deleteFileConfirmButton: () => cy.get("[data-testid=button-confirm-deletion]"), + deleteFileConfirmButton: () => cy.get("[data-testid=button-confirm-deletion]", { timeout: 10000 }), uploadStatusToast: () => cy.get("[data-cy=upload-status-toast-message]", { timeout: 10000 }), // file browser row elements @@ -29,11 +29,11 @@ export const homePage = { createFolderModal: () => cy.get("[data-cy=modal-create-folder]", { timeout: 10000 }), folderNameInput: () => cy.get("[data-cy=input-folder-name]"), cancelButton: () => cy.get("[data-cy=button-cancel-create-folder]"), - createButton: () => cy.get("[data-cy=button-create-folder]"), + createButton: () => cy.get("[data-cy=button-create-folder]", { timeout: 10000 }), folderCreationErrorLabel: () => cy.get("[data-cy=folder-creation-form] span.default.error"), // upload modal elements - startUploadButton: () => cy.get("[data-testId=button-start-upload]"), + startUploadButton: () => cy.get("[data-testId=button-start-upload]", { timeout: 10000 }), uploadCancelButton: () => cy.get("[data-testId=button-cancel-upload]"), fileListRemoveButton: () => cy.get("[data-testid=button-remove-from-file-list]"), fileUploadList: () => cy.get("[data-testid=file-list-fileUpload] li"), diff --git a/packages/files-ui/cypress/tests/file-management-spec.ts b/packages/files-ui/cypress/tests/file-management-spec.ts index 7f2583bd00..806f2abe69 100644 --- a/packages/files-ui/cypress/tests/file-management-spec.ts +++ b/packages/files-ui/cypress/tests/file-management-spec.ts @@ -111,7 +111,7 @@ describe("File management", () => { homePage.fileItemKebabButton().first().click() homePage.deleteMenuOption().click() homePage.deleteFileDialog().should("be.visible") - homePage.deleteFileConfirmButton().click() + homePage.deleteFileConfirmButton().safeClick() homePage.deleteFileDialog().should("not.exist") homePage.fileItemRow().should("not.exist") @@ -159,7 +159,7 @@ describe("File management", () => { homePage.fileItemKebabButton().first().click() homePage.deleteMenuOption().click() homePage.deleteFileDialog().should("be.visible") - homePage.deleteFileConfirmButton().click() + homePage.deleteFileConfirmButton().safeClick() homePage.deleteFileDialog().should("not.exist") homePage.fileItemRow().should("not.exist") diff --git a/packages/files-ui/cypress/tests/main-navigation-spec.ts b/packages/files-ui/cypress/tests/main-navigation-spec.ts index ca49540edb..6c5b6136f2 100644 --- a/packages/files-ui/cypress/tests/main-navigation-spec.ts +++ b/packages/files-ui/cypress/tests/main-navigation-spec.ts @@ -5,7 +5,7 @@ import { homePage } from "../support/page-objects/homePage" describe("Main Navigation", () => { context("desktop", () => { - before(() => { + beforeEach(() => { cy.web3Login() }) @@ -35,7 +35,7 @@ describe("Main Navigation", () => { }) context("mobile", () => { - before(() => { + beforeEach(() => { cy.web3Login() }) diff --git a/packages/files-ui/cypress/tests/settings-spec.ts b/packages/files-ui/cypress/tests/settings-spec.ts index e0e0ea037f..80e8e69389 100644 --- a/packages/files-ui/cypress/tests/settings-spec.ts +++ b/packages/files-ui/cypress/tests/settings-spec.ts @@ -5,7 +5,7 @@ import { homePage } from "../support/page-objects/homePage" describe("Settings", () => { context("desktop", () => { - before(() => { + beforeEach(() => { cy.web3Login() }) @@ -27,7 +27,7 @@ describe("Settings", () => { cy.viewport("iphone-6") }) - before(() => { + beforeEach(() => { cy.web3Login() }) From 439fbc2b1b3fc7d7d20344e7e4410b0f2bddf566 Mon Sep 17 00:00:00 2001 From: ryry79261 Date: Fri, 6 Aug 2021 20:50:00 +0200 Subject: [PATCH 25/31] Fixed spacing --- .../Modules/FileSystemItem/FileSystemTableItem.tsx | 14 +++++++++++--- .../storage-ui/src/Components/Pages/BucketPage.tsx | 1 - .../storage-ui/src/Contexts/StorageContext.tsx | 11 +---------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx index 3dbb46378d..2ca870cf6e 100644 --- a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx +++ b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx @@ -23,13 +23,17 @@ import { ISelectedFile, useFileBrowser } from "../../../Contexts/FileBrowserCont const useStyles = makeStyles(({ breakpoints, constants, palette }: CSSTheme) => { const desktopGridSettings = "50px 69px 3fr 190px 100px 45px !important" + const ipfsDesktopGridSettings = "50px 69px 3fr 190px 45px !important" const mobileGridSettings = "69px 3fr 45px !important" return createStyles({ tableRow: { border: "2px solid transparent", [breakpoints.up("md")]: { - gridTemplateColumns: desktopGridSettings + gridTemplateColumns: desktopGridSettings, + "&.ipfs": { + gridTemplateColumns: ipfsDesktopGridSettings + } }, [breakpoints.down("md")]: { gridTemplateColumns: mobileGridSettings @@ -100,7 +104,10 @@ const useStyles = makeStyles(({ breakpoints, constants, palette }: CSSTheme) => }, dropdownItem: { backgroundColor: constants.fileSystemItemRow.itemBackground, - color: constants.fileSystemItemRow.itemColor + color: constants.fileSystemItemRow.itemColor, + "& a": { + textDecoration: "none" + } } }) }) @@ -168,7 +175,8 @@ const FileSystemTableItem = React.forwardRef( = () => { const handleDownload = useCallback(async ( toDownload: ISelectedFile ) => { - // throw new Error("Not implemented") const itemToDownload = pathContents.find(item => item.cid === toDownload.cid) if (!itemToDownload || !bucket) return diff --git a/packages/storage-ui/src/Contexts/StorageContext.tsx b/packages/storage-ui/src/Contexts/StorageContext.tsx index 9dc6aaeef4..057c500387 100644 --- a/packages/storage-ui/src/Contexts/StorageContext.tsx +++ b/packages/storage-ui/src/Contexts/StorageContext.tsx @@ -270,18 +270,9 @@ const StorageProvider = ({ children }: StorageContextProps) => { const getFileContent = useCallback(async ( bucketId: string, - { cid, cancelToken, onDownloadProgress, file, path }: GetFileContentParams + { cancelToken, onDownloadProgress, path }: GetFileContentParams ) => { - // when a file is accessed from the search page, a file and a path are passed in - // because the current path will not reflect the right state of the app - const fileToGet = file - - if (!fileToGet) { - console.error("No file passed, and no file found for cid:", cid, "in pathContents:", path) - throw new Error("No file found.") - } - try { const result = await storageApiClient.getBucketObjectContent( bucketId, From acec9f2af1c3d58b1d7be20bde0ef6bac0a124f3 Mon Sep 17 00:00:00 2001 From: ryry79261 Date: Fri, 6 Aug 2021 20:52:49 +0200 Subject: [PATCH 26/31] Resting to changes from dev --- .../Modules/FileSystemItem/FileSystemTableItem.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx index f472f9e06f..6416a77487 100644 --- a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx +++ b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx @@ -23,17 +23,13 @@ import { ISelectedFile, useFileBrowser } from "../../../Contexts/FileBrowserCont const useStyles = makeStyles(({ breakpoints, constants, palette }: CSSTheme) => { const desktopGridSettings = "50px 69px 3fr 190px 100px 45px !important" - const ipfsDesktopGridSettings = "50px 69px 3fr 190px 45px !important" const mobileGridSettings = "69px 3fr 45px !important" return createStyles({ tableRow: { border: "2px solid transparent", [breakpoints.up("md")]: { - gridTemplateColumns: desktopGridSettings, - "&.ipfs": { - gridTemplateColumns: ipfsDesktopGridSettings - } + gridTemplateColumns: desktopGridSettings }, [breakpoints.down("md")]: { gridTemplateColumns: mobileGridSettings From 174d4a2e8fae2b42c5468bacd78b5927f14d8ed2 Mon Sep 17 00:00:00 2001 From: ryry79261 Date: Tue, 10 Aug 2021 11:46:10 +0200 Subject: [PATCH 27/31] Simple overflow patch --- .../Modules/FileSystemItem/FileSystemTableItem.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx index 6416a77487..daac99c449 100644 --- a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx +++ b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx @@ -104,6 +104,10 @@ const useStyles = makeStyles(({ breakpoints, constants, palette }: CSSTheme) => "& a": { textDecoration: "none" } + }, + overflowCell: { + textOverflow: "ellipsis", + overflow: "hidden" } }) }) @@ -240,7 +244,7 @@ const FileSystemTableItem = React.forwardRef( } { - + {!isFolder && cid} } From 46bef83ad02004067d64ca151cd5bfe71bb5332d Mon Sep 17 00:00:00 2001 From: Ryan Noble Date: Tue, 10 Aug 2021 16:37:54 +0200 Subject: [PATCH 28/31] Expose decryption key (#1426) * Hidden component done * lingui extract * Update packages/common-components/src/ToggleHiddenText/ToggleHiddenText.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/files-ui/src/Components/Modules/FileBrowsers/FileInfoModal.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/common-components/src/ToggleHiddenText/ToggleHiddenText.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/files-ui/src/Components/Modules/FileBrowsers/FileInfoModal.tsx Co-authored-by: Andrew Snaith * Update packages/common-components/src/ToggleHiddenText/ToggleHiddenText.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * lingui extract * Cleaned * using useMemo and prevent repetitions * spaces Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: Andrew Snaith Co-authored-by: Thibaut Sardan --- .../src/Icons/svgs/eye-closed.svg | 2 +- .../src/Icons/svgs/eye-open.svg | 2 +- .../src/ToggleHiddenText/ToggleHiddenText.tsx | 68 +++++++++++++++++++ .../src/ToggleHiddenText/index.ts | 2 + packages/common-components/src/index.ts | 1 + .../src/Overrides/ToggleHiddenText.ts | 4 ++ packages/common-theme/src/Overrides/index.ts | 2 + .../Modules/FileBrowsers/FileInfoModal.tsx | 26 ++++++- .../files-ui/src/Contexts/FilesContext.tsx | 2 + packages/files-ui/src/Themes/DarkTheme.ts | 5 ++ packages/files-ui/src/Themes/LightTheme.ts | 5 ++ 11 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 packages/common-components/src/ToggleHiddenText/ToggleHiddenText.tsx create mode 100644 packages/common-components/src/ToggleHiddenText/index.ts create mode 100644 packages/common-theme/src/Overrides/ToggleHiddenText.ts diff --git a/packages/common-components/src/Icons/svgs/eye-closed.svg b/packages/common-components/src/Icons/svgs/eye-closed.svg index e60a7d4095..8026693b30 100644 --- a/packages/common-components/src/Icons/svgs/eye-closed.svg +++ b/packages/common-components/src/Icons/svgs/eye-closed.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/packages/common-components/src/Icons/svgs/eye-open.svg b/packages/common-components/src/Icons/svgs/eye-open.svg index 7a28413435..c25ff7a57c 100644 --- a/packages/common-components/src/Icons/svgs/eye-open.svg +++ b/packages/common-components/src/Icons/svgs/eye-open.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/packages/common-components/src/ToggleHiddenText/ToggleHiddenText.tsx b/packages/common-components/src/ToggleHiddenText/ToggleHiddenText.tsx new file mode 100644 index 0000000000..fa9c05ab7d --- /dev/null +++ b/packages/common-components/src/ToggleHiddenText/ToggleHiddenText.tsx @@ -0,0 +1,68 @@ +import { createStyles, ITheme, makeStyles } from "@chainsafe/common-theme" +import React, { ReactNode, useCallback, useMemo, useState } from "react" +import clsx from "clsx" +import { EyeClosedSvg } from "../Icons/icons/EyeClosed.icon" +import { EyeOpenSvg } from "../Icons/icons/EyeOpen.icon" + +const useStyles = makeStyles(({ constants, overrides }: ITheme) => + createStyles({ + root: { + display: "inline-flex", + flexDirection: "row", + justifyContent: "flex-start", + alignItems: "center", + marginLeft: constants.generalUnit, + ...overrides?.ToggleHiddenText?.root + }, + icon: { + marginRight: constants.generalUnit, + cursor: "pointer", + ...overrides?.ToggleHiddenText?.icon + } + }) +) + +interface IToggleHiddenText { + children: ReactNode + iconPosition?: "left" | "right" + hiddenLength?: number + className?: string +} + +const ToggleHiddenText = ({ className, iconPosition = "left", hiddenLength = 6, children }: IToggleHiddenText) => { + const classes = useStyles() + const [hidden, setHidden] = useState(true) + const hiddenKey = useMemo(() => new Array(hiddenLength).fill("●"), [hiddenLength]) + + const EyeClosed = useCallback(() => setHidden(false)} + /> + , [classes.icon]) + + const EyeOpen = useCallback(() => setHidden(true)} + /> + , [classes.icon]) + + return ( + + { + hidden + ? <> + {iconPosition === "left" && } + {hiddenKey} + {iconPosition === "right" && } + + : <> + {iconPosition === "left" && } + {children} + {iconPosition === "right" && } + + } + + ) +} + +export default ToggleHiddenText diff --git a/packages/common-components/src/ToggleHiddenText/index.ts b/packages/common-components/src/ToggleHiddenText/index.ts new file mode 100644 index 0000000000..bfdef4a23c --- /dev/null +++ b/packages/common-components/src/ToggleHiddenText/index.ts @@ -0,0 +1,2 @@ +export { default as ToggleHiddenText } from "./ToggleHiddenText" +export * from "./ToggleHiddenText" diff --git a/packages/common-components/src/index.ts b/packages/common-components/src/index.ts index 1f0cb4216a..72c5520605 100644 --- a/packages/common-components/src/index.ts +++ b/packages/common-components/src/index.ts @@ -32,6 +32,7 @@ export * from "./Table" export * from "./Tabs" export * from "./TagsInput" export * from "./Toaster" +export * from "./ToggleHiddenText" export * from "./TextInput" export * from "./TreeView" export * from "./Typography" diff --git a/packages/common-theme/src/Overrides/ToggleHiddenText.ts b/packages/common-theme/src/Overrides/ToggleHiddenText.ts new file mode 100644 index 0000000000..f11b3ca929 --- /dev/null +++ b/packages/common-theme/src/Overrides/ToggleHiddenText.ts @@ -0,0 +1,4 @@ +export interface IToggleHiddenText { + root?: Record + icon?: Record +} diff --git a/packages/common-theme/src/Overrides/index.ts b/packages/common-theme/src/Overrides/index.ts index a9c6ddd30f..ac1f67a883 100644 --- a/packages/common-theme/src/Overrides/index.ts +++ b/packages/common-theme/src/Overrides/index.ts @@ -24,6 +24,7 @@ import { ITextInputOverride } from "./TextInput" import { IToasterOverride } from "./Toaster" import { ITypographyOverride } from "./Typography" import { ITagsInputOverride } from "./TagsInput" +import { IToggleHiddenText } from "./ToggleHiddenText" export interface IComponentOverrides { Avatar?: IAvatarOverride @@ -50,6 +51,7 @@ export interface IComponentOverrides { Tabs?: ITabsOverride TextInput?: ITextInputOverride Toaster?: IToasterOverride + ToggleHiddenText?: IToggleHiddenText Typography?: ITypographyOverride TagsInput?: ITagsInputOverride } diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/FileInfoModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/FileInfoModal.tsx index ec3be54bc1..73a1122989 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/FileInfoModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/FileInfoModal.tsx @@ -7,12 +7,13 @@ import React, { useState, useEffect } from "react" import CustomModal from "../../Elements/CustomModal" import CustomButton from "../../Elements/CustomButton" import { Trans } from "@lingui/macro" -import { FileFullInfo } from "../../../Contexts/FilesContext" +import { FileFullInfo, useFiles } from "../../../Contexts/FilesContext" import { Button, formatBytes, Grid, Loading, + ToggleHiddenText, Typography } from "@chainsafe/common-components" import clsx from "clsx" @@ -160,6 +161,7 @@ interface IFileInfoModuleProps { const FileInfoModal = ({ filePath, close }: IFileInfoModuleProps) => { const classes = useStyles() const { filesApiClient } = useFilesApi() + const { personalEncryptionKey } = useFiles() const [loadingFileInfo, setLoadingInfo] = useState(false) const [fullFileInfo, setFullFullInfo] = useState() const { bucket } = useFileBrowser() @@ -361,6 +363,28 @@ const FileInfoModal = ({ filePath, close }: IFileInfoModuleProps) => { {fullFileInfo.content?.cid}
+
+ + + Decryption key + + + + + { personalEncryptionKey } + + +
diff --git a/packages/files-ui/src/Contexts/FilesContext.tsx b/packages/files-ui/src/Contexts/FilesContext.tsx index faf7153a2a..dd3d5a4921 100644 --- a/packages/files-ui/src/Contexts/FilesContext.tsx +++ b/packages/files-ui/src/Contexts/FilesContext.tsx @@ -81,6 +81,7 @@ type FilesContext = { uploadsInProgress: UploadProgress[] downloadsInProgress: DownloadProgress[] storageSummary: BucketSummaryResponse | undefined + personalEncryptionKey: string | undefined getStorageSummary: () => Promise uploadFiles: (bucketId: string, files: File[], path: string, encryptionKey?: string) => Promise downloadFile: (bucketId: string, itemToDownload: FileSystemItem, path: string) => void @@ -588,6 +589,7 @@ const FilesProvider = ({ children }: FilesContextProps) => { uploadFiles, downloadFile, getFileContent, + personalEncryptionKey, uploadsInProgress, storageSummary, getStorageSummary, diff --git a/packages/files-ui/src/Themes/DarkTheme.ts b/packages/files-ui/src/Themes/DarkTheme.ts index 2802c7beca..178c752840 100644 --- a/packages/files-ui/src/Themes/DarkTheme.ts +++ b/packages/files-ui/src/Themes/DarkTheme.ts @@ -686,6 +686,11 @@ export const darkTheme = createTheme({ } } } + }, + ToggleHiddenText: { + icon: { + stroke: "var(--gray9)" + } } } } diff --git a/packages/files-ui/src/Themes/LightTheme.ts b/packages/files-ui/src/Themes/LightTheme.ts index cdcc968af0..3c4f3a9f64 100644 --- a/packages/files-ui/src/Themes/LightTheme.ts +++ b/packages/files-ui/src/Themes/LightTheme.ts @@ -203,6 +203,11 @@ export const lightTheme = createTheme({ } } } + }, + ToggleHiddenText: { + icon: { + stroke: "var(--gray9)" + } } } } From 92ce96f9732d08d2743a4e34857aacb9ebe37deb Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Tue, 10 Aug 2021 16:52:55 +0200 Subject: [PATCH 29/31] fix the overflow --- .../Modules/FileSystemItem/FileSystemTableItem.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx index daac99c449..7ac96874a5 100644 --- a/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx +++ b/packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx @@ -20,11 +20,9 @@ import { CSSTheme } from "../../../Themes/types" import { FileSystemItem } from "../../../Contexts/StorageContext" import { nameValidator } from "../../../Utils/validationSchema" import { ISelectedFile, useFileBrowser } from "../../../Contexts/FileBrowserContext" +import { desktopGridSettings, mobileGridSettings } from "../FilesList/FilesList" const useStyles = makeStyles(({ breakpoints, constants, palette }: CSSTheme) => { - const desktopGridSettings = "50px 69px 3fr 190px 100px 45px !important" - const mobileGridSettings = "69px 3fr 45px !important" - return createStyles({ tableRow: { border: "2px solid transparent", @@ -104,10 +102,6 @@ const useStyles = makeStyles(({ breakpoints, constants, palette }: CSSTheme) => "& a": { textDecoration: "none" } - }, - overflowCell: { - textOverflow: "ellipsis", - overflow: "hidden" } }) }) @@ -244,7 +238,7 @@ const FileSystemTableItem = React.forwardRef(
} { - + {!isFolder && cid} } From a43c72c177acce477a8ec71ddc97dff00d09f7ef Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Tue, 10 Aug 2021 19:06:40 +0200 Subject: [PATCH 30/31] [Storage] Adapt the email login from like done on Files (#1427) * storage * lingui extract * eth logo Co-authored-by: GitHub Actions --- .../Modules/LoginModule/InitialScreen.tsx | 2 +- .../src/Components/Modules/LoginModule.tsx | 111 +++++++-- .../Modules/LoginModule/PasswordlessEmail.tsx | 227 ++++++------------ .../storage-ui/src/Utils/validationSchema.ts | 13 + .../storage-ui/src/locales/en/messages.po | 18 +- 5 files changed, 196 insertions(+), 175 deletions(-) diff --git a/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx b/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx index fe3499b564..f9cfe992c9 100644 --- a/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx +++ b/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx @@ -168,7 +168,7 @@ const InitialScreen = ({ className }: IInitialScreen) => { const classes = useStyles() const [loginMode, setLoginMode] = useState<"web3" | "email" | LOGIN_TYPE | undefined>() const [error, setError] = useState() - const [errorEmail, setErrorEmail] = useState("") + const [errorEmail, setErrorEmail] = useState("") const maintenanceMode = process.env.REACT_APP_MAINTENANCE_MODE === "true" const [isConnecting, setIsConnecting] = useState(false) const { filesApiClient } = useFilesApi() diff --git a/packages/storage-ui/src/Components/Modules/LoginModule.tsx b/packages/storage-ui/src/Components/Modules/LoginModule.tsx index 70667c2f0f..ed4d13dfd5 100644 --- a/packages/storage-ui/src/Components/Modules/LoginModule.tsx +++ b/packages/storage-ui/src/Components/Modules/LoginModule.tsx @@ -1,5 +1,14 @@ -import React, { useState } from "react" -import { Button, GithubLogoIcon, GoogleLogoIcon, Loading, MailIcon, Typography } from "@chainsafe/common-components" +import React, { useCallback, useState } from "react" +import { + Button, + EthereumLogoIcon, + FormikTextInput, + GithubLogoIcon, + GoogleLogoIcon, + Loading, + MailIcon, + Typography +} from "@chainsafe/common-components" import { createStyles, makeStyles, useThemeSwitcher } from "@chainsafe/common-theme" import { CSSTheme } from "../../Themes/types" import { t, Trans } from "@lingui/macro" @@ -9,6 +18,8 @@ import { ROUTE_LINKS } from "../StorageRoutes" import clsx from "clsx" import { IdentityProvider } from "@chainsafe/files-api-client" import PasswordlessEmail from "./LoginModule/PasswordlessEmail" +import { Form, FormikProvider, useFormik } from "formik" +import { emailValidation } from "../../Utils/validationSchema" const useStyles = makeStyles( ({ constants, palette, breakpoints, typography }: CSSTheme) => @@ -126,6 +137,19 @@ const useStyles = makeStyles( }, web3Button: { minHeight: 41 + }, + input: { + margin: 0, + width: "100%", + marginBottom: constants.generalUnit + }, + inputLabel: { + fontSize: "16px", + lineHeight: "24px", + marginBottom: constants.generalUnit + }, + secondaryLoginText: { + paddingTop: constants.generalUnit * 2 } }) ) @@ -143,6 +167,10 @@ const LoginModule = ({ className }: IInitialScreen) => { const [error, setError] = useState() const maintenanceMode = process.env.REACT_APP_MAINTENANCE_MODE === "true" const [isConnecting, setIsConnecting] = useState(false) + const { storageApiClient } = useStorageApi() + const [email, setEmail] = useState("") + const [errorEmail, setErrorEmail] = useState("") + const handleSelectWalletAndConnect = async () => { setError(undefined) @@ -164,6 +192,7 @@ const LoginModule = ({ className }: IInitialScreen) => { const resetLogin = async () => { setError(undefined) + setErrorEmail("") setLoginMode(undefined) resetStatus() } @@ -199,6 +228,32 @@ const LoginModule = ({ className }: IInitialScreen) => { setIsConnecting(false) } + const onSubmitEmail = useCallback((values: {email: string}) => { + setIsConnecting(true) + setErrorEmail("") + const trimmedEmail = values.email.trim() + + storageApiClient + .getIdentityEmailToken({ email: trimmedEmail }) + .then(() => { + setEmail(trimmedEmail) + setLoginMode("email") + }) + .catch((e) => { + setErrorEmail(t`Something went wrong with email login! Please try again.`) + console.error(e) + }) + .finally(() => setIsConnecting(false)) + }, [storageApiClient]) + + const formik = useFormik({ + initialValues: { + email: "" + }, + validationSchema: emailValidation, + onSubmit: onSubmitEmail + }) + const ConnectWallet = () => { if (!wallet) { console.error("No wallet found") @@ -269,7 +324,7 @@ const LoginModule = ({ className }: IInitialScreen) => { + + + + Or using one of the following: + - - - - : <> - +
+ - - - Verification code sent! - - - We’ve sent an email to {email}. It contains a verification code that’ll sign you in super quickly! - - - {error && ( - - {error} - - )} - - -
- - {!hasEmailResent - ? Verification code sent! + + + We’ve sent an email to {email}. It contains a verification code that’ll sign you in super quickly! + + + {error && ( + - - + {error} + + )} + + + + + {!hasEmailResent + ? + + Didn't receive the email ? - - - - + + + + Send another email - - - - : - - + + + + : + + Check your inbox! We've sent another email. - - - - } - + + + }
isCid(value) ) +}) + +export const emailValidation = object().shape({ + email: string() + .trim() + .email("Please enter a valid email") + .required(t`Email is required`) +}) + +export const nonceValidation = object().shape({ + nonce: string() + .trim() + .required(t`Verification code is required`) }) \ No newline at end of file diff --git a/packages/storage-ui/src/locales/en/messages.po b/packages/storage-ui/src/locales/en/messages.po index 86f7e31ed7..2390aa8c27 100644 --- a/packages/storage-ui/src/locales/en/messages.po +++ b/packages/storage-ui/src/locales/en/messages.po @@ -160,9 +160,6 @@ msgstr "Email is required" msgid "Enter the verification code:" msgstr "Enter the verification code:" -msgid "Enter your email:" -msgstr "Enter your email:" - msgid "Failed to get signature" msgstr "Failed to get signature" @@ -253,6 +250,9 @@ msgstr "One sec, getting files ready..." msgid "Open on Gateway" msgstr "Open on Gateway" +msgid "Or using one of the following:" +msgstr "Or using one of the following:" + msgid "Paste the CID to pin it with ChainSafe Storage" msgstr "Paste the CID to pin it with ChainSafe Storage" @@ -271,9 +271,6 @@ msgstr "Please enter a folder name" msgid "Please enter a name" msgstr "Please enter a name" -msgid "Please enter a valid email" -msgstr "Please enter a valid email" - msgid "Please select a file to upload" msgstr "Please select a file to upload" @@ -322,12 +319,12 @@ msgstr "Sign-in with {0}" msgid "Size" msgstr "Size" +msgid "Something went wrong with email login! Please try again." +msgstr "Something went wrong with email login! Please try again." + msgid "Something went wrong!" msgstr "Something went wrong!" -msgid "Something went wrong! Please try again." -msgstr "Something went wrong! Please try again." - msgid "Something went wrong. We couldn't upload your file" msgstr "Something went wrong. We couldn't upload your file" @@ -388,6 +385,9 @@ msgstr "Uploading {0} files" msgid "Use a different login method" msgstr "Use a different login method" +msgid "Using an email:" +msgstr "Using an email:" + msgid "Verification code is required" msgstr "Verification code is required" From 7167faa91ae206ba9bf93bd7b0f1a08d868b0197 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Wed, 11 Aug 2021 15:00:26 +0200 Subject: [PATCH 31/31] Fix lingui failing for weblate PRs (#1425) * lingui * test * more test * Update .github/workflows/lingui-extract-files.yml * another try * 2 * 3 * 4 * 5 * 6 * 7 * lingui extract * 8 * 9 * 10 * 11 * 12 * 13 * Update packages/files-ui/src/Components/Elements/MnemonicForm.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: GitHub Actions --- .github/workflows/lingui-extract-files.yml | 2 +- .github/workflows/lingui-extract-gaming.yml | 4 ++-- .github/workflows/lingui-extract-storage.yml | 8 ++------ .../files-ui/src/Components/Elements/MnemonicForm.tsx | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/workflows/lingui-extract-files.yml b/.github/workflows/lingui-extract-files.yml index d607f5d6a5..56f3a07e3c 100644 --- a/.github/workflows/lingui-extract-files.yml +++ b/.github/workflows/lingui-extract-files.yml @@ -16,7 +16,6 @@ jobs: with: ref: ${{ github.event.pull_request.head.ref }} ssh-key: ${{ secrets.LINGUI_GH_ACTION_COMMIT_KEY }} - - name: set user run: | git config --global user.name 'GitHub Actions' @@ -32,6 +31,7 @@ jobs: run: yarn install --immutable - name: lingui-extract and commit + if: ${{ github.actor != 'weblate' }} run: | (cd packages/files-ui && yarn extract --clean) git add packages/files-ui/src/locales/* diff --git a/.github/workflows/lingui-extract-gaming.yml b/.github/workflows/lingui-extract-gaming.yml index bcd4ab293e..5381a04312 100644 --- a/.github/workflows/lingui-extract-gaming.yml +++ b/.github/workflows/lingui-extract-gaming.yml @@ -16,7 +16,6 @@ jobs: with: ref: ${{ github.event.pull_request.head.ref }} ssh-key: ${{ secrets.LINGUI_GH_ACTION_COMMIT_KEY }} - - name: set user run: | git config --global user.name 'GitHub Actions' @@ -31,7 +30,8 @@ jobs: - name: install packages run: yarn install --immutable - - name: lingui-extract + - name: lingui-extract and commit + if: ${{ github.actor != 'weblate' }} run: | (cd packages/gaming-ui && yarn extract --clean) git add packages/gaming-ui/src/locales/* diff --git a/.github/workflows/lingui-extract-storage.yml b/.github/workflows/lingui-extract-storage.yml index f9ceaf053d..3a9c9a3c5f 100644 --- a/.github/workflows/lingui-extract-storage.yml +++ b/.github/workflows/lingui-extract-storage.yml @@ -16,7 +16,6 @@ jobs: with: ref: ${{ github.event.pull_request.head.ref }} ssh-key: ${{ secrets.LINGUI_GH_ACTION_COMMIT_KEY }} - - name: set user run: | git config --global user.name 'GitHub Actions' @@ -29,13 +28,10 @@ jobs: key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - name: install packages - env: - GITHUB_PACKAGES_AUTH_TOKEN: ${{ secrets.GH_PKG_AUTH_TOKEN }} run: yarn install --immutable - - name: lingui-extract - env: - GITHUB_PACKAGES_AUTH_TOKEN: ${{ secrets.GH_PKG_AUTH_TOKEN }} + - name: lingui-extract and commit + if: ${{ github.actor != 'weblate' }} run: | (cd packages/storage-ui && yarn extract --clean) git add packages/storage-ui/src/locales/* diff --git a/packages/files-ui/src/Components/Elements/MnemonicForm.tsx b/packages/files-ui/src/Components/Elements/MnemonicForm.tsx index 11ee58758a..ae064dfca4 100644 --- a/packages/files-ui/src/Components/Elements/MnemonicForm.tsx +++ b/packages/files-ui/src/Components/Elements/MnemonicForm.tsx @@ -184,4 +184,4 @@ const MnemonicForm = ({ buttonLabel, onComplete }: Props) => { ) } -export default MnemonicForm \ No newline at end of file +export default MnemonicForm