Skip to content

Commit

Permalink
Fixed Bug 54884 - Client.Files. Removed the possibility of simultaneo…
Browse files Browse the repository at this point in the history
…us operations with files.
gopienkonikita committed Jan 18, 2022

Verified

This commit was signed with the committer’s verified signature.
fiji-flo Florian Dieminger
1 parent 21f3c39 commit aea69a3
Showing 6 changed files with 190 additions and 84 deletions.
Original file line number Diff line number Diff line change
@@ -436,21 +436,21 @@ class TreeFolders extends React.Component {
const {
selectedKeys,
isLoading,
setIsLoading,
onSelect,
dragging,
expandedKeys,
expandedPanelKeys,
treeFolders,
data,
disabled,
} = this.props;

return (
<StyledTreeMenu
className="files-tree-menu"
checkable={false}
draggable={dragging}
disabled={isLoading}
disabled={isLoading || disabled}
multiple={false}
showIcon
switcherIcon={this.switcherIcon}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useState } from "react";
import { withRouter } from "react-router";
import ModalDialogContainer from "../ModalDialogContainer";
import ModalDialog from "@appserver/components/modal-dialog";
import RadioButtonGroup from "@appserver/components/radio-button-group";
import Button from "@appserver/components/button";
@@ -9,6 +8,26 @@ import { withTranslation } from "react-i18next";
import { inject, observer } from "mobx-react";
import { ConflictResolveType } from "@appserver/common/constants";
import toastr from "studio/toastr";
import styled from "styled-components";

const StyledModalDialog = styled(ModalDialog)`
.conflict-resolve-dialog-text {
padding-bottom: 8px;
}
.conflict-resolve-radio-button {
svg {
overflow: visible;
}
}
.modal-dialog-aside-footer {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
width: 90%;
}
`;

const ConflictResolveDialog = (props) => {
const {
@@ -21,6 +40,8 @@ const ConflictResolveDialog = (props) => {
itemOperationToFolder,
activeFiles,
setActiveFiles,
setMoveToPanelVisible,
setThirdPartyMoveDialogVisible,
} = props;

const {
@@ -37,6 +58,11 @@ const ConflictResolveDialog = (props) => {

const onSelectResolveType = (e) => setResolveType(e.target.value);
const onClose = () => setConflictResolveDialogVisible(false);
const onClosePanels = () => {
setConflictResolveDialogVisible(false);
setMoveToPanelVisible(false);
setThirdPartyMoveDialogVisible(false);
};
const onCloseDialog = () => {
let newActiveFiles = activeFiles;

@@ -75,7 +101,7 @@ const ConflictResolveDialog = (props) => {
}

setActiveFiles(newActiveFiles);
if (!folderIds.length && !newFileIds.length) return onClose();
if (!folderIds.length && !newFileIds.length) return onClosePanels();

const data = {
destFolderId,
@@ -87,7 +113,7 @@ const ConflictResolveDialog = (props) => {
translations,
};

onClose();
onClosePanels();
try {
await itemOperationToFolder(data);
} catch (error) {
@@ -131,10 +157,11 @@ const ConflictResolveDialog = (props) => {
const file = items[0].title;

return (
<ModalDialogContainer
<StyledModalDialog
isLoading={!tReady}
visible={visible}
onClose={onCloseDialog}
displayType="aside"
>
<ModalDialog.Header>{t("ConflictResolveTitle")}</ModalDialog.Header>
<ModalDialog.Body>
@@ -167,6 +194,7 @@ const ConflictResolveDialog = (props) => {
label={t("Common:OKButton")}
size="medium"
primary
scale
onClick={onAcceptType}
//isLoading={isLoading}
/>
@@ -175,11 +203,12 @@ const ConflictResolveDialog = (props) => {
key="CancelButton"
label={t("Common:CancelButton")}
size="medium"
scale
onClick={onCloseDialog}
//isLoading={isLoading}
/>
</ModalDialog.Footer>
</ModalDialogContainer>
</StyledModalDialog>
);
};

@@ -189,6 +218,8 @@ export default inject(({ dialogsStore, uploadDataStore, filesStore }) => {
setConflictResolveDialogVisible,
conflictResolveDialogData,
conflictResolveDialogItems: items,
setMoveToPanelVisible,
setThirdPartyMoveDialogVisible,
} = dialogsStore;

const { itemOperationToFolder } = uploadDataStore;
@@ -202,6 +233,8 @@ export default inject(({ dialogsStore, uploadDataStore, filesStore }) => {
itemOperationToFolder,
activeFiles,
setActiveFiles,
setMoveToPanelVisible,
setThirdPartyMoveDialogVisible,
};
})(
withRouter(
Original file line number Diff line number Diff line change
@@ -147,16 +147,6 @@ const ModalDialogContainer = styled(ModalDialog)`
width: 90%;
}
}
.conflict-resolve-dialog-text {
padding-bottom: 8px;
}
.conflict-resolve-radio-button {
svg {
overflow: visible;
}
}
`;

export default ModalDialogContainer;
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import React from "react";
import React, { useState } from "react";
import styled from "styled-components";

import { withTranslation } from "react-i18next";
import ModalDialog from "@appserver/components/modal-dialog";
import Text from "@appserver/components/text";
import Button from "@appserver/components/button";
import { inject, observer } from "mobx-react";
import toastr from "@appserver/components/toast/toastr";

const StyledOperationDialog = styled(ModalDialog)`
.operation-button {
margin-right: 8px;
}
.modal-dialog-aside-footer {
display: flex;
width: 90%;
}
`;

const PureThirdPartyMoveContainer = ({
@@ -21,13 +27,16 @@ const PureThirdPartyMoveContainer = ({
selection,
destFolderId,
setDestFolderId,
checkOperationConflict,
checkFileConflicts,
setConflictDialogData,
setThirdPartyMoveDialogVisible,
setBufferSelection,
}) => {
const zIndex = 310;
const deleteAfter = false; // TODO: get from settings

const [isLoading, setIsLoading] = useState(false);

const onClose = () => {
setBufferSelection(null);
setDestFolderId(false);
@@ -59,8 +68,22 @@ const PureThirdPartyMoveContainer = ({
},
};

checkOperationConflict(data);
onClose();
setIsLoading(true);
checkFileConflicts(destFolderId, folderIds, fileIds)
.then(async (conflicts) => {
if (conflicts.length) {
setConflictDialogData(conflicts, data);
setIsLoading(false);
} else {
setIsLoading(false);
onClose();
await itemOperationToFolder(data);
}
})
.catch((err) => toastr.error(err))
.finally(() => {
setIsLoading(false);
});
};

return (
@@ -69,6 +92,7 @@ const PureThirdPartyMoveContainer = ({
visible={visible}
zIndex={zIndex}
onClose={onClose}
displayType="aside"
>
<ModalDialog.Header>{t("MoveConfirmation")}</ModalDialog.Header>
<ModalDialog.Body>
@@ -82,21 +106,30 @@ const PureThirdPartyMoveContainer = ({
className="operation-button"
label={t("Translations:Move")}
size="big"
scale
primary
onClick={startOperation}
isLoading={isLoading}
isDisabled={isLoading}
/>
<Button
data-copy="copy"
className="operation-button"
label={t("Translations:Copy")}
size="big"
scale
onClick={startOperation}
isLoading={isLoading}
isDisabled={isLoading}
/>
<Button
className="operation-button"
label={t("Common:CancelButton")}
size="big"
scale
onClick={onClose}
isLoading={isLoading}
isDisabled={isLoading}
/>
</ModalDialog.Footer>
</StyledOperationDialog>
@@ -111,7 +144,7 @@ export default inject(({ filesStore, dialogsStore, filesActionsStore }) => {
setDestFolderId,
} = dialogsStore;
const { bufferSelection, setBufferSelection } = filesStore;
const { checkOperationConflict } = filesActionsStore;
const { checkFileConflicts, setConflictDialogData } = filesActionsStore;

const selection = filesStore.selection.length
? filesStore.selection
@@ -123,9 +156,10 @@ export default inject(({ filesStore, dialogsStore, filesActionsStore }) => {
destFolderId,
setDestFolderId,
provider: selection[0].providerKey,
checkOperationConflict,
checkFileConflicts,
selection,
setBufferSelection,
setConflictDialogData,
};
})(
withTranslation(["ThirdPartyMoveDialog", "Common", "Translations"])(
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import React from "react";
import React, { useState } from "react";
import { withRouter } from "react-router";
import ModalDialog from "@appserver/components/modal-dialog";
import { withTranslation } from "react-i18next";
import { StyledAsidePanel } from "../StyledPanels";
import TreeFolders from "../../Article/Body/TreeFolders";
import { inject, observer } from "mobx-react";
import toastr from "studio/toastr";
import Button from "@appserver/components/button";
import styled from "styled-components";

const StyledModalDialog = styled(ModalDialog)`
.modal-dialog-aside-footer {
width: 90%;
}
`;

const OperationsPanelComponent = (props) => {
const {
@@ -23,7 +30,9 @@ const OperationsPanelComponent = (props) => {
setCopyPanelVisible,
setExpandedPanelKeys,
setMoveToPanelVisible,
checkOperationConflict,
setConflictDialogData,
itemOperationToFolder,
checkFileConflicts,
setThirdPartyMoveDialogVisible,
} = props;

@@ -32,36 +41,40 @@ const OperationsPanelComponent = (props) => {

const expandedKeys = props.expandedKeys.map((item) => item.toString());

const [isLoading, setIsLoading] = useState(false);
const [selectedFolder, setSelectedFolder] = useState(null);
const [folderTitle, setFolderTitle] = useState(null);
const [providerKey, setProviderKey] = useState(null);

const onClose = () => {
isCopy ? setCopyPanelVisible(false) : setMoveToPanelVisible(false);
setExpandedPanelKeys(null);
};

const onSelect = (folder, treeNode) => {
const folderTitle = treeNode.node.props.title;
const destFolderId = isNaN(+folder[0]) ? folder[0] : +folder[0];

if (currentFolderId === destFolderId) {
return onClose();
const onSubmit = () => {
if (currentFolderId === selectedFolder) {
return;
}

if (isCopy) {
startOperation(isCopy, destFolderId, folderTitle);
startOperation(isCopy, selectedFolder, folderTitle);
} else {
if (
provider &&
treeNode.node.props.providerKey !== provider.providerKey
) {
setDestFolderId(destFolderId);
if (provider && providerKey !== provider.providerKey) {
setDestFolderId(selectedFolder);
setThirdPartyMoveDialogVisible(true);
} else {
startOperation(isCopy, destFolderId, folderTitle);
startOperation(isCopy, selectedFolder, folderTitle);
}
}
onClose();
};

const startOperation = (isCopy, destFolderId, folderTitle) => {
const onSelect = (folder, treeNode) => {
setProviderKey(treeNode.node.props.providerKey);
setFolderTitle(treeNode.node.props.title);
setSelectedFolder(isNaN(+folder[0]) ? folder[0] : +folder[0]);
};

const startOperation = async (isCopy, destFolderId, folderTitle) => {
const isProviderFolder = selection.find((x) => !x.providerKey);
const items =
isProviderFolder && !isCopy
@@ -83,7 +96,7 @@ const OperationsPanelComponent = (props) => {

if (!folderIds.length && !fileIds.length) return;

checkOperationConflict({
const operationData = {
destFolderId,
folderIds,
fileIds,
@@ -94,37 +107,64 @@ const OperationsPanelComponent = (props) => {
copy: t("Translations:CopyOperation"),
move: t("Translations:MoveToOperation"),
},
});
};

setIsLoading(true);
checkFileConflicts(destFolderId, folderIds, fileIds).then(
async (conflicts) => {
if (conflicts.length) {
setConflictDialogData(conflicts, operationData);
setIsLoading(false);
} else {
setIsLoading(false);
onClose();
await itemOperationToFolder(operationData);
}
}
);
};

//console.log("Operations panel render");
return (
<StyledAsidePanel visible={visible}>
<ModalDialog
visible={visible}
displayType="aside"
zIndex={zIndex}
onClose={onClose}
isLoading={!tReady}
>
<ModalDialog.Header>
{isRecycleBin
? t("Translations:Restore")
: isCopy
? t("Translations:Copy")
: t("Translations:Move")}
</ModalDialog.Header>
<ModalDialog.Body>
<TreeFolders
expandedPanelKeys={expandedKeys}
data={operationsFolders}
filter={filter}
onSelect={onSelect}
needUpdate={false}
/>
</ModalDialog.Body>
</ModalDialog>
</StyledAsidePanel>
<StyledModalDialog
visible={visible}
displayType="aside"
zIndex={zIndex}
onClose={onClose}
isLoading={!tReady}
className="operations-panel-dialog"
>
<ModalDialog.Header>
{isRecycleBin
? t("Translations:Restore")
: isCopy
? t("Translations:Copy")
: t("Translations:Move")}
</ModalDialog.Header>
<ModalDialog.Body>
<TreeFolders
expandedPanelKeys={expandedKeys}
data={operationsFolders}
filter={filter}
onSelect={onSelect}
needUpdate={false}
disabled={isLoading || isLoading}
selectedKeys={[selectedFolder + ""]}
/>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
scale
key="OkButton"
label={t("Translations:Move")}
size="medium"
primary
onClick={onSubmit}
isLoading={isLoading}
isDisabled={!selectedFolder || isLoading}
/>
</ModalDialog.Footer>
</StyledModalDialog>
);
};

@@ -139,6 +179,7 @@ export default inject(
selectedFolderStore,
dialogsStore,
filesActionsStore,
uploadDataStore,
}) => {
const { filter, selection, bufferSelection } = filesStore;
const {
@@ -147,7 +188,8 @@ export default inject(
setExpandedPanelKeys,
expandedPanelKeys,
} = treeFoldersStore;
const { checkOperationConflict } = filesActionsStore;
const { setConflictDialogData, checkFileConflicts } = filesActionsStore;
const { itemOperationToFolder } = uploadDataStore;

const {
moveToPanelVisible,
@@ -178,8 +220,10 @@ export default inject(
setMoveToPanelVisible,
setDestFolderId,
setThirdPartyMoveDialogVisible,
checkOperationConflict,
setConflictDialogData,
setExpandedPanelKeys,
itemOperationToFolder,
checkFileConflicts,
};
}
)(withRouter(observer(OperationsPanel)));
31 changes: 18 additions & 13 deletions products/ASC.Files/Client/src/store/FilesActionsStore.js
Original file line number Diff line number Diff line change
@@ -150,7 +150,7 @@ class FilesActionStore {
this.updateCurrentFolder(fileIds, folderIds);
if (isRecycleBinFolder) {
return toastr.success(translations.deleteFromTrash);
}
}

if (selection.length > 1) {
return toastr.success(translations.deleteSelectedElem);
@@ -207,7 +207,8 @@ class FilesActionStore {
};
await this.uploadDataStore.loopFilesOperations(data, pbData);
toastr.success(translations.successOperation);
this.updateCurrentFolder(fileIds, folderIds); });
this.updateCurrentFolder(fileIds, folderIds);
});
} catch (err) {
clearActiveOperations(fileIds, folderIds);
setSecondaryProgressBarData({
@@ -662,13 +663,17 @@ class FilesActionStore {
this.checkOperationConflict(operationData);
};

checkFileConflicts = (destFolderId, folderIds, fileIds) =>
checkFileConflicts(destFolderId, folderIds, fileIds);

setConflictDialogData = (conflicts, operationData) => {
this.dialogsStore.setConflictResolveDialogItems(conflicts);
this.dialogsStore.setConflictResolveDialogData(operationData);
this.dialogsStore.setConflictResolveDialogVisible(true);
};

checkOperationConflict = async (operationData) => {
const { destFolderId, folderIds, fileIds } = operationData;
const {
setConflictResolveDialogData,
setConflictResolveDialogVisible,
setConflictResolveDialogItems,
} = this.dialogsStore;
const { setBufferSelection, addActiveItems } = this.filesStore;

addActiveItems(fileIds);
@@ -677,16 +682,18 @@ class FilesActionStore {
let conflicts;

try {
conflicts = await checkFileConflicts(destFolderId, folderIds, fileIds);
conflicts = await this.checkFileConflicts(
destFolderId,
folderIds,
fileIds
);
} catch (err) {
setBufferSelection(null);
return toastr.error(err.message ? err.message : err);
}

if (conflicts.length) {
setConflictResolveDialogItems(conflicts);
setConflictResolveDialogData(operationData);
setConflictResolveDialogVisible(true);
this.setConflictDialogData(conflicts, operationData);
} else {
try {
await this.uploadDataStore.itemOperationToFolder(operationData);
@@ -695,8 +702,6 @@ class FilesActionStore {
return toastr.error(err.message ? err.message : err);
}
}

setBufferSelection(null);
};

isAvailableOption = (option) => {

0 comments on commit aea69a3

Please sign in to comment.