Merge branch 'develop' into bugfix/redesign-author-filter

This commit is contained in:
DmitrySychugov 2023-03-01 20:16:52 +05:00
commit ce9e972d22
34 changed files with 351 additions and 353 deletions

View File

@ -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)

View File

@ -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);
}

View File

@ -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)));

View File

@ -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");

View File

@ -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([

View File

@ -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

View File

@ -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]}

View File

@ -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,
};

View File

@ -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)));

View File

@ -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 (

View File

@ -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));

View File

@ -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);

View File

@ -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;

View File

@ -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));

View File

@ -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

View File

@ -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))))

View File

@ -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>
);
};

View File

@ -244,6 +244,12 @@ const StyledTile = styled.div`
.new-items {
min-width: 16px;
}
${(props) =>
props.isHighlight &&
css`
${animationStyles}
`}
`;
const StyledFileTileTop = styled.div`

View File

@ -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)));

View File

@ -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,
};
}
)(

View File

@ -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,

View File

@ -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":

View File

@ -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));
};

View File

@ -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,

View File

@ -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) {

View File

@ -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] === "/"

View File

@ -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);

View File

@ -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) => {

View File

@ -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);

View File

@ -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;

View File

@ -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",

View File

@ -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": "Горячие клавиши",

View File

@ -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] };
})();
}

View File

@ -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())
{