Merge branch 'hotfix/v2.6.1' into bugfix/Bug69601
This commit is contained in:
commit
df02095c37
@ -117,6 +117,7 @@
|
|||||||
"OpenLocation": "Open location",
|
"OpenLocation": "Open location",
|
||||||
"PasswordAccess": "Password access",
|
"PasswordAccess": "Password access",
|
||||||
"PasswordLink": "Add a password to protect your link.",
|
"PasswordLink": "Add a password to protect your link.",
|
||||||
|
"PasswordProtectedFiles": "Please <0>enter a password</0> for the protected files to continue",
|
||||||
"PasswordSuccessfullyCopied": "Password successfully copied",
|
"PasswordSuccessfullyCopied": "Password successfully copied",
|
||||||
"Pin": "Pin",
|
"Pin": "Pin",
|
||||||
"PinToTop": "Pin to top",
|
"PinToTop": "Pin to top",
|
||||||
|
@ -62,21 +62,14 @@ export default function withFileActions(WrappedFileItem) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onDropZoneUpload = (files, uploadToFolder) => {
|
onDropZoneUpload = (files, uploadToFolder) => {
|
||||||
const { t, dragging, setDragging, startUpload, uploadEmptyFolders } =
|
const { t, dragging, setDragging, startUpload, createFoldersTree } =
|
||||||
this.props;
|
this.props;
|
||||||
|
|
||||||
dragging && setDragging(false);
|
dragging && setDragging(false);
|
||||||
|
|
||||||
const emptyFolders = files.filter((f) => f.isEmptyDirectory);
|
createFoldersTree(files, uploadToFolder).then((f) => {
|
||||||
|
if (f.length > 0) startUpload(f, null, t);
|
||||||
if (emptyFolders.length > 0) {
|
});
|
||||||
uploadEmptyFolders(emptyFolders, uploadToFolder).then(() => {
|
|
||||||
const onlyFiles = files.filter((f) => !f.isEmptyDirectory);
|
|
||||||
if (onlyFiles.length > 0) startUpload(onlyFiles, uploadToFolder, t);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
startUpload(files, uploadToFolder, t);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onDrop = (items) => {
|
onDrop = (items) => {
|
||||||
@ -371,7 +364,7 @@ export default function withFileActions(WrappedFileItem) {
|
|||||||
onSelectItem,
|
onSelectItem,
|
||||||
//setNewBadgeCount,
|
//setNewBadgeCount,
|
||||||
openFileAction,
|
openFileAction,
|
||||||
uploadEmptyFolders,
|
createFoldersTree,
|
||||||
} = filesActionsStore;
|
} = filesActionsStore;
|
||||||
const { setSharingPanelVisible } = dialogsStore;
|
const { setSharingPanelVisible } = dialogsStore;
|
||||||
const {
|
const {
|
||||||
@ -475,7 +468,7 @@ export default function withFileActions(WrappedFileItem) {
|
|||||||
dragging,
|
dragging,
|
||||||
setDragging,
|
setDragging,
|
||||||
startUpload,
|
startUpload,
|
||||||
uploadEmptyFolders,
|
createFoldersTree,
|
||||||
draggable,
|
draggable,
|
||||||
setTooltipPosition,
|
setTooltipPosition,
|
||||||
setStartDrag,
|
setStartDrag,
|
||||||
|
@ -68,7 +68,7 @@ const Item = ({
|
|||||||
onBadgeClick,
|
onBadgeClick,
|
||||||
showDragItems,
|
showDragItems,
|
||||||
startUpload,
|
startUpload,
|
||||||
uploadEmptyFolders,
|
createFoldersTree,
|
||||||
setDragging,
|
setDragging,
|
||||||
showBadge,
|
showBadge,
|
||||||
labelBadge,
|
labelBadge,
|
||||||
@ -86,18 +86,12 @@ const Item = ({
|
|||||||
const onDropZoneUpload = React.useCallback(
|
const onDropZoneUpload = React.useCallback(
|
||||||
(files, uploadToFolder) => {
|
(files, uploadToFolder) => {
|
||||||
dragging && setDragging(false);
|
dragging && setDragging(false);
|
||||||
const emptyFolders = files.filter((f) => f.isEmptyDirectory);
|
|
||||||
|
|
||||||
if (emptyFolders.length > 0) {
|
createFoldersTree(files, uploadToFolder).then((f) => {
|
||||||
uploadEmptyFolders(emptyFolders, uploadToFolder).then(() => {
|
if (f.length > 0) startUpload(f, null, t);
|
||||||
const onlyFiles = files.filter((f) => !f.isEmptyDirectory);
|
});
|
||||||
if (onlyFiles.length > 0) startUpload(onlyFiles, uploadToFolder, t);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
startUpload(files, uploadToFolder, t);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[t, dragging, setDragging, startUpload, uploadEmptyFolders],
|
[t, dragging, setDragging, startUpload, createFoldersTree],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onDrop = React.useCallback(
|
const onDrop = React.useCallback(
|
||||||
@ -193,7 +187,7 @@ const Items = ({
|
|||||||
dragging,
|
dragging,
|
||||||
setDragging,
|
setDragging,
|
||||||
startUpload,
|
startUpload,
|
||||||
uploadEmptyFolders,
|
createFoldersTree,
|
||||||
isVisitor,
|
isVisitor,
|
||||||
isCollaborator,
|
isCollaborator,
|
||||||
isAdmin,
|
isAdmin,
|
||||||
@ -326,7 +320,7 @@ const Items = ({
|
|||||||
t={t}
|
t={t}
|
||||||
setDragging={setDragging}
|
setDragging={setDragging}
|
||||||
startUpload={startUpload}
|
startUpload={startUpload}
|
||||||
uploadEmptyFolders={uploadEmptyFolders}
|
createFoldersTree={createFoldersTree}
|
||||||
item={item}
|
item={item}
|
||||||
setBufferSelection={setBufferSelection}
|
setBufferSelection={setBufferSelection}
|
||||||
dragging={dragging}
|
dragging={dragging}
|
||||||
@ -388,7 +382,7 @@ const Items = ({
|
|||||||
showText,
|
showText,
|
||||||
setDragging,
|
setDragging,
|
||||||
startUpload,
|
startUpload,
|
||||||
uploadEmptyFolders,
|
createFoldersTree,
|
||||||
trashIsEmpty,
|
trashIsEmpty,
|
||||||
isAdmin,
|
isAdmin,
|
||||||
isVisitor,
|
isVisitor,
|
||||||
@ -449,7 +443,7 @@ export default inject(
|
|||||||
const { id, access: folderAccess } = selectedFolderStore;
|
const { id, access: folderAccess } = selectedFolderStore;
|
||||||
const {
|
const {
|
||||||
moveDragItems,
|
moveDragItems,
|
||||||
uploadEmptyFolders,
|
createFoldersTree,
|
||||||
deleteAction,
|
deleteAction,
|
||||||
emptyTrashInProgress,
|
emptyTrashInProgress,
|
||||||
} = filesActionsStore;
|
} = filesActionsStore;
|
||||||
@ -478,7 +472,7 @@ export default inject(
|
|||||||
setBufferSelection,
|
setBufferSelection,
|
||||||
deleteAction,
|
deleteAction,
|
||||||
startUpload,
|
startUpload,
|
||||||
uploadEmptyFolders,
|
createFoldersTree,
|
||||||
setEmptyTrashDialogVisible,
|
setEmptyTrashDialogVisible,
|
||||||
trashIsEmpty,
|
trashIsEmpty,
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ import { resendInvitesAgain } from "@docspace/shared/api/people";
|
|||||||
import { getCorrectFourValuesStyle } from "@docspace/shared/utils";
|
import { getCorrectFourValuesStyle } from "@docspace/shared/utils";
|
||||||
import { ArticleButtonLoader } from "@docspace/shared/skeletons/article";
|
import { ArticleButtonLoader } from "@docspace/shared/skeletons/article";
|
||||||
import { isMobile, isTablet } from "react-device-detect";
|
import { isMobile, isTablet } from "react-device-detect";
|
||||||
|
import getFilesFromEvent from "@docspace/shared/components/drag-and-drop/get-files-from-event";
|
||||||
|
|
||||||
const StyledButton = styled(Button)`
|
const StyledButton = styled(Button)`
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@ -180,6 +181,7 @@ const ArticleMainButtonContent = (props) => {
|
|||||||
|
|
||||||
parentRoomType,
|
parentRoomType,
|
||||||
isFolder,
|
isFolder,
|
||||||
|
createFoldersTree,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -239,8 +241,12 @@ const ArticleMainButtonContent = (props) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const onFileChange = React.useCallback(
|
const onFileChange = React.useCallback(
|
||||||
(e) => {
|
async (e) => {
|
||||||
startUpload(e.target.files, null, t);
|
const files = await getFilesFromEvent(e);
|
||||||
|
|
||||||
|
createFoldersTree(files).then((f) => {
|
||||||
|
if (f.length > 0) startUpload(f, null, t);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[startUpload, t],
|
[startUpload, t],
|
||||||
);
|
);
|
||||||
@ -249,7 +255,7 @@ const ArticleMainButtonContent = (props) => {
|
|||||||
if (isPrivacy) {
|
if (isPrivacy) {
|
||||||
encryptionUploadDialog((encryptedFile, encrypted) => {
|
encryptionUploadDialog((encryptedFile, encrypted) => {
|
||||||
encryptedFile.encrypted = encrypted;
|
encryptedFile.encrypted = encrypted;
|
||||||
startUpload([encryptedFile], null, t);
|
startUpload([encryptedFile], null, t); // TODO: createFoldersTree
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
inputFilesElement.current.click();
|
inputFilesElement.current.click();
|
||||||
@ -901,6 +907,7 @@ export default inject(
|
|||||||
versionHistoryStore,
|
versionHistoryStore,
|
||||||
userStore,
|
userStore,
|
||||||
currentTariffStatusStore,
|
currentTariffStatusStore,
|
||||||
|
filesActionsStore,
|
||||||
}) => {
|
}) => {
|
||||||
const { showArticleLoader } = clientLoadingStore;
|
const { showArticleLoader } = clientLoadingStore;
|
||||||
const { mainButtonMobileVisible } = filesStore;
|
const { mainButtonMobileVisible } = filesStore;
|
||||||
@ -945,6 +952,8 @@ export default inject(
|
|||||||
|
|
||||||
const { frameConfig, isFrame } = settingsStore;
|
const { frameConfig, isFrame } = settingsStore;
|
||||||
|
|
||||||
|
const { createFoldersTree } = filesActionsStore;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isGracePeriod,
|
isGracePeriod,
|
||||||
setInviteUsersWarningDialogVisible,
|
setInviteUsersWarningDialogVisible,
|
||||||
@ -997,6 +1006,7 @@ export default inject(
|
|||||||
isFolder,
|
isFolder,
|
||||||
selectFileFormRoomDialogVisible,
|
selectFileFormRoomDialogVisible,
|
||||||
setSelectFileFormRoomDialogVisible,
|
setSelectFileFormRoomDialogVisible,
|
||||||
|
createFoldersTree,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(
|
)(
|
||||||
|
@ -38,6 +38,7 @@ import { IconButton } from "@docspace/shared/components/icon-button";
|
|||||||
import RoomsFilter from "@docspace/shared/api/rooms/filter";
|
import RoomsFilter from "@docspace/shared/api/rooms/filter";
|
||||||
|
|
||||||
import { RoomSearchArea } from "@docspace/shared/enums";
|
import { RoomSearchArea } from "@docspace/shared/enums";
|
||||||
|
import { frameCallEvent } from "@docspace/shared/utils/common";
|
||||||
import { getCategoryUrl } from "SRC_DIR/helpers/utils";
|
import { getCategoryUrl } from "SRC_DIR/helpers/utils";
|
||||||
import { CategoryType } from "SRC_DIR/helpers/constants";
|
import { CategoryType } from "SRC_DIR/helpers/constants";
|
||||||
|
|
||||||
@ -60,6 +61,8 @@ const RoomNoAccessContainer = (props) => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
frameCallEvent({ event: "onNoAccess" });
|
||||||
|
|
||||||
const timer = setTimeout(onGoToShared, 5000);
|
const timer = setTimeout(onGoToShared, 5000);
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -88,7 +88,7 @@ const ExternalLinks = ({
|
|||||||
copyLink(link.shareLink);
|
copyLink(link.shareLink);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
!externalLinksVisible ? editLink() : disableLink();
|
!externalLinksVisible ? await editLink() : await disableLink();
|
||||||
}
|
}
|
||||||
onChangeExternalLinksVisible(!externalLinksVisible);
|
onChangeExternalLinksVisible(!externalLinksVisible);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -98,9 +98,10 @@ const ExternalLinks = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const disableLink = () => {
|
const disableLink = async () => {
|
||||||
setInvitationLinks(roomId, "Invite", 0, shareLinks[0].id);
|
shareLinks?.length &&
|
||||||
setShareLinks([]);
|
(await setInvitationLinks(roomId, "Invite", 0, shareLinks[0].id));
|
||||||
|
return setShareLinks([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const editLink = async () => {
|
const editLink = async () => {
|
||||||
@ -120,7 +121,7 @@ const ExternalLinks = ({
|
|||||||
|
|
||||||
copyLink(shareLink);
|
copyLink(shareLink);
|
||||||
setShareLinks([activeLink]);
|
setShareLinks([activeLink]);
|
||||||
setActiveLink(activeLink);
|
return setActiveLink(activeLink);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSelectAccess = async (access) => {
|
const onSelectAccess = async (access) => {
|
||||||
|
@ -54,7 +54,10 @@ export const GreetingContainer = styled.div`
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tooltip {
|
.tooltip {
|
||||||
p {
|
.invitation-text {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,15 +68,13 @@ export const GreetingContainer = styled.div`
|
|||||||
|
|
||||||
.portal-logo {
|
.portal-logo {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
max-width: 386px;
|
||||||
|
height: 44px;
|
||||||
|
margin: 0 auto;
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
height: 26.56px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.injected-svg {
|
|
||||||
height: 26.56px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -485,7 +485,7 @@ const CreateUserForm = (props) => {
|
|||||||
<PortalLogo className="portal-logo" />
|
<PortalLogo className="portal-logo" />
|
||||||
{linkData.type === "LinkInvite" && (
|
{linkData.type === "LinkInvite" && (
|
||||||
<div className="tooltip">
|
<div className="tooltip">
|
||||||
<Text fontSize="16px">
|
<Text fontSize="16px" as="div" className="invitation-text">
|
||||||
{roomName ? (
|
{roomName ? (
|
||||||
<Trans
|
<Trans
|
||||||
t={t}
|
t={t}
|
||||||
|
@ -97,6 +97,12 @@ const StyledForm = styled(Box)`
|
|||||||
.set-app-description {
|
.set-app-description {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
|
|
||||||
|
.portal-logo {
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 386px;
|
||||||
|
height: 44px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.set-app-title {
|
.set-app-title {
|
||||||
|
@ -52,7 +52,7 @@ const useFiles = ({
|
|||||||
dragging,
|
dragging,
|
||||||
setDragging,
|
setDragging,
|
||||||
disableDrag,
|
disableDrag,
|
||||||
uploadEmptyFolders,
|
createFoldersTree,
|
||||||
startUpload,
|
startUpload,
|
||||||
|
|
||||||
fetchFiles,
|
fetchFiles,
|
||||||
@ -118,16 +118,9 @@ const useFiles = ({
|
|||||||
|
|
||||||
if (disableDrag) return;
|
if (disableDrag) return;
|
||||||
|
|
||||||
const emptyFolders = files.filter((f) => f.isEmptyDirectory);
|
createFoldersTree(files, uploadToFolder).then((f) => {
|
||||||
|
if (f.length > 0) startUpload(f, null, t);
|
||||||
if (emptyFolders.length > 0) {
|
});
|
||||||
uploadEmptyFolders(emptyFolders, uploadToFolder).then(() => {
|
|
||||||
const onlyFiles = files.filter((f) => !f.isEmptyDirectory);
|
|
||||||
if (onlyFiles.length > 0) startUpload(onlyFiles, uploadToFolder, t);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
startUpload(files, uploadToFolder, t);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
@ -264,8 +264,8 @@ const StyledProperties = styled.div`
|
|||||||
grid-template-columns: 120px 1fr;
|
grid-template-columns: 120px 1fr;
|
||||||
grid-column-gap: 24px;
|
grid-column-gap: 24px;
|
||||||
|
|
||||||
-webkit-box-align: center;
|
-webkit-box-align: baseline;
|
||||||
align-items: center;
|
align-items: baseline;
|
||||||
|
|
||||||
.property-title {
|
.property-title {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
@ -138,15 +138,8 @@ class InsideGroupTableHeader extends React.Component {
|
|||||||
newFilter.sortBy = sortBy;
|
newFilter.sortBy = sortBy;
|
||||||
|
|
||||||
if (sortBy === "AZ") {
|
if (sortBy === "AZ") {
|
||||||
if (
|
if (newFilter.sortBy !== "displayname") {
|
||||||
newFilter.sortBy !== "lastname" &&
|
newFilter.sortBy = "displayname";
|
||||||
newFilter.sortBy !== "firstname"
|
|
||||||
) {
|
|
||||||
newFilter.sortBy = "firstname";
|
|
||||||
} else if (newFilter.sortBy === "lastname") {
|
|
||||||
newFilter.sortBy = "firstname";
|
|
||||||
} else {
|
|
||||||
newFilter.sortBy = "lastname";
|
|
||||||
}
|
}
|
||||||
newFilter.sortOrder =
|
newFilter.sortOrder =
|
||||||
newFilter.sortOrder === "ascending" ? "descending" : "ascending";
|
newFilter.sortOrder === "ascending" ? "descending" : "ascending";
|
||||||
@ -176,10 +169,7 @@ class InsideGroupTableHeader extends React.Component {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
const { sortOrder } = filter;
|
const { sortOrder } = filter;
|
||||||
|
|
||||||
const sortBy =
|
const sortBy = filter.sortBy === "displayname" ? "AZ" : filter.sortBy;
|
||||||
filter.sortBy === "firstname" || filter.sortBy === "lastname"
|
|
||||||
? "AZ"
|
|
||||||
: filter.sortBy;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableHeader
|
<TableHeader
|
||||||
|
@ -143,7 +143,7 @@ class PeopleTableHeader extends React.Component {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
newFilter.sortBy === sortBy ||
|
newFilter.sortBy === sortBy ||
|
||||||
(sortBy === "AZ" && newFilter.sortBy === "firstname")
|
(sortBy === "AZ" && newFilter.sortBy === "displayname")
|
||||||
) {
|
) {
|
||||||
newFilter.sortOrder =
|
newFilter.sortOrder =
|
||||||
newFilter.sortOrder === "ascending" ? "descending" : "ascending";
|
newFilter.sortOrder === "ascending" ? "descending" : "ascending";
|
||||||
@ -151,7 +151,7 @@ class PeopleTableHeader extends React.Component {
|
|||||||
newFilter.sortBy = sortBy;
|
newFilter.sortBy = sortBy;
|
||||||
|
|
||||||
if (sortBy === "AZ") {
|
if (sortBy === "AZ") {
|
||||||
newFilter.sortBy = "firstname";
|
newFilter.sortBy = "displayname";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,10 +178,7 @@ class PeopleTableHeader extends React.Component {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
const { sortOrder } = filter;
|
const { sortOrder } = filter;
|
||||||
|
|
||||||
const sortBy =
|
const sortBy = filter.sortBy === "displayname" ? "AZ" : filter.sortBy;
|
||||||
filter.sortBy === "firstname" || filter.sortBy === "lastname"
|
|
||||||
? "AZ"
|
|
||||||
: filter.sortBy;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableHeader
|
<TableHeader
|
||||||
|
@ -1961,16 +1961,9 @@ const SectionFilterContent = ({
|
|||||||
const options = [];
|
const options = [];
|
||||||
|
|
||||||
const firstName = {
|
const firstName = {
|
||||||
id: "sort-by_first-name",
|
id: "sort-by_displayname",
|
||||||
key: "firstname",
|
key: "displayname",
|
||||||
label: t("Common:FirstName"),
|
label: t("Common:Name"),
|
||||||
default: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const lastName = {
|
|
||||||
id: "sort-by_last-name",
|
|
||||||
key: "lastname",
|
|
||||||
label: t("Common:LastName"),
|
|
||||||
default: true,
|
default: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2012,7 +2005,7 @@ const SectionFilterContent = ({
|
|||||||
hideableColumns.Storage = storage;
|
hideableColumns.Storage = storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
options.push(firstName, lastName, type, department, email);
|
options.push(firstName, type, department, email);
|
||||||
if (showStorageInfo) options.push(storage);
|
if (showStorageInfo) options.push(storage);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
|
@ -50,6 +50,7 @@ import {
|
|||||||
getCategoryUrl,
|
getCategoryUrl,
|
||||||
} from "SRC_DIR/helpers/utils";
|
} from "SRC_DIR/helpers/utils";
|
||||||
import TariffBar from "SRC_DIR/components/TariffBar";
|
import TariffBar from "SRC_DIR/components/TariffBar";
|
||||||
|
import getFilesFromEvent from "@docspace/shared/components/drag-and-drop/get-files-from-event";
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -225,6 +226,7 @@ const SectionHeaderContent = (props) => {
|
|||||||
getHeaderOptions,
|
getHeaderOptions,
|
||||||
setBufferSelection,
|
setBufferSelection,
|
||||||
setGroupsBufferSelection,
|
setGroupsBufferSelection,
|
||||||
|
createFoldersTree,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@ -239,8 +241,12 @@ const SectionHeaderContent = (props) => {
|
|||||||
const isSettingsPage = location.pathname.includes("/settings");
|
const isSettingsPage = location.pathname.includes("/settings");
|
||||||
|
|
||||||
const onFileChange = React.useCallback(
|
const onFileChange = React.useCallback(
|
||||||
(e) => {
|
async (e) => {
|
||||||
startUpload(e.target.files, null, t);
|
const files = await getFilesFromEvent(e);
|
||||||
|
|
||||||
|
createFoldersTree(files).then((f) => {
|
||||||
|
if (f.length > 0) startUpload(f, null, t);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[startUpload, t],
|
[startUpload, t],
|
||||||
);
|
);
|
||||||
@ -639,6 +645,7 @@ export default inject(
|
|||||||
moveToRoomsPage,
|
moveToRoomsPage,
|
||||||
onClickBack,
|
onClickBack,
|
||||||
moveToPublicRoom,
|
moveToPublicRoom,
|
||||||
|
createFoldersTree,
|
||||||
} = filesActionsStore;
|
} = filesActionsStore;
|
||||||
|
|
||||||
const { setIsVisible, isVisible } = infoPanelStore;
|
const { setIsVisible, isVisible } = infoPanelStore;
|
||||||
@ -802,6 +809,7 @@ export default inject(
|
|||||||
getHeaderOptions,
|
getHeaderOptions,
|
||||||
setBufferSelection,
|
setBufferSelection,
|
||||||
setGroupsBufferSelection,
|
setGroupsBufferSelection,
|
||||||
|
createFoldersTree,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(
|
)(
|
||||||
|
@ -82,7 +82,7 @@ const PureHome = (props) => {
|
|||||||
startUpload,
|
startUpload,
|
||||||
setDragging,
|
setDragging,
|
||||||
dragging,
|
dragging,
|
||||||
uploadEmptyFolders,
|
createFoldersTree,
|
||||||
disableDrag,
|
disableDrag,
|
||||||
uploaded,
|
uploaded,
|
||||||
converted,
|
converted,
|
||||||
@ -182,7 +182,7 @@ const PureHome = (props) => {
|
|||||||
dragging,
|
dragging,
|
||||||
setDragging,
|
setDragging,
|
||||||
disableDrag,
|
disableDrag,
|
||||||
uploadEmptyFolders,
|
createFoldersTree,
|
||||||
startUpload,
|
startUpload,
|
||||||
fetchFiles,
|
fetchFiles,
|
||||||
fetchRooms,
|
fetchRooms,
|
||||||
@ -543,7 +543,7 @@ export default inject(
|
|||||||
const { setUploadPanelVisible, startUpload, uploaded, converted } =
|
const { setUploadPanelVisible, startUpload, uploaded, converted } =
|
||||||
uploadDataStore;
|
uploadDataStore;
|
||||||
|
|
||||||
const { uploadEmptyFolders, onClickBack } = filesActionsStore;
|
const { createFoldersTree, onClickBack } = filesActionsStore;
|
||||||
|
|
||||||
const selectionLength = isProgressFinished ? selection.length : null;
|
const selectionLength = isProgressFinished ? selection.length : null;
|
||||||
const selectionTitle = isProgressFinished
|
const selectionTitle = isProgressFinished
|
||||||
@ -635,7 +635,7 @@ export default inject(
|
|||||||
|
|
||||||
setUploadPanelVisible,
|
setUploadPanelVisible,
|
||||||
startUpload,
|
startUpload,
|
||||||
uploadEmptyFolders,
|
createFoldersTree,
|
||||||
|
|
||||||
setToPreviewFile,
|
setToPreviewFile,
|
||||||
setIsPreview,
|
setIsPreview,
|
||||||
|
@ -130,6 +130,7 @@ const Manager = (props) => {
|
|||||||
);
|
);
|
||||||
const [selectedColumns, setSelectedColumns] = useState([
|
const [selectedColumns, setSelectedColumns] = useState([
|
||||||
{ key: "Name", label: t("Common:Name") },
|
{ key: "Name", label: t("Common:Name") },
|
||||||
|
{ key: "Size", label: t("Common:Size") },
|
||||||
{ key: "Type", label: t("Common:Type") },
|
{ key: "Type", label: t("Common:Type") },
|
||||||
{ key: "Tags", label: t("Common:Tags") },
|
{ key: "Tags", label: t("Common:Tags") },
|
||||||
]);
|
]);
|
||||||
|
@ -125,6 +125,17 @@ class EditGroupStore {
|
|||||||
|
|
||||||
const addedIds = Array.from(this.addedMembersMap.keys());
|
const addedIds = Array.from(this.addedMembersMap.keys());
|
||||||
const removedIds = Array.from(this.removedMembersMap.keys());
|
const removedIds = Array.from(this.removedMembersMap.keys());
|
||||||
|
const oldManager = this.group.manager;
|
||||||
|
const oldManagerRemovedButRemainsAsMember =
|
||||||
|
oldManager &&
|
||||||
|
oldManager.id !== this.manager?.id &&
|
||||||
|
!this.removedMembersMap.has(oldManager.id);
|
||||||
|
|
||||||
|
// Requires when new group is without manager and old manager moved to members. updateGroup api method doesn't provide possibility to do it without setting new manager
|
||||||
|
if (this.manager === null && oldManagerRemovedButRemainsAsMember) {
|
||||||
|
await api.groups.removeGroupMembers(this.group.id, [oldManager.id]);
|
||||||
|
addedIds.push(oldManager.id);
|
||||||
|
}
|
||||||
|
|
||||||
await updateGroup(
|
await updateGroup(
|
||||||
this.group?.id,
|
this.group?.id,
|
||||||
|
@ -229,17 +229,21 @@ class FilesActionStore {
|
|||||||
let level = { result };
|
let level = { result };
|
||||||
try {
|
try {
|
||||||
folders.forEach((folder) => {
|
folders.forEach((folder) => {
|
||||||
folder.path
|
const folderPath = folder.path.split("/").filter((name) => name !== "");
|
||||||
.split("/")
|
|
||||||
.filter((name) => name !== "")
|
|
||||||
.reduce((r, name, i, a) => {
|
|
||||||
if (!r[name]) {
|
|
||||||
r[name] = { result: [] };
|
|
||||||
r.result.push({ name, children: r[name].result });
|
|
||||||
}
|
|
||||||
|
|
||||||
return r[name];
|
folderPath.reduce((r, name, i, a) => {
|
||||||
}, level);
|
if (!r[name]) {
|
||||||
|
r[name] = { result: [] };
|
||||||
|
r.result.push({
|
||||||
|
name,
|
||||||
|
children: r[name].result,
|
||||||
|
isFile: folderPath.length - 1 === i && !folder.isEmptyDirectory,
|
||||||
|
file: folder,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return r[name];
|
||||||
|
}, level);
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("convertToTree", e);
|
console.error("convertToTree", e);
|
||||||
@ -247,52 +251,67 @@ class FilesActionStore {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
createFolderTree = async (treeList, parentFolderId) => {
|
createFolderTree = async (treeList, parentFolderId, filesList) => {
|
||||||
if (!treeList || !treeList.length) return;
|
if (!treeList || !treeList.length) return;
|
||||||
|
|
||||||
for (let i = 0; i < treeList.length; i++) {
|
for (let i = 0; i < treeList.length; i++) {
|
||||||
const treeNode = treeList[i];
|
const treeNode = treeList[i];
|
||||||
|
const isFile = treeList[i].isFile;
|
||||||
|
|
||||||
// console.log(
|
// console.log(
|
||||||
// `createFolderTree parent id = ${parentFolderId} name '${treeNode.name}': `,
|
// `createFolderTree parent id = ${parentFolderId} name '${treeNode.name}': `,
|
||||||
// treeNode.children
|
// treeNode.children
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
if (isFile) {
|
||||||
|
treeList[i].file.parentFolderId = parentFolderId;
|
||||||
|
filesList.push(treeList[i].file);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const folder = await createFolder(parentFolderId, treeNode.name);
|
const folder = await createFolder(parentFolderId, treeNode.name);
|
||||||
const parentId = folder.id;
|
const parentId = folder.id;
|
||||||
|
|
||||||
if (treeNode.children.length == 0) continue;
|
if (treeNode.children.length == 0) continue;
|
||||||
|
|
||||||
await this.createFolderTree(treeNode.children, parentId);
|
await this.createFolderTree(treeNode.children, parentId, filesList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return treeList;
|
||||||
};
|
};
|
||||||
|
|
||||||
uploadEmptyFolders = async (emptyFolders, folderId) => {
|
createFoldersTree = async (files, folderId) => {
|
||||||
//console.log("uploadEmptyFolders", emptyFolders, folderId);
|
//console.log("createFoldersTree", files, folderId);
|
||||||
|
|
||||||
const { secondaryProgressDataStore } = this.uploadDataStore;
|
const { primaryProgressDataStore } = this.uploadDataStore;
|
||||||
const { setSecondaryProgressBarData, clearSecondaryProgressData } =
|
|
||||||
secondaryProgressDataStore;
|
const { setPrimaryProgressBarData, clearPrimaryProgressData } =
|
||||||
|
primaryProgressDataStore;
|
||||||
|
|
||||||
const operationId = uniqueid("operation_");
|
const operationId = uniqueid("operation_");
|
||||||
|
|
||||||
const toFolderId = folderId ? folderId : this.selectedFolderStore.id;
|
const toFolderId = folderId ? folderId : this.selectedFolderStore.id;
|
||||||
|
|
||||||
setSecondaryProgressBarData({
|
setPrimaryProgressBarData({
|
||||||
icon: "file",
|
icon: "upload",
|
||||||
visible: true,
|
visible: true,
|
||||||
percent: 0,
|
percent: 0,
|
||||||
label: "",
|
label: "",
|
||||||
alert: false,
|
alert: false,
|
||||||
operationId,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const tree = this.convertToTree(emptyFolders);
|
const tree = this.convertToTree(files);
|
||||||
await this.createFolderTree(tree, toFolderId);
|
|
||||||
|
const filesList = [];
|
||||||
|
await this.createFolderTree(tree, toFolderId, filesList);
|
||||||
|
|
||||||
this.updateCurrentFolder(null, [folderId], null, operationId);
|
this.updateCurrentFolder(null, [folderId], null, operationId);
|
||||||
|
|
||||||
setTimeout(() => clearSecondaryProgressData(operationId), TIMEOUT);
|
if (!filesList.length) {
|
||||||
|
setTimeout(() => clearPrimaryProgressData(), TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filesList;
|
||||||
};
|
};
|
||||||
|
|
||||||
updateFilesAfterDelete = (operationId) => {
|
updateFilesAfterDelete = (operationId) => {
|
||||||
|
@ -683,9 +683,8 @@ class HotkeyStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
uploadClipboardFiles = async (t, event) => {
|
uploadClipboardFiles = async (t, event) => {
|
||||||
const { uploadEmptyFolders } = this.filesActionsStore;
|
const { createFoldersTree } = this.filesActionsStore;
|
||||||
const { startUpload } = this.uploadDataStore;
|
const { startUpload } = this.uploadDataStore;
|
||||||
const currentFolderId = this.selectedFolderStore.id;
|
|
||||||
|
|
||||||
if (this.filesStore.hotkeysClipboard.length) {
|
if (this.filesStore.hotkeysClipboard.length) {
|
||||||
return this.moveFilesFromClipboard(t);
|
return this.moveFilesFromClipboard(t);
|
||||||
@ -693,16 +692,9 @@ class HotkeyStore {
|
|||||||
|
|
||||||
const files = await getFilesFromEvent(event);
|
const files = await getFilesFromEvent(event);
|
||||||
|
|
||||||
const emptyFolders = files.filter((f) => f.isEmptyDirectory);
|
createFoldersTree(files, uploadToFolder).then((f) => {
|
||||||
|
if (f.length > 0) startUpload(f, null, t);
|
||||||
if (emptyFolders.length > 0) {
|
});
|
||||||
uploadEmptyFolders(emptyFolders, currentFolderId).then(() => {
|
|
||||||
const onlyFiles = files.filter((f) => !f.isEmptyDirectory);
|
|
||||||
if (onlyFiles.length > 0) startUpload(onlyFiles, currentFolderId, t);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
startUpload(files, currentFolderId, t);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
get countTilesInRow() {
|
get countTilesInRow() {
|
||||||
|
@ -489,7 +489,7 @@ class LdapFormStore {
|
|||||||
completed: true,
|
completed: true,
|
||||||
percents: 100,
|
percents: 100,
|
||||||
certificateConfirmRequest: null,
|
certificateConfirmRequest: null,
|
||||||
error: "",
|
error: t("Common:UnexpectedError"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +518,6 @@ class LdapFormStore {
|
|||||||
toastr.success(t("Common:SuccessfullyCompletedOperation"));
|
toastr.success(t("Common:SuccessfullyCompletedOperation"));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
|
||||||
toastr.error(error);
|
toastr.error(error);
|
||||||
this.endProcess();
|
this.endProcess();
|
||||||
}
|
}
|
||||||
|
@ -347,7 +347,7 @@ class ProfileActionsStore {
|
|||||||
|
|
||||||
let bookTraining = null;
|
let bookTraining = null;
|
||||||
|
|
||||||
if (!isMobile && this.isTeamTrainingAlertAvailable) {
|
if (!isMobile && this.authStore.isTeamTrainingAlertAvailable) {
|
||||||
bookTraining = {
|
bookTraining = {
|
||||||
key: "user-menu-book-training",
|
key: "user-menu-book-training",
|
||||||
icon: BookTrainingReactSvgUrl,
|
icon: BookTrainingReactSvgUrl,
|
||||||
|
@ -25,9 +25,11 @@
|
|||||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||||
|
|
||||||
import { makeAutoObservable, runInAction } from "mobx";
|
import { makeAutoObservable, runInAction } from "mobx";
|
||||||
|
import { Trans } from "react-i18next";
|
||||||
import { TIMEOUT } from "@docspace/client/src/helpers/filesConstants";
|
import { TIMEOUT } from "@docspace/client/src/helpers/filesConstants";
|
||||||
import uniqueid from "lodash/uniqueId";
|
import uniqueid from "lodash/uniqueId";
|
||||||
import sumBy from "lodash/sumBy";
|
import sumBy from "lodash/sumBy";
|
||||||
|
import uniqBy from "lodash/uniqBy";
|
||||||
import { ConflictResolveType } from "@docspace/shared/enums";
|
import { ConflictResolveType } from "@docspace/shared/enums";
|
||||||
import {
|
import {
|
||||||
getFileInfo,
|
getFileInfo,
|
||||||
@ -57,6 +59,8 @@ import {
|
|||||||
getCategoryTypeByFolderType,
|
getCategoryTypeByFolderType,
|
||||||
getCategoryUrl,
|
getCategoryUrl,
|
||||||
} from "SRC_DIR/helpers/utils";
|
} from "SRC_DIR/helpers/utils";
|
||||||
|
import { Link } from "@docspace/shared/components/link";
|
||||||
|
import { globalColors } from "@docspace/shared/themes";
|
||||||
|
|
||||||
class UploadDataStore {
|
class UploadDataStore {
|
||||||
settingsStore;
|
settingsStore;
|
||||||
@ -636,7 +640,7 @@ class UploadDataStore {
|
|||||||
|
|
||||||
if (this.uploaded || (this.isParallel && allFilesIsUploaded)) {
|
if (this.uploaded || (this.isParallel && allFilesIsUploaded)) {
|
||||||
this.setConversionPercent(100);
|
this.setConversionPercent(100);
|
||||||
this.finishUploadFiles();
|
this.finishUploadFiles(t);
|
||||||
} else {
|
} else {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.converted = true;
|
this.converted = true;
|
||||||
@ -773,7 +777,8 @@ class UploadDataStore {
|
|||||||
file: file,
|
file: file,
|
||||||
uniqueId: uniqueid("download_row-key_"),
|
uniqueId: uniqueid("download_row-key_"),
|
||||||
fileId: null,
|
fileId: null,
|
||||||
toFolderId,
|
// toFolderId,
|
||||||
|
toFolderId: file.parentFolderId,
|
||||||
action: "upload",
|
action: "upload",
|
||||||
error: file.size ? null : t("Files:EmptyFile"),
|
error: file.size ? null : t("Files:EmptyFile"),
|
||||||
fileInfo: null,
|
fileInfo: null,
|
||||||
@ -1263,7 +1268,7 @@ class UploadDataStore {
|
|||||||
let files = this.files;
|
let files = this.files;
|
||||||
|
|
||||||
if (files.length === 0 || this.filesSize === 0) {
|
if (files.length === 0 || this.filesSize === 0) {
|
||||||
return this.finishUploadFiles();
|
return this.finishUploadFiles(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
const progressData = {
|
const progressData = {
|
||||||
@ -1310,7 +1315,7 @@ class UploadDataStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.filesToConversion.length) {
|
if (!this.filesToConversion.length) {
|
||||||
this.finishUploadFiles();
|
this.finishUploadFiles(t);
|
||||||
} else {
|
} else {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.uploaded = true;
|
this.uploaded = true;
|
||||||
@ -1372,7 +1377,7 @@ class UploadDataStore {
|
|||||||
toFolderId,
|
toFolderId,
|
||||||
fileName,
|
fileName,
|
||||||
fileSize,
|
fileSize,
|
||||||
relativePath,
|
"", // relativePath,
|
||||||
file.encrypted,
|
file.encrypted,
|
||||||
file.lastModifiedDate,
|
file.lastModifiedDate,
|
||||||
createNewIfExist,
|
createNewIfExist,
|
||||||
@ -1512,7 +1517,7 @@ class UploadDataStore {
|
|||||||
|
|
||||||
if (allFilesIsUploaded) {
|
if (allFilesIsUploaded) {
|
||||||
if (!this.filesToConversion.length) {
|
if (!this.filesToConversion.length) {
|
||||||
this.finishUploadFiles();
|
this.finishUploadFiles(t);
|
||||||
} else {
|
} else {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.uploaded = true;
|
this.uploaded = true;
|
||||||
@ -1542,7 +1547,7 @@ class UploadDataStore {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
finishUploadFiles = () => {
|
finishUploadFiles = (t) => {
|
||||||
const { fetchFiles, filter } = this.filesStore;
|
const { fetchFiles, filter } = this.filesStore;
|
||||||
const { withPaging } = this.settingsStore;
|
const { withPaging } = this.settingsStore;
|
||||||
|
|
||||||
@ -1554,7 +1559,7 @@ class UploadDataStore {
|
|||||||
this.asyncUploadObj = {};
|
this.asyncUploadObj = {};
|
||||||
|
|
||||||
for (let item of this.tempFiles) {
|
for (let item of this.tempFiles) {
|
||||||
const { uploadFiles, folderId, t } = item;
|
const { uploadFiles, folderId } = item;
|
||||||
this.startUpload(uploadFiles, folderId, t);
|
this.startUpload(uploadFiles, folderId, t);
|
||||||
}
|
}
|
||||||
this.tempFiles = [];
|
this.tempFiles = [];
|
||||||
@ -1562,12 +1567,36 @@ class UploadDataStore {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalErrorsCount = sumBy(this.files, (f) => {
|
const filesWithErrors = this.files.filter((f) => f.error);
|
||||||
f.error && toastr.error(f.error);
|
|
||||||
return f.error ? 1 : 0;
|
const totalErrorsCount = filesWithErrors.length;
|
||||||
});
|
|
||||||
|
|
||||||
if (totalErrorsCount > 0) {
|
if (totalErrorsCount > 0) {
|
||||||
|
const uniqErrors = uniqBy(filesWithErrors, "error");
|
||||||
|
uniqErrors.forEach((f) =>
|
||||||
|
f.error.indexOf("password") > -1
|
||||||
|
? toastr.warning(
|
||||||
|
<Trans
|
||||||
|
i18nKey="Files:PasswordProtectedFiles"
|
||||||
|
t={t}
|
||||||
|
components={[
|
||||||
|
<Link
|
||||||
|
isHovered
|
||||||
|
color={globalColors.link}
|
||||||
|
onClick={() => {
|
||||||
|
toastr.clear();
|
||||||
|
this.setUploadPanelVisible(true);
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
]}
|
||||||
|
/>,
|
||||||
|
null,
|
||||||
|
60000,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
: toastr.error(f.error),
|
||||||
|
);
|
||||||
|
|
||||||
this.primaryProgressDataStore.setPrimaryProgressBarShowError(true); // for empty file
|
this.primaryProgressDataStore.setPrimaryProgressBarShowError(true); // for empty file
|
||||||
this.primaryProgressDataStore.setPrimaryProgressBarErrors(
|
this.primaryProgressDataStore.setPrimaryProgressBarErrors(
|
||||||
totalErrorsCount,
|
totalErrorsCount,
|
||||||
|
@ -146,6 +146,14 @@ export const addGroupMembers = (groupId: string, members: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const removeGroupMembers = (groupId: string, membersIds: string[]) => {
|
||||||
|
return request({
|
||||||
|
method: "delete",
|
||||||
|
url: `/group/${groupId}/members`,
|
||||||
|
data: { id: groupId, members: membersIds },
|
||||||
|
}) as Promise<TGroup>;
|
||||||
|
};
|
||||||
|
|
||||||
// * Delete
|
// * Delete
|
||||||
|
|
||||||
export const deleteGroup = (groupId: string) => {
|
export const deleteGroup = (groupId: string) => {
|
||||||
|
@ -29,7 +29,7 @@ import { getObjectByLocation, toUrlParams } from "../../utils/common";
|
|||||||
const DEFAULT_PAGE = 0;
|
const DEFAULT_PAGE = 0;
|
||||||
const DEFAULT_PAGE_COUNT = 25;
|
const DEFAULT_PAGE_COUNT = 25;
|
||||||
const DEFAULT_TOTAL = 0;
|
const DEFAULT_TOTAL = 0;
|
||||||
const DEFAULT_SORT_BY = "firstname";
|
const DEFAULT_SORT_BY = "displayname";
|
||||||
const DEFAULT_SORT_ORDER = "ascending";
|
const DEFAULT_SORT_ORDER = "ascending";
|
||||||
const DEFAULT_EMPLOYEE_STATUS = null;
|
const DEFAULT_EMPLOYEE_STATUS = null;
|
||||||
const DEFAULT_ACTIVATION_STATUS = null;
|
const DEFAULT_ACTIVATION_STATUS = null;
|
||||||
|
@ -29,7 +29,7 @@ import moment from "moment";
|
|||||||
export const getCalendarYears = (observedDate: moment.Moment) => {
|
export const getCalendarYears = (observedDate: moment.Moment) => {
|
||||||
const years = [];
|
const years = [];
|
||||||
const selectedYear = observedDate.year();
|
const selectedYear = observedDate.year();
|
||||||
const firstYear = selectedYear - (selectedYear % 10) - 1;
|
const firstYear = selectedYear - 1;
|
||||||
|
|
||||||
for (let i = firstYear; i <= firstYear + 15; i += 1) {
|
for (let i = firstYear; i <= firstYear + 15; i += 1) {
|
||||||
years.push(moment(i, "YYYY").format("YYYY"));
|
years.push(moment(i, "YYYY").format("YYYY"));
|
||||||
|
@ -40,7 +40,7 @@ const StyledErrorContainer = styled.div<{ isEditor: boolean }>`
|
|||||||
css`
|
css`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
`}
|
`}
|
||||||
overflow-x: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -996,6 +996,7 @@ export const ImageViewer = ({
|
|||||||
onDoubleClick={handleDoubleTapOrClick}
|
onDoubleClick={handleDoubleTapOrClick}
|
||||||
onLoad={imageLoaded}
|
onLoad={imageLoaded}
|
||||||
onError={onError}
|
onError={onError}
|
||||||
|
onContextMenu={(event) => event.preventDefault()}
|
||||||
/>
|
/>
|
||||||
</ImageWrapper>
|
</ImageWrapper>
|
||||||
</ImageViewerContainer>
|
</ImageViewerContainer>
|
||||||
|
@ -36,7 +36,9 @@ export const PlayerBigPlayButton = ({
|
|||||||
if (!visible) return;
|
if (!visible) return;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WrapperPlayerBigPlayButton>
|
<WrapperPlayerBigPlayButton
|
||||||
|
onContextMenu={(event) => event.preventDefault()}
|
||||||
|
>
|
||||||
<BigIconPlay onClick={onClick} />
|
<BigIconPlay onClick={onClick} />
|
||||||
</WrapperPlayerBigPlayButton>
|
</WrapperPlayerBigPlayButton>
|
||||||
);
|
);
|
||||||
|
@ -406,6 +406,10 @@ export const ViewerPlayer = ({
|
|||||||
const percent = Number(event.target.value);
|
const percent = Number(event.target.value);
|
||||||
const newCurrentTime = (percent / 100) * videoRef.current.duration;
|
const newCurrentTime = (percent / 100) * videoRef.current.duration;
|
||||||
|
|
||||||
|
const videoCurrentTime = videoRef.current.currentTime;
|
||||||
|
|
||||||
|
if (Math.abs(newCurrentTime - videoCurrentTime) <= 0.1) return;
|
||||||
|
|
||||||
handleProgress();
|
handleProgress();
|
||||||
setTimeline(percent);
|
setTimeline(percent);
|
||||||
setCurrentTime(newCurrentTime);
|
setCurrentTime(newCurrentTime);
|
||||||
@ -653,6 +657,7 @@ export const ViewerPlayer = ({
|
|||||||
onDurationChange={handleDurationChange}
|
onDurationChange={handleDurationChange}
|
||||||
onLoadedMetadata={handleLoadedMetaDataVideo}
|
onLoadedMetadata={handleLoadedMetaDataVideo}
|
||||||
onPlay={() => setIsPlaying(true)}
|
onPlay={() => setIsPlaying(true)}
|
||||||
|
onContextMenu={(event) => event.preventDefault()}
|
||||||
/>
|
/>
|
||||||
<PlayerBigPlayButton
|
<PlayerBigPlayButton
|
||||||
onClick={handleBigPlayButtonClick}
|
onClick={handleBigPlayButtonClick}
|
||||||
|
@ -79,7 +79,8 @@ const ControlButtons = ({
|
|||||||
onClick={onNavigationButtonClick}
|
onClick={onNavigationButtonClick}
|
||||||
/>
|
/>
|
||||||
) : null;
|
) : null;
|
||||||
const children = tariffBar ? React.cloneElement(tariffBar, { title }) : null;
|
const children =
|
||||||
|
tariffBar && !isFrame ? React.cloneElement(tariffBar, { title }) : null;
|
||||||
const isTabletView = isTablet();
|
const isTabletView = isTablet();
|
||||||
|
|
||||||
const contextOptionsFolder = getContextOptionsFolder();
|
const contextOptionsFolder = getContextOptionsFolder();
|
||||||
|
@ -145,3 +145,7 @@ export interface SectionProps {
|
|||||||
isDesktop?: boolean;
|
isDesktop?: boolean;
|
||||||
getContextModel?: () => ContextMenuModel[];
|
getContextModel?: () => ContextMenuModel[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SectionContextMenuProps {
|
||||||
|
getContextModel: () => ContextMenuModel[];
|
||||||
|
}
|
||||||
|
@ -29,14 +29,13 @@ import { useLocation } from "react-router-dom";
|
|||||||
|
|
||||||
// import { inject, observer } from "mobx-react";
|
// import { inject, observer } from "mobx-react";
|
||||||
|
|
||||||
import { ContextMenu } from "@docspace/shared/components/context-menu";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
StyledDropZoneBody,
|
StyledDropZoneBody,
|
||||||
StyledSpacer,
|
StyledSpacer,
|
||||||
StyledSectionBody,
|
StyledSectionBody,
|
||||||
} from "../Section.styled";
|
} from "../Section.styled";
|
||||||
import { SectionBodyProps } from "../Section.types";
|
import { SectionBodyProps } from "../Section.types";
|
||||||
|
import SectionContextMenu from "./SectionContextMenu";
|
||||||
|
|
||||||
const SectionBody = React.memo(
|
const SectionBody = React.memo(
|
||||||
({
|
({
|
||||||
@ -53,49 +52,9 @@ const SectionBody = React.memo(
|
|||||||
getContextModel,
|
getContextModel,
|
||||||
}: SectionBodyProps) => {
|
}: SectionBodyProps) => {
|
||||||
const focusRef = React.useRef<HTMLDivElement | null>(null);
|
const focusRef = React.useRef<HTMLDivElement | null>(null);
|
||||||
const cmRef = React.useRef<null | {
|
|
||||||
show: (e: React.MouseEvent | MouseEvent) => void;
|
|
||||||
hide: (e: React.MouseEvent | MouseEvent) => void;
|
|
||||||
toggle: (e: React.MouseEvent | MouseEvent) => boolean;
|
|
||||||
getVisible: () => boolean;
|
|
||||||
}>(null);
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
const [isOpen, setIsOpen] = React.useState(false);
|
|
||||||
|
|
||||||
const onContextMenu = React.useCallback(
|
|
||||||
(e: MouseEvent | React.MouseEvent<Element, MouseEvent>) => {
|
|
||||||
const bodyElem = document.getElementsByClassName(
|
|
||||||
"section-body",
|
|
||||||
)[0] as HTMLDivElement;
|
|
||||||
|
|
||||||
const target = e.target as Node;
|
|
||||||
|
|
||||||
if (
|
|
||||||
!getContextModel ||
|
|
||||||
!getContextModel() ||
|
|
||||||
!bodyElem ||
|
|
||||||
!bodyElem.contains(target)
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
// if (cmRef.current) cmRef.current.toggle(e);
|
|
||||||
if (cmRef.current) {
|
|
||||||
if (!isOpen) cmRef?.current?.show(e);
|
|
||||||
else cmRef?.current?.hide(e);
|
|
||||||
setIsOpen(!isOpen);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[getContextModel, isOpen],
|
|
||||||
);
|
|
||||||
|
|
||||||
const onHide = () => {
|
|
||||||
setIsOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const focusSectionBody = React.useCallback(() => {
|
const focusSectionBody = React.useCallback(() => {
|
||||||
if (focusRef.current) focusRef.current.focus({ preventScroll: true });
|
if (focusRef.current) focusRef.current.focus({ preventScroll: true });
|
||||||
}, []);
|
}, []);
|
||||||
@ -108,14 +67,6 @@ const SectionBody = React.memo(
|
|||||||
[focusSectionBody],
|
[focusSectionBody],
|
||||||
);
|
);
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
document.addEventListener("contextmenu", onContextMenu);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener("contextmenu", onContextMenu);
|
|
||||||
};
|
|
||||||
}, [onContextMenu]);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!autoFocus) return;
|
if (!autoFocus) return;
|
||||||
|
|
||||||
@ -145,16 +96,6 @@ const SectionBody = React.memo(
|
|||||||
}
|
}
|
||||||
: {};
|
: {};
|
||||||
|
|
||||||
const contextBlock = (
|
|
||||||
<ContextMenu
|
|
||||||
ref={cmRef}
|
|
||||||
onHide={onHide}
|
|
||||||
getContextModel={getContextModel}
|
|
||||||
withBackdrop
|
|
||||||
model={[]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
return uploadFiles ? (
|
return uploadFiles ? (
|
||||||
<StyledDropZoneBody
|
<StyledDropZoneBody
|
||||||
isDropZone
|
isDropZone
|
||||||
@ -179,7 +120,7 @@ const SectionBody = React.memo(
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{contextBlock}
|
<SectionContextMenu getContextModel={getContextModel} />
|
||||||
</StyledDropZoneBody>
|
</StyledDropZoneBody>
|
||||||
) : (
|
) : (
|
||||||
<StyledSectionBody
|
<StyledSectionBody
|
||||||
@ -200,7 +141,7 @@ const SectionBody = React.memo(
|
|||||||
) : (
|
) : (
|
||||||
<div className="section-wrapper">{children}</div>
|
<div className="section-wrapper">{children}</div>
|
||||||
)}
|
)}
|
||||||
{contextBlock}
|
<SectionContextMenu getContextModel={getContextModel} />
|
||||||
</StyledSectionBody>
|
</StyledSectionBody>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { ContextMenu } from "@docspace/shared/components/context-menu";
|
||||||
|
import isEqual from "lodash/isEqual";
|
||||||
|
import { SectionContextMenuProps } from "../Section.types";
|
||||||
|
|
||||||
|
const areEqual = (
|
||||||
|
prevProps: SectionContextMenuProps,
|
||||||
|
nextProps: SectionContextMenuProps,
|
||||||
|
) => {
|
||||||
|
if (!isEqual(prevProps, nextProps)) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SectionContextMenu = React.memo(
|
||||||
|
({ getContextModel }: SectionContextMenuProps) => {
|
||||||
|
const [isOpen, setIsOpen] = React.useState(false);
|
||||||
|
|
||||||
|
const cmRef = React.useRef<null | {
|
||||||
|
show: (e: React.MouseEvent | MouseEvent) => void;
|
||||||
|
hide: (e: React.MouseEvent | MouseEvent) => void;
|
||||||
|
toggle: (e: React.MouseEvent | MouseEvent) => boolean;
|
||||||
|
getVisible: () => boolean;
|
||||||
|
}>(null);
|
||||||
|
|
||||||
|
const onHide = () => {
|
||||||
|
setIsOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onContextMenu = React.useCallback(
|
||||||
|
(e: MouseEvent | React.MouseEvent<Element, MouseEvent>) => {
|
||||||
|
const bodyElem = document.getElementsByClassName(
|
||||||
|
"section-body",
|
||||||
|
)[0] as HTMLDivElement;
|
||||||
|
|
||||||
|
const target = e.target as Node;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!getContextModel ||
|
||||||
|
!getContextModel() ||
|
||||||
|
!bodyElem ||
|
||||||
|
!bodyElem.contains(target)
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// if (cmRef.current) cmRef.current.toggle(e);
|
||||||
|
if (cmRef.current) {
|
||||||
|
if (!isOpen) cmRef?.current?.show(e);
|
||||||
|
else cmRef?.current?.hide(e);
|
||||||
|
setIsOpen(!isOpen);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[getContextModel, isOpen],
|
||||||
|
);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
document.addEventListener("contextmenu", onContextMenu);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("contextmenu", onContextMenu);
|
||||||
|
};
|
||||||
|
}, [onContextMenu]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ContextMenu
|
||||||
|
ref={cmRef}
|
||||||
|
onHide={onHide}
|
||||||
|
getContextModel={getContextModel}
|
||||||
|
withBackdrop
|
||||||
|
model={[]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
areEqual,
|
||||||
|
);
|
||||||
|
SectionContextMenu.displayName = "SectionContextMenu";
|
||||||
|
|
||||||
|
export default SectionContextMenu;
|
@ -75,6 +75,7 @@ export type TFrameEvents = {
|
|||||||
onAuthSuccess: null | ((e: Event) => void);
|
onAuthSuccess: null | ((e: Event) => void);
|
||||||
onSignOut: null | ((e: Event) => void);
|
onSignOut: null | ((e: Event) => void);
|
||||||
onDownload: null | ((e: Event) => void);
|
onDownload: null | ((e: Event) => void);
|
||||||
|
onNoAccess: null | ((e: Event) => void);
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TFrameConfig = {
|
export type TFrameConfig = {
|
||||||
@ -96,6 +97,7 @@ export type TFrameConfig = {
|
|||||||
showSelectorCancel: boolean;
|
showSelectorCancel: boolean;
|
||||||
showSelectorHeader: boolean;
|
showSelectorHeader: boolean;
|
||||||
showHeader: boolean;
|
showHeader: boolean;
|
||||||
|
showHeaderBanner: string;
|
||||||
showTitle: boolean;
|
showTitle: boolean;
|
||||||
showMenu: boolean;
|
showMenu: boolean;
|
||||||
showFilter: boolean;
|
showFilter: boolean;
|
||||||
|
@ -220,10 +220,12 @@ class AxiosClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const loginURL = combineUrl(proxyURL, "/login");
|
const loginURL = combineUrl(proxyURL, "/login");
|
||||||
|
|
||||||
if (!this.isSSR) {
|
if (!this.isSSR) {
|
||||||
switch (error.response?.status) {
|
switch (error.response?.status) {
|
||||||
case 401: {
|
case 401: {
|
||||||
if (options.skipUnauthorized) return Promise.resolve();
|
if (options.skipUnauthorized || window?.ClientConfig?.isFrame)
|
||||||
|
return Promise.resolve();
|
||||||
if (options.skipLogout) return Promise.reject(error);
|
if (options.skipLogout) return Promise.reject(error);
|
||||||
|
|
||||||
const opt: AxiosRequestConfig = {
|
const opt: AxiosRequestConfig = {
|
||||||
@ -244,14 +246,13 @@ class AxiosClient {
|
|||||||
break;
|
break;
|
||||||
case 403: {
|
case 403: {
|
||||||
const pathname = window.location.pathname;
|
const pathname = window.location.pathname;
|
||||||
const isFrame = window?.ClientConfig?.isFrame;
|
|
||||||
|
|
||||||
const isArchived = pathname.indexOf("/rooms/archived") !== -1;
|
const isArchived = pathname.indexOf("/rooms/archived") !== -1;
|
||||||
|
|
||||||
const isRooms =
|
const isRooms =
|
||||||
pathname.indexOf("/rooms/shared") !== -1 || isArchived;
|
pathname.indexOf("/rooms/shared") !== -1 || isArchived;
|
||||||
|
|
||||||
if (isRooms && !skipRedirect && !isFrame) {
|
if (isRooms && !skipRedirect && !window?.ClientConfig?.isFrame) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.DocSpace.navigate(isArchived ? "/archived" : "/");
|
window.DocSpace.navigate(isArchived ? "/archived" : "/");
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
showSignOut: true,
|
showSignOut: true,
|
||||||
destroyText: "",
|
destroyText: "",
|
||||||
viewAs: "row", //TODO: ["row", "table", "tile"]
|
viewAs: "row", //TODO: ["row", "table", "tile"]
|
||||||
viewTableColumns: "Name,Type,Tags",
|
viewTableColumns: "Name,Size,Type,Tags",
|
||||||
checkCSP: true,
|
checkCSP: true,
|
||||||
disableActionButton: false,
|
disableActionButton: false,
|
||||||
showSettings: false,
|
showSettings: false,
|
||||||
@ -97,6 +97,8 @@
|
|||||||
onAuthSuccess: null,
|
onAuthSuccess: null,
|
||||||
onSignOut: null,
|
onSignOut: null,
|
||||||
onDownload: null,
|
onDownload: null,
|
||||||
|
onNoAccess: null,
|
||||||
|
onContentReady: null,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -813,7 +815,10 @@
|
|||||||
targetFrame.style.height = this.config.height;
|
targetFrame.style.height = this.config.height;
|
||||||
targetFrame.parentNode.style.height = "inherit";
|
targetFrame.parentNode.style.height = "inherit";
|
||||||
|
|
||||||
if (loader) loader.remove();
|
if (loader) {
|
||||||
|
loader.remove();
|
||||||
|
this.config.events.onContentReady();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user