Merge branch 'develop' into feature/translations

This commit is contained in:
Alexey Safronov 2021-04-28 13:08:52 +03:00
commit 8fc80a419b
26 changed files with 143 additions and 76 deletions

View File

@ -1,5 +1,5 @@
{ {
"version": "0.1.7", "version": "0.1.8",
"npmClient": "yarn", "npmClient": "yarn",
"packages": [ "packages": [
"packages/asc-web-components", "packages/asc-web-components",

View File

@ -12,7 +12,7 @@ export function openEdit(fileId, version, doc) {
} }
if (doc) { if (doc) {
params.push(`version=${version}`); params.push(`doc=${doc}`);
} }
const paramsString = params.length > 0 ? `?${params.join("&")}` : ""; const paramsString = params.length > 0 ? `?${params.join("&")}` : "";

View File

@ -1,6 +1,6 @@
{ {
"name": "@appserver/common", "name": "@appserver/common",
"version": "0.0.2", "version": "0.0.3",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "echo 'skip it'", "build": "echo 'skip it'",

View File

@ -8,7 +8,7 @@ import UserStore from "./UserStore";
import { logout as logoutDesktop, desktopConstants } from "../desktop"; import { logout as logoutDesktop, desktopConstants } from "../desktop";
import { combineUrl, isAdmin } from "../utils"; import { combineUrl, isAdmin } from "../utils";
import isEmpty from "lodash/isEmpty"; import isEmpty from "lodash/isEmpty";
import { AppServerConfig } from "../constants"; import { AppServerConfig, LANGUAGE } from "../constants";
const { proxyURL } = AppServerConfig; const { proxyURL } = AppServerConfig;
class AuthStore { class AuthStore {
@ -43,7 +43,14 @@ class AuthStore {
return Promise.all(requests); return Promise.all(requests);
}; };
setLanguage() {
if (this.userStore.user.cultureName) {
localStorage.getItem(LANGUAGE) !== this.userStore.user.cultureName &&
localStorage.setItem(LANGUAGE, this.userStore.user.cultureName);
} else {
localStorage.setItem(LANGUAGE, this.settingsStore.culture || "en-US");
}
}
get isLoaded() { get isLoaded() {
let success = false; let success = false;
if (this.isAuthenticated) { if (this.isAuthenticated) {
@ -51,6 +58,8 @@ class AuthStore {
this.userStore.isLoaded && this.userStore.isLoaded &&
this.moduleStore.isLoaded && this.moduleStore.isLoaded &&
this.settingsStore.isLoaded; this.settingsStore.isLoaded;
success && this.setLanguage();
} else { } else {
success = this.settingsStore.isLoaded; success = this.settingsStore.isLoaded;
} }

View File

@ -1,6 +1,5 @@
import { action, makeObservable, observable } from "mobx"; import { action, makeObservable, observable } from "mobx";
import api from "../api"; import api from "../api";
import { LANGUAGE } from "../constants";
class UserStore { class UserStore {
user = null; user = null;
@ -21,9 +20,7 @@ class UserStore {
getCurrentUser = async () => { getCurrentUser = async () => {
const user = await api.people.getUser(); const user = await api.people.getUser();
user.cultureName &&
localStorage.getItem(LANGUAGE) !== user.cultureName &&
localStorage.setItem(LANGUAGE, user.cultureName);
this.setUser(user); this.setUser(user);
}; };

View File

@ -15,6 +15,7 @@ const StyledLabel = styled.label`
.checkbox { .checkbox {
margin-right: 12px; margin-right: 12px;
overflow: visible;
} }
/* ${(props) => /* ${(props) =>

View File

@ -1,6 +1,6 @@
{ {
"name": "@appserver/components", "name": "@appserver/components",
"version": "0.0.2", "version": "0.0.3",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "echo 'skip it'", "build": "echo 'skip it'",

View File

@ -1,6 +1,6 @@
{ {
"name": "@appserver/crm", "name": "@appserver/crm",
"version": "0.1.7", "version": "0.1.8",
"private": "true", "private": "true",
"homepage": "/products/crm", "homepage": "/products/crm",
"title": "ONLYOFFICE", "title": "ONLYOFFICE",

View File

@ -1,6 +1,6 @@
{ {
"name": "@appserver/files", "name": "@appserver/files",
"version": "0.1.7", "version": "0.1.8",
"private": "true", "private": "true",
"homepage": "/products/files", "homepage": "/products/files",
"id": "e67be73d-f9ae-4ce1-8fec-1880cb518cb4", "id": "e67be73d-f9ae-4ce1-8fec-1880cb518cb4",

View File

@ -81,6 +81,7 @@ const PureTreeSettings = ({
history, history,
setIsLoading, setIsLoading,
t, t,
isVisitor,
}) => { }) => {
const { setting } = match.params; const { setting } = match.params;
@ -168,7 +169,7 @@ const PureTreeSettings = ({
title={t("TreeSettingsAdminSettings")} title={t("TreeSettingsAdminSettings")}
/> />
) : null} ) : null}
{enableThirdParty ? ( {enableThirdParty && !isVisitor ? (
<TreeNode <TreeNode
selectable={true} selectable={true}
className="settings-node" className="settings-node"
@ -226,6 +227,7 @@ export default inject(
return { return {
isAdmin: auth.isAdmin, isAdmin: auth.isAdmin,
isVisitor: auth.userStore.user.isVisitor,
isLoading, isLoading,
selectedTreeNode, selectedTreeNode,
enableThirdParty, enableThirdParty,

View File

@ -85,6 +85,7 @@ class ArticleBodyContent extends React.Component {
onTreeDrop, onTreeDrop,
selectedTreeNode, selectedTreeNode,
enableThirdParty, enableThirdParty,
isVisitor,
} = this.props; } = this.props;
return isEmpty(treeFolders) ? ( return isEmpty(treeFolders) ? (
@ -99,7 +100,7 @@ class ArticleBodyContent extends React.Component {
onTreeDrop={onTreeDrop} onTreeDrop={onTreeDrop}
/> />
<TreeSettings /> <TreeSettings />
{enableThirdParty && <ThirdPartyList />} {enableThirdParty && !isVisitor && <ThirdPartyList />}
</> </>
); );
} }
@ -107,6 +108,7 @@ class ArticleBodyContent extends React.Component {
export default inject( export default inject(
({ ({
auth,
filesStore, filesStore,
treeFoldersStore, treeFoldersStore,
selectedFolderStore, selectedFolderStore,
@ -129,6 +131,7 @@ export default inject(
selectedTreeNode, selectedTreeNode,
filter, filter,
enableThirdParty: settingsStore.enableThirdParty, enableThirdParty: settingsStore.enableThirdParty,
isVisitor: auth.userStore.user.isVisitor,
setIsLoading, setIsLoading,
fetchFiles, fetchFiles,

View File

@ -48,7 +48,7 @@ const Badges = ({
hoverColor="#3B72A7" hoverColor="#3B72A7"
/> />
)} )}
{locked && ( {locked && accessToEdit && (
<StyledFileActionsLockedIcon <StyledFileActionsLockedIcon
className="badge lock-file icons-group" className="badge lock-file icons-group"
size="small" size="small"

View File

@ -77,14 +77,10 @@ class SharingPanelComponent extends React.Component {
}; };
updateRowData = (newRowData) => { updateRowData = (newRowData) => {
const { setFile, setFolder } = this.props; const { getFileInfo, getFolderInfo } = this.props;
for (let item of newRowData) { for (let item of newRowData) {
if (!item.fileExst) { !item.fileExst ? getFolderInfo(item.id) : getFileInfo(item.id);
setFolder(item);
} else {
setFile(item);
}
} }
}; };
@ -172,8 +168,8 @@ class SharingPanelComponent extends React.Component {
ownerId ownerId
) )
.then((res) => { .then((res) => {
if (ownerId) { if (!ownerId) {
this.updateRowData(res[0]); this.updateRowData(selection);
} }
if (isPrivacy && isDesktop) { if (isPrivacy && isDesktop) {
if (share.length === 0) return Promise.resolve(); if (share.length === 0) return Promise.resolve();
@ -610,6 +606,8 @@ const SharingPanel = inject(
getShareUsers, getShareUsers,
setShareFiles, setShareFiles,
setIsLoading, setIsLoading,
getFileInfo,
getFolderInfo,
isLoading, isLoading,
} = filesStore; } = filesStore;
const { isPrivacyFolder } = treeFoldersStore; const { isPrivacyFolder } = treeFoldersStore;
@ -644,6 +642,8 @@ const SharingPanel = inject(
setFolder, setFolder,
getShareUsers, getShareUsers,
setShareFiles, setShareFiles,
getFileInfo,
getFolderInfo,
}; };
} }
)(observer(withTranslation("SharingPanel")(SharingPanelComponent))); )(observer(withTranslation("SharingPanel")(SharingPanelComponent)));

View File

@ -323,6 +323,7 @@ class SectionHeaderContent extends React.Component {
isOnlyFoldersSelected, isOnlyFoldersSelected,
isFavoritesFolder, isFavoritesFolder,
isRecentFolder, isRecentFolder,
isShareFolder,
} = this.props; } = this.props;
let menu = [ let menu = [
@ -401,6 +402,7 @@ class SectionHeaderContent extends React.Component {
disabled: disabled:
isFavoritesFolder || isFavoritesFolder ||
isRecentFolder || isRecentFolder ||
isShareFolder ||
!isAccessedSelected || !isAccessedSelected ||
!selectionCount || !selectionCount ||
isThirdPartySelection, isThirdPartySelection,
@ -591,6 +593,7 @@ export default inject(
isPrivacyFolder, isPrivacyFolder,
isFavoritesFolder, isFavoritesFolder,
isRecentFolder, isRecentFolder,
isShareFolder,
} = treeFoldersStore; } = treeFoldersStore;
const { setAction } = fileActionStore; const { setAction } = fileActionStore;
const { const {
@ -614,6 +617,7 @@ export default inject(
isPrivacy: isPrivacyFolder, isPrivacy: isPrivacyFolder,
isFavoritesFolder, isFavoritesFolder,
isRecentFolder, isRecentFolder,
isShareFolder,
filter, filter,
canCreate, canCreate,
selectionCount: selection.length, selectionCount: selection.length,

View File

@ -71,17 +71,18 @@ class FilesActionStore {
} }
if (folderIds.length || fileIds.length) { if (folderIds.length || fileIds.length) {
setSecondaryProgressBarData({
icon: "trash",
visible: true,
label: translations.deleteOperation,
percent: 0,
alert: false,
});
return removeFiles(folderIds, fileIds, deleteAfter, immediately) return removeFiles(folderIds, fileIds, deleteAfter, immediately)
.then((res) => { .then((res) => {
const id = res[0] && res[0].id ? res[0].id : null; const id = res[0] && res[0].id ? res[0].id : null;
const currentProcess = res.find((x) => x.id === id);
setSecondaryProgressBarData({
icon: "trash",
visible: true,
label: translations.deleteOperation,
percent: currentProcess.progress,
alert: false,
});
this.loopDeleteOperation(id, translations); this.loopDeleteOperation(id, translations);
}) })
.catch((err) => { .catch((err) => {

View File

@ -574,7 +574,7 @@ class FilesStore {
]); ]);
} }
if (isCommonFolder) if (isCommonFolder) {
if (!this.userAccess) { if (!this.userAccess) {
fileOptions = this.removeOptions(fileOptions, [ fileOptions = this.removeOptions(fileOptions, [
"owner-change", "owner-change",
@ -586,6 +586,7 @@ class FilesStore {
fileOptions = this.removeOptions(fileOptions, ["separator2"]); fileOptions = this.removeOptions(fileOptions, ["separator2"]);
} }
} }
}
if (withoutShare) { if (withoutShare) {
fileOptions = this.removeOptions(fileOptions, [ fileOptions = this.removeOptions(fileOptions, [
@ -604,6 +605,10 @@ class FilesStore {
fileOptions = this.removeOptions(fileOptions, ["separator2"]); fileOptions = this.removeOptions(fileOptions, ["separator2"]);
} }
if (isShareFolder) {
fileOptions = this.removeOptions(fileOptions, ["move-to"]);
}
return fileOptions; return fileOptions;
} else { } else {
let folderOptions = [ let folderOptions = [
@ -630,6 +635,10 @@ class FilesStore {
folderOptions = this.removeOptions(folderOptions, ["copy"]); folderOptions = this.removeOptions(folderOptions, ["copy"]);
} }
if (isShareFolder) {
folderOptions = this.removeOptions(folderOptions, ["move-to"]);
}
if (isRecycleBinFolder) { if (isRecycleBinFolder) {
folderOptions = this.removeOptions(folderOptions, [ folderOptions = this.removeOptions(folderOptions, [
"open", "open",
@ -1222,6 +1231,11 @@ class FilesStore {
this.setFile(fileInfo); this.setFile(fileInfo);
}; };
getFolderInfo = async (id) => {
const folderInfo = await api.files.getFolderInfo(id);
this.setFolder(folderInfo);
};
openDocEditor = (id, providerKey = null, tab = null, url = null) => { openDocEditor = (id, providerKey = null, tab = null, url = null) => {
if (providerKey) { if (providerKey) {
tab tab

View File

@ -1,6 +1,6 @@
{ {
"name": "@appserver/people", "name": "@appserver/people",
"version": "0.1.7", "version": "0.1.8",
"private": "true", "private": "true",
"homepage": "/products/people", "homepage": "/products/people",
"id": "f4d98afd-d336-4332-8778-3c6945c81ea0", "id": "f4d98afd-d336-4332-8778-3c6945c81ea0",

View File

@ -40,7 +40,7 @@ class GroupAction extends React.Component {
render() { render() {
console.log("GroupAction render"); console.log("GroupAction render");
const { group, match } = this.props; const { group, match, tReady } = this.props;
return ( return (
<> <>
@ -63,7 +63,7 @@ class GroupAction extends React.Component {
</PageLayout.SectionHeader> </PageLayout.SectionHeader>
<PageLayout.SectionBody> <PageLayout.SectionBody>
<SectionBodyContent /> <SectionBodyContent tReady={tReady} />
</PageLayout.SectionBody> </PageLayout.SectionBody>
</PageLayout> </PageLayout>
) : ( ) : (

View File

@ -1,6 +1,6 @@
{ {
"name": "@appserver/projects", "name": "@appserver/projects",
"version": "0.1.7", "version": "0.1.8",
"private": "true", "private": "true",
"homepage": "/products/projects", "homepage": "/products/projects",
"id": "1e044602-43b5-4d79-82f3-fd6208a11960", "id": "1e044602-43b5-4d79-82f3-fd6208a11960",

View File

@ -1,6 +1,6 @@
{ {
"name": "@appserver/studio", "name": "@appserver/studio",
"version": "0.1.7", "version": "0.1.8",
"private": "true", "private": "true",
"homepage": "", "homepage": "",
"title": "ONLYOFFICE", "title": "ONLYOFFICE",

View File

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { Link } from 'react-router-dom'; import { Link } from "react-router-dom";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import styled from "styled-components"; import styled from "styled-components";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
@ -25,7 +25,7 @@ const NavLogoItem = (props) => {
//console.log("NavLogoItem render"); //console.log("NavLogoItem render");
return ( return (
<LogoItem opened={props.opened}> <LogoItem opened={props.opened}>
<Link className="nav-logo-wrapper" to="/"> <Link className="nav-logo-wrapper" to="/" onClick={props.onClick}>
<img className="nav-logo-icon" src={props.logoUrl} /> <img className="nav-logo-icon" src={props.logoUrl} />
</Link> </Link>
</LogoItem> </LogoItem>

View File

@ -1,5 +1,5 @@
import React, { lazy } from "react"; import React, { lazy } from "react";
import { Route, Switch } from "react-router-dom"; import { Switch } from "react-router-dom";
import ConfirmRoute from "../../../helpers/confirmRoute"; import ConfirmRoute from "../../../helpers/confirmRoute";
const ActivateUserForm = lazy(() => import("./sub-components/activateUser")); const ActivateUserForm = lazy(() => import("./sub-components/activateUser"));
@ -37,7 +37,7 @@ const Confirm = ({ match }) => {
path={`${match.path}/EmailChange`} path={`${match.path}/EmailChange`}
component={ChangeEmailForm} component={ChangeEmailForm}
/> />
<Route <ConfirmRoute
forUnauthorized forUnauthorized
path={`${match.path}/PasswordChange`} path={`${match.path}/PasswordChange`}
component={ChangePasswordForm} component={ChangePasswordForm}
@ -47,7 +47,7 @@ const Confirm = ({ match }) => {
path={`${match.path}/ProfileRemove`} path={`${match.path}/ProfileRemove`}
component={ProfileRemoveForm} component={ProfileRemoveForm}
/> />
<Route <ConfirmRoute
exact exact
path={`${match.path}/PhoneActivation`} path={`${match.path}/PhoneActivation`}
component={ChangePhoneForm} component={ChangePhoneForm}
@ -57,7 +57,6 @@ const Confirm = ({ match }) => {
path={`${match.path}/PortalOwnerChange`} path={`${match.path}/PortalOwnerChange`}
component={ChangeOwnerForm} component={ChangeOwnerForm}
/> />
{/* <Route component={Error404} /> */}
</Switch> </Switch>
); );
}; };

View File

@ -12,6 +12,7 @@ import SaveCancelButtons from "@appserver/components/save-cancel-buttons";
import { saveToSessionStorage, getFromSessionStorage } from "../../utils"; import { saveToSessionStorage, getFromSessionStorage } from "../../utils";
import { setDocumentTitle } from "../../../../../helpers/utils"; import { setDocumentTitle } from "../../../../../helpers/utils";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import { LANGUAGE } from "@appserver/common/constants";
const mapCulturesToArray = (cultures, t) => { const mapCulturesToArray = (cultures, t) => {
return cultures.map((culture) => { return cultures.map((culture) => {
@ -176,7 +177,13 @@ class LanguageAndTimeZone extends React.Component {
timezoneDefault, timezoneDefault,
languageDefault, languageDefault,
} = this.state; } = this.state;
const { i18n, language, nameSchemaId, getCurrentCustomSchema } = this.props; const {
i18n,
language,
nameSchemaId,
getCurrentCustomSchema,
t,
} = this.props;
if (timezones.length && languages.length && !prevState.isLoadedData) { if (timezones.length && languages.length && !prevState.isLoadedData) {
this.setState({ isLoadedData: true }); this.setState({ isLoadedData: true });
@ -229,12 +236,20 @@ class LanguageAndTimeZone extends React.Component {
}; };
onSaveLngTZSettings = () => { onSaveLngTZSettings = () => {
const { t, setLanguageAndTime, i18n } = this.props; const { t, setLanguageAndTime, user, language: lng } = this.props;
const { language, timezone } = this.state; const { language, timezone } = this.state;
this.setState({ isLoading: true }, function () { this.setState({ isLoading: true }, function () {
setLanguageAndTime(language.key, timezone.key) setLanguageAndTime(language.key, timezone.key)
.then(() => i18n.changeLanguage(language.key)) .then(
() =>
!user.cultureName &&
localStorage.setItem(LANGUAGE, language.key || "en-US")
)
.then(() => toastr.success(t("SuccessfullySaveSettingsMessage"))) .then(() => toastr.success(t("SuccessfullySaveSettingsMessage")))
.then(
() => !user.cultureName && lng !== language.key && location.reload()
)
.catch((error) => toastr.error(error)) .catch((error) => toastr.error(error))
.finally(() => this.setState({ isLoading: false })); .finally(() => this.setState({ isLoading: false }));
}); });
@ -403,9 +418,12 @@ export default inject(({ auth, setup }) => {
getCurrentCustomSchema, getCurrentCustomSchema,
} = auth.settingsStore; } = auth.settingsStore;
const { user } = auth.userStore;
const { setLanguageAndTime } = setup; const { setLanguageAndTime } = setup;
return { return {
user,
portalLanguage: culture, portalLanguage: culture,
portalTimeZoneId: timezone, portalTimeZoneId: timezone,
language: culture, language: culture,

View File

@ -1,6 +1,6 @@
{ {
"name": "@appserver/editor", "name": "@appserver/editor",
"version": "0.1.7", "version": "0.1.8",
"private": "true", "private": "true",
"homepage": "/products/files/doceditor", "homepage": "/products/files/doceditor",
"title": "ONLYOFFICE", "title": "ONLYOFFICE",

View File

@ -93,17 +93,21 @@ const Editor = () => {
//showLoader(); //showLoader();
const docApiUrl = await getDocServiceUrl(); const docApiUrl = await getDocServiceUrl();
const success = await checkIsAuthenticated();
if (!doc) { if (!doc && !success) {
const success = await checkIsAuthenticated(); return tryRedirectTo(combineUrl(AppServerConfig.proxyURL, "/login"));
}
if (!success) {
return tryRedirectTo(combineUrl(AppServerConfig.proxyURL, "/login")); if (success) {
} else { try {
setIsAuthenticated(success); fileInfo = await getFileInfo(fileId);
} } catch (err) {
console.error(err);
}
setIsAuthenticated(success);
} }
fileInfo = await getFileInfo(fileId);
config = await openEdit(fileId, version, doc); config = await openEdit(fileId, version, doc);
@ -145,7 +149,8 @@ const Editor = () => {
if ( if (
config && config &&
config.document.permissions.edit && config.document.permissions.edit &&
config.document.permissions.modifyFilter config.document.permissions.modifyFilter &&
fileInfo
) { ) {
const sharingSettings = await SharingDialog.getSharingSettings(fileId); const sharingSettings = await SharingDialog.getSharingSettings(fileId);
config.document.info = { config.document.info = {
@ -249,20 +254,36 @@ const Editor = () => {
config.type = "mobile"; config.type = "mobile";
} }
const filterObj = FilesFilter.getDefault(); let goback;
filterObj.folder = fileInfo.folderId;
const urlFilter = filterObj.toUrlParams();
config.editorConfig.customization = { if (fileInfo) {
...config.editorConfig.customization, const filterObj = FilesFilter.getDefault();
goback: { filterObj.folder = fileInfo.folderId;
const urlFilter = filterObj.toUrlParams();
goback = {
blank: true, blank: true,
requestClose: false, requestClose: false,
text: i18n.t("FileLocation"), text: i18n.t("FileLocation"),
url: `${combineUrl(filesUrl, `/filter?${urlFilter}`)}`, url: `${combineUrl(filesUrl, `/filter?${urlFilter}`)}`,
}, };
}
config.editorConfig.customization = {
...config.editorConfig.customization,
goback,
}; };
let onRequestSharingSettings;
if (
fileInfo &&
config.document.permissions.edit &&
config.document.permissions.modifyFilter
) {
onRequestSharingSettings = onSDKRequestSharingSettings;
}
const events = { const events = {
events: { events: {
onAppReady: onSDKAppReady, onAppReady: onSDKAppReady,
@ -272,10 +293,7 @@ const Editor = () => {
onInfo: onSDKInfo, onInfo: onSDKInfo,
onWarning: onSDKWarning, onWarning: onSDKWarning,
onError: onSDKError, onError: onSDKError,
...(config.document.permissions.edit && onRequestSharingSettings,
config.document.permissions.modifyFilter && {
onRequestSharingSettings: onSDKRequestSharingSettings,
}),
}, },
}; };
@ -357,13 +375,14 @@ const Editor = () => {
{!isLoading ? ( {!isLoading ? (
<> <>
<div id="editor"></div> <div id="editor"></div>
{fileInfo && (
<SharingDialog <SharingDialog
isVisible={isVisible} isVisible={isVisible}
sharingObject={fileInfo} sharingObject={fileInfo}
onCancel={onCancel} onCancel={onCancel}
onSuccess={updateUsersRightsList} onSuccess={updateUsersRightsList}
/> />
)}
</> </>
) : ( ) : (
<Box paddingProp="16px"> <Box paddingProp="16px">

View File

@ -1,6 +1,6 @@
{ {
"name": "@appserver/login", "name": "@appserver/login",
"version": "0.1.7", "version": "0.1.8",
"private": "true", "private": "true",
"homepage": "/login", "homepage": "/login",
"title": "ONLYOFFICE", "title": "ONLYOFFICE",