Skip to content

Commit

Permalink
[CP-2191] I want only supported files to be uploaded (#1393)
Browse files Browse the repository at this point in the history
  • Loading branch information
OskarMichalkiewicz authored and dkarski committed Sep 29, 2023
1 parent 8ca1e54 commit 06aa8d0
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"component.collectingDataModalBody": "I agree on sending anonymized data to Mudita"
}
}
4 changes: 4 additions & 0 deletions packages/app/src/files-manager/actions/base.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ export const setDuplicatedFiles = createAction<string[]>(
FilesManagerEvent.SetDuplicatedFiles
)
export const resetFiles = createAction(FilesManagerEvent.ResetFiles)

export const setInvalidFiles = createAction<string[]>(
FilesManagerEvent.SetInvalidFiles
)
20 changes: 12 additions & 8 deletions packages/app/src/files-manager/actions/upload-file.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { uploadFilesRequest } from "App/files-manager/requests"
import { getFiles } from "App/files-manager/actions/get-files.action"
import {
setDuplicatedFiles,
setInvalidFiles,
setPendingFilesToUpload,
setUploadBlocked,
setUploadingFileCount,
Expand Down Expand Up @@ -52,9 +53,9 @@ export const uploadFile = createAsyncThunk<
return rejectWithValue("no files to upload")
}

const allFilesSupported = checkFilesExtensions(filePaths)
const { validFiles, invalidFiles } = checkFilesExtensions(filePaths)

if (!allFilesSupported) {
if (!validFiles.length && invalidFiles.length) {
dispatch(setUploadBlocked(false))
return rejectWithValue(
new AppError(
Expand All @@ -66,11 +67,11 @@ export const uploadFile = createAsyncThunk<

const duplicatedFiles = getDuplicatedFiles(
state.filesManager.files,
filePaths
validFiles
)

if (duplicatedFiles.length > 0) {
const uniqueFiles = getUniqueFiles(state.filesManager.files, filePaths)
const uniqueFiles = getUniqueFiles(state.filesManager.files, validFiles)
dispatch(setPendingFilesToUpload(uniqueFiles))
dispatch(setDuplicatedFiles(duplicatedFiles))
dispatch(setUploadBlocked(false))
Expand All @@ -96,17 +97,17 @@ export const uploadFile = createAsyncThunk<

if (
state.device.deviceType === DeviceType.MuditaHarmony &&
harmonyFreeFilesSlotsCount < filePaths.length
harmonyFreeFilesSlotsCount < validFiles.length
) {
dispatch(
setPendingFilesToUpload(filePaths.slice(0, harmonyFreeFilesSlotsCount))
setPendingFilesToUpload(validFiles.slice(0, harmonyFreeFilesSlotsCount))
)
dispatch(setUploadingState(State.Pending))
dispatch(setUploadBlocked(false))
return
}

dispatch(setUploadingFileCount(filePaths.length))
dispatch(setUploadingFileCount(validFiles.length))
dispatch(setUploadingState(State.Loading))

const directory =
Expand All @@ -116,7 +117,7 @@ export const uploadFile = createAsyncThunk<

const result = await uploadFilesRequest({
directory,
filePaths,
filePaths: validFiles,
})

void dispatch(getFiles(directory))
Expand All @@ -128,6 +129,9 @@ export const uploadFile = createAsyncThunk<
void dispatch(loadStorageInfoAction())
dispatch(setUploadingState(State.Loaded))
dispatch(setUploadBlocked(false))
if (invalidFiles.length) {
dispatch(setInvalidFiles(invalidFiles))
}

return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ const FilesManager: FunctionComponent<FilesManagerProps> = ({
Array.from(fileInputRef.current?.files).map((file) => file.path)
)
)
fileInputRef.current.value = ""
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/

import { defineMessages } from "react-intl"
import { FunctionComponent } from "App/__deprecated__/renderer/types/function-component.interface"
import { useDispatch, useSelector } from "react-redux"
import { getInvalidFiles } from "App/files-manager/selectors/get-invalid-files.selector"
import {
ModalContent,
ModalDialog,
RoundIconWrapper,
} from "App/ui/components/modal-dialog"
import React from "react"
import { ModalSize } from "App/__deprecated__/renderer/components/core/modal/modal.interface"
import { intl } from "App/__deprecated__/renderer/utils/intl"
import Icon from "App/__deprecated__/renderer/components/core/icon/icon.component"
import { IconType } from "App/__deprecated__/renderer/components/core/icon/icon-type"
import Text, {
TextDisplayStyle,
} from "App/__deprecated__/renderer/components/core/text/text.component"
import { resetUploadingState } from "App/files-manager/actions"
import styled from "styled-components"
import {
fontWeight,
textColor,
} from "App/__deprecated__/renderer/styles/theming/theme-getters"
import { ipcRenderer } from "electron-better-ipc"
import { HelpActions } from "App/__deprecated__/common/enums/help-actions.enum"

const messages = defineMessages({
title: {
id: "module.filesManager.invalidFiledModalTitle",
},
filesInfo: {
id: "module.filesManager.invalidFiledModalFilesInfo",
},
helpInfo: {
id: "module.filesManager.invalidFiledModalHelpInfo",
},
})

const StyledLink = styled.a`
text-decoration: underline;
cursor: pointer;
font-size: 1.4rem;
font-weight: ${fontWeight("default")};
color: ${textColor("action")};
`
const StyledModalContent = styled(ModalContent)`
p {
text-align: left;
}
`

export const InvalidFilesModal: FunctionComponent = ({ ...props }) => {
const invalidFiles = useSelector(getInvalidFiles)
const openHelpWindow = () => ipcRenderer.callMain(HelpActions.OpenWindow)

const dispatch = useDispatch()
return (
<ModalDialog
size={ModalSize.Small}
title={intl.formatMessage(messages.title)}
open={!!invalidFiles.length}
closeButton
onCloseButton={() => {
dispatch(resetUploadingState())
}}
{...props}
>
<StyledModalContent>
<RoundIconWrapper>
<Icon type={IconType.Info} width={3.2} />
</RoundIconWrapper>
<Text
displayStyle={TextDisplayStyle.Paragraph4}
color="secondary"
message={messages.filesInfo}
/>
<Text
displayStyle={TextDisplayStyle.Paragraph4}
color="secondary"
message={{
...messages.helpInfo,
values: {
link: (
<StyledLink onClick={openHelpWindow}>help pages</StyledLink>
),
},
}}
/>
</StyledModalContent>
</ModalDialog>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import PendingUploadModal from "App/files-manager/components/pending-upload-moda
import DuplicatedFilesModal from "App/files-manager/components/duplicated-files-modal/duplicated-files-modal.component"
import UnsupportedFileFormatModal from "App/files-manager/components/unsupported-file-format-modal/unsupported-file-format-modal.component"
import UnsupportedFileSizeModal from "App/files-manager/components/unsupported-file-size-modal/unsupported-file-size-modal.component"
import { InvalidFilesModal } from "../invalid-files-modal/invalid-files-modal.component"

const messages = defineMessages({
uploadingModalInfo: { id: "module.filesManager.uploadingModalInfo" },
Expand Down Expand Up @@ -100,6 +101,7 @@ export const UploadFilesModals: FunctionComponent<UploadFilesModalProps> = ({
<DuplicatedFilesModal />
<UnsupportedFileFormatModal />
<UnsupportedFileSizeModal />
<InvalidFilesModal />
</>
)
}
1 change: 1 addition & 0 deletions packages/app/src/files-manager/constants/event.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ export enum FilesManagerEvent {
AbortPendingUpload = "FILES_MANAGER_ABORT_PENDING_UPLOAD",
ContinuePendingUpload = "FILES_MANAGER_CONTINUE_PENDING_UPLOAD",
SetDuplicatedFiles = "FILES_MANAGER_SET_DUPLICATED_FILES",
SetInvalidFiles = "FILES_MANAGER_SET_INVALID_FILES",
ResetFiles = "FILES_MANAGER_RESET_FILES",
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,25 @@ const supportedFiles = eligibleFormat.map((extension) => `file.${extension}`)

describe("`checkFilesExtensions` helper", () => {
test("all correct extensions", () => {
expect(checkFilesExtensions(supportedFiles)).toBeTruthy()
expect(checkFilesExtensions(supportedFiles)).toEqual({
validFiles: supportedFiles,
invalidFiles: [],
})
})

test("empty files array", () => {
expect(checkFilesExtensions([])).toBeTruthy()
expect(checkFilesExtensions([])).toEqual({
validFiles: [],
invalidFiles: [],
})
})

test("at least one unsupported extension", () => {
const unsupportedFiles = [...supportedFiles, "file.unsupported"]
expect(checkFilesExtensions(unsupportedFiles)).toBeFalsy()
const unsupportedFiles = ["file.unsupported"]
const allFiles = [...supportedFiles, ...unsupportedFiles]
expect(checkFilesExtensions(allFiles)).toEqual({
validFiles: supportedFiles,
invalidFiles: unsupportedFiles,
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@

import { eligibleFormat } from "App/files-manager/constants/eligible-format.constant"

export const checkFilesExtensions = (filesPaths: string[]): boolean => {
return filesPaths.every((filePath) => {
return eligibleFormat.includes(
(filePath.split(".").pop() ?? "").toLocaleLowerCase()
)
})
export const checkFilesExtensions = (
filesPaths: string[]
): { validFiles: string[]; invalidFiles: string[] } => {
const isPathEligible = (path: string) =>
eligibleFormat.includes((path.split(".").pop() ?? "").toLocaleLowerCase())
const validFiles = filesPaths.filter((filePath) => isPathEligible(filePath))
const invalidFiles = filesPaths.filter(
(filePath) => !isPathEligible(filePath)
)

return { validFiles, invalidFiles }
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ export interface FilesManagerState {
uploadBlocked: boolean
uploadPendingFiles: string[]
duplicatedFiles: string[]
invalidFiles: string[]
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
setDuplicatedFiles,
resetUploadingStateAfterSuccess,
resetFiles,
setInvalidFiles,
} from "App/files-manager/actions"
import { changeLocation } from "App/core/actions"
import { FilesManagerState } from "App/files-manager/reducers/files-manager.interface"
Expand All @@ -42,6 +43,7 @@ export const initialState: FilesManagerState = {
error: null,
uploadPendingFiles: [],
duplicatedFiles: [],
invalidFiles: [],
}

export const filesManagerReducer = createReducer<FilesManagerState>(
Expand Down Expand Up @@ -173,6 +175,7 @@ export const filesManagerReducer = createReducer<FilesManagerState>(
uploadingFileCount: 0,
uploadBlocked: false,
duplicatedFiles: [],
invalidFiles: [],
}
})
.addCase(resetUploadingStateAfterSuccess, (state) => {
Expand Down Expand Up @@ -203,6 +206,9 @@ export const filesManagerReducer = createReducer<FilesManagerState>(
.addCase(setDuplicatedFiles, (state, action) => {
state.duplicatedFiles = action.payload
})
.addCase(setInvalidFiles, (state, action) => {
state.invalidFiles = action.payload
})
.addCase(resetFiles, (state, _) => {
state.files = null
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/

import { createSelector } from "@reduxjs/toolkit"
import { getFilesManager } from "App/files-manager/selectors/get-files-manager.selector"

export const getInvalidFiles = createSelector(
getFilesManager,
(filesManager): string[] => {
return filesManager.invalidFiles
}
)

0 comments on commit 06aa8d0

Please sign in to comment.