Merge branch 'bugfix/page-scroll' of https://github.com/ONLYOFFICE/DocSpace-client into bugfix/page-scroll

This commit is contained in:
Tatiana Lopaeva 2023-12-13 15:56:07 +03:00
commit 0206dbf000
27 changed files with 205 additions and 40 deletions

81
.github/workflows/codeql.yaml vendored Normal file
View File

@ -0,0 +1,81 @@
name: "CodeQL"
on:
push:
branches:
- 'release/**'
- 'hotfix/**'
paths-ignore:
- '**/README.md'
- '**/LICENSE'
- '.github/**'
pull_request:
# The branches below must be a subset of the branches above
branches:
- 'release/**'
- 'hotfix/**'
paths-ignore:
- '**/README.md'
- '**/LICENSE'
- '.github/**'
schedule:
- cron: '45 3 * * 5'
jobs:
analyze:
name: Analyze
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners
# Consider using larger runners for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ]
# Use only 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout client
uses: actions/checkout@v3
with:
path: client
- name: Checkout buildtools
uses: actions/checkout@v3
with:
repository: ONLYOFFICE/DocSpace-buildtools
path: buildtools
ref: ${{ github.base_ref || github.ref }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
- name: build
run: |
cd ./client
yarn install
yarn build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

View File

@ -1,6 +1,6 @@
{
"name": "docspace",
"version": "2.0.0",
"version": "2.0.1",
"private": true,
"workspaces": {
"packages": [

View File

@ -1,6 +1,6 @@
{
"name": "@docspace/client",
"version": "2.0.0",
"version": "2.0.1",
"private": true,
"homepage": "",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"AddedToClipboard": "項目は、クリップボードに追加されました",
"AdditionalLinks": "추가 링크",
"AdditionalLinks": "追加リンク",
"AddMembersDescription": "新しいチームメンバーを手動で追加したり、リンクで招待したりすることができます。",
"AddNewLink": "新しいリンクの追加",
"All": "すべて",

View File

@ -1,4 +1,4 @@
import React, { useEffect } from "react";
import { useEffect, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { observer, inject } from "mobx-react";
import { useNavigate } from "react-router-dom";
@ -67,17 +67,24 @@ const withHotkeys = (Component) => {
const navigate = useNavigate();
const [isEnabled, setIsEnabled] = useState(true);
const hotkeysFilter = {
filter: (ev) =>
ev.target?.type === "checkbox" || ev.target?.tagName !== "INPUT",
filterPreventDefault: false,
enableOnTags: ["INPUT"],
enabled: enabledHotkeys && !mediaViewerIsVisible && !filesIsLoading,
enabled:
enabledHotkeys && !mediaViewerIsVisible && !filesIsLoading && isEnabled,
// keyup: true,
// keydown: false,
};
const onKeyDown = (e) => activateHotkeys(e);
const onKeyDown = (e) => {
const someDialogIsOpen = checkDialogsOpen();
setIsEnabled(!someDialogIsOpen);
activateHotkeys(e);
};
const folderWithNoAction =
isFavoritesFolder ||

View File

@ -71,6 +71,7 @@ export type useRootHelperProps = {
onSetBaseFolderPath?: (
value: number | string | undefined | BreadCrumb[]
) => void;
isUserOnly?: boolean;
};
export type useRoomsHelperProps = {
@ -129,6 +130,7 @@ export type FilesSelectorProps = {
isThirdParty: boolean;
rootThirdPartyId?: string;
isRoomsOnly: boolean;
isUserOnly: boolean;
isRoomBackup: boolean;
isEditorDialog: boolean;
setMoveToPublicRoomVisible: (visible: boolean, operationData: object) => void;
@ -217,5 +219,6 @@ export type FilesSelectorProps = {
embedded: boolean;
withHeader: boolean;
withCancelButton: boolean;
settings: any;
};

View File

@ -20,6 +20,7 @@ const useRootHelper = ({
setIsNextPageLoading,
setTotal,
setHasNextPage,
isUserOnly,
}: useRootHelperProps) => {
const [isRoot, setIsRoot] = React.useState<boolean>(false);
@ -41,7 +42,7 @@ const useRootHelper = ({
const avatar = getCatalogIconUrlByType(folder.rootFolderType);
if (
folder.rootFolderType === FolderType.Rooms ||
(!isUserOnly && folder.rootFolderType === FolderType.Rooms) ||
folder.rootFolderType === FolderType.USER
) {
newItems.push({

View File

@ -38,6 +38,7 @@ const FilesSelector = ({
// withoutImmediatelyClose = false,
isThirdParty = false,
isRoomsOnly = false,
isUserOnly = false,
isEditorDialog = false,
rootThirdPartyId,
@ -100,6 +101,7 @@ const FilesSelector = ({
embedded,
withHeader,
withCancelButton = true,
getIcon,
isRoomBackup,
}: FilesSelectorProps) => {
@ -164,6 +166,7 @@ const FilesSelector = ({
setHasNextPage,
setIsNextPageLoading,
onSetBaseFolderPath,
isUserOnly,
});
const { getRoomList } = useRoomsHelper({
@ -523,7 +526,7 @@ const FilesSelector = ({
onSelect={onSelectAction}
acceptButtonLabel={acceptButtonLabel}
onAccept={onAcceptAction}
withCancelButton
withCancelButton={withCancelButton}
cancelButtonLabel={t("Common:CancelButton")}
onCancel={onCloseAction}
emptyScreenImage={
@ -567,7 +570,9 @@ const FilesSelector = ({
currentFooterInputValue={currentFooterInputValue}
footerCheckboxLabel={footerCheckboxLabel}
descriptionText={
!filterParam ? "" : descriptionText ?? t("Common:SelectDOCXFormat")
!filterParam || filterParam === "ALL"
? ""
: descriptionText ?? t("Common:SelectDOCXFormat")
}
acceptButtonId={
isMove || isCopy || isRestore ? "select-file-modal-submit" : ""

View File

@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
import { CreateRoomDialog } from "../dialogs";
const CreateRoomEvent = ({
title,
visible,
onClose,
@ -57,6 +58,7 @@ const CreateRoomEvent = ({
return (
<CreateRoomDialog
title={title}
t={t}
visible={
visible &&

View File

@ -31,6 +31,7 @@ const GlobalEvents = ({ enablePlugins, eventListenerItemsList }) => {
});
const [createRoomDialogProps, setCreateRoomDialogProps] = useState({
title: "",
visible: false,
onClose: null,
});
@ -101,9 +102,10 @@ const GlobalEvents = ({ enablePlugins, eventListenerItemsList }) => {
const onCreateRoom = useCallback((e) => {
setCreateRoomDialogProps({
title: e?.title,
visible: true,
onClose: () =>
setCreateRoomDialogProps({ visible: false, onClose: null }),
setCreateRoomDialogProps({ title: "", visible: false, onClose: null }),
});
}, []);

View File

@ -33,7 +33,7 @@ const StyledMain = styled.main`
`;
const Main = (props) => {
const { mainBarVisible, isBannerVisible } = props;
const { mainBarVisible, isBannerVisible, isFrame } = props;
//console.log("Main render");
const [mainHeight, setMainHeight] = React.useState(window.innerHeight);
const updateSizeRef = React.useRef(null);
@ -51,7 +51,7 @@ const Main = (props) => {
React.useEffect(() => {
onResize();
}, [mainBarVisible, isBannerVisible]);
}, [mainBarVisible, isBannerVisible, isFrame]);
const onResize = React.useCallback(
(e) => {
@ -89,13 +89,13 @@ const Main = (props) => {
}
// 48 - its nav menu with burger, logo and user avatar
if (isMobileUtils()) {
if (isMobileUtils() && !isFrame) {
correctHeight -= 48;
}
setMainHeight(correctHeight);
},
[mainBarVisible, isBannerVisible]
[mainBarVisible, isBannerVisible, isFrame]
);
return <StyledMain className="main" mainHeight={mainHeight} {...props} />;
@ -106,9 +106,10 @@ Main.displayName = "Main";
export default inject(({ auth }) => {
const { isBannerVisible } = auth.bannerStore;
const { mainBarVisible } = auth.settingsStore;
const { mainBarVisible, isFrame } = auth.settingsStore;
return {
mainBarVisible,
isBannerVisible,
isFrame,
};
})(observer(Main));

View File

@ -43,7 +43,7 @@ const convertToItems = (folders) => {
const icon = logo.medium ? logo.medium : getRoomLogo(roomType);
const color = logo.color;
return { id, label: title, icon, color };
return { id, label: title, icon, color, logo, roomType };
});
return items;

View File

@ -35,6 +35,7 @@ const StyledModalDialog = styled(ModalDialog)`
const CreateRoomDialog = ({
t,
visible,
title,
onClose,
onCreate,
@ -59,7 +60,7 @@ const CreateRoomDialog = ({
const startRoomParams = {
type: undefined,
title: "",
title: title,
tags: [],
isPrivate: false,
storageLocation: {
@ -93,7 +94,7 @@ const CreateRoomDialog = ({
}));
};
const isRoomTitleChanged = roomParams.title.trim() !== "" ? false : true;
const isRoomTitleChanged = roomParams?.title?.trim() !== "" ? false : true;
const onKeyUpHandler = (e) => {
if (isWrongTitle) return;
@ -101,7 +102,7 @@ const CreateRoomDialog = ({
};
const onCreateRoom = async () => {
if (!roomParams.title.trim()) {
if (!roomParams?.title?.trim()) {
setIsValidTitle(false);
return;
}

View File

@ -63,7 +63,7 @@ const ExternalLinks = ({
const editLink = async () => {
const type =
roomType === RoomsType.PublicRoom
? ShareAccessRights.RoomManager
? ShareAccessRights.Collaborator
: ShareAccessRights.ReadOnly;
const link = await setInvitationLinks(roomId, "Invite", type);

View File

@ -138,6 +138,8 @@ export const getCategoryType = (location) => {
categoryType = CategoryType.Settings;
} else if (pathname.startsWith("/accounts/filter")) {
categoryType = CategoryType.Accounts;
} else if (pathname.startsWith("/form-gallery")) {
categoryType = CategoryType.Personal;
}
return categoryType;

View File

@ -70,6 +70,7 @@ const WelcomePageSettings = (props) => {
greetingTitleDefaultFromSessionStorage = getFromSessionStorage(
"greetingTitleDefault"
);
getGreetingSettingsIsDefault();
setDocumentTitle(t("CustomTitlesWelcome"));
@ -193,8 +194,10 @@ const WelcomePageSettings = (props) => {
toastr.success(t("SuccessfullySaveGreetingSettingsMessage"));
})
.catch((error) => toastr.error(error))
.finally(() =>
setState((val) => ({ ...val, isLoadingGreetingSave: false }))
.finally(() => {
getGreetingSettingsIsDefault();
setState((val) => ({ ...val, isLoadingGreetingSave: false }));
}
);
setState((val) => ({ ...val, showReminder: false }));
@ -206,9 +209,10 @@ const WelcomePageSettings = (props) => {
const onRestoreGreetingSettings = () => {
setState((val) => ({ ...val, isLoadingGreetingRestore: true }));
restoreGreetingTitle()
.then(() => {
.then((defaultTitle) => {
setState((val) => ({
...val,
greetingTitle: defaultTitle,
showReminder: false,
}));
@ -218,8 +222,10 @@ const WelcomePageSettings = (props) => {
toastr.success(t("SuccessfullySaveGreetingSettingsMessage"));
})
.catch((error) => toastr.error(error))
.finally(() =>
setState((val) => ({ ...val, isLoadingGreetingRestore: false }))
.finally(() => {
getGreetingSettingsIsDefault();
setState((val) => ({ ...val, isLoadingGreetingRestore: false }));
}
);
};

View File

@ -12,6 +12,7 @@ import {
createPasswordHash,
frameCallCommand,
} from "@docspace/common/utils";
import { RoomsType } from "@docspace/common/constants";
const Sdk = ({
frameConfig,
@ -25,6 +26,8 @@ const Sdk = ({
getSettings,
user,
updateProfileCulture,
getRoomsIcon,
getPrimaryLink,
}) => {
useEffect(() => {
window.addEventListener("message", handleMessage, false);
@ -118,8 +121,18 @@ const Sdk = ({
};
const onSelectRoom = useCallback(
(data) => {
data[0].icon = toRelativeUrl(data[0].icon);
async (data) => {
if (data[0].logo.large !== "") {
data[0].icon = toRelativeUrl(data[0].logo.large);
} else {
data[0].icon = await getRoomsIcon(data[0].roomType, false, 32);
}
if (data[0].roomType === RoomsType.PublicRoom) {
const { sharedTo } = await getPrimaryLink(data[0].id);
data[0].requestToken = sharedTo?.requestToken;
}
frameCallEvent({ event: "onSelectCallback", data });
},
[frameCallEvent]
@ -150,8 +163,8 @@ const Sdk = ({
case "room-selector":
component = (
<RoomSelector
withCancelButton={true}
withHeader={false}
withCancelButton={frameConfig?.showSelectorCancel}
withHeader={frameConfig?.showSelectorHeader}
onAccept={onSelectRoom}
onCancel={onClose}
/>
@ -162,11 +175,14 @@ const Sdk = ({
<FilesSelector
isPanelVisible={true}
embedded={true}
withHeader={false}
withHeader={frameConfig?.showSelectorHeader}
isSelect={true}
onSelectFile={onSelectFile}
onClose={onClose}
filterParam={"ALL"}
isUserOnly={selectorType === "userFolderOnly"}
isRoomsOnly={selectorType === "roomsOnly"}
withCancelButton={frameConfig?.showSelectorCancel}
/>
);
break;
@ -177,13 +193,14 @@ const Sdk = ({
return component;
};
export default inject(({ auth, settingsStore, peopleStore }) => {
export default inject(({ auth, settingsStore, peopleStore, filesStore }) => {
const { login, logout, userStore } = auth;
const { theme, setFrameConfig, frameConfig, getSettings, isLoaded } =
auth.settingsStore;
const { loadCurrentUser, user } = userStore;
const { updateProfileCulture } = peopleStore.targetUserStore;
const { getIcon } = settingsStore;
const { getIcon, getRoomsIcon } = settingsStore;
const { getPrimaryLink } = filesStore;
return {
theme,
@ -194,8 +211,10 @@ export default inject(({ auth, settingsStore, peopleStore }) => {
getSettings,
loadCurrentUser,
getIcon,
getRoomsIcon,
isLoaded,
updateProfileCulture,
user,
getPrimaryLink,
};
})(observer(Sdk));

View File

@ -430,9 +430,12 @@ class ContextOptionsStore {
this.dialogsStore.setDownloadDialogVisible(true);
};
onClickCreateRoom = () => {
onClickCreateRoom = (item) => {
this.filesActionsStore.setProcessCreatingRoomFromData(true);
const event = new Event(Events.ROOM_CREATE);
if (item && item.isFolder) {
event.title = item.title;
}
window.dispatchEvent(event);
};
@ -1355,7 +1358,7 @@ class ContextOptionsStore {
key: "create-room",
label: t("Files:CreateRoom"),
icon: CatalogRoomsReactSvgUrl,
onClick: this.onClickCreateRoom,
onClick: () => this.onClickCreateRoom(item),
disabled: this.selectedFolderStore.rootFolderType !== FolderType.USER,
},
{

View File

@ -25,6 +25,10 @@ import {
import { combineUrl } from "@docspace/common/utils";
import config from "PACKAGE_FILE";
import { getUnexpectedErrorText } from "SRC_DIR/helpers/filesUtils";
import {
getCategoryTypeByFolderType,
getCategoryUrl,
} from "SRC_DIR/helpers/utils";
const UPLOAD_LIMIT_AT_ONCE = 5;
@ -1527,6 +1531,26 @@ class UploadDataStore {
return operationItem;
};
navigateToNewFolderLocation = async (folderId) => {
const { filter } = this.filesStore;
filter.folder = folderId;
try {
const { rootFolderType, parentId } = await getFolderInfo(folderId);
const path = getCategoryUrl(
getCategoryTypeByFolderType(rootFolderType, parentId),
folderId
);
window.DocSpace.navigate(`${path}?${filter.toUrlParams()}`, {
replace: true,
});
} catch (e) {
console.log(e);
}
};
moveToCopyTo = (destFolderId, pbData, isCopy, fileIds, folderIds) => {
const {
fetchFiles,
@ -1539,6 +1563,7 @@ class UploadDataStore {
const { clearSecondaryProgressData, setSecondaryProgressBarData, label } =
this.secondaryProgressDataStore;
const { withPaging } = this.authStore.settingsStore;
const isMovingCurrentFolder = !isCopy && this.dialogsStore.isFolderActions;
let receivedFolder = destFolderId;
let updatedFolder = this.selectedFolderStore.id;
@ -1558,6 +1583,8 @@ class UploadDataStore {
() => clearSecondaryProgressData(pbData.operationId),
TIMEOUT
);
isMovingCurrentFolder &&
this.navigateToNewFolderLocation(this.selectedFolderStore.id);
this.dialogsStore.setIsFolderActions(false);
return;
}
@ -1578,6 +1605,8 @@ class UploadDataStore {
() => clearSecondaryProgressData(pbData.operationId),
TIMEOUT
);
isMovingCurrentFolder &&
this.navigateToNewFolderLocation(this.selectedFolderStore.id);
this.dialogsStore.setIsFolderActions(false);
});
} else {

View File

@ -1,6 +1,6 @@
{
"name": "@docspace/common",
"version": "2.0.0",
"version": "2.0.1",
"private": true,
"scripts": {
"build": "echo 'skip it'",

View File

@ -938,6 +938,7 @@ class SettingsStore {
};
get isFrame() {
console.log("get isFrame:", this.frameConfig?.name === window.name);
return this.frameConfig?.name === window.name;
}

View File

@ -72,7 +72,7 @@ Badge.propTypes = {
/** CSS font-size */
fontSize: PropTypes.string,
/** CSS font-weight */
fontWeight: PropTypes.number,
fontWeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
/** CSS border-radius */
borderRadius: PropTypes.string,
/** CSS padding */

View File

@ -1,6 +1,6 @@
{
"name": "@docspace/components",
"version": "2.0.0",
"version": "2.0.1",
"private": true,
"scripts": {
"build": "echo 'skip it'",

View File

@ -221,7 +221,7 @@ SnackBar.propTypes = {
/** Sets the font size */
fontSize: PropTypes.string,
/** Sets the font weight */
fontWeight: PropTypes.string,
fontWeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
/** Specifies the text alignment */
textAlign: PropTypes.string,
/** Allows displaying content in HTML format */

View File

@ -1,6 +1,6 @@
{
"name": "@docspace/editor",
"version": "2.0.0",
"version": "2.0.1",
"private": true,
"homepage": "/doceditor",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@docspace/login",
"version": "2.0.0",
"version": "2.0.1",
"private": true,
"homepage": "/login",
"scripts": {

View File

@ -15,6 +15,8 @@
editorType: "embedded", //TODO: ["desktop", "embedded"]
editorGoBack: true,
selectorType: "exceptPrivacyTrashArchiveFolders", //TODO: ["roomsOnly", "userFolderOnly", "exceptPrivacyTrashArchiveFolders", "exceptSortedByTagsFolders"]
showSelectorCancel: false,
showSelectorHeader: false,
showHeader: false,
showTitle: true,
showMenu: false,