Merge branch 'develop' into bugfix/redesign-author-filter
This commit is contained in:
commit
ce9e972d22
@ -45,6 +45,8 @@ public class TenantManager
|
||||
internal CoreBaseSettings CoreBaseSettings { get; set; }
|
||||
internal CoreSettings CoreSettings { get; set; }
|
||||
|
||||
private readonly static object _lock = new object();
|
||||
|
||||
static TenantManager()
|
||||
{
|
||||
_thisCompAddresses.Add("localhost");
|
||||
@ -333,7 +335,10 @@ public class TenantManager
|
||||
|
||||
public void SetTenantQuotaRow(TenantQuotaRow row, bool exchange)
|
||||
{
|
||||
QuotaService.SetTenantQuotaRow(row, exchange);
|
||||
lock (_lock)
|
||||
{
|
||||
QuotaService.SetTenantQuotaRow(row, exchange);
|
||||
}
|
||||
}
|
||||
|
||||
public List<TenantQuotaRow> FindTenantQuotaRows(int tenantId)
|
||||
|
@ -99,7 +99,7 @@ public class S3ZipWriteOperator : IDataWriteOperator
|
||||
stream.Position = 0;
|
||||
var buffer = new byte[_sessionHolder.MaxChunkUploadSize];
|
||||
int bytesRead;
|
||||
while ((bytesRead = _fileStream.Read(buffer, 0, (int)_sessionHolder.MaxChunkUploadSize)) > 0)
|
||||
while ((bytesRead = stream.Read(buffer, 0, (int)_sessionHolder.MaxChunkUploadSize)) > 0)
|
||||
{
|
||||
_sha.TransformBlock(buffer, 0, bytesRead, buffer, 0);
|
||||
}
|
||||
|
@ -171,6 +171,7 @@ const Items = ({
|
||||
onHide,
|
||||
firstLoad,
|
||||
deleteAction,
|
||||
startDrag,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
data.forEach((elem) => {
|
||||
@ -265,7 +266,12 @@ const Items = ({
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!draggableItems || draggableItems.find((x) => x.id === item.id))
|
||||
if (
|
||||
!draggableItems ||
|
||||
draggableItems.find(
|
||||
(x) => x.id === item.id && x.isFolder === item.isFolder
|
||||
)
|
||||
)
|
||||
return false;
|
||||
|
||||
if (
|
||||
@ -281,7 +287,7 @@ const Items = ({
|
||||
(item.pathParts[0] === myId || item.pathParts[0] === commonId)) ||
|
||||
item.rootFolderType === FolderType.USER ||
|
||||
item.rootFolderType === FolderType.COMMON ||
|
||||
item.rootFolderType === FolderType.TRASH
|
||||
(item.rootFolderType === FolderType.TRASH && startDrag)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -417,9 +423,9 @@ export default inject(
|
||||
selection,
|
||||
dragging,
|
||||
setDragging,
|
||||
setStartDrag,
|
||||
trashIsEmpty,
|
||||
firstLoad,
|
||||
startDrag,
|
||||
} = filesStore;
|
||||
|
||||
const { startUpload } = uploadDataStore;
|
||||
@ -456,7 +462,6 @@ export default inject(
|
||||
draggableItems: dragging ? selection : null,
|
||||
dragging,
|
||||
setDragging,
|
||||
setStartDrag,
|
||||
moveDragItems,
|
||||
deleteAction,
|
||||
startUpload,
|
||||
@ -465,6 +470,7 @@ export default inject(
|
||||
trashIsEmpty,
|
||||
rootFolderType,
|
||||
firstLoad,
|
||||
startDrag,
|
||||
};
|
||||
}
|
||||
)(withTranslation(["Files", "Common", "Translations"])(observer(Items)));
|
||||
|
@ -15,6 +15,7 @@ const ChangeUserTypeEvent = ({
|
||||
peopleFilter,
|
||||
updateUserType,
|
||||
getUsersList,
|
||||
onClose,
|
||||
}) => {
|
||||
const {
|
||||
toType,
|
||||
@ -58,7 +59,7 @@ const ChangeUserTypeEvent = ({
|
||||
};
|
||||
|
||||
const onChangeUserType = () => {
|
||||
onClose();
|
||||
onClosePanel();
|
||||
updateUserType(toType, userIDs, peopleFilter, fromType)
|
||||
.then(() => {
|
||||
toastr.success(t("SuccessChangeUserType"));
|
||||
@ -83,14 +84,15 @@ const ChangeUserTypeEvent = ({
|
||||
});
|
||||
};
|
||||
|
||||
const onClose = () => {
|
||||
const onClosePanel = () => {
|
||||
setVisible(false);
|
||||
onClose();
|
||||
};
|
||||
|
||||
const onCloseAction = async () => {
|
||||
await getUsersList(peopleFilter);
|
||||
abortCallback && abortCallback();
|
||||
onClose();
|
||||
onClosePanel();
|
||||
};
|
||||
|
||||
const getType = (type) => {
|
||||
@ -99,6 +101,8 @@ const ChangeUserTypeEvent = ({
|
||||
return t("Common:DocSpaceAdmin");
|
||||
case "manager":
|
||||
return t("Common:RoomAdmin");
|
||||
case "collaborator":
|
||||
return t("Common:Collaborator");
|
||||
case "user":
|
||||
default:
|
||||
return t("Common:User");
|
||||
|
@ -42,6 +42,8 @@ const InvitePanel = ({
|
||||
reloadSelectionParentRoom,
|
||||
setUpdateRoomMembers,
|
||||
roomsView,
|
||||
getUsersList,
|
||||
filter,
|
||||
}) => {
|
||||
const [selectedRoom, setSelectedRoom] = useState(null);
|
||||
const [hasErrors, setHasErrors] = useState(false);
|
||||
@ -186,6 +188,10 @@ const InvitePanel = ({
|
||||
} catch (err) {
|
||||
toastr.error(err);
|
||||
setIsLoading(false);
|
||||
} finally {
|
||||
if (roomId === -1) {
|
||||
await getUsersList(filter , false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -269,7 +275,8 @@ const InvitePanel = ({
|
||||
export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
|
||||
const { theme } = auth.settingsStore;
|
||||
|
||||
const { getUsersByQuery, inviteUsers } = peopleStore.usersStore;
|
||||
const { getUsersByQuery, inviteUsers, getUsersList } = peopleStore.usersStore;
|
||||
const { filter } = peopleStore.filterStore;
|
||||
const {
|
||||
setIsMobileHidden: setInfoPanelIsMobileHidden,
|
||||
reloadSelectionParentRoom,
|
||||
@ -323,6 +330,8 @@ export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
|
||||
reloadSelectionParentRoom,
|
||||
setUpdateRoomMembers,
|
||||
roomsView,
|
||||
getUsersList,
|
||||
filter,
|
||||
};
|
||||
})(
|
||||
withTranslation([
|
||||
|
@ -67,7 +67,9 @@ export default inject(({ uploadDataStore }, { item }) => {
|
||||
const loadingFile = !file || !file.uniqueId ? null : file;
|
||||
|
||||
const currentFileUploadProgress =
|
||||
file && loadingFile.uniqueId === item.uniqueId ? loadingFile.percent : null;
|
||||
file && loadingFile?.uniqueId === item?.uniqueId
|
||||
? loadingFile.percent
|
||||
: null;
|
||||
|
||||
return {
|
||||
percent: isParallel
|
||||
|
@ -39,6 +39,8 @@ const HistoryBlock = ({
|
||||
? initiator.avatarSmall
|
||||
: DefaultUserAvatarSmall;
|
||||
|
||||
const isSelectedFile = !selection.isFolder && !selection.isRoom;
|
||||
|
||||
return (
|
||||
<StyledHistoryBlock
|
||||
withBottomDivider={!isLastEntity}
|
||||
@ -75,7 +77,7 @@ const HistoryBlock = ({
|
||||
selectionParentRoom={selectionParentRoom}
|
||||
/>
|
||||
|
||||
{isItemAction && (
|
||||
{isItemAction && !isSelectedFile && (
|
||||
<HistoryBlockItemList
|
||||
t={t}
|
||||
items={[json, ...groupedFeeds]}
|
||||
|
@ -21,14 +21,23 @@ export const HistoryBlockItemList = ({
|
||||
const onShowMore = () => setIsShowMore(true);
|
||||
|
||||
const parsedItems = items.map((item) => {
|
||||
const indexPoint = item.Title.lastIndexOf(".");
|
||||
const splitTitle = item.Title.split(".");
|
||||
const splitTitleLength = splitTitle.length;
|
||||
|
||||
const fileExst =
|
||||
splitTitleLength != 1 ? `.${splitTitle[splitTitleLength - 1]}` : null;
|
||||
|
||||
const title =
|
||||
splitTitleLength <= 2 ? splitTitle[0] : item.Title.slice(0, indexPoint);
|
||||
|
||||
return {
|
||||
...item,
|
||||
isRoom: item.Item === "room",
|
||||
isFolder: item.Item === "folder",
|
||||
roomType: RoomsType[item.AdditionalInfo],
|
||||
title: splitTitle[0],
|
||||
fileExst: splitTitle[1] ? `.${splitTitle[1]}` : null,
|
||||
title,
|
||||
fileExst,
|
||||
id: item.ItemId.split("_")[0],
|
||||
viewUrl: item.itemId,
|
||||
};
|
||||
|
@ -20,12 +20,6 @@ const History = ({
|
||||
openUser,
|
||||
isVisitor,
|
||||
isCollaborator,
|
||||
searchTitleOpenLocation,
|
||||
itemOpenLocation,
|
||||
isLoadedSearchFiles,
|
||||
getFolderInfo,
|
||||
getFileInfo,
|
||||
setSelectionFiles,
|
||||
}) => {
|
||||
const [history, setHistory] = useState(null);
|
||||
const [showLoader, setShowLoader] = useState(false);
|
||||
@ -36,27 +30,6 @@ const History = ({
|
||||
return () => (isMount.current = false);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!(searchTitleOpenLocation && isLoadedSearchFiles && itemOpenLocation))
|
||||
return;
|
||||
|
||||
const requestInfo = itemOpenLocation.isFolder ? getFolderInfo : getFileInfo;
|
||||
|
||||
requestInfo(+itemOpenLocation.id).then((res) => {
|
||||
if (itemOpenLocation.isFolder) res.isFolder = true;
|
||||
|
||||
setSelectionFiles([res]);
|
||||
setSelection(res);
|
||||
});
|
||||
}, [
|
||||
searchTitleOpenLocation,
|
||||
isLoadedSearchFiles,
|
||||
itemOpenLocation,
|
||||
getFolderInfo,
|
||||
getFileInfo,
|
||||
setSelectionFiles,
|
||||
]);
|
||||
|
||||
const fetchHistory = async (itemId) => {
|
||||
let module = "files";
|
||||
if (selection.isRoom) module = "rooms";
|
||||
@ -167,18 +140,8 @@ export default inject(({ auth, filesStore, filesActionsStore }) => {
|
||||
} = auth.infoPanelStore;
|
||||
const { personal, culture } = auth.settingsStore;
|
||||
|
||||
const {
|
||||
getHistory,
|
||||
getFolderInfo,
|
||||
getFileInfo,
|
||||
setSelection: setSelectionFiles,
|
||||
} = filesStore;
|
||||
const {
|
||||
checkAndOpenLocationAction,
|
||||
searchTitleOpenLocation,
|
||||
itemOpenLocation,
|
||||
isLoadedSearchFiles,
|
||||
} = filesActionsStore;
|
||||
const { getHistory } = filesStore;
|
||||
const { checkAndOpenLocationAction } = filesActionsStore;
|
||||
|
||||
const { user } = userStore;
|
||||
const isVisitor = user.isVisitor;
|
||||
@ -196,11 +159,5 @@ export default inject(({ auth, filesStore, filesActionsStore }) => {
|
||||
openUser,
|
||||
isVisitor,
|
||||
isCollaborator,
|
||||
searchTitleOpenLocation,
|
||||
itemOpenLocation,
|
||||
isLoadedSearchFiles,
|
||||
getFolderInfo,
|
||||
getFileInfo,
|
||||
setSelectionFiles,
|
||||
};
|
||||
})(withTranslation(["InfoPanel", "Common", "Translations"])(observer(History)));
|
||||
|
@ -90,6 +90,8 @@ const User = ({
|
||||
? "admin"
|
||||
: option.key === "roomAdmin"
|
||||
? "manager"
|
||||
: option.key === "collaborator"
|
||||
? "collaborator"
|
||||
: "user";
|
||||
|
||||
const successCallback = () => {
|
||||
@ -98,7 +100,13 @@ const User = ({
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
if (!changeUserType(userType, [user], successCallback, abortCallback)) {
|
||||
const needChangeUserType =
|
||||
((user.isVisitor || user.isCollaborator) && userType === "manager") ||
|
||||
(user.isVisitor && userType === "collaborator");
|
||||
|
||||
if (needChangeUserType) {
|
||||
changeUserType(userType, [user], successCallback, abortCallback);
|
||||
} else {
|
||||
updateRole(option);
|
||||
}
|
||||
};
|
||||
@ -110,7 +118,7 @@ const User = ({
|
||||
const withTooltip = user.isOwner || user.isAdmin;
|
||||
|
||||
const tooltipContent = `${
|
||||
user.isAdmin ? t("Common:DocSpaceAdmin") : t("Common:Owner")
|
||||
user.isOwner ? t("Common:DocSpaceOwner") : t("Common:DocSpaceAdmin")
|
||||
}. ${t("Common:HasFullAccess")}`;
|
||||
|
||||
return (
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from "react";
|
||||
import React, { useEffect, useMemo } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import RowContainer from "@docspace/components/row-container";
|
||||
import SimpleFilesRow from "./SimpleFilesRow";
|
||||
@ -83,7 +83,7 @@ const FilesRowContainer = ({
|
||||
isRooms,
|
||||
isTrashFolder,
|
||||
withPaging,
|
||||
setUploadedFileIdWithVersion,
|
||||
highlightFile,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
if ((viewAs !== "table" && viewAs !== "row") || !sectionWidth) return;
|
||||
@ -100,6 +100,32 @@ const FilesRowContainer = ({
|
||||
}
|
||||
}, [sectionWidth]);
|
||||
|
||||
const filesListNode = useMemo(() => {
|
||||
return filesList.map((item, index) => (
|
||||
<SimpleFilesRow
|
||||
id={`${item?.isFolder ? "folder" : "file"}_${item.id}`}
|
||||
key={
|
||||
item?.version ? `${item.id}_${item.version}` : `${item.id}_${index}`
|
||||
}
|
||||
item={item}
|
||||
itemIndex={index}
|
||||
sectionWidth={sectionWidth}
|
||||
isRooms={isRooms}
|
||||
isTrashFolder={isTrashFolder}
|
||||
isHighlight={
|
||||
highlightFile.id == item.id && highlightFile.isExst === !item.fileExst
|
||||
}
|
||||
/>
|
||||
));
|
||||
}, [
|
||||
filesList,
|
||||
sectionWidth,
|
||||
isRooms,
|
||||
highlightFile.id,
|
||||
highlightFile.isExst,
|
||||
isTrashFolder,
|
||||
]);
|
||||
|
||||
return (
|
||||
<StyledRowContainer
|
||||
className="files-row-container"
|
||||
@ -111,18 +137,7 @@ const FilesRowContainer = ({
|
||||
useReactWindow={!withPaging}
|
||||
itemHeight={59}
|
||||
>
|
||||
{filesList.map((item, index) => (
|
||||
<SimpleFilesRow
|
||||
id={`${item?.isFolder ? "folder" : "file"}_${item.id}`}
|
||||
key={`${item.id}_${index}`}
|
||||
item={item}
|
||||
itemIndex={index}
|
||||
sectionWidth={sectionWidth}
|
||||
isRooms={isRooms}
|
||||
isTrashFolder={isTrashFolder}
|
||||
setUploadedFileIdWithVersion={setUploadedFileIdWithVersion}
|
||||
/>
|
||||
))}
|
||||
{filesListNode}
|
||||
</StyledRowContainer>
|
||||
);
|
||||
};
|
||||
@ -136,7 +151,7 @@ export default inject(({ filesStore, auth, treeFoldersStore }) => {
|
||||
fetchMoreFiles,
|
||||
hasMoreFiles,
|
||||
roomsFilterTotal,
|
||||
setUploadedFileIdWithVersion,
|
||||
highlightFile,
|
||||
} = filesStore;
|
||||
const { isVisible: infoPanelVisible } = auth.infoPanelStore;
|
||||
const { isRoomsFolder, isArchiveFolder, isTrashFolder } = treeFoldersStore;
|
||||
@ -155,6 +170,6 @@ export default inject(({ filesStore, auth, treeFoldersStore }) => {
|
||||
isRooms,
|
||||
isTrashFolder,
|
||||
withPaging,
|
||||
setUploadedFileIdWithVersion,
|
||||
highlightFile,
|
||||
};
|
||||
})(observer(FilesRowContainer));
|
||||
|
@ -78,7 +78,7 @@ const StyledSimpleFilesRow = styled(Row)`
|
||||
${(props) =>
|
||||
props.isHighlight &&
|
||||
css`
|
||||
${checkedStyle}
|
||||
${marginStyles}
|
||||
|
||||
margin-top: -2px;
|
||||
padding-top: 1px;
|
||||
@ -251,14 +251,11 @@ const SimpleFilesRow = (props) => {
|
||||
isRooms,
|
||||
|
||||
folderCategory,
|
||||
setUploadedFileIdWithVersion,
|
||||
isHighlight,
|
||||
} = props;
|
||||
|
||||
const [isDragOver, setIsDragOver] = React.useState(false);
|
||||
const [isHighlight, setIsHighlight] = React.useState(false);
|
||||
|
||||
let timeoutRef = React.useRef(null);
|
||||
let isMounted;
|
||||
const withAccess = item.security?.Lock;
|
||||
const isSmallContainer = sectionWidth <= 500;
|
||||
|
||||
@ -272,28 +269,6 @@ const SimpleFilesRow = (props) => {
|
||||
/>
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setIsHighlight(false);
|
||||
return () => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
timeoutRef.current = null;
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!item.upgradeVersion) return;
|
||||
|
||||
isMounted = true;
|
||||
setIsHighlight(true);
|
||||
setUploadedFileIdWithVersion(null);
|
||||
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
isMounted && setIsHighlight(false);
|
||||
}, 2000);
|
||||
}, [item]);
|
||||
|
||||
const onDragOver = (dragOver) => {
|
||||
if (dragOver !== isDragOver) {
|
||||
setIsDragOver(dragOver);
|
||||
|
@ -193,6 +193,10 @@ const StyledTableRow = styled(TableRow)`
|
||||
}
|
||||
}
|
||||
|
||||
.table-container_cell:not(.table-container_element-wrapper, .table-container_file-name-cell) {
|
||||
padding-right: ${(props) => props.hideColumns && `0px`};
|
||||
}
|
||||
|
||||
.table-container_file-name-cell {
|
||||
margin-left: -24px;
|
||||
padding-left: 24px;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useCallback } from "react";
|
||||
import React, { useEffect, useRef, useCallback, useMemo } from "react";
|
||||
import elementResizeDetectorMaker from "element-resize-detector";
|
||||
import TableContainer from "@docspace/components/table-container";
|
||||
import { inject, observer } from "mobx-react";
|
||||
@ -120,7 +120,7 @@ const Table = ({
|
||||
withPaging,
|
||||
columnStorageName,
|
||||
columnInfoPanelStorageName,
|
||||
setUploadedFileIdWithVersion,
|
||||
highlightFile,
|
||||
}) => {
|
||||
const [tagCount, setTagCount] = React.useState(null);
|
||||
const [hideColumns, setHideColumns] = React.useState(false);
|
||||
@ -175,6 +175,41 @@ const Table = ({
|
||||
}
|
||||
}, []);
|
||||
|
||||
const filesListNode = useMemo(() => {
|
||||
return filesList.map((item, index) => (
|
||||
<TableRow
|
||||
id={`${item?.isFolder ? "folder" : "file"}_${item.id}`}
|
||||
key={
|
||||
item?.version ? `${item.id}_${item.version}` : `${item.id}_${index}`
|
||||
}
|
||||
item={item}
|
||||
itemIndex={index}
|
||||
index={index}
|
||||
setFirsElemChecked={setFirsElemChecked}
|
||||
setHeaderBorder={setHeaderBorder}
|
||||
theme={theme}
|
||||
tagCount={tagCount}
|
||||
isRooms={isRooms}
|
||||
isTrashFolder={isTrashFolder}
|
||||
hideColumns={hideColumns}
|
||||
isHighlight={
|
||||
highlightFile.id == item.id && highlightFile.isExst === !item.fileExst
|
||||
}
|
||||
/>
|
||||
));
|
||||
}, [
|
||||
filesList,
|
||||
setFirsElemChecked,
|
||||
setHeaderBorder,
|
||||
theme,
|
||||
tagCount,
|
||||
isRooms,
|
||||
hideColumns,
|
||||
highlightFile.id,
|
||||
highlightFile.isExst,
|
||||
isTrashFolder,
|
||||
]);
|
||||
|
||||
return (
|
||||
<StyledTableContainer useReactWindow={!withPaging} forwardedRef={ref}>
|
||||
<TableHeader
|
||||
@ -195,23 +230,7 @@ const Table = ({
|
||||
columnInfoPanelStorageName={columnInfoPanelStorageName}
|
||||
itemHeight={49}
|
||||
>
|
||||
{filesList.map((item, index) => (
|
||||
<TableRow
|
||||
id={`${item?.isFolder ? "folder" : "file"}_${item.id}`}
|
||||
key={`${item.id}_${index}`}
|
||||
item={item}
|
||||
itemIndex={index}
|
||||
index={index}
|
||||
setFirsElemChecked={setFirsElemChecked}
|
||||
setHeaderBorder={setHeaderBorder}
|
||||
theme={theme}
|
||||
tagCount={tagCount}
|
||||
isRooms={isRooms}
|
||||
isTrashFolder={isTrashFolder}
|
||||
hideColumns={hideColumns}
|
||||
setUploadedFileIdWithVersion={setUploadedFileIdWithVersion}
|
||||
/>
|
||||
))}
|
||||
{filesListNode}
|
||||
</TableBody>
|
||||
</StyledTableContainer>
|
||||
);
|
||||
@ -235,7 +254,7 @@ export default inject(({ filesStore, treeFoldersStore, auth, tableStore }) => {
|
||||
hasMoreFiles,
|
||||
filterTotal,
|
||||
roomsFilterTotal,
|
||||
setUploadedFileIdWithVersion,
|
||||
highlightFile,
|
||||
} = filesStore;
|
||||
|
||||
const { withPaging, theme } = auth.settingsStore;
|
||||
@ -257,6 +276,6 @@ export default inject(({ filesStore, treeFoldersStore, auth, tableStore }) => {
|
||||
withPaging,
|
||||
columnStorageName,
|
||||
columnInfoPanelStorageName,
|
||||
setUploadedFileIdWithVersion,
|
||||
highlightFile,
|
||||
};
|
||||
})(observer(Table));
|
||||
|
@ -39,14 +39,11 @@ const FilesTableRow = (props) => {
|
||||
id,
|
||||
isRooms,
|
||||
isTrashFolder,
|
||||
setUploadedFileIdWithVersion,
|
||||
isHighlight,
|
||||
hideColumns,
|
||||
} = props;
|
||||
const [isHighlight, setIsHighlight] = React.useState(false);
|
||||
const { acceptBackground, background } = theme.dragAndDrop;
|
||||
|
||||
let timeoutRef = React.useRef(null);
|
||||
let isMounted;
|
||||
|
||||
const element = (
|
||||
<ItemIcon
|
||||
id={item.id}
|
||||
@ -100,29 +97,6 @@ const FilesTableRow = (props) => {
|
||||
}
|
||||
}, [checkedProps, isActive, showHotkeyBorder]);
|
||||
|
||||
React.useEffect(() => {
|
||||
setIsHighlight(false);
|
||||
|
||||
return () => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
timeoutRef.current = null;
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!item.upgradeVersion) return;
|
||||
|
||||
isMounted = true;
|
||||
setIsHighlight(true);
|
||||
setUploadedFileIdWithVersion(null);
|
||||
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
isMounted && setIsHighlight(false);
|
||||
}, 2000);
|
||||
}, [item]);
|
||||
|
||||
const idWithFileExst = item.fileExst
|
||||
? `${item.id}_${item.fileExst}`
|
||||
: item.id ?? "";
|
||||
@ -168,6 +142,7 @@ const FilesTableRow = (props) => {
|
||||
}
|
||||
isRoom={item.isRoom}
|
||||
isHighlight={isHighlight}
|
||||
hideColumns={hideColumns}
|
||||
>
|
||||
{isRooms ? (
|
||||
<RoomsRowDataComponent
|
||||
|
@ -54,25 +54,9 @@ const FileTile = (props) => {
|
||||
isRooms,
|
||||
withCtrlSelect,
|
||||
withShiftSelect,
|
||||
setUploadedFileIdWithVersion,
|
||||
isHighlight,
|
||||
} = props;
|
||||
|
||||
const [isHighlight, setIsHighlight] = React.useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setIsHighlight(false);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!item.upgradeVersion) return;
|
||||
|
||||
setIsHighlight(true);
|
||||
|
||||
return () => {
|
||||
if (isHighlight) setUploadedFileIdWithVersion(null);
|
||||
};
|
||||
}, [item, isHighlight]);
|
||||
|
||||
const temporaryExtension =
|
||||
item.id === -1 ? `.${item.fileExst}` : item.fileExst;
|
||||
|
||||
@ -159,28 +143,33 @@ const FileTile = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ settingsStore, filesStore, treeFoldersStore }) => {
|
||||
const { getIcon } = settingsStore;
|
||||
const {
|
||||
setSelection,
|
||||
withCtrlSelect,
|
||||
withShiftSelect,
|
||||
setUploadedFileIdWithVersion,
|
||||
} = filesStore;
|
||||
export default inject(
|
||||
({ settingsStore, filesStore, treeFoldersStore }, { item }) => {
|
||||
const { getIcon } = settingsStore;
|
||||
const {
|
||||
setSelection,
|
||||
withCtrlSelect,
|
||||
withShiftSelect,
|
||||
highlightFile,
|
||||
} = filesStore;
|
||||
|
||||
const { isRoomsFolder, isArchiveFolder } = treeFoldersStore;
|
||||
const isHighlight =
|
||||
highlightFile.id == item?.id && highlightFile.isExst === !item?.fileExst;
|
||||
|
||||
const isRooms = isRoomsFolder || isArchiveFolder;
|
||||
const { isRoomsFolder, isArchiveFolder } = treeFoldersStore;
|
||||
|
||||
return {
|
||||
getIcon,
|
||||
setSelection,
|
||||
isRooms,
|
||||
withCtrlSelect,
|
||||
withShiftSelect,
|
||||
setUploadedFileIdWithVersion,
|
||||
};
|
||||
})(
|
||||
const isRooms = isRoomsFolder || isArchiveFolder;
|
||||
|
||||
return {
|
||||
getIcon,
|
||||
setSelection,
|
||||
isRooms,
|
||||
withCtrlSelect,
|
||||
withShiftSelect,
|
||||
isHighlight,
|
||||
};
|
||||
}
|
||||
)(
|
||||
withTranslation(["Files", "InfoPanel"])(
|
||||
withRouter(
|
||||
withFileActions(withBadges(withQuickButtons(observer(FileTile))))
|
||||
|
@ -1,4 +1,10 @@
|
||||
import React, { useEffect, useRef, useCallback, useState } from "react";
|
||||
import React, {
|
||||
useEffect,
|
||||
useRef,
|
||||
useCallback,
|
||||
useState,
|
||||
useMemo,
|
||||
} from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import elementResizeDetectorMaker from "element-resize-detector";
|
||||
import TileContainer from "./sub-components/TileContainer";
|
||||
@ -89,6 +95,38 @@ const FilesTileContainer = ({ filesList, t, sectionWidth, withPaging }) => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const filesListNode = useMemo(() => {
|
||||
return filesList.map((item, index) => {
|
||||
return index % 11 == 0 ? (
|
||||
<FileTile
|
||||
id={`${item?.isFolder ? "folder" : "file"}_${item.id}`}
|
||||
key={
|
||||
item?.version ? `${item.id}_${item.version}` : `${item.id}_${index}`
|
||||
}
|
||||
item={item}
|
||||
itemIndex={index}
|
||||
sectionWidth={sectionWidth}
|
||||
selectableRef={onSetTileRef}
|
||||
thumbSize={thumbSize}
|
||||
columnCount={columnCount}
|
||||
withRef={true}
|
||||
/>
|
||||
) : (
|
||||
<FileTile
|
||||
id={`${item?.isFolder ? "folder" : "file"}_${item.id}`}
|
||||
key={
|
||||
item?.version ? `${item.id}_${item.version}` : `${item.id}_${index}`
|
||||
}
|
||||
item={item}
|
||||
itemIndex={index}
|
||||
sectionWidth={sectionWidth}
|
||||
thumbSize={thumbSize}
|
||||
columnCount={columnCount}
|
||||
/>
|
||||
);
|
||||
});
|
||||
}, [filesList, sectionWidth, onSetTileRef, thumbSize, columnCount]);
|
||||
|
||||
return (
|
||||
<TileContainer
|
||||
className="tile-container"
|
||||
@ -97,31 +135,7 @@ const FilesTileContainer = ({ filesList, t, sectionWidth, withPaging }) => {
|
||||
headingFolders={t("Translations:Folders")}
|
||||
headingFiles={t("Translations:Files")}
|
||||
>
|
||||
{filesList.map((item, index) => {
|
||||
return index % 11 == 0 ? (
|
||||
<FileTile
|
||||
id={`${item?.isFolder ? "folder" : "file"}_${item.id}`}
|
||||
key={`${item.id}_${index}`}
|
||||
item={item}
|
||||
itemIndex={index}
|
||||
sectionWidth={sectionWidth}
|
||||
selectableRef={onSetTileRef}
|
||||
thumbSize={thumbSize}
|
||||
columnCount={columnCount}
|
||||
withRef={true}
|
||||
/>
|
||||
) : (
|
||||
<FileTile
|
||||
id={`${item?.isFolder ? "folder" : "file"}_${item.id}`}
|
||||
key={`${item.id}_${index}`}
|
||||
item={item}
|
||||
itemIndex={index}
|
||||
sectionWidth={sectionWidth}
|
||||
thumbSize={thumbSize}
|
||||
columnCount={columnCount}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{filesListNode}
|
||||
</TileContainer>
|
||||
);
|
||||
};
|
||||
|
@ -244,6 +244,12 @@ const StyledTile = styled.div`
|
||||
.new-items {
|
||||
min-width: 16px;
|
||||
}
|
||||
|
||||
${(props) =>
|
||||
props.isHighlight &&
|
||||
css`
|
||||
${animationStyles}
|
||||
`}
|
||||
`;
|
||||
|
||||
const StyledFileTileTop = styled.div`
|
||||
|
@ -163,13 +163,6 @@ StyledTileContainer.defaultProps = { theme: Base };
|
||||
class TileContainer extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
selectedFilterData: {
|
||||
sortId: props.filter.sortBy,
|
||||
sortDirection: props.filter.sortOrder,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -181,10 +174,9 @@ class TileContainer extends React.PureComponent {
|
||||
style,
|
||||
headingFolders,
|
||||
headingFiles,
|
||||
isDesc,
|
||||
} = this.props;
|
||||
|
||||
const { selectedFilterData } = this.state;
|
||||
|
||||
const Rooms = [];
|
||||
const Folders = [];
|
||||
const Files = [];
|
||||
@ -260,7 +252,7 @@ class TileContainer extends React.PureComponent {
|
||||
className={`${className} files-tile-container`}
|
||||
style={style}
|
||||
useReactWindow={useReactWindow}
|
||||
isDesc={selectedFilterData.sortDirection === "desc"}
|
||||
isDesc={isDesc}
|
||||
>
|
||||
{useReactWindow ? (
|
||||
<InfiniteGrid>{renderTile}</InfiniteGrid>
|
||||
@ -284,20 +276,19 @@ TileContainer.defaultProps = {
|
||||
id: "tileContainer",
|
||||
};
|
||||
|
||||
export default inject(
|
||||
({ auth, filesStore, treeFoldersStore, selectedFolderStore }) => {
|
||||
const { personal } = auth.settingsStore;
|
||||
const { fetchFiles, filter, setIsLoading } = filesStore;
|
||||
const { isFavoritesFolder, isRecentFolder } = treeFoldersStore;
|
||||
export default inject(({ auth, filesStore, treeFoldersStore }) => {
|
||||
const { personal } = auth.settingsStore;
|
||||
const { fetchFiles, filter, setIsLoading } = filesStore;
|
||||
const { isFavoritesFolder, isRecentFolder } = treeFoldersStore;
|
||||
|
||||
return {
|
||||
personal,
|
||||
fetchFiles,
|
||||
filter,
|
||||
setIsLoading,
|
||||
isFavoritesFolder,
|
||||
isRecentFolder,
|
||||
selectedFolderId: selectedFolderStore.id,
|
||||
};
|
||||
}
|
||||
)(observer(withTranslation(["Files", "Common"])(TileContainer)));
|
||||
const isDesc = filter?.sortOrder === "desc";
|
||||
|
||||
return {
|
||||
personal,
|
||||
fetchFiles,
|
||||
setIsLoading,
|
||||
isFavoritesFolder,
|
||||
isRecentFolder,
|
||||
isDesc,
|
||||
};
|
||||
})(observer(withTranslation(["Files", "Common"])(TileContainer)));
|
||||
|
@ -40,7 +40,6 @@ const SectionBodyContent = (props) => {
|
||||
setScrollToItem,
|
||||
filesList,
|
||||
uploaded,
|
||||
setSearchTitleOpenLocation,
|
||||
} = props;
|
||||
|
||||
useEffect(() => {
|
||||
@ -117,7 +116,6 @@ const SectionBodyContent = (props) => {
|
||||
e.target.closest(".search-input-block")
|
||||
) {
|
||||
setSelection([]);
|
||||
setSearchTitleOpenLocation(null);
|
||||
setBufferSelection(null);
|
||||
setHotkeyCaretStart(null);
|
||||
setHotkeyCaret(null);
|
||||
@ -315,7 +313,6 @@ export default inject(
|
||||
setScrollToItem,
|
||||
filesList,
|
||||
uploaded: uploadDataStore.uploaded,
|
||||
setSearchTitleOpenLocation: filesActionsStore.setSearchTitleOpenLocation,
|
||||
};
|
||||
}
|
||||
)(
|
||||
|
@ -174,9 +174,6 @@ const SectionFilterContent = ({
|
||||
isPersonalRoom,
|
||||
setCurrentRoomsFilter,
|
||||
providers,
|
||||
searchTitleOpenLocation,
|
||||
isLoadedLocationFiles,
|
||||
setIsLoadedSearchFiles,
|
||||
isLoadedEmptyPage,
|
||||
isEmptyPage,
|
||||
clearSearch,
|
||||
@ -196,12 +193,6 @@ const SectionFilterContent = ({
|
||||
}
|
||||
}, [isLoadedEmptyPage, isEmptyPage]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!(searchTitleOpenLocation && isLoadedLocationFiles)) return;
|
||||
|
||||
onSearch(searchTitleOpenLocation);
|
||||
}, [searchTitleOpenLocation, isLoadedLocationFiles, onSearch]);
|
||||
|
||||
const onFilter = React.useCallback(
|
||||
(data) => {
|
||||
if (isRooms) {
|
||||
@ -316,7 +307,6 @@ const SectionFilterContent = ({
|
||||
setIsLoading(false)
|
||||
);
|
||||
} else {
|
||||
setIsLoadedSearchFiles(false);
|
||||
const newFilter = filter.clone();
|
||||
newFilter.page = 0;
|
||||
newFilter.search = data;
|
||||
@ -325,7 +315,6 @@ const SectionFilterContent = ({
|
||||
|
||||
fetchFiles(selectedFolderId, newFilter).finally(() => {
|
||||
setIsLoading(false);
|
||||
setIsLoadedSearchFiles(true);
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -337,7 +326,6 @@ const SectionFilterContent = ({
|
||||
selectedFolderId,
|
||||
filter,
|
||||
roomsFilter,
|
||||
setIsLoadedSearchFiles,
|
||||
]
|
||||
);
|
||||
|
||||
@ -394,21 +382,14 @@ const SectionFilterContent = ({
|
||||
);
|
||||
|
||||
const getSelectedInputValue = React.useCallback(() => {
|
||||
return searchTitleOpenLocation
|
||||
? searchTitleOpenLocation
|
||||
: isRooms
|
||||
return isRooms
|
||||
? roomsFilter.filterValue
|
||||
? roomsFilter.filterValue
|
||||
: ""
|
||||
: filter.search
|
||||
? filter.search
|
||||
: "";
|
||||
}, [
|
||||
isRooms,
|
||||
roomsFilter.filterValue,
|
||||
filter.search,
|
||||
searchTitleOpenLocation,
|
||||
]);
|
||||
}, [isRooms, roomsFilter.filterValue, filter.search]);
|
||||
|
||||
const getSelectedSortData = React.useCallback(() => {
|
||||
const currentFilter = isRooms ? roomsFilter : filter;
|
||||
@ -1506,13 +1487,6 @@ export default inject(
|
||||
|
||||
const { isVisible: infoPanelVisible } = auth.infoPanelStore;
|
||||
|
||||
const {
|
||||
searchTitleOpenLocation,
|
||||
setSearchTitleOpenLocation,
|
||||
isLoadedLocationFiles,
|
||||
setIsLoadedSearchFiles,
|
||||
} = filesActionsStore;
|
||||
|
||||
return {
|
||||
user,
|
||||
userId: user.id,
|
||||
@ -1540,11 +1514,6 @@ export default inject(
|
||||
setCurrentRoomsFilter,
|
||||
providers,
|
||||
|
||||
searchTitleOpenLocation,
|
||||
setSearchTitleOpenLocation,
|
||||
isLoadedLocationFiles,
|
||||
setIsLoadedSearchFiles,
|
||||
|
||||
isLoadedEmptyPage,
|
||||
isEmptyPage,
|
||||
|
||||
|
@ -38,7 +38,7 @@ class AccessRightsStore {
|
||||
|
||||
const { id: userId, statusType, role } = user;
|
||||
|
||||
if (userId === id || statusType === EmployeeStatus.Disabled) return false;
|
||||
if (userId === id || statusType === "disabled") return false;
|
||||
|
||||
switch (role) {
|
||||
case "owner":
|
||||
|
@ -51,9 +51,6 @@ class FilesActionStore {
|
||||
accessRightsStore;
|
||||
|
||||
isBulkDownload = false;
|
||||
searchTitleOpenLocation = null;
|
||||
itemOpenLocation = null;
|
||||
isLoadedLocationFiles = false;
|
||||
isLoadedSearchFiles = false;
|
||||
isGroupMenuBlocked = false;
|
||||
|
||||
@ -1160,48 +1157,26 @@ class FilesActionStore {
|
||||
}
|
||||
};
|
||||
|
||||
setSearchTitleOpenLocation = (searchTitleOpenLocation) => {
|
||||
this.searchTitleOpenLocation = searchTitleOpenLocation;
|
||||
};
|
||||
|
||||
setItemOpenLocation = (itemOpenLocation) => {
|
||||
this.itemOpenLocation = itemOpenLocation;
|
||||
};
|
||||
|
||||
setIsLoadedLocationFiles = (isLoadedLocationFiles) => {
|
||||
this.isLoadedLocationFiles = isLoadedLocationFiles;
|
||||
};
|
||||
|
||||
setIsLoadedSearchFiles = (isLoadedSearchFiles) => {
|
||||
this.isLoadedSearchFiles = isLoadedSearchFiles;
|
||||
};
|
||||
|
||||
openLocationAction = async (locationId) => {
|
||||
this.setIsLoadedLocationFiles(false);
|
||||
this.filesStore.setBufferSelection(null);
|
||||
|
||||
const files = await this.filesStore.fetchFiles(locationId, null);
|
||||
this.setIsLoadedLocationFiles(true);
|
||||
return files;
|
||||
};
|
||||
|
||||
checkAndOpenLocationAction = async (item) => {
|
||||
const filterData = FilesFilter.getDefault();
|
||||
const { filter, setHighlightFile, fetchFiles } = this.filesStore;
|
||||
const newFilter = filter.clone();
|
||||
|
||||
this.setIsLoadedSearchFiles(false);
|
||||
newFilter.page = 0;
|
||||
newFilter.search = item.title;
|
||||
|
||||
if (this.itemOpenLocation?.title !== item.title) {
|
||||
this.setSearchTitleOpenLocation(null);
|
||||
}
|
||||
|
||||
this.setItemOpenLocation(null);
|
||||
|
||||
api.files
|
||||
.getFolder(item.ExtraLocation, filterData)
|
||||
fetchFiles(item.ExtraLocation, newFilter)
|
||||
.then(() => {
|
||||
this.openLocationAction(item.ExtraLocation);
|
||||
this.setSearchTitleOpenLocation(item.title);
|
||||
this.setItemOpenLocation(item);
|
||||
setHighlightFile({
|
||||
highlightFileId: item.id,
|
||||
isFileHasExst: !item.fileExst,
|
||||
});
|
||||
})
|
||||
.catch((err) => toastr.error(err));
|
||||
};
|
||||
|
@ -42,6 +42,7 @@ const PaymentRequiredHttpCode = 402;
|
||||
const UnauthorizedHttpCode = 401;
|
||||
|
||||
const THUMBNAILS_CACHE = 500;
|
||||
let timerId;
|
||||
|
||||
class FilesStore {
|
||||
authStore;
|
||||
@ -126,7 +127,8 @@ class FilesStore {
|
||||
isLoadedEmptyPage = false;
|
||||
isPreview = false;
|
||||
tempFilter = null;
|
||||
uploadedFileIdWithVersion = null;
|
||||
|
||||
highlightFile = {};
|
||||
thumbnails = new Set();
|
||||
|
||||
constructor(
|
||||
@ -476,8 +478,28 @@ class FilesStore {
|
||||
this.tempFilter = filser;
|
||||
};
|
||||
|
||||
setUploadedFileIdWithVersion = (uploadedFileIdWithVersion) => {
|
||||
this.uploadedFileIdWithVersion = uploadedFileIdWithVersion;
|
||||
setHighlightFile = (highlightFile) => {
|
||||
const { highlightFileId, isFileHasExst } = highlightFile;
|
||||
|
||||
runInAction(() => {
|
||||
this.highlightFile = {
|
||||
id: highlightFileId,
|
||||
isExst: isFileHasExst,
|
||||
};
|
||||
});
|
||||
|
||||
if (timerId) {
|
||||
clearTimeout(timerId);
|
||||
timerId = null;
|
||||
}
|
||||
|
||||
if (Object.keys(highlightFile).length === 0) return;
|
||||
|
||||
timerId = setTimeout(() => {
|
||||
runInAction(() => {
|
||||
this.highlightFile = {};
|
||||
});
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
checkSelection = (file) => {
|
||||
@ -2450,8 +2472,6 @@ class FilesStore {
|
||||
viewAccessability,
|
||||
} = item;
|
||||
|
||||
const upgradeVersion = id === this.uploadedFileIdWithVersion;
|
||||
|
||||
const thirdPartyIcon = this.thirdPartyStore.getThirdPartyIcon(
|
||||
item.providerKey,
|
||||
"small"
|
||||
@ -2530,7 +2550,6 @@ class FilesStore {
|
||||
comment,
|
||||
contentLength,
|
||||
contextOptions,
|
||||
upgradeVersion,
|
||||
created,
|
||||
createdBy,
|
||||
encrypted,
|
||||
|
@ -367,6 +367,8 @@ class UploadDataStore {
|
||||
isShareFolder,
|
||||
} = this.treeFoldersStore;
|
||||
|
||||
if (!this.converted) return;
|
||||
|
||||
const { storeOriginalFiles } = this.settingsStore;
|
||||
|
||||
const isSortedFolder = isRecentFolder || isFavoritesFolder || isShareFolder;
|
||||
@ -513,7 +515,7 @@ class UploadDataStore {
|
||||
}
|
||||
});
|
||||
|
||||
storeOriginalFiles && this.refreshFiles(file);
|
||||
storeOriginalFiles && fileInfo && this.refreshFiles(file);
|
||||
|
||||
if (fileInfo && fileInfo !== "password") {
|
||||
file.fileInfo = fileInfo;
|
||||
@ -540,8 +542,11 @@ class UploadDataStore {
|
||||
const percent = this.getConversationPercent(index + 1);
|
||||
this.setConversionPercent(percent, !!error);
|
||||
|
||||
if (file.fileInfo.version > 2) {
|
||||
this.filesStore.setUploadedFileIdWithVersion(file.fileInfo.id);
|
||||
if (!file.error && file.fileInfo.version > 2) {
|
||||
this.filesStore.setHighlightFile({
|
||||
highlightFileId: file.fileInfo.id,
|
||||
isFileHasExst: !file.fileInfo.fileExst,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -623,8 +628,9 @@ class UploadDataStore {
|
||||
}) > -1;
|
||||
|
||||
if (hasFolder) {
|
||||
if (this.uploaded) this.isParallel = false;
|
||||
else {
|
||||
if (this.uploaded) {
|
||||
this.isParallel = false;
|
||||
} else if (this.isParallel) {
|
||||
this.tempFiles.push({ uploadFiles, folderId, t });
|
||||
return;
|
||||
}
|
||||
@ -850,7 +856,7 @@ class UploadDataStore {
|
||||
newPercent = this.getFilesPercent(uploadedSize);
|
||||
}
|
||||
|
||||
const percentCurrentFile = (index / length) * 100;
|
||||
const percentCurrentFile = ((index + 1) / length) * 100;
|
||||
|
||||
const fileIndex = this.uploadedFilesHistory.findIndex(
|
||||
(f) => f.uniqueId === this.files[indexOfFile].uniqueId
|
||||
@ -888,7 +894,10 @@ class UploadDataStore {
|
||||
});
|
||||
|
||||
if (fileInfo.version > 2) {
|
||||
this.filesStore.setUploadedFileIdWithVersion(fileInfo.id);
|
||||
this.filesStore.setHighlightFile({
|
||||
highlightFileId: fileInfo.id,
|
||||
isFileHasExst: !fileInfo.fileExst,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1130,8 +1139,9 @@ class UploadDataStore {
|
||||
if (!this.isParallel) return;
|
||||
|
||||
const allFilesIsUploaded =
|
||||
this.files.findIndex((f) => f.action !== "uploaded" && !f.error) ===
|
||||
-1;
|
||||
this.files.findIndex(
|
||||
(f) => f.action !== "uploaded" && f.action !== "convert" && !f.error
|
||||
) === -1;
|
||||
|
||||
if (allFilesIsUploaded) {
|
||||
if (!this.filesToConversion.length) {
|
||||
|
@ -2,6 +2,7 @@ const combineUrl = (host = "", ...params) => {
|
||||
let url = host.replace(/\/+$/, "");
|
||||
|
||||
params.forEach((part) => {
|
||||
if (!part) return;
|
||||
const newPart = part.trim().replace(/^\/+/, "");
|
||||
url += newPart
|
||||
? url.length > 0 && url[url.length - 1] === "/"
|
||||
|
@ -22,7 +22,12 @@ const PureText = ({ type, color, ...props }) => <Text {...props} />;
|
||||
const StyledText = styled(PureText)`
|
||||
text-decoration: ${(props) => props.theme.link.textDecoration};
|
||||
|
||||
${(props) => !props.enableUserSelect && NoUserSelect}
|
||||
${(props) =>
|
||||
props.enableUserSelect
|
||||
? css`
|
||||
user-select: text;
|
||||
`
|
||||
: NoUserSelect}
|
||||
|
||||
cursor: ${(props) => props.theme.link.cursor};
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
|
@ -472,6 +472,7 @@ export default function ViewerPlayer(props) {
|
||||
}
|
||||
if (displayUI && props.isPlay && state.isFirstTap) {
|
||||
props.setIsPlay(false);
|
||||
videoRef.current.pause();
|
||||
return dispatch(
|
||||
createAction(ACTION_TYPES.update, {
|
||||
isFirstTap: false,
|
||||
@ -535,6 +536,12 @@ export default function ViewerPlayer(props) {
|
||||
isFirstStart: false,
|
||||
})
|
||||
);
|
||||
|
||||
if (!state.isPlaying) {
|
||||
videoRef.current.play();
|
||||
} else {
|
||||
videoRef.current.pause();
|
||||
}
|
||||
};
|
||||
|
||||
const handleVolumeUpdate = (e) => {
|
||||
@ -734,6 +741,12 @@ export default function ViewerPlayer(props) {
|
||||
|
||||
const lasting = `${currentTime} / ${duration}`;
|
||||
|
||||
if (progress === 100 || !state.isPlaying) {
|
||||
videoRef.current.stop();
|
||||
} else {
|
||||
videoRef.current.play();
|
||||
}
|
||||
|
||||
dispatch(
|
||||
createAction(ACTION_TYPES.update, {
|
||||
duration: lasting,
|
||||
@ -827,10 +840,6 @@ export default function ViewerPlayer(props) {
|
||||
return () => window.removeEventListener("resize", handleResize);
|
||||
}, [videoRef.current, state.isFullScreen]);
|
||||
|
||||
React.useEffect(() => {
|
||||
state.isPlaying ? videoRef.current.play() : videoRef.current.pause();
|
||||
}, [state.isPlaying, videoRef.current]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (videoRef && videoRef.current) {
|
||||
videoRef.current.addEventListener("error", (event) => {
|
||||
|
@ -76,11 +76,22 @@ public class PhotoController : PeopleControllerBase
|
||||
if (!string.IsNullOrEmpty(inDto.TmpFile))
|
||||
{
|
||||
var fileName = Path.GetFileName(inDto.TmpFile);
|
||||
var data = await _userPhotoManager.GetTempPhotoData(fileName);
|
||||
var data = await _userPhotoManager.GetTempPhotoData(fileName);
|
||||
|
||||
UserPhotoThumbnailSettings settings = null;
|
||||
|
||||
if (inDto.Width == 0 && inDto.Height == 0)
|
||||
{
|
||||
using var img = Image.Load(data, out var format);
|
||||
settings = new UserPhotoThumbnailSettings(inDto.X, inDto.Y, img.Width, img.Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings = new UserPhotoThumbnailSettings(inDto.X, inDto.Y, inDto.Width, inDto.Height);
|
||||
}
|
||||
|
||||
_settingsManager.Save(settings, user.Id);
|
||||
|
||||
var settings = new UserPhotoThumbnailSettings(inDto.X, inDto.Y, inDto.Width, inDto.Height);
|
||||
|
||||
_settingsManager.Save(settings, user.Id);
|
||||
await _userPhotoManager.RemovePhoto(user.Id);
|
||||
await _userPhotoManager.SaveOrUpdatePhoto(user.Id, data);
|
||||
await _userPhotoManager.RemoveTempPhoto(fileName);
|
||||
|
@ -186,7 +186,7 @@ public class UserController : PeopleControllerBase
|
||||
UpdateContacts(inDto.Contacts, user);
|
||||
|
||||
_cache.Insert("REWRITE_URL" + _tenantManager.GetCurrentTenant().Id, HttpContext.Request.GetUrlRewriter().ToString(), TimeSpan.FromMinutes(5));
|
||||
user = await _userManagerWrapper.AddUser(user, inDto.PasswordHash, true, false, inDto.Type,
|
||||
user = await _userManagerWrapper.AddUser(user, inDto.PasswordHash, true, false, inDto.Type,
|
||||
false, true, true);
|
||||
|
||||
user.ActivationStatus = EmployeeActivationStatus.Activated;
|
||||
@ -272,10 +272,10 @@ public class UserController : PeopleControllerBase
|
||||
user.WorkFromDate = inDto.Worksfrom != null && inDto.Worksfrom != DateTime.MinValue ? _tenantUtil.DateTimeFromUtc(inDto.Worksfrom) : DateTime.UtcNow.Date;
|
||||
|
||||
UpdateContacts(inDto.Contacts, user, !inDto.FromInviteLink);
|
||||
|
||||
|
||||
_cache.Insert("REWRITE_URL" + _tenantManager.GetCurrentTenant().Id, HttpContext.Request.GetUrlRewriter().ToString(), TimeSpan.FromMinutes(5));
|
||||
|
||||
user = await _userManagerWrapper.AddUser(user, inDto.PasswordHash, inDto.FromInviteLink, true, inDto.Type,
|
||||
|
||||
user = await _userManagerWrapper.AddUser(user, inDto.PasswordHash, inDto.FromInviteLink, true, inDto.Type,
|
||||
inDto.FromInviteLink && options is { IsCorrect: true }, true, true, byEmail);
|
||||
|
||||
await UpdateDepartments(inDto.Department, user);
|
||||
@ -308,7 +308,7 @@ public class UserController : PeopleControllerBase
|
||||
}
|
||||
|
||||
[HttpPost("invite")]
|
||||
public async IAsyncEnumerable<EmployeeDto> InviteUsersAsync(InviteUsersRequestDto inDto)
|
||||
public async Task<List<EmployeeDto>> InviteUsersAsync(InviteUsersRequestDto inDto)
|
||||
{
|
||||
foreach (var invite in inDto.Invitations)
|
||||
{
|
||||
@ -324,12 +324,16 @@ public class UserController : PeopleControllerBase
|
||||
_logger.Debug(link);
|
||||
}
|
||||
|
||||
var result = new List<EmployeeDto>();
|
||||
|
||||
var users = _userManager.GetUsers().Where(u => u.ActivationStatus == EmployeeActivationStatus.Pending);
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
yield return await _employeeDtoHelper.Get(user);
|
||||
result.Add(await _employeeDtoHelper.Get(user));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpPut("{userid}/password")]
|
||||
@ -1097,16 +1101,16 @@ public class UserController : PeopleControllerBase
|
||||
updatedUsers.Add(user);
|
||||
}
|
||||
}
|
||||
|
||||
_messageService.Send(MessageAction.UsersUpdatedType, _messageTarget.Create(updatedUsers.Select(x => x.Id)),
|
||||
|
||||
_messageService.Send(MessageAction.UsersUpdatedType, _messageTarget.Create(updatedUsers.Select(x => x.Id)),
|
||||
updatedUsers.Select(x => x.DisplayUserName(false, _displayUserSettingsHelper)));
|
||||
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
yield return await _employeeFullDtoHelper.GetFull(user);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("recalculatequota")]
|
||||
public void RecalculateQuota()
|
||||
{
|
||||
@ -1323,7 +1327,7 @@ public class UserController : PeopleControllerBase
|
||||
includeGroups.Add(new List<Guid> { Constants.GroupAdmin.ID });
|
||||
break;
|
||||
case EmployeeType.RoomAdmin:
|
||||
excludeGroups.Add(Constants.GroupUser.ID);
|
||||
excludeGroups.Add(Constants.GroupUser.ID);
|
||||
excludeGroups.Add(Constants.GroupAdmin.ID);
|
||||
excludeGroups.Add(Constants.GroupCollaborator.ID);
|
||||
break;
|
||||
|
@ -75,6 +75,7 @@
|
||||
"Delete": "Delete",
|
||||
"Disconnect": "Disconnect",
|
||||
"DocSpaceAdmin": "DocSpace admin",
|
||||
"DocSpaceOwner": "DocSpace owner",
|
||||
"Documents": "Documents",
|
||||
"DomainIpAddress": "Domains as IP addresses are not supported",
|
||||
"Done": "Done",
|
||||
|
@ -75,6 +75,7 @@
|
||||
"Delete": "Удалить",
|
||||
"Disconnect": "Отключить",
|
||||
"DocSpaceAdmin": "DocSpace администратор",
|
||||
"DocSpaceOwner": "DocSpace владелец",
|
||||
"Documents": "Документы",
|
||||
"DomainIpAddress": "IP адрес в качестве домена не поддерживается",
|
||||
"Done": "Успешно",
|
||||
@ -99,6 +100,7 @@
|
||||
"FirstName": "Имя",
|
||||
"FullAccess": "Полный доступ",
|
||||
"Gigabyte": "Гб",
|
||||
"HasFullAccess": "У него есть полный доступ в комнату",
|
||||
"HelpCenter": "Справочный центр",
|
||||
"HideArticleMenu": "Скрыть меню",
|
||||
"Hotkeys": "Горячие клавиши",
|
||||
|
@ -9,6 +9,7 @@
|
||||
Edge: 107,
|
||||
Opera: 93,
|
||||
Safari: 13,
|
||||
SafariMobile: 12,
|
||||
AscDesktopEditor: 6,
|
||||
SamsungBrowser: 3,
|
||||
};
|
||||
@ -47,6 +48,10 @@
|
||||
match.splice(1, 1, temp[1]);
|
||||
}
|
||||
|
||||
if ((temp = agent.match(/mobile\/(\d+)/i)) != null) {
|
||||
match[0] += "Mobile";
|
||||
}
|
||||
|
||||
return { name: match[0], version: match[1] };
|
||||
})();
|
||||
}
|
||||
|
@ -39,12 +39,7 @@ public static class UserPhotoThumbnailManager
|
||||
}
|
||||
|
||||
public static async Task<List<ThumbnailItem>> SaveThumbnails(UserPhotoManager userPhotoManager, SettingsManager settingsManager, UserPhotoThumbnailSettings thumbnailSettings, Guid userId)
|
||||
{
|
||||
if (thumbnailSettings.Size.IsEmpty)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
{
|
||||
var thumbnailsData = new ThumbnailsData(userId, userPhotoManager);
|
||||
|
||||
var resultBitmaps = new List<ThumbnailItem>();
|
||||
@ -55,6 +50,11 @@ public static class UserPhotoThumbnailManager
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (thumbnailSettings.Size.IsEmpty)
|
||||
{
|
||||
thumbnailSettings.Size = new Size(img.Width, img.Height);
|
||||
}
|
||||
|
||||
foreach (var thumbnail in await thumbnailsData.ThumbnailList())
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user