Merge branch 'release/rc-v1.2.0' of github.com:ONLYOFFICE/AppServer into release/rc-v1.2.0

This commit is contained in:
Vlada Gazizova 2022-12-14 22:30:45 +03:00
commit c16a9dfb2e
26 changed files with 206 additions and 70 deletions

View File

@ -345,7 +345,11 @@ public class UserManager
var oldUserData = _userService.GetUserByUserName(_tenantManager.GetCurrentTenant().Id, u.UserName);
var newUser = UpdateUserInfo(u);
if (_coreBaseSettings.DisableDocSpace)
{
await SyncCardDavAsync(u, oldUserData, newUser);
}
return newUser;
}

View File

@ -63,7 +63,7 @@ public class UserSecurityProvider : SecurityObject
EmployeeType.DocSpaceAdmin => new[] { AuthConstants.DocSpaceAdmin },
EmployeeType.RoomAdmin => new[] { AuthConstants.RoomAdmin },
EmployeeType.User => new[] { AuthConstants.User },
_ => throw new NotImplementedException(),
_ => Array.Empty<IRole>(),
};
}

View File

@ -26,7 +26,7 @@ map $request_uri $cache_control {
default "no-cache, no-store, must-revalidate";
~*\/(api\/2\.0.*|storage|login\.ashx|products\/.+\/httphandlers\/filehandler\.ashx|ChunkedUploader.ashx|ThirdPartyAppHandler|apisystem|sh|remoteEntry\.js|debuginfo\.md) "no-cache, no-store, must-revalidate";
~*\/(locales.*\.json) "public, no-transform";
~*\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|md|css|js)$ "public, no-transform";
~*\.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|md|css|js)$ "public, no-transform, max-age=0, s-maxage=3153600";
}
include /etc/nginx/includes/onlyoffice-*.conf;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -30,6 +30,7 @@ const CreateEvent = ({
openDocEditor,
setIsUpdatingRowItem,
gallerySelected,
setGallerySelected,
setCreatedItem,
parentId,
@ -55,6 +56,13 @@ const CreateEvent = ({
const { t } = useTranslation(["Translations", "Common"]);
const onCloseAction = () => {
if (gallerySelected) {
setGallerySelected && setGallerySelected(null);
}
onClose && onClose();
};
React.useEffect(() => {
const defaultName = getDefaultFileName(extension);
@ -116,7 +124,7 @@ const CreateEvent = ({
createdFolderId && folderIds.push(createdFolderId);
clearActiveOperations(null, folderIds);
onClose();
onCloseAction();
return setIsLoading(false);
});
} else {
@ -161,7 +169,7 @@ const CreateEvent = ({
createdFileId && fileIds.push(createdFileId);
clearActiveOperations(fileIds);
onClose();
onCloseAction();
return setIsLoading(false);
});
} else if (fromTemplate) {
@ -186,7 +194,7 @@ const CreateEvent = ({
createdFileId && fileIds.push(createdFileId);
clearActiveOperations(fileIds);
onClose();
onCloseAction();
return setIsLoading(false);
});
} else {
@ -222,7 +230,7 @@ const CreateEvent = ({
createdFileId && fileIds.push(createdFileId);
clearActiveOperations(fileIds);
onClose();
onCloseAction();
return setIsLoading(false);
});
}
@ -231,9 +239,9 @@ const CreateEvent = ({
const onCancel = React.useCallback(
(e) => {
onClose && onClose();
onCloseAction && onCloseAction();
},
[onClose]
[onCloseAction]
);
return (
@ -244,7 +252,7 @@ const CreateEvent = ({
startValue={startValue}
onSave={onSave}
onCancel={onCancel}
onClose={onClose}
onClose={onCloseAction}
/>
);
};
@ -270,7 +278,7 @@ export default inject(
setCreatedItem,
} = filesStore;
const { gallerySelected } = oformsStore;
const { gallerySelected, setGallerySelected } = oformsStore;
const { editCompleteAction } = filesActionsStore;
@ -301,6 +309,7 @@ export default inject(
openDocEditor,
setIsUpdatingRowItem,
gallerySelected,
setGallerySelected,
setCreatedItem,
parentId,

View File

@ -3,6 +3,7 @@ import { inject, observer } from "mobx-react";
import { useTranslation } from "react-i18next";
import { EditRoomDialog } from "../dialogs";
import { Encoder } from "@docspace/common/utils/encoder";
import api from "@docspace/common/api";
const EditRoomEvent = ({
visible,
@ -148,9 +149,14 @@ const EditRoomEvent = ({
};
useEffect(async () => {
const imgExst = item.logo.original.slice(".")[1];
if (item.logo.original) {
const file = await fetch(item.logo.original)
const logo = item?.logo?.original
? item.logo.original
: await api.rooms.getLogoIcon(item?.logoHandlers?.original);
if (logo) {
const imgExst = logo.slice(".")[1];
const file = await fetch(logo)
.then((res) => res.arrayBuffer())
.then(
(buf) =>

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback } from "react";
import React, { useState, useEffect, useRef } from "react";
import { inject, observer } from "mobx-react";
import PropTypes from "prop-types";
import { I18nextProvider, withTranslation } from "react-i18next";
@ -11,6 +11,8 @@ import { getUserList } from "@docspace/common/api/people";
import Loaders from "@docspace/common/components/Loaders";
import { getUserRole } from "SRC_DIR/helpers/people-helpers";
let timer = null;
const PeopleSelector = ({
acceptButtonLabel,
accessRights,
@ -50,13 +52,33 @@ const PeopleSelector = ({
const [total, setTotal] = useState(0);
const [hasNextPage, setHasNextPage] = useState(true);
const [isNextPageLoading, setIsNextPageLoading] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const cleanTimer = () => {
timer && clearTimeout(timer);
timer = null;
};
useEffect(() => {
setIsLoading(true);
loadNextPage(0);
}, []);
useEffect(() => {
if (isLoading) {
cleanTimer();
timer = setTimeout(() => {
setIsLoading(true);
}, 100);
} else {
cleanTimer();
setIsLoading(false);
}
return () => {
cleanTimer();
};
}, [isLoading]);
const toListItem = (item) => {
const { id, email, avatar, icon, displayName } = item;
@ -76,8 +98,11 @@ const PeopleSelector = ({
const pageCount = 100;
setIsNextPageLoading(true);
setIsLoading(true);
const currentFilter =
typeof filter === "function" ? filter() : filter ?? Filter.getDefault();
const currentFilter = filter || Filter.getDefault();
currentFilter.page = startIndex / pageCount;
currentFilter.pageCount = pageCount;
@ -117,13 +142,11 @@ const PeopleSelector = ({
const onSearch = (value) => {
setSearchValue(value);
setIsLoading(true);
loadNextPage(0, value);
};
const onClearSearch = () => {
setSearchValue("");
setIsLoading(true);
loadNextPage(0, "");
};

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useCallback } from "react";
import { inject, observer } from "mobx-react";
import PropTypes from "prop-types";
import Backdrop from "@docspace/components/backdrop";
@ -11,6 +11,7 @@ import { withTranslation } from "react-i18next";
import Loaders from "@docspace/common/components/Loaders";
import withLoader from "../../../HOCs/withLoader";
import toastr from "@docspace/components/toast/toastr";
import Filter from "@docspace/common/api/people/filter";
const AddUsersPanel = ({
isEncrypted,
@ -34,6 +35,10 @@ const AddUsersPanel = ({
: ShareAccessRights.ReadOnly;
const onBackClick = () => onClose();
const getFilterWithOutDisabledUser = useCallback(
() => Filter.getFilterWithOutDisabledUser(),
[]
);
const onKeyPress = (e) => {
if (e.key === "Esc" || e.key === "Escape") onClose();
@ -115,6 +120,7 @@ const AddUsersPanel = ({
withCancelButton={!isMultiSelect}
withAccessRights={isMultiSelect}
withSelectAll={isMultiSelect}
filter={getFilterWithOutDisabledUser}
/>
</Aside>
</>

View File

@ -195,7 +195,7 @@ const RegisterContainer = styled.div`
}
.auth-form-fields {
@media (max-width: 768px) {
@media ${hugeMobile} {
display: ${(props) => props.isGreetingMode && "none"};
}
}

View File

@ -9,6 +9,7 @@ import Text from "@docspace/components/text";
import DetailsHelper from "../../helpers/DetailsHelper.js";
import { StyledNoThumbnail, StyledThumbnail } from "../../styles/details.js";
import { StyledProperties, StyledSubtitle } from "../../styles/common.js";
import api from "@docspace/common/api/index.js";
const Details = ({
t,
@ -21,6 +22,7 @@ const Details = ({
isVisitor,
}) => {
const [itemProperties, setItemProperties] = useState([]);
const [largeLogoIcon, setLargeLogoIcon] = useState("");
const [isThumbnailError, setIsThumbmailError] = useState(false);
const onThumbnailError = () => setIsThumbmailError(true);
@ -37,9 +39,24 @@ const Details = ({
culture,
});
const getLargeRoomLogo = React.useCallback(
async (url) => {
if (selection?.logo?.large) return setLargeLogoIcon(selection.logo.large);
const icon = await api.rooms.getLogoIcon(url);
setLargeLogoIcon(icon);
},
[selection?.logo?.large]
);
useEffect(async () => {
setItemProperties(detailsHelper.getPropertyList());
if ((selection?.isRoom || selection?.roomType) && !selection.isArchive) {
getLargeRoomLogo(selection?.logoHandlers?.large);
}
if (
!selection.isFolder &&
selection.thumbnailStatus === 0 &&
@ -50,7 +67,11 @@ const Details = ({
) {
await createThumbnail(selection.id);
}
}, [selection]);
}, [selection, getLargeRoomLogo]);
const currentIcon = largeLogoIcon
? largeLogoIcon
: getInfoPanelItemIcon(selection, 96);
return (
<>
@ -70,7 +91,7 @@ const Details = ({
className={`no-thumbnail-img ${selection.isRoom && "is-room"} ${
selection.isRoom && selection.logo?.large && "custom-logo"
}`}
src={getInfoPanelItemIcon(selection, 96)}
src={currentIcon}
alt="thumbnail-icon-big"
/>
</StyledNoThumbnail>

View File

@ -9,6 +9,18 @@ import { isTablet } from "@docspace/components/utils/device";
import { Base } from "@docspace/components/themes";
const StyledRowContainer = styled(RowContainer)`
.row-list-item:first-child {
.row-selected {
.files-row {
border-top: ${(props) =>
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
margin-top: -1px;
padding-top: 0px;
padding-bottom: 1px;
${marginStyles};
}
}
}
.row-selected + .row-wrapper:not(.row-selected) {
.files-row {
border-top: ${(props) =>
@ -39,7 +51,6 @@ const StyledRowContainer = styled(RowContainer)`
.files-row {
border-bottom: ${(props) =>
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
padding-bottom: 1px;
${marginStyles}
}
.files-row::after {
@ -50,8 +61,10 @@ const StyledRowContainer = styled(RowContainer)`
.files-row {
border-top: ${(props) =>
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
margin-top: -1px;
${marginStyles}
margin-top: -2px;
padding-top: 1px;
padding-bottom: 1px;
${marginStyles};
}
}
`;

View File

@ -39,9 +39,13 @@ const StyledSimpleFilesRow = styled(Row)`
cursor: pointer;
${checkedStyle}
margin-top: -1px;
margin-top: -2px;
padding-top: 1px;
padding-bottom: 1px;
border-top: ${(props) =>
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
border-bottom: ${(props) =>
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
}
`};

View File

@ -17,6 +17,7 @@ import TypeCell from "./sub-components/TypeCell";
import TagsCell from "./sub-components/TagsCell";
import styled, { css } from "styled-components";
import Base from "@docspace/components/themes/base";
import { classNames } from "@docspace/components/utils/classNames";
const hotkeyBorderStyle = css`
border-bottom: 1px solid;
@ -399,18 +400,19 @@ const FilesTableRow = (props) => {
availableColumns.includes("Activity") && !hideColumns;
}
const idWithFileExst = item.fileExst
? `${item.id}_${item.fileExst}`
: item.id ?? "";
return (
<StyledDragAndDrop
id={id}
data-title={item.title}
value={value}
className={`files-item ${className} ${item.id}_${item.fileExst} ${
showHotkeyBorder
? "table-hotkey-border"
: checkedProps || isActive
? "table-row-selected"
: ""
}`}
className={classNames("files-item", className, idWithFileExst, {
["table-hotkey-border"]: showHotkeyBorder,
["table-row-selected"]: !showHotkeyBorder && (checkedProps || isActive),
})}
onDrop={onDrop}
onMouseDown={onMouseDown}
dragging={dragging && isDragging}
@ -445,7 +447,10 @@ const FilesTableRow = (props) => {
>
<TableCell
{...dragStyles}
className={`${selectionProp?.className} table-container_file-name-cell`}
className={classNames(
selectionProp?.className,
"table-container_file-name-cell"
)}
value={value}
>
<FileNameCell
@ -586,7 +591,10 @@ const FilesTableRow = (props) => {
!buttonsAvailableDrag ? { background: "none" } : dragStyles.style
}
{...selectionProp}
className={`${selectionProp?.className} table-container_quick-buttons-wrapper`}
className={classNames(
selectionProp?.className,
"table-container_quick-buttons-wrapper"
)}
>
<StyledQuickButtonsContainer>
{quickButtonsComponent}

View File

@ -257,6 +257,7 @@ class AmazonSettings extends React.Component {
return (
<>
<HelpButton
offsetRight={0}
iconName={"/static/images/help.react.svg"}
tooltipContent={
<>

View File

@ -145,7 +145,13 @@ class FilesStore {
newFiles.pop(); // Remove last
}
const newFilter = this.filter;
newFilter.total += 1;
runInAction(() => {
this.setFilter(newFilter);
this.setFiles(newFiles);
});
}
break;
case "update":
@ -2013,16 +2019,17 @@ class FilesStore {
getRoomLogo = async (logoHandlers) => {
const newLogos = {};
let disableFetch = false;
for (let key in logoHandlers) {
const icon = disableFetch
? ""
: await api.rooms.getLogoIcon(logoHandlers[key]);
let icon = "";
if (!icon) disableFetch = true;
if (key === "medium") {
icon = await api.rooms.getLogoIcon(logoHandlers[key]);
newLogos[key] = icon ? icon : "";
// check for null
icon = icon ? icon : "";
}
newLogos[key] = icon;
}
return newLogos;
@ -2042,7 +2049,13 @@ class FilesStore {
})
);
if (
(this.treeFoldersStore.isRoomsFolder ||
this.treeFoldersStore.isArchiveFolder) &&
this.selectedFolderStore.navigationPath.length === 0
) {
this.setFolders(newRooms);
}
};
get filesList() {

View File

@ -25,6 +25,7 @@ class SelectedFolderStore {
pinned = null;
isRoom = null;
logo = null;
logoHandlers = null;
tags = null;
rootFolderId = null;
settingsStore = null;

View File

@ -431,7 +431,7 @@ class UploadDataStore {
}
});
storeOriginalFiles && this.refreshFiles(file);
// storeOriginalFiles && this.refreshFiles(file);
if (fileInfo && fileInfo !== "password") {
file.fileInfo = fileInfo;
@ -769,8 +769,10 @@ class UploadDataStore {
return Promise.resolve();
} else {
if (currentFile.action === "uploaded") {
if (currentFile?.path?.length > 1) {
this.refreshFiles(currentFile);
}
}
return Promise.resolve();
}
};

View File

@ -343,7 +343,7 @@ class UsersStore {
}
getUsersByQuery = async (query) => {
const filter = Filter.getDefault();
const filter = Filter.getFilterWithOutDisabledUser();
filter.search = query;
filter.pageCount = 100;

View File

@ -12,6 +12,8 @@ const DEFAULT_SEARCH = "";
const DEFAULT_GROUP = null;
const DEFAULT_PAYMENTS = null;
const ACTIVE_EMPLOYEE_STATUS = 1;
const EMPLOYEE_STATUS = "employeestatus";
const ACTIVATION_STATUS = "activationstatus";
const ROLE = "employeeType";
@ -28,6 +30,21 @@ class Filter {
return new Filter(DEFAULT_PAGE, DEFAULT_PAGE_COUNT, total);
}
static getFilterWithOutDisabledUser() {
return new Filter(
DEFAULT_PAGE,
DEFAULT_PAGE_COUNT,
DEFAULT_TOTAL,
DEFAULT_SORT_BY,
DEFAULT_SORT_ORDER,
ACTIVE_EMPLOYEE_STATUS,
DEFAULT_ACTIVATION_STATUS,
DEFAULT_ROLE,
DEFAULT_SEARCH,
DEFAULT_GROUP,
DEFAULT_PAYMENTS
);
}
static getFilter(location) {
if (!location) return this.getDefault();

View File

@ -40,6 +40,8 @@ export function getRooms(filter) {
}
export function getLogoIcon(url) {
if (!url) return "";
const options = {
// baseURL: combineUrl(AppServerConfig.proxyURL, config.homepage),
method: "get",

View File

@ -72,7 +72,7 @@ const Selector = ({
const onClearSearchAction = React.useCallback(() => {
onClearSearch && onClearSearch();
setIsSearch(true);
setIsSearch(false);
}, [onClearSearch]);
const onSelectAction = (item) => {
@ -258,7 +258,10 @@ const Selector = ({
newSelectedItems.length !== renderedItems.length &&
newSelectedItems.length !== 0
}
isAllChecked={newSelectedItems.length === renderedItems.length}
isAllChecked={
newSelectedItems.length === renderedItems.length &&
renderedItems.length !== 0
}
placeholder={searchPlaceholder}
value={searchValue}
onSearch={onSearchAction}

View File

@ -2125,7 +2125,7 @@ const Dark = {
filterInput: {
button: {
border: "1px solid #474747",
hoverBorder: "1px solid #a3a9ae",
hoverBorder: "1px solid #858585",
openBackground: "#a3a9ae",

View File

@ -1029,11 +1029,13 @@ public class UserController : PeopleControllerBase
}
user.Status = EmployeeStatus.Active;
await _userManager.UpdateUserInfoWithSyncCardDavAsync(user);
}
break;
case EmployeeStatus.Terminated:
user.Status = EmployeeStatus.Terminated;
await _userManager.UpdateUserInfoWithSyncCardDavAsync(user);
await _cookiesManager.ResetUserCookie(user.Id);

View File

@ -167,6 +167,16 @@ public class StudioNotifyService
{
var auditEventDate = DateTime.UtcNow;
auditEventDate = new DateTime(
auditEventDate.Year,
auditEventDate.Month,
auditEventDate.Day,
auditEventDate.Hour,
auditEventDate.Minute,
auditEventDate.Second,
0,
DateTimeKind.Utc);
var hash = auditEventDate.ToString("s");
var confirmationUrl = _commonLinkUtility.GetConfirmationEmailUrl(userInfo.Email, ConfirmType.PasswordChange, hash, userInfo.Id);

View File

@ -566,16 +566,7 @@ namespace ASC.Web.Core.PublicResources {
///
///The link is valid for 7 days.
///
///Dont want to change your password? Just ignore this message&lt;/value&gt;
/// &lt;/data&gt;
/// &lt;data name=&quot;pattern_personal_change_password_v115&quot; xml:space=&quot;preserve&quot;&gt;
/// &lt;value&gt;Want to change the password on your ONLYOFFICE Personal account? Click the button below to confirm.
///
///$GreenButton
///
///The link is valid for 7 days.
///
///Dont want to change your password? Just ignore [rest of string was truncated]&quot;;.
///Dont want to change your password? Just ignore this message.
/// </summary>
public static string pattern_change_password_v115 {
get {

View File

@ -1181,10 +1181,10 @@ $GreenButton
The link is valid for 7 days.
Dont want to change your password? Just ignore this message&lt;/value&gt;
&lt;/data&gt;
&lt;data name="pattern_personal_change_password_v115" xml:space="preserve"&gt;
&lt;value&gt;Want to change the password on your ONLYOFFICE Personal account? Click the button below to confirm.
Dont want to change your password? Just ignore this message</value>
</data>
<data name="pattern_personal_change_password_v115" xml:space="preserve">
<value>Want to change the password on your ONLYOFFICE Personal account? Click the button below to confirm.
$GreenButton