Merge pull request #685 from ONLYOFFICE/feature/group-context-menu

Feature/group context menu
This commit is contained in:
Ilya Oleshko 2022-06-01 18:35:41 +03:00 committed by GitHub
commit 9ba8378cae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 187 additions and 24 deletions

View File

@ -16,7 +16,6 @@ import { StyledFilterInput, StyledSearchInput } from "./StyledFilterInput";
const FilterInput = React.memo(
({
t,
sectionWidth,
getFilterData,
getSortData,
getViewSettingsData,

View File

@ -70,7 +70,7 @@ class Row extends React.Component {
};
const onContextMenu = (e) => {
rowContextClick && rowContextClick();
rowContextClick && rowContextClick(e.button === 2);
if (!this.cm.current.menuRef.current) {
this.row.current.click(e); //TODO: need fix context menu to global
}

View File

@ -23,7 +23,7 @@ const TableRow = (props) => {
const row = useRef();
const onContextMenu = (e) => {
fileContextClick && fileContextClick();
fileContextClick && fileContextClick(e.button === 2);
if (cm.current && !cm.current.menuRef.current) {
row.current.click(e);
}

View File

@ -21,11 +21,12 @@ export default function withFileActions(WrappedFileItem) {
id !== -1 && onSelectItem({ id, isFolder });
};
onFileContextClick = () => {
onFileContextClick = (isSingleFile) => {
const { onSelectItem } = this.props;
const { id, isFolder } = this.props.item;
id !== -1 && onSelectItem({ id, isFolder }, true);
id !== -1 &&
onSelectItem({ id, isFolder }, false, !isSingleFile || isMobile);
};
onHideContextMenu = () => {

View File

@ -7,14 +7,6 @@ import CustomScrollbarsVirtualList from "@appserver/components/scrollbar";
import { StyledGridWrapper, StyledTileContainer } from "../StyledTileView";
class TileContainer extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
contextOptions: [],
};
}
renderTile = memo(({ data, index, style }) => {
return <div style={style}>{data[index]}</div>;
}, areEqual);

View File

@ -427,7 +427,7 @@ class Tile extends React.PureComponent {
};
const onContextMenu = (e) => {
tileContextClick && tileContextClick();
tileContextClick && tileContextClick(e.button === 2);
if (!this.cm.current.menuRef.current) {
this.tile.current.click(e); //TODO: need fix context menu to global
}

View File

@ -630,7 +630,157 @@ class ContextOptionsStore {
return options;
};
getGroupContextOptions = (t) => {
const { selection } = this.filesStore;
const { setDeleteDialogVisible } = this.dialogsStore;
const { isRecycleBinFolder } = this.treeFoldersStore;
const downloadAs =
selection.findIndex((k) => k.contextOptions.includes("download-as")) !==
-1;
const sharingItems = selection.filter(
(k) => k.contextOptions.includes("sharing-settings") && k.canShare
).length;
const favoriteItems = selection.filter((k) =>
k.contextOptions.includes("mark-as-favorite")
);
const moveItems = selection.filter((k) =>
k.contextOptions.includes("move-to")
).length;
const copyItems = selection.filter((k) =>
k.contextOptions.includes("copy-to")
).length;
const restoreItems = selection.filter((k) =>
k.contextOptions.includes("restore")
).length;
const removeFromFavoriteItems = selection.filter((k) =>
k.contextOptions.includes("remove-from-favorites")
);
const deleteItems = selection.filter((k) =>
k.contextOptions.includes("delete")
).length;
const isRootThirdPartyFolder = selection.some(
(x) => x.providerKey && x.id === x.rootFolderId
);
const favoriteItemsIds = favoriteItems.map((item) => item.id);
const removeFromFavoriteItemsIds = removeFromFavoriteItems.map(
(item) => item.id
);
const options = [
{
key: "sharing-settings",
label: t("SharingSettings"),
icon: "/static/images/share.react.svg",
onClick: this.onClickShare,
disabled: !sharingItems,
},
{
key: "separator0",
isSeparator: true,
disabled: !sharingItems,
},
{
key: "mark-as-favorite",
label: t("MarkAsFavorite"),
icon: "images/favorites.react.svg",
onClick: (e) => this.onClickFavorite(e, favoriteItemsIds, t),
disabled: !favoriteItems.length,
"data-action": "mark",
action: "mark",
},
{
key: "remove-from-favorites",
label: t("RemoveFromFavorites"),
icon: "images/favorites.react.svg",
onClick: (e) => this.onClickFavorite(e, removeFromFavoriteItemsIds, t),
disabled: favoriteItems.length || !removeFromFavoriteItems.length,
"data-action": "remove",
action: "remove",
},
{
key: "download",
label: t("Common:Download"),
icon: "images/download.react.svg",
onClick: () =>
this.filesActionsStore
.downloadAction(t("Translations:ArchivingData"))
.catch((err) => toastr.error(err)),
disabled: false,
},
{
key: "download-as",
label: t("Translations:DownloadAs"),
icon: "images/download-as.react.svg",
onClick: this.onClickDownloadAs,
disabled: !downloadAs,
},
{
key: "move-to",
label: t("MoveTo"),
icon: "images/move.react.svg",
onClick: this.onMoveAction,
disabled: isRecycleBinFolder || !moveItems,
},
{
key: "copy-to",
label: t("Translations:Copy"),
icon: "/static/images/copy.react.svg",
onClick: this.onCopyAction,
disabled: isRecycleBinFolder || !copyItems,
},
{
key: "restore",
label: t("Common:Restore"),
icon: "images/move.react.svg",
onClick: this.onMoveAction,
disabled: !isRecycleBinFolder || !restoreItems,
},
{
key: "separator1",
isSeparator: true,
disabled: !deleteItems || isRootThirdPartyFolder,
},
{
key: "delete",
label: t("Common:Delete"),
icon: "images/trash.react.svg",
onClick: () => {
if (this.settingsStore.confirmDelete) {
setDeleteDialogVisible(true);
} else {
const translations = {
deleteOperation: t("Translations:DeleteOperation"),
deleteFromTrash: t("Translations:DeleteFromTrash"),
deleteSelectedElem: t("Translations:DeleteSelectedElem"),
FileRemoved: t("Home:FileRemoved"),
FolderRemoved: t("Home:FolderRemoved"),
};
this.filesActionsStore
.deleteAction(translations)
.catch((err) => toastr.error(err));
}
},
disabled: !deleteItems || isRootThirdPartyFolder,
},
];
return options;
};
getModel = (item, t) => {
const { selection } = this.filesStore;
const { type, id, extension } = this.filesStore.fileActionStore;
const { fileExst, contextOptions } = item;
@ -638,7 +788,9 @@ class ContextOptionsStore {
const contextOptionsProps =
!isEdit && contextOptions && contextOptions.length > 0
? this.getFilesContextOptions(item, t)
? selection.length > 1
? this.getGroupContextOptions(t)
: this.getFilesContextOptions(item, t)
: [];
return contextOptionsProps;

View File

@ -185,7 +185,6 @@ class FilesActionStore {
const { addActiveItems } = this.filesStore;
const {
secondaryProgressDataStore,
loopFilesOperations,
clearActiveOperations,
} = this.uploadDataStore;
const {
@ -472,18 +471,18 @@ class FilesActionStore {
}
};
onSelectItem = ({ id, isFolder }, isBuffer = false) => {
onSelectItem = ({ id, isFolder }, isBuffer = false, isSingleFile) => {
const {
setBufferSelection,
selected,
setSelected,
selection,
setSelection,
setHotkeyCaretStart,
setHotkeyCaret,
setEnabledHotkeys,
filesList,
} = this.filesStore;
/* selected === "close" && */ setSelected("none");
if (!id) return;
@ -495,8 +494,16 @@ class FilesActionStore {
if (isBuffer) {
setBufferSelection(item);
setEnabledHotkeys(false);
setSelected("none");
} else {
setSelection([item]);
const isSelected = selection.findIndex(
(f) => f.id === id && f.isFolder === isFolder
);
if (isSelected === -1 || isSingleFile) {
setSelected("none");
setSelection([item]);
}
setHotkeyCaret(null);
setHotkeyCaretStart(null);
}
@ -636,28 +643,40 @@ class FilesActionStore {
);
};
getFilesInfo = (items) => {
const requests = [];
let i = items.length;
while (i !== 0) {
requests.push(this.filesStore.getFileInfo(items[i - 1]));
i--;
}
return Promise.all(requests);
};
setFavoriteAction = (action, id) => {
const {
markItemAsFavorite,
removeItemFromFavorite,
fetchFavoritesFolder,
getFileInfo,
setSelected,
} = this.filesStore;
const items = Array.isArray(id) ? id : [id];
//let data = selection.map(item => item.id)
switch (action) {
case "mark":
return markItemAsFavorite([id]).then(() => getFileInfo(id));
return markItemAsFavorite(items)
.then(() => {
return this.getFilesInfo(items);
})
.then(() => setSelected("close"));
case "remove":
return removeItemFromFavorite(items)
.then(() => {
return this.treeFoldersStore.isFavoritesFolder
? fetchFavoritesFolder(this.selectedFolderStore.id)
: getFileInfo(id);
: this.getFilesInfo(items);
})
.then(() => setSelected("close"));
default:

View File

@ -480,7 +480,7 @@ class FilesStore {
}
this.selected = selected;
const files = this.files.concat(this.folders);
const files = this.filesList;
this.selection = this.getFilesBySelected(files, selected);
};