Merge branch 'develop' into feature/active-sessions
This commit is contained in:
commit
bc52d11ea9
541
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
vendored
541
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
vendored
File diff suppressed because one or more lines are too long
550
.yarn/plugins/@yarnpkg/plugin-version.cjs
vendored
550
.yarn/plugins/@yarnpkg/plugin-version.cjs
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
801
.yarn/releases/yarn-3.2.4.cjs
vendored
801
.yarn/releases/yarn-3.2.4.cjs
vendored
File diff suppressed because one or more lines are too long
893
.yarn/releases/yarn-4.0.2.cjs
vendored
Executable file
893
.yarn/releases/yarn-4.0.2.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
12
.yarnrc.yml
12
.yarnrc.yml
@ -1,13 +1,11 @@
|
||||
compressionLevel: mixed
|
||||
|
||||
enableGlobalCache: false
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
|
||||
spec: "@yarnpkg/plugin-workspace-tools"
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||
spec: "@yarnpkg/plugin-interactive-tools"
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-version.cjs
|
||||
spec: "@yarnpkg/plugin-version"
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-licenses-audit.cjs
|
||||
spec: "https://raw.githubusercontent.com/tophat/yarn-plugin-licenses/master/bundles/@yarnpkg/plugin-licenses-audit.js"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.2.4.cjs
|
||||
yarnPath: .yarn/releases/yarn-4.0.2.cjs
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docspace",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.2",
|
||||
"private": true,
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
@ -8,8 +8,8 @@
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18",
|
||||
"yarn": ">=3"
|
||||
"node": ">=20",
|
||||
"yarn": ">=4"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node ./common/scripts/before-build.js && yarn workspaces foreach -vptiR --from '{@docspace/client,@docspace/login,@docspace/editor,@docspace/management}' run build",
|
||||
@ -44,5 +44,5 @@
|
||||
"shx": "^0.3.4",
|
||||
"terser": "^5.16.6"
|
||||
},
|
||||
"packageManager": "yarn@3.2.4"
|
||||
"packageManager": "yarn@4.0.2"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@docspace/client",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.2",
|
||||
"private": true,
|
||||
"homepage": "",
|
||||
"scripts": {
|
||||
|
@ -3,7 +3,7 @@ import { inject, observer } from "mobx-react";
|
||||
import { useLocation, Outlet } from "react-router-dom";
|
||||
import { withTranslation } from "react-i18next";
|
||||
|
||||
import Article from "@docspace/common/components/Article";
|
||||
import Article from "@docspace/shared/components/article";
|
||||
import {
|
||||
updateTempContent,
|
||||
showLoader,
|
||||
@ -20,6 +20,7 @@ import {
|
||||
ArticleHeaderContent,
|
||||
ArticleMainButtonContent,
|
||||
} from "./components/Article";
|
||||
import ArticleWrapper from "./components/ArticleWrapper";
|
||||
|
||||
const ClientArticle = React.memo(
|
||||
({
|
||||
@ -29,7 +30,7 @@ const ClientArticle = React.memo(
|
||||
showArticleLoader,
|
||||
}) => {
|
||||
return (
|
||||
<Article
|
||||
<ArticleWrapper
|
||||
withMainButton={withMainButton}
|
||||
onLogoClickAction={() => {
|
||||
setIsFilterLoading(true, false);
|
||||
@ -48,7 +49,7 @@ const ClientArticle = React.memo(
|
||||
<Article.Body>
|
||||
<ArticleBodyContent />
|
||||
</Article.Body>
|
||||
</Article>
|
||||
</ArticleWrapper>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -203,7 +203,7 @@ export default function withFileActions(WrappedFileItem) {
|
||||
item.foldersCount === 0
|
||||
) {
|
||||
setParentId(item.parentId);
|
||||
setRoomType(item.roomType);
|
||||
// setRoomType(item.roomType);
|
||||
}
|
||||
|
||||
openFileAction(item);
|
||||
|
@ -15,10 +15,10 @@ import AccountsFilter from "@docspace/shared/api/people/filter";
|
||||
|
||||
import Banner from "./Banner";
|
||||
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
|
||||
import { getCategoryUrl } from "SRC_DIR/helpers/utils";
|
||||
import { CategoryType } from "SRC_DIR/helpers/constants";
|
||||
import { ArticleFolderLoader } from "@docspace/shared/skeletons/article";
|
||||
import { MEDIA_VIEW_URL } from "@docspace/shared/constants";
|
||||
|
||||
const StyledBlock = styled.div`
|
||||
padding: 0 20px;
|
||||
@ -221,7 +221,7 @@ const ArticleBodyContent = (props) => {
|
||||
return setActiveItemId(rootFolderId || roomsFolderId);
|
||||
}
|
||||
|
||||
if (location.pathname.includes("/products/files/#preview")) {
|
||||
if (location.pathname.includes(MEDIA_VIEW_URL)) {
|
||||
setActiveItemId(rootFolderId);
|
||||
}
|
||||
}, [
|
||||
@ -239,7 +239,7 @@ const ArticleBodyContent = (props) => {
|
||||
setIsBurgerLoading(showArticleLoader);
|
||||
}, [showArticleLoader]);
|
||||
|
||||
if (showArticleLoader) return <Loaders.ArticleFolder />;
|
||||
if (showArticleLoader) return <ArticleFolderLoader />;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -1,8 +1,9 @@
|
||||
import React from "react";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import withLoader from "../../../HOCs/withLoader";
|
||||
import { ArticleHeaderLoader } from "@docspace/shared/skeletons/article";
|
||||
|
||||
const ArticleHeaderContent = ({ currentModuleName }) => {
|
||||
return <>{currentModuleName}</>;
|
||||
@ -14,6 +15,6 @@ export default inject(({ auth }) => {
|
||||
};
|
||||
})(
|
||||
withTranslation([])(
|
||||
withLoader(observer(ArticleHeaderContent))(<Loaders.ArticleHeader />)
|
||||
withLoader(observer(ArticleHeaderContent))(<ArticleHeaderLoader />)
|
||||
)
|
||||
);
|
||||
|
@ -22,7 +22,6 @@ import { toastr } from "@docspace/shared/components/toast";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
|
||||
import { withTranslation } from "react-i18next";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
import { encryptionUploadDialog } from "../../../helpers/desktop";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
|
||||
@ -34,6 +33,7 @@ import styled, { css } from "styled-components";
|
||||
|
||||
import { resendInvitesAgain } from "@docspace/shared/api/people";
|
||||
import { getCorrectFourValuesStyle } from "@docspace/shared/utils";
|
||||
import { ArticleButtonLoader } from "@docspace/shared/skeletons/article";
|
||||
|
||||
const StyledButton = styled(Button)`
|
||||
font-weight: 700;
|
||||
@ -512,7 +512,7 @@ const ArticleMainButtonContent = (props) => {
|
||||
}
|
||||
|
||||
if (showArticleLoader)
|
||||
return isMobileArticle ? null : <Loaders.ArticleButton height="32px" />;
|
||||
return isMobileArticle ? null : <ArticleButtonLoader height="32px" />;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
141
packages/client/src/components/ArticleWrapper/index.tsx
Normal file
141
packages/client/src/components/ArticleWrapper/index.tsx
Normal file
@ -0,0 +1,141 @@
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
import Article from "@docspace/shared/components/article";
|
||||
import { ArticleProps } from "@docspace/shared/components/article/Article.types";
|
||||
|
||||
const ArticleWrapper = (props: ArticleProps) => {
|
||||
return <Article {...props} />;
|
||||
};
|
||||
|
||||
export default inject(
|
||||
({ auth, uploadDataStore, profileActionsStore, dialogsStore }: any) => {
|
||||
const {
|
||||
settingsStore,
|
||||
userStore,
|
||||
isLiveChatAvailable,
|
||||
bannerStore,
|
||||
currentQuotaStore,
|
||||
|
||||
isPaymentPageAvailable,
|
||||
isTeamTrainingAlertAvailable,
|
||||
isSubmitToGalleryAlertAvailable,
|
||||
currentTariffStatusStore,
|
||||
isEnterprise,
|
||||
} = auth;
|
||||
|
||||
const { getActions, getUserRole, onProfileClick } = profileActionsStore;
|
||||
|
||||
const { withSendAgain, user } = userStore;
|
||||
|
||||
const { isBannerVisible } = bannerStore;
|
||||
|
||||
const { primaryProgressDataStore, secondaryProgressDataStore } =
|
||||
uploadDataStore;
|
||||
|
||||
const { email, displayName } = user;
|
||||
|
||||
const isAdmin = user?.isAdmin;
|
||||
|
||||
const { visible: primaryProgressDataVisible } = primaryProgressDataStore;
|
||||
const { visible: secondaryProgressDataStoreVisible } =
|
||||
secondaryProgressDataStore;
|
||||
|
||||
const showProgress =
|
||||
primaryProgressDataVisible || secondaryProgressDataStoreVisible;
|
||||
|
||||
const {
|
||||
showText,
|
||||
setShowText,
|
||||
articleOpen,
|
||||
setIsMobileArticle,
|
||||
toggleShowText,
|
||||
toggleArticleOpen,
|
||||
currentColorScheme,
|
||||
setArticleOpen,
|
||||
mainBarVisible,
|
||||
zendeskKey,
|
||||
isMobileArticle,
|
||||
|
||||
currentDeviceType,
|
||||
standalone,
|
||||
articleAlertsData,
|
||||
incrementIndexOfArticleAlertsData,
|
||||
isBurgerLoading,
|
||||
whiteLabelLogoUrls,
|
||||
removeAlertFromArticleAlertsData,
|
||||
bookTrainingEmail,
|
||||
} = settingsStore;
|
||||
|
||||
const { setSubmitToGalleryDialogVisible } = dialogsStore;
|
||||
|
||||
const { isFreeTariff, isNonProfit, isTrial, currentTariffPlanTitle } =
|
||||
currentQuotaStore;
|
||||
const {
|
||||
isGracePeriod,
|
||||
isLicenseExpiring,
|
||||
isLicenseDateExpired,
|
||||
trialDaysLeft,
|
||||
paymentDate,
|
||||
} = currentTariffStatusStore;
|
||||
|
||||
return {
|
||||
bookTrainingEmail,
|
||||
onProfileClick,
|
||||
user,
|
||||
getUserRole,
|
||||
getActions,
|
||||
|
||||
currentTariffPlanTitle,
|
||||
email,
|
||||
displayName,
|
||||
|
||||
zendeskKey,
|
||||
isMobileArticle,
|
||||
showProgress,
|
||||
|
||||
isBurgerLoading,
|
||||
whiteLabelLogoUrls,
|
||||
isEnterprise,
|
||||
isTrial,
|
||||
isLicenseDateExpired,
|
||||
trialDaysLeft,
|
||||
paymentDate,
|
||||
|
||||
toggleArticleOpen,
|
||||
|
||||
articleAlertsData,
|
||||
incrementIndexOfArticleAlertsData,
|
||||
|
||||
showText,
|
||||
isNonProfit,
|
||||
isGracePeriod,
|
||||
isFreeTariff,
|
||||
isPaymentPageAvailable,
|
||||
isTeamTrainingAlertAvailable,
|
||||
isSubmitToGalleryAlertAvailable,
|
||||
isLicenseExpiring,
|
||||
|
||||
standalone,
|
||||
|
||||
setShowText,
|
||||
articleOpen,
|
||||
setIsMobileArticle,
|
||||
toggleShowText,
|
||||
|
||||
removeAlertFromArticleAlertsData,
|
||||
setSubmitToGalleryDialogVisible,
|
||||
|
||||
currentColorScheme,
|
||||
setArticleOpen,
|
||||
withSendAgain,
|
||||
mainBarVisible,
|
||||
isBannerVisible,
|
||||
|
||||
isLiveChatAvailable,
|
||||
|
||||
currentDeviceType,
|
||||
|
||||
isAdmin,
|
||||
};
|
||||
}
|
||||
)(observer(Article));
|
@ -29,6 +29,7 @@ export type Item = {
|
||||
security: Security;
|
||||
roomType: number;
|
||||
fileExst?: string;
|
||||
shared: boolean;
|
||||
};
|
||||
|
||||
export type BreadCrumb = {
|
||||
|
@ -13,6 +13,8 @@ import { Backdrop } from "@docspace/shared/components/backdrop";
|
||||
import { Portal } from "@docspace/shared/components/portal";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
|
||||
import { RowLoader, SearchLoader } from "@docspace/shared/skeletons/selector";
|
||||
|
||||
import EmptyScreenFilterAltSvgUrl from "PUBLIC_DIR/images/empty_screen_filter_alt.svg?url";
|
||||
import EmptyScreenFilterAltDarkSvgUrl from "PUBLIC_DIR/images/empty_screen_filter_alt_dark.svg?url";
|
||||
import EmptyScreenAltSvgUrl from "PUBLIC_DIR/images/empty_screen_alt.svg?url";
|
||||
@ -224,6 +226,7 @@ const FilesSelector = ({
|
||||
isRoom:
|
||||
item.parentId === 0 && item.rootFolderType === FolderType.Rooms,
|
||||
roomType: item.roomType,
|
||||
shared: item.shared,
|
||||
},
|
||||
]);
|
||||
setSelectedItemId(item.id);
|
||||
@ -363,7 +366,7 @@ const FilesSelector = ({
|
||||
onCloseAction();
|
||||
};
|
||||
|
||||
const onSearchAction = (value: string) => {
|
||||
const onSearchAction = (value: string, callback?: Function) => {
|
||||
setIsFirstLoad(true);
|
||||
setItems(null);
|
||||
if (selectedItemType === "rooms") {
|
||||
@ -373,9 +376,10 @@ const FilesSelector = ({
|
||||
}
|
||||
|
||||
setSearchValue(value);
|
||||
callback?.();
|
||||
};
|
||||
|
||||
const onClearSearchAction = () => {
|
||||
const onClearSearchAction = (callback?: Function) => {
|
||||
setIsFirstLoad(true);
|
||||
setItems(null);
|
||||
if (selectedItemType === "rooms") {
|
||||
@ -385,6 +389,7 @@ const FilesSelector = ({
|
||||
}
|
||||
|
||||
setSearchValue("");
|
||||
callback?.();
|
||||
};
|
||||
|
||||
const onAcceptAction = (
|
||||
@ -552,13 +557,13 @@ const FilesSelector = ({
|
||||
isBreadCrumbsLoading={showBreadCrumbsLoader}
|
||||
withSearch={!isRoot && items ? items.length > 0 : !isRoot && isFirstLoad}
|
||||
rowLoader={
|
||||
<Loaders.SelectorRowLoader
|
||||
<RowLoader
|
||||
isMultiSelect={false}
|
||||
isUser={isRoot}
|
||||
isContainer={showLoader}
|
||||
/>
|
||||
}
|
||||
searchLoader={<Loaders.SelectorSearchLoader />}
|
||||
searchLoader={<SearchLoader />}
|
||||
breadCrumbsLoader={<Loaders.SelectorBreadCrumbsLoader />}
|
||||
alwaysShowFooter={true}
|
||||
isNextPageLoading={isNextPageLoading}
|
||||
|
@ -19,7 +19,7 @@ const ChangeUserTypeEvent = ({
|
||||
onClose,
|
||||
setSelected,
|
||||
getPeopleListItem,
|
||||
setSelection,
|
||||
setInfoPanelSelection,
|
||||
needResetUserSelection,
|
||||
isRoomAdmin,
|
||||
}) => {
|
||||
@ -70,7 +70,7 @@ const ChangeUserTypeEvent = ({
|
||||
if (!needResetUserSelection) {
|
||||
const user = getPeopleListItem(users[0]);
|
||||
|
||||
setSelection(user);
|
||||
setInfoPanelSelection(user);
|
||||
}
|
||||
|
||||
successCallback && successCallback(users);
|
||||
@ -144,7 +144,7 @@ export default inject(({ auth, dialogsStore, peopleStore }) => {
|
||||
setChangeUserTypeDialogVisible: setVisible,
|
||||
} = dialogsStore;
|
||||
const { isRoomAdmin, infoPanelStore } = auth;
|
||||
const { setSelection } = infoPanelStore;
|
||||
const { setInfoPanelSelection } = infoPanelStore;
|
||||
const { dialogStore, filterStore, usersStore } = peopleStore;
|
||||
|
||||
const { data: peopleDialogData } = dialogStore;
|
||||
@ -160,7 +160,7 @@ export default inject(({ auth, dialogsStore, peopleStore }) => {
|
||||
isRoomAdmin,
|
||||
needResetUserSelection,
|
||||
getPeopleListItem,
|
||||
setSelection,
|
||||
setInfoPanelSelection,
|
||||
setSelected,
|
||||
|
||||
visible,
|
||||
|
@ -44,9 +44,8 @@ const EditRoomEvent = ({
|
||||
updateLogoPathsCacheBreaker,
|
||||
removeLogoPaths,
|
||||
|
||||
reloadInfoPanelSelection,
|
||||
updateInfoPanelSelection,
|
||||
changeRoomOwner,
|
||||
reloadSelectionParentRoom,
|
||||
}) => {
|
||||
const { t } = useTranslation(["CreateEditRoomDialog", "Common", "Files"]);
|
||||
|
||||
@ -108,6 +107,8 @@ const EditRoomEvent = ({
|
||||
const uploadLogoData = new FormData();
|
||||
uploadLogoData.append(0, roomParams.icon.uploadedFile);
|
||||
|
||||
let room = null;
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
@ -115,7 +116,7 @@ const EditRoomEvent = ({
|
||||
await changeRoomOwner(t, roomParams?.roomOwner?.id);
|
||||
}
|
||||
|
||||
let room = await editRoom(item.id, editRoomParams);
|
||||
room = await editRoom(item.id, editRoomParams);
|
||||
|
||||
room.isLogoLoading = true;
|
||||
|
||||
@ -154,15 +155,14 @@ const EditRoomEvent = ({
|
||||
}
|
||||
|
||||
!withPaging && updateRoom(item, room);
|
||||
reloadSelectionParentRoom();
|
||||
reloadInfoPanelSelection();
|
||||
// updateInfoPanelSelection();
|
||||
URL.revokeObjectURL(img.src);
|
||||
setActiveFolders([]);
|
||||
};
|
||||
img.src = url;
|
||||
} else {
|
||||
!withPaging && updateRoom(item, room);
|
||||
reloadInfoPanelSelection();
|
||||
// updateInfoPanelSelection();
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
@ -173,14 +173,14 @@ const EditRoomEvent = ({
|
||||
updateEditedSelectedRoom(editRoomParams.title, tags);
|
||||
if (item.logo.original && !roomParams.icon.uploadedFile) {
|
||||
removeLogoPaths();
|
||||
reloadInfoPanelSelection();
|
||||
// updateInfoPanelSelection();
|
||||
} else if (!item.logo.original && roomParams.icon.uploadedFile)
|
||||
addDefaultLogoPaths();
|
||||
else if (item.logo.original && roomParams.icon.uploadedFile)
|
||||
updateLogoPathsCacheBreaker();
|
||||
}
|
||||
|
||||
reloadSelectionParentRoom();
|
||||
updateInfoPanelSelection(room);
|
||||
setIsLoading(false);
|
||||
onClose();
|
||||
}
|
||||
@ -272,10 +272,7 @@ export default inject(
|
||||
const { getThirdPartyIcon } = settingsStore.thirdPartyStore;
|
||||
const { setCreateRoomDialogVisible } = dialogsStore;
|
||||
const { withPaging } = auth.settingsStore;
|
||||
const {
|
||||
reloadSelection: reloadInfoPanelSelection,
|
||||
reloadSelectionParentRoom,
|
||||
} = auth.infoPanelStore;
|
||||
const { updateInfoPanelSelection } = auth.infoPanelStore;
|
||||
return {
|
||||
addActiveItems,
|
||||
setActiveFolders,
|
||||
@ -308,9 +305,8 @@ export default inject(
|
||||
updateLogoPathsCacheBreaker,
|
||||
removeLogoPaths,
|
||||
|
||||
reloadInfoPanelSelection,
|
||||
updateInfoPanelSelection,
|
||||
changeRoomOwner,
|
||||
reloadSelectionParentRoom,
|
||||
};
|
||||
}
|
||||
)(observer(EditRoomEvent));
|
||||
|
@ -3,7 +3,6 @@ import CatalogFolderReactSvgUrl from "PUBLIC_DIR/images/catalog.folder.react.svg
|
||||
import React from "react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import Filter from "@docspace/shared/api/people/filter";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { getSelectedGroup } from "../../../helpers/people-helpers";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@ -13,6 +12,7 @@ import config from "PACKAGE_FILE";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
import { ArticleItem } from "@docspace/shared/components/article-item";
|
||||
import withLoader from "../../../HOCs/withLoader";
|
||||
import { ArticleFolderLoader } from "@docspace/shared/skeletons/article";
|
||||
|
||||
const departmentsIcon = DepartmentsGroupReactSvgUrl;
|
||||
const groupIcon = CatalogFolderReactSvgUrl;
|
||||
@ -128,7 +128,7 @@ const ArticleBodyContent = ({
|
||||
};
|
||||
|
||||
const BodyContent = withTranslation(["Article"])(
|
||||
withLoader(ArticleBodyContent)(<Loaders.ArticleFolder />)
|
||||
withLoader(ArticleBodyContent)(<ArticleFolderLoader />)
|
||||
);
|
||||
|
||||
export default inject(({ auth, peopleStore }) => {
|
||||
|
@ -23,6 +23,7 @@ import {
|
||||
import MobileView from "./MobileView";
|
||||
|
||||
import withLoader from "../../../HOCs/withLoader";
|
||||
import { ArticleButtonLoader } from "@docspace/shared/skeletons/article";
|
||||
|
||||
const ArticleMainButtonContent = (props) => {
|
||||
const [dialogVisible, setDialogVisible] = React.useState(false);
|
||||
@ -128,6 +129,6 @@ export default inject(({ auth }) => {
|
||||
};
|
||||
})(
|
||||
withTranslation(["Article", "Common", "PeopleTranslations"])(
|
||||
withLoader(observer(ArticleMainButtonContent))(<Loaders.ArticleButton />)
|
||||
withLoader(observer(ArticleMainButtonContent))(<ArticleButtonLoader />)
|
||||
)
|
||||
);
|
||||
|
@ -1,40 +0,0 @@
|
||||
import i18n from "i18next";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/shared/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/shared/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { getCookie } from "@docspace/shared/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
.use(Backend)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
lng: getCookie(LANGUAGE) || "en",
|
||||
|
||||
fallbackLng: "en",
|
||||
load: "currentOnly",
|
||||
//debug: true,
|
||||
|
||||
interpolation: {
|
||||
escapeValue: false, // not needed for react as it escapes by default
|
||||
format: function (value, format) {
|
||||
if (format === "lowercase") return value.toLowerCase();
|
||||
return value;
|
||||
},
|
||||
},
|
||||
|
||||
backend: {
|
||||
loadPath: loadLanguagePath(config.homepage),
|
||||
},
|
||||
|
||||
ns: ["PeopleSelector", "Common", "PeopleTranslations"],
|
||||
defaultNS: "PeopleSelector",
|
||||
|
||||
react: {
|
||||
useSuspense: false,
|
||||
},
|
||||
});
|
||||
|
||||
export default newInstance;
|
@ -1,286 +0,0 @@
|
||||
import i18n from "./i18n";
|
||||
import PropTypes from "prop-types";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { I18nextProvider, withTranslation } from "react-i18next";
|
||||
|
||||
import { Selector } from "@docspace/shared/components/selector";
|
||||
|
||||
import { getUserRole } from "@docspace/shared/utils/common";
|
||||
import Filter from "@docspace/shared/api/people/filter";
|
||||
import { getUserList } from "@docspace/shared/api/people";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
import { EmployeeStatus } from "@docspace/shared/enums";
|
||||
import { LOADER_TIMEOUT } from "@docspace/shared/constants";
|
||||
|
||||
import useLoadingWithTimeout from "SRC_DIR/Hooks/useLoadingWithTimeout";
|
||||
|
||||
import DefaultUserPhoto from "PUBLIC_DIR/images/default_user_photo_size_82-82.png";
|
||||
|
||||
import EmptyScreenPersonsSvgUrl from "PUBLIC_DIR/images/empty_screen_persons.svg?url";
|
||||
import CatalogAccountsReactSvgUrl from "PUBLIC_DIR/images/catalog.accounts.react.svg?url";
|
||||
import EmptyScreenPersonsSvgDarkUrl from "PUBLIC_DIR/images/empty_screen_persons_dark.svg?url";
|
||||
|
||||
const PeopleSelector = ({
|
||||
acceptButtonLabel,
|
||||
accessRights,
|
||||
cancelButtonLabel,
|
||||
className,
|
||||
emptyScreenDescription,
|
||||
emptyScreenHeader,
|
||||
headerLabel,
|
||||
id,
|
||||
isMultiSelect,
|
||||
items,
|
||||
onAccept,
|
||||
onAccessRightsChange,
|
||||
onBackClick,
|
||||
onCancel,
|
||||
onSelect,
|
||||
onSelectAll,
|
||||
searchEmptyScreenDescription,
|
||||
searchEmptyScreenHeader,
|
||||
searchPlaceholder,
|
||||
selectAllIcon,
|
||||
selectAllLabel,
|
||||
selectedAccessRight,
|
||||
selectedItems,
|
||||
style,
|
||||
t,
|
||||
withAccessRights,
|
||||
withCancelButton,
|
||||
withSelectAll,
|
||||
filter,
|
||||
excludeItems,
|
||||
currentUserId,
|
||||
theme,
|
||||
withOutCurrentAuthorizedUser,
|
||||
withAbilityCreateRoomUsers,
|
||||
withFooterCheckbox,
|
||||
footerCheckboxLabel,
|
||||
isChecked,
|
||||
setIsChecked,
|
||||
filterUserId,
|
||||
}) => {
|
||||
const [itemsList, setItemsList] = useState(items);
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
const [total, setTotal] = useState(0);
|
||||
const [hasNextPage, setHasNextPage] = useState(true);
|
||||
const [isNextPageLoading, setIsNextPageLoading] = useState(false);
|
||||
const [isLoading, setIsLoading] = useLoadingWithTimeout(
|
||||
LOADER_TIMEOUT,
|
||||
false
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
loadNextPage(0);
|
||||
}, []);
|
||||
|
||||
const toListItem = (item) => {
|
||||
const {
|
||||
id,
|
||||
email,
|
||||
avatar,
|
||||
icon,
|
||||
displayName,
|
||||
hasAvatar,
|
||||
isOwner,
|
||||
isAdmin,
|
||||
isVisitor,
|
||||
isCollaborator,
|
||||
} = item;
|
||||
|
||||
const role = getUserRole(item);
|
||||
|
||||
const userAvatar = hasAvatar ? avatar : DefaultUserPhoto;
|
||||
|
||||
return {
|
||||
id,
|
||||
email,
|
||||
avatar: userAvatar,
|
||||
icon,
|
||||
label: displayName || email,
|
||||
role,
|
||||
isOwner,
|
||||
isAdmin,
|
||||
isVisitor,
|
||||
isCollaborator,
|
||||
hasAvatar,
|
||||
};
|
||||
};
|
||||
|
||||
const moveCurrentUserToTopOfList = (listUser) => {
|
||||
const currentUserIndex = listUser.findIndex(
|
||||
(user) => user.id === currentUserId
|
||||
);
|
||||
|
||||
// return if the current user is already at the top of the list or not found
|
||||
if (currentUserIndex < 1) return listUser;
|
||||
|
||||
const [currentUser] = listUser.splice(currentUserIndex, 1);
|
||||
|
||||
listUser.splice(0, 0, currentUser);
|
||||
|
||||
return listUser;
|
||||
};
|
||||
|
||||
const removeCurrentUserFromList = (listUser) => {
|
||||
if (filterUserId) {
|
||||
return listUser.filter((user) => user.id !== filterUserId);
|
||||
}
|
||||
return listUser.filter((user) => user.id !== currentUserId);
|
||||
};
|
||||
|
||||
const loadNextPage = (startIndex, search = searchValue) => {
|
||||
const pageCount = 100;
|
||||
|
||||
setIsNextPageLoading(true);
|
||||
|
||||
if (startIndex === 0) {
|
||||
setIsLoading(true);
|
||||
}
|
||||
|
||||
const currentFilter =
|
||||
typeof filter === "function" ? filter() : filter ?? Filter.getDefault();
|
||||
|
||||
currentFilter.page = startIndex / pageCount;
|
||||
currentFilter.pageCount = pageCount;
|
||||
|
||||
if (!!search.length) {
|
||||
currentFilter.search = search;
|
||||
}
|
||||
|
||||
getUserList(currentFilter)
|
||||
.then((response) => {
|
||||
let newItems = startIndex ? itemsList : [];
|
||||
let totalDifferent = startIndex ? response.total - total : 0;
|
||||
|
||||
const items = response.items
|
||||
.filter((item) => {
|
||||
const excludeUser =
|
||||
withAbilityCreateRoomUsers &&
|
||||
((!item.isAdmin && !item.isOwner && !item.isRoomAdmin) ||
|
||||
item.status === EmployeeStatus.Disabled);
|
||||
|
||||
if (excludeItems.includes(item.id) || excludeUser) {
|
||||
totalDifferent++;
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
})
|
||||
.map((item) => toListItem(item));
|
||||
|
||||
const tempItems = [...newItems, ...items];
|
||||
|
||||
newItems = withOutCurrentAuthorizedUser
|
||||
? removeCurrentUserFromList(tempItems)
|
||||
: moveCurrentUserToTopOfList(tempItems);
|
||||
|
||||
const newTotal = withOutCurrentAuthorizedUser
|
||||
? response.total - totalDifferent - 1
|
||||
: response.total - totalDifferent;
|
||||
|
||||
setHasNextPage(newItems.length < newTotal);
|
||||
setItemsList(newItems);
|
||||
setTotal(newTotal);
|
||||
|
||||
setIsNextPageLoading(false);
|
||||
setIsLoading(false);
|
||||
})
|
||||
.catch((error) => console.log(error));
|
||||
};
|
||||
|
||||
const onSearch = (value) => {
|
||||
setSearchValue(value);
|
||||
loadNextPage(0, value);
|
||||
};
|
||||
|
||||
const onClearSearch = () => {
|
||||
setSearchValue("");
|
||||
loadNextPage(0, "");
|
||||
};
|
||||
|
||||
const emptyScreenImage = theme.isBase
|
||||
? EmptyScreenPersonsSvgUrl
|
||||
: EmptyScreenPersonsSvgDarkUrl;
|
||||
|
||||
return (
|
||||
<Selector
|
||||
id={id}
|
||||
className={className}
|
||||
style={style}
|
||||
headerLabel={headerLabel || t("ListAccounts")}
|
||||
onBackClick={onBackClick}
|
||||
searchPlaceholder={searchPlaceholder || t("Common:Search")}
|
||||
searchValue={searchValue}
|
||||
onSearch={onSearch}
|
||||
onClearSearch={onClearSearch}
|
||||
items={itemsList}
|
||||
isMultiSelect={isMultiSelect}
|
||||
selectedItems={selectedItems}
|
||||
acceptButtonLabel={acceptButtonLabel || t("Common:SelectAction")}
|
||||
onAccept={onAccept}
|
||||
withSelectAll={withSelectAll}
|
||||
selectAllLabel={selectAllLabel || t("AllAccounts")}
|
||||
selectAllIcon={selectAllIcon}
|
||||
withAccessRights={withAccessRights}
|
||||
accessRights={accessRights}
|
||||
selectedAccessRight={selectedAccessRight}
|
||||
withCancelButton={withCancelButton}
|
||||
cancelButtonLabel={cancelButtonLabel || t("Common:CancelButton")}
|
||||
onCancel={onCancel}
|
||||
emptyScreenImage={emptyScreenImage}
|
||||
emptyScreenHeader={emptyScreenHeader || t("EmptyHeader")}
|
||||
emptyScreenDescription={emptyScreenDescription || t("EmptyDescription")}
|
||||
searchEmptyScreenImage={emptyScreenImage}
|
||||
searchEmptyScreenHeader={
|
||||
searchEmptyScreenHeader || t("People:NotFoundUsers")
|
||||
}
|
||||
searchEmptyScreenDescription={
|
||||
searchEmptyScreenDescription || t("People:NotFoundUsersDescription")
|
||||
}
|
||||
hasNextPage={hasNextPage}
|
||||
isNextPageLoading={isNextPageLoading}
|
||||
loadNextPage={loadNextPage}
|
||||
totalItems={total}
|
||||
isLoading={isLoading}
|
||||
withFooterCheckbox={withFooterCheckbox}
|
||||
footerCheckboxLabel={footerCheckboxLabel}
|
||||
isChecked={isChecked}
|
||||
setIsChecked={setIsChecked}
|
||||
searchLoader={<Loaders.SelectorSearchLoader />}
|
||||
isSearchLoading={isLoading}
|
||||
rowLoader={<Loaders.SelectorRowLoader isUser isContainer={isLoading} />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
PeopleSelector.propTypes = { excludeItems: PropTypes.array };
|
||||
|
||||
PeopleSelector.defaultProps = {
|
||||
excludeItems: [],
|
||||
selectAllIcon: CatalogAccountsReactSvgUrl,
|
||||
};
|
||||
|
||||
const ExtendedPeopleSelector = inject(({ auth }) => {
|
||||
return {
|
||||
theme: auth.settingsStore.theme,
|
||||
currentUserId: auth.userStore.user.id,
|
||||
};
|
||||
})(
|
||||
observer(
|
||||
withTranslation([
|
||||
"PeopleSelector",
|
||||
"PeopleTranslations",
|
||||
"People",
|
||||
"Common",
|
||||
])(PeopleSelector)
|
||||
)
|
||||
);
|
||||
|
||||
export default (props) => (
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<ExtendedPeopleSelector {...props} />
|
||||
</I18nextProvider>
|
||||
);
|
@ -1,62 +0,0 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { Avatar } from "@docspace/shared/components/avatar";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import StyledUserTooltip from "./StyledUserTooltip";
|
||||
|
||||
const UserTooltip = ({ avatarUrl, label, email, position, theme }) => (
|
||||
<StyledUserTooltip theme={theme}>
|
||||
<div className="block-avatar">
|
||||
<Avatar
|
||||
theme={theme}
|
||||
className="user-avatar"
|
||||
size="min"
|
||||
role="user"
|
||||
source={avatarUrl}
|
||||
userName=""
|
||||
editing={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="block-info">
|
||||
<Text
|
||||
theme={theme}
|
||||
isBold={true}
|
||||
fontSize="13px"
|
||||
fontWeight={600}
|
||||
truncate={true}
|
||||
title={label}
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
<Text
|
||||
theme={theme}
|
||||
color={theme.peopleSelector.textColor}
|
||||
fontSize="13px"
|
||||
className="email-text"
|
||||
truncate={true}
|
||||
title={email}
|
||||
>
|
||||
{email}
|
||||
</Text>
|
||||
<Text
|
||||
theme={theme}
|
||||
fontSize="13px"
|
||||
fontWeight={600}
|
||||
truncate={true}
|
||||
title={position}
|
||||
>
|
||||
{position}
|
||||
</Text>
|
||||
</div>
|
||||
</StyledUserTooltip>
|
||||
);
|
||||
|
||||
UserTooltip.propTypes = {
|
||||
avatarUrl: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
email: PropTypes.string,
|
||||
position: PropTypes.string,
|
||||
};
|
||||
|
||||
export default UserTooltip;
|
@ -4,7 +4,7 @@ import { inject, observer } from "mobx-react";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import { withTranslation } from "react-i18next";
|
||||
|
||||
import PeopleSelector from "SRC_DIR/components/PeopleSelector";
|
||||
import PeopleSelector from "@docspace/shared/selectors/People";
|
||||
|
||||
import Filter from "@docspace/shared/api/people/filter";
|
||||
|
||||
@ -118,6 +118,7 @@ const ChangePortalOwnerDialog = ({
|
||||
onAccept={onAccept}
|
||||
onCancel={onBackClick}
|
||||
onBackClick={onBackClick}
|
||||
currentUserId={id}
|
||||
/>
|
||||
</ModalDialog.Container>
|
||||
)}
|
||||
|
@ -40,7 +40,7 @@ class ChangeUserStatusDialogComponent extends React.Component {
|
||||
onClose,
|
||||
userIDs,
|
||||
getPeopleListItem,
|
||||
setSelection,
|
||||
setInfoPanelSelection,
|
||||
infoPanelVisible,
|
||||
needResetUserSelection,
|
||||
} = this.props;
|
||||
@ -51,7 +51,7 @@ class ChangeUserStatusDialogComponent extends React.Component {
|
||||
if (users.length === 1 && infoPanelVisible) {
|
||||
const user = getPeopleListItem(users[0]);
|
||||
|
||||
setSelection(user);
|
||||
setInfoPanelSelection(user);
|
||||
}
|
||||
|
||||
toastr.success(t("PeopleTranslations:SuccessChangeUserStatus"));
|
||||
@ -176,7 +176,8 @@ export default inject(({ peopleStore, auth }) => {
|
||||
const { getPeopleListItem, updateUserStatus, needResetUserSelection } =
|
||||
peopleStore.usersStore;
|
||||
|
||||
const { setSelection, isVisible: infoPanelVisible } = auth.infoPanelStore;
|
||||
const { setInfoPanelSelection, isVisible: infoPanelVisible } =
|
||||
auth.infoPanelStore;
|
||||
|
||||
return {
|
||||
needResetUserSelection,
|
||||
@ -186,7 +187,7 @@ export default inject(({ peopleStore, auth }) => {
|
||||
|
||||
getPeopleListItem,
|
||||
|
||||
setSelection,
|
||||
setInfoPanelSelection,
|
||||
infoPanelVisible,
|
||||
};
|
||||
})(observer(ChangeUserStatusDialog));
|
||||
|
@ -42,7 +42,7 @@ const DropdownDesktop = ({ t, open, chooseRoomType }) => {
|
||||
return (
|
||||
<StyledDropdownDesktop className="dropdown-content-wrapper" isOpen={open}>
|
||||
<div className="dropdown-content">
|
||||
{Object.values(RoomsTypeValues).map((roomType) => (
|
||||
{RoomsTypeValues.map((roomType) => (
|
||||
<RoomType
|
||||
id={roomType}
|
||||
t={t}
|
||||
|
@ -31,7 +31,7 @@ const DropdownMobile = ({ t, open, onClose, chooseRoomType }) => {
|
||||
<>
|
||||
<Backdrop visible={open} onClick={onClose} zIndex={450} />
|
||||
<StyledDropdownMobile className="dropdown-mobile" isOpen={open}>
|
||||
{Object.values(RoomsTypeValues).map((roomType) => (
|
||||
{RoomsTypeValues.map((roomType) => (
|
||||
<RoomType
|
||||
id={roomType}
|
||||
t={t}
|
||||
|
@ -19,7 +19,7 @@ const StyledRoomTypeList = styled.div`
|
||||
const RoomTypeList = ({ t, setRoomType }) => {
|
||||
return (
|
||||
<StyledRoomTypeList>
|
||||
{Object.values(RoomsTypeValues).map((roomType) => (
|
||||
{RoomsTypeValues.map((roomType) => (
|
||||
<RoomType
|
||||
id={roomType}
|
||||
t={t}
|
||||
|
@ -2,7 +2,7 @@ import { useState, useEffect } from "react";
|
||||
import styled from "styled-components";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import PeopleSelector from "@docspace/client/src/components/PeopleSelector";
|
||||
import PeopleSelector from "@docspace/shared/selectors/People";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { ModalDialog } from "@docspace/shared/components/modal-dialog";
|
||||
import { Backdrop } from "@docspace/shared/components/backdrop";
|
||||
@ -177,23 +177,24 @@ const DataReassignmentDialog = ({
|
||||
visible={visible}
|
||||
onClose={onClosePeopleSelector}
|
||||
containerVisible={selectorVisible}
|
||||
withFooterBorder={true}
|
||||
withBodyScroll={true}
|
||||
withFooterBorder
|
||||
withBodyScroll
|
||||
>
|
||||
<Backdrop
|
||||
onClick={onClosePeopleSelector}
|
||||
visible={selectorVisible}
|
||||
isAside={true}
|
||||
isAside
|
||||
/>
|
||||
<ModalDialog.Container>
|
||||
<PeopleSelector
|
||||
acceptButtonLabel={t("Common:SelectAction")}
|
||||
excludeItems={[user.id]}
|
||||
currentUserId={user.id}
|
||||
onAccept={onAccept}
|
||||
onCancel={onClosePeopleSelector}
|
||||
onBackClick={onTogglePeopleSelector}
|
||||
withCancelButton={true}
|
||||
withAbilityCreateRoomUsers={true}
|
||||
withCancelButton
|
||||
withAbilityCreateRoomUsers
|
||||
/>
|
||||
</ModalDialog.Container>
|
||||
</StyledModalDialog>
|
||||
@ -206,8 +207,8 @@ const DataReassignmentDialog = ({
|
||||
visible={visible}
|
||||
onClose={onClose}
|
||||
containerVisible={selectorVisible}
|
||||
withFooterBorder={true}
|
||||
withBodyScroll={true}
|
||||
withFooterBorder
|
||||
withBodyScroll
|
||||
>
|
||||
<ModalDialog.Header>
|
||||
{t("DataReassignmentDialog:DataReassignment")}
|
||||
|
@ -121,7 +121,7 @@ const DeleteLinkDialog = withTranslation(["Common", "Files"])(
|
||||
);
|
||||
|
||||
export default inject(({ auth, dialogsStore, publicRoomStore, filesStore }) => {
|
||||
const { selectionParentRoom } = auth.infoPanelStore;
|
||||
const { infoPanelSelection } = auth.infoPanelStore;
|
||||
const {
|
||||
deleteLinkDialogVisible: visible,
|
||||
setDeleteLinkDialogVisible: setIsVisible,
|
||||
@ -132,11 +132,11 @@ export default inject(({ auth, dialogsStore, publicRoomStore, filesStore }) => {
|
||||
return {
|
||||
visible,
|
||||
setIsVisible,
|
||||
roomId: selectionParentRoom.id,
|
||||
roomId: infoPanelSelection.id,
|
||||
link: linkParams.link,
|
||||
editExternalLink,
|
||||
deleteExternalLink,
|
||||
isPublicRoomType: selectionParentRoom.roomType === RoomsType.PublicRoom,
|
||||
isPublicRoomType: infoPanelSelection.roomType === RoomsType.PublicRoom,
|
||||
setRoomShared: filesStore.setRoomShared,
|
||||
};
|
||||
})(observer(DeleteLinkDialog));
|
||||
|
@ -12,7 +12,7 @@ import { getUserRole } from "@docspace/shared/utils/common";
|
||||
import Filter from "@docspace/shared/api/people/filter";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
import { getMembersList } from "@docspace/shared/api/people";
|
||||
import useLoadingWithTimeout from "SRC_DIR/Hooks/useLoadingWithTimeout";
|
||||
import useLoadingWithTimeout from "@docspace/shared/hooks/useLoadingWithTimeout";
|
||||
import { ShareAccessRights } from "@docspace/shared/enums";
|
||||
import { LOADER_TIMEOUT } from "@docspace/shared/constants";
|
||||
|
||||
@ -23,6 +23,7 @@ import DefaultUserPhoto from "PUBLIC_DIR/images/default_user_photo_size_82-82.pn
|
||||
import EmptyScreenPersonsSvgUrl from "PUBLIC_DIR/images/empty_screen_persons.svg?url";
|
||||
import CatalogAccountsReactSvgUrl from "PUBLIC_DIR/images/catalog.accounts.react.svg?url";
|
||||
import EmptyScreenPersonsSvgDarkUrl from "PUBLIC_DIR/images/empty_screen_persons_dark.svg?url";
|
||||
import { RowLoader, SearchLoader } from "@docspace/shared/skeletons/selector";
|
||||
|
||||
const AddUsersPanel = ({
|
||||
isEncrypted,
|
||||
@ -257,10 +258,10 @@ const AddUsersPanel = ({
|
||||
loadNextPage={loadNextPage}
|
||||
totalItems={total}
|
||||
isLoading={isLoading}
|
||||
searchLoader={<Loaders.SelectorSearchLoader />}
|
||||
searchLoader={<SearchLoader />}
|
||||
isSearchLoading={isLoading && !isLoadingSearch}
|
||||
rowLoader={
|
||||
<Loaders.SelectorRowLoader
|
||||
<RowLoader
|
||||
isUser
|
||||
count={15}
|
||||
isContainer={isLoading}
|
||||
|
@ -3,7 +3,7 @@ import { inject, observer } from "mobx-react";
|
||||
import styled, { css } from "styled-components";
|
||||
import { Aside } from "@docspace/shared/components/aside";
|
||||
import { Backdrop } from "@docspace/shared/components/backdrop";
|
||||
import PeopleSelector from "@docspace/client/src/components/PeopleSelector";
|
||||
import PeopleSelector from "@docspace/shared/selectors/People";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import Filter from "@docspace/shared/api/people/filter";
|
||||
import { EmployeeType, DeviceType } from "@docspace/shared/enums";
|
||||
@ -45,6 +45,8 @@ const ChangeRoomOwner = (props) => {
|
||||
currentDeviceType,
|
||||
roomOwnerId,
|
||||
changeRoomOwner,
|
||||
userId,
|
||||
updateInfoPanelSelection,
|
||||
} = props;
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@ -70,6 +72,7 @@ const ChangeRoomOwner = (props) => {
|
||||
setIsLoading(true);
|
||||
|
||||
await changeRoomOwner(t, user[0]?.id, isChecked);
|
||||
updateInfoPanelSelection();
|
||||
setIsLoading(false);
|
||||
}
|
||||
onClose();
|
||||
@ -120,6 +123,7 @@ const ChangeRoomOwner = (props) => {
|
||||
setIsChecked={setIsChecked}
|
||||
withOutCurrentAuthorizedUser
|
||||
filterUserId={roomOwnerId}
|
||||
currentUserId={userId}
|
||||
/>
|
||||
</Aside>
|
||||
</StyledChangeRoomOwner>
|
||||
@ -145,9 +149,10 @@ export default inject(
|
||||
setChangeRoomOwnerIsVisible,
|
||||
changeRoomOwnerData,
|
||||
} = dialogsStore;
|
||||
const { settingsStore } = auth;
|
||||
|
||||
const { settingsStore, userStore, infoPanelStore } = auth;
|
||||
const { selection, bufferSelection } = filesStore;
|
||||
const { currentDeviceType } = settingsStore;
|
||||
const { updateInfoPanelSelection } = infoPanelStore;
|
||||
|
||||
const room = selection.length
|
||||
? selection[0]
|
||||
@ -155,7 +160,7 @@ export default inject(
|
||||
? bufferSelection
|
||||
: selectedFolderStore;
|
||||
|
||||
const { currentDeviceType } = settingsStore;
|
||||
const { id } = userStore.user;
|
||||
|
||||
return {
|
||||
visible: changeRoomOwnerIsVisible,
|
||||
@ -165,6 +170,8 @@ export default inject(
|
||||
roomOwnerId: room?.createdBy?.id,
|
||||
currentDeviceType,
|
||||
changeRoomOwner: filesActionsStore.changeRoomOwner,
|
||||
userId: id,
|
||||
updateInfoPanelSelection,
|
||||
};
|
||||
}
|
||||
)(observer(withTranslation(["Files"])(ChangeRoomOwner)));
|
||||
|
@ -271,7 +271,7 @@ const EditLinkPanel = (props) => {
|
||||
};
|
||||
|
||||
export default inject(({ auth, dialogsStore, publicRoomStore }) => {
|
||||
const { selectionParentRoom } = auth.infoPanelStore;
|
||||
const { infoPanelSelection } = auth.infoPanelStore;
|
||||
const {
|
||||
editLinkPanelIsVisible,
|
||||
setEditLinkPanelIsVisible,
|
||||
@ -286,7 +286,7 @@ export default inject(({ auth, dialogsStore, publicRoomStore }) => {
|
||||
const link = externalLinks.find((l) => l?.sharedTo?.id === linkId);
|
||||
|
||||
const shareLink = link?.sharedTo?.shareLink;
|
||||
const isPublic = selectionParentRoom?.roomType === RoomsType.PublicRoom;
|
||||
const isPublic = infoPanelSelection?.roomType === RoomsType.PublicRoom;
|
||||
|
||||
return {
|
||||
visible: editLinkPanelIsVisible,
|
||||
@ -294,7 +294,7 @@ export default inject(({ auth, dialogsStore, publicRoomStore }) => {
|
||||
isEdit,
|
||||
linkId: link?.sharedTo?.id,
|
||||
editExternalLink,
|
||||
roomId: selectionParentRoom.id,
|
||||
roomId: infoPanelSelection.id,
|
||||
setExternalLink,
|
||||
isLocked: !!link?.sharedTo?.password,
|
||||
password: link?.sharedTo?.password ?? "",
|
||||
|
@ -54,9 +54,8 @@ const InvitePanel = ({
|
||||
defaultAccess,
|
||||
inviteUsers,
|
||||
setInfoPanelIsMobileHidden,
|
||||
reloadSelectionParentRoom,
|
||||
setUpdateRoomMembers,
|
||||
roomsView,
|
||||
updateInfoPanelSelection,
|
||||
addInfoPanelMembers,
|
||||
setInviteLanguage,
|
||||
getUsersList,
|
||||
filter,
|
||||
@ -277,15 +276,15 @@ const InvitePanel = ({
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const result =
|
||||
roomId === -1
|
||||
? await inviteUsers(data)
|
||||
: await setRoomSecurity(roomId, data);
|
||||
const isRooms = roomId !== -1;
|
||||
const result = !isRooms
|
||||
? await inviteUsers(data)
|
||||
: await setRoomSecurity(roomId, data);
|
||||
|
||||
setIsLoading(false);
|
||||
|
||||
if (roomsView === "info_members") {
|
||||
setUpdateRoomMembers(true);
|
||||
if (isRooms) {
|
||||
addInfoPanelMembers(t, result.members, true);
|
||||
}
|
||||
|
||||
onClose();
|
||||
@ -295,7 +294,7 @@ const InvitePanel = ({
|
||||
toastr.warning(result?.warning);
|
||||
}
|
||||
|
||||
reloadSelectionParentRoom();
|
||||
updateInfoPanelSelection();
|
||||
} catch (err) {
|
||||
toastr.error(err);
|
||||
setIsLoading(false);
|
||||
@ -471,10 +470,8 @@ export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
|
||||
const { filter } = peopleStore.filterStore;
|
||||
const {
|
||||
setIsMobileHidden: setInfoPanelIsMobileHidden,
|
||||
reloadSelectionParentRoom,
|
||||
setUpdateRoomMembers,
|
||||
roomsView,
|
||||
filesView,
|
||||
updateInfoPanelSelection,
|
||||
addInfoPanelMembers,
|
||||
} = auth.infoPanelStore;
|
||||
|
||||
const {
|
||||
@ -517,9 +514,8 @@ export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
|
||||
collaboratorLink,
|
||||
inviteUsers,
|
||||
setInfoPanelIsMobileHidden,
|
||||
reloadSelectionParentRoom,
|
||||
setUpdateRoomMembers,
|
||||
roomsView,
|
||||
updateInfoPanelSelection,
|
||||
addInfoPanelMembers,
|
||||
getUsersList,
|
||||
filter,
|
||||
currentDeviceType,
|
||||
|
@ -3,7 +3,7 @@ import PropTypes from "prop-types";
|
||||
import { Backdrop } from "@docspace/shared/components/backdrop";
|
||||
import { Heading } from "@docspace/shared/components/heading";
|
||||
import { Aside } from "@docspace/shared/components/aside";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
|
||||
import { FloatingButton } from "@docspace/shared/components/floating-button";
|
||||
import { Portal } from "@docspace/shared/components/portal";
|
||||
import { DeviceType } from "@docspace/shared/enums";
|
||||
@ -17,6 +17,7 @@ import {
|
||||
import { SectionBodyContent } from "../../../pages/VersionHistory/Section/";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { ArticleHeaderLoader } from "@docspace/shared/skeletons/article";
|
||||
|
||||
class PureVersionHistoryPanel extends React.Component {
|
||||
onClose = () => {
|
||||
@ -70,7 +71,7 @@ class PureVersionHistoryPanel extends React.Component {
|
||||
{versions[0].title}
|
||||
</Heading>
|
||||
) : (
|
||||
<Loaders.ArticleHeader
|
||||
<ArticleHeaderLoader
|
||||
className="loader-version-history"
|
||||
height="28"
|
||||
width="688"
|
||||
|
@ -2,7 +2,7 @@ import React from "react";
|
||||
import { useLocation, Navigate } from "react-router-dom";
|
||||
import { AuthenticatedAction, ValidationResult } from "./../helpers/constants";
|
||||
import { Loader } from "@docspace/shared/components/loader";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import { checkConfirmLink } from "@docspace/shared/api/user"; //TODO: Move AuthStore
|
||||
import { getObjectByLocation } from "@docspace/shared/utils/common";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
|
@ -150,11 +150,6 @@ export const LinkType = Object.freeze({
|
||||
|
||||
export const SSO_LABEL = "SSO";
|
||||
|
||||
export const ARTICLE_ALERTS = Object.freeze({
|
||||
TeamTraining: "TeamTraining",
|
||||
SubmitToFormGallery: "SubmitToFormGallery",
|
||||
});
|
||||
|
||||
export const AuthenticatedAction = Object.freeze({
|
||||
None: 0,
|
||||
Logout: 1,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useEffect } from "react";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import { I18nextProvider, withTranslation } from "react-i18next";
|
||||
import { setDocumentTitle } from "SRC_DIR/helpers/utils";
|
||||
import i18n from "./i18n";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { Loader } from "@docspace/shared/components/loader";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
import tryRedirectTo from "@docspace/shared/utils/tryRedirectTo";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { Loader } from "@docspace/shared/components/loader";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import { loginWithConfirmKey } from "@docspace/shared/api/user";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
|
@ -2,7 +2,7 @@ import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Loader } from "@docspace/shared/components/loader";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
import tryRedirectTo from "@docspace/shared/utils/tryRedirectTo";
|
||||
import SectionWrapper from "SRC_DIR/components/Section";
|
||||
|
@ -5,7 +5,7 @@ import { I18nextProvider, useTranslation } from "react-i18next";
|
||||
import ErrorContainer from "@docspace/common/components/ErrorContainer";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Link } from "@docspace/shared/components/link";
|
||||
import { ZendeskAPI } from "@docspace/common/components/Zendesk";
|
||||
import { ZendeskAPI } from "@docspace/shared/components/zendesk";
|
||||
|
||||
import { ReportDialog } from "SRC_DIR/components/dialogs";
|
||||
import DocspaceLogo from "SRC_DIR/DocspaceLogo";
|
||||
|
@ -5,7 +5,7 @@ import { useState, useRef } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { Scrollbar } from "@docspace/shared/components/scrollbar";
|
||||
import { ComboButton } from "@docspace/shared/components/combobox";
|
||||
import { ComboButton } from "@docspace/shared/components/combobox/sub-components/ComboButton";
|
||||
import { Backdrop } from "@docspace/shared/components/backdrop";
|
||||
import { isMobile } from "@docspace/shared/utils";
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import { observer, inject } from "mobx-react";
|
||||
import { useLocation, useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
|
@ -6,9 +6,11 @@ import FilesFilter from "@docspace/shared/api/files/filter";
|
||||
import RoomsFilter from "@docspace/shared/api/rooms/filter";
|
||||
import { getGroup } from "@docspace/shared/api/groups";
|
||||
import { getUserById } from "@docspace/shared/api/people";
|
||||
import { MEDIA_VIEW_URL } from "@docspace/shared/constants";
|
||||
|
||||
import { Events, RoomSearchArea } from "@docspace/shared/enums";
|
||||
import { getObjectByLocation } from "@docspace/shared/utils/common";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
import { getCategoryType, getCategoryUrl } from "SRC_DIR/helpers/utils";
|
||||
import { CategoryType } from "SRC_DIR/helpers/constants";
|
||||
@ -44,6 +46,7 @@ const useFiles = ({
|
||||
folderSecurity,
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
const { id } = useParams();
|
||||
|
||||
const fetchDefaultFiles = () => {
|
||||
const filter = FilesFilter.getDefault();
|
||||
@ -98,7 +101,7 @@ const useFiles = ({
|
||||
if (location.pathname === "/") setIsLoading(true, true, true);
|
||||
else setIsLoading(true, false, false);
|
||||
|
||||
if (!window.location.href.includes("#preview")) {
|
||||
if (!window.location.href.includes(MEDIA_VIEW_URL)) {
|
||||
// localStorage.removeItem("isFirstUrl");
|
||||
// Media viewer
|
||||
removeFirstUrl();
|
||||
@ -109,12 +112,12 @@ const useFiles = ({
|
||||
let filterObj = null;
|
||||
let isRooms = false;
|
||||
|
||||
if (window.location.href.indexOf("/#preview") > 1 && playlist.length < 1) {
|
||||
const pathname = window.location.href;
|
||||
const fileId = pathname.slice(pathname.indexOf("#preview") + 9);
|
||||
|
||||
if (
|
||||
window.location.href.indexOf(MEDIA_VIEW_URL) > 1 &&
|
||||
playlist.length < 1
|
||||
) {
|
||||
setTimeout(() => {
|
||||
getFileInfo(fileId)
|
||||
getFileInfo(id)
|
||||
.then((data) => {
|
||||
const canOpenPlayer =
|
||||
data.viewAccessibility.ImageView ||
|
||||
@ -132,7 +135,7 @@ const useFiles = ({
|
||||
return setIsLoading(false);
|
||||
}
|
||||
|
||||
if (window.location.href.indexOf("/#preview") > 1)
|
||||
if (window.location.href.indexOf(MEDIA_VIEW_URL) > 1)
|
||||
return setIsLoading(false);
|
||||
|
||||
const isRoomFolder = getObjectByLocation(window.location)?.folder;
|
||||
|
@ -1,7 +1,5 @@
|
||||
const excludeGeneralOptions = ["select", "show-info"];
|
||||
const excludeRoomOptions = ["separator0", "room-info"];
|
||||
const excludeOptionsIntoRoom = ["pin-room", "unpin-room"];
|
||||
const excludeOptionsIntoFolder = ["open", "separator0", "separator1"];
|
||||
|
||||
class ContextHelper {
|
||||
constructor(props) {
|
||||
@ -38,20 +36,7 @@ class ContextHelper {
|
||||
if (idx !== -1) options.splice(idx, 1);
|
||||
});
|
||||
|
||||
if (this.selection.isSelectedFolder) {
|
||||
excludeOptionsIntoRoom.forEach((excludeOption) => {
|
||||
const idx = options.findIndex((o) => o === excludeOption);
|
||||
if (idx !== -1) options.splice(idx, 1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.selection?.isSelectedFolder && !this.selection?.isRoom) {
|
||||
excludeOptionsIntoFolder.forEach((excludeOption) => {
|
||||
const idx = options.findIndex((o) => o === excludeOption);
|
||||
if (idx !== -1) options.splice(idx, 1);
|
||||
});
|
||||
}
|
||||
|
||||
const length = options.length;
|
||||
|
||||
|
@ -1,20 +1,15 @@
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
import ViewHelper from "./helpers/ViewHelper";
|
||||
import ItemTitle from "./sub-components/ItemTitle";
|
||||
|
||||
import { StyledInfoPanelBody } from "./styles/common";
|
||||
import { getRoomInfo } from "@docspace/shared/api/rooms";
|
||||
|
||||
const InfoPanelBodyContent = ({
|
||||
selection,
|
||||
setSelection,
|
||||
calculateSelection,
|
||||
normalizeSelection,
|
||||
infoPanelSelection,
|
||||
setNewInfoPanelSelection,
|
||||
isItemChanged,
|
||||
selectionParentRoom,
|
||||
setSelectionParentRoom,
|
||||
roomsView,
|
||||
fileView,
|
||||
getIsFiles,
|
||||
@ -36,13 +31,15 @@ const InfoPanelBodyContent = ({
|
||||
const isSeveralItems = props.selectedItems?.length > 1;
|
||||
|
||||
const isNoItemGallery = isGallery && !gallerySelected;
|
||||
const itemIsRoot =
|
||||
selection?.isSelectedFolder && selection?.id === selection?.rootFolderId;
|
||||
const isRoot =
|
||||
infoPanelSelection?.isFolder &&
|
||||
infoPanelSelection?.id === infoPanelSelection?.rootFolderId;
|
||||
const isNoItem =
|
||||
!isSeveralItems && (isNoItemGallery || (itemIsRoot && !isGallery));
|
||||
!infoPanelSelection ||
|
||||
(!isSeveralItems && (isNoItemGallery || (isRoot && !isGallery)));
|
||||
|
||||
const defaultProps = {
|
||||
selection,
|
||||
infoPanelSelection,
|
||||
isFiles,
|
||||
isRooms,
|
||||
isAccounts,
|
||||
@ -111,45 +108,14 @@ const InfoPanelBodyContent = ({
|
||||
if (selectedFolderChanged) setSelectedFolder(props.selectedFolder);
|
||||
}, [props.selectedFolder]);
|
||||
|
||||
// Updating selectionParentRoom after selectFolder change
|
||||
// Updating infoPanelSelection after selectFolder change
|
||||
// if it is located in another room
|
||||
|
||||
const updateSelectionParentRoomAction = useCallback(async () => {
|
||||
if (!isRooms) return;
|
||||
if (selection?.isRoom && roomsView === "members") return;
|
||||
|
||||
const currentFolderRoomId =
|
||||
selectedFolder?.pathParts &&
|
||||
selectedFolder?.pathParts?.length > 1 &&
|
||||
selectedFolder.pathParts[1].id;
|
||||
|
||||
const storeRoomId = selectionParentRoom?.id;
|
||||
if (!currentFolderRoomId || currentFolderRoomId === storeRoomId) return;
|
||||
|
||||
const newSelectionParentRoom = await getRoomInfo(currentFolderRoomId);
|
||||
|
||||
if (storeRoomId === newSelectionParentRoom.id) return;
|
||||
|
||||
setSelectionParentRoom(normalizeSelection(newSelectionParentRoom));
|
||||
}, [selectedFolder]);
|
||||
|
||||
// Setting infoPanelSelection after selectedItems or selectedFolder update
|
||||
useEffect(() => {
|
||||
updateSelectionParentRoomAction();
|
||||
}, [selectedFolder, updateSelectionParentRoomAction]);
|
||||
|
||||
// Setting selection after selectedItems or selectedFolder update
|
||||
useEffect(() => {
|
||||
setSelection(calculateSelection());
|
||||
setNewInfoPanelSelection();
|
||||
}, [selectedItems, selectedFolder]);
|
||||
|
||||
// * DEV-ONLY - Logs selection change
|
||||
// useEffect(() => {
|
||||
// console.log("\nfor-dev Selected items: ", selectedItems);
|
||||
// console.log("\nfor-dev Selected folder: ", selectedFolder);
|
||||
// }, [selectedItems, selectedFolder]);
|
||||
|
||||
if (!selection && !isGallery) return null;
|
||||
|
||||
return (
|
||||
<StyledInfoPanelBody>
|
||||
{!isNoItem && (
|
||||
@ -166,38 +132,27 @@ const InfoPanelBodyContent = ({
|
||||
|
||||
export default inject(({ auth, selectedFolderStore, oformsStore }) => {
|
||||
const {
|
||||
selection,
|
||||
setSelection,
|
||||
calculateSelection,
|
||||
normalizeSelection,
|
||||
infoPanelSelection,
|
||||
setNewInfoPanelSelection,
|
||||
isItemChanged,
|
||||
selectionParentRoom,
|
||||
setSelectionParentRoom,
|
||||
roomsView,
|
||||
fileView,
|
||||
getIsFiles,
|
||||
getIsRooms,
|
||||
getIsAccounts,
|
||||
getIsGallery,
|
||||
infoPanelSelectedItems,
|
||||
getInfoPanelSelectedFolder,
|
||||
} = auth.infoPanelStore;
|
||||
|
||||
const { gallerySelected } = oformsStore;
|
||||
|
||||
const { isRootFolder } = selectedFolderStore;
|
||||
|
||||
const selectedItems = auth.infoPanelStore.getSelectedItems();
|
||||
|
||||
const selectedFolder = auth.infoPanelStore.getSelectedFolder();
|
||||
|
||||
return {
|
||||
selection,
|
||||
setSelection,
|
||||
calculateSelection,
|
||||
normalizeSelection,
|
||||
infoPanelSelection,
|
||||
setNewInfoPanelSelection,
|
||||
isItemChanged,
|
||||
|
||||
selectionParentRoom,
|
||||
setSelectionParentRoom,
|
||||
roomsView,
|
||||
fileView,
|
||||
getIsFiles,
|
||||
@ -205,8 +160,8 @@ export default inject(({ auth, selectedFolderStore, oformsStore }) => {
|
||||
getIsAccounts,
|
||||
getIsGallery,
|
||||
|
||||
selectedItems,
|
||||
selectedFolder,
|
||||
selectedItems: infoPanelSelectedItems,
|
||||
selectedFolder: getInfoPanelSelectedFolder(),
|
||||
|
||||
isRootFolder,
|
||||
gallerySelected,
|
||||
|
@ -9,13 +9,13 @@ import { Button } from "@docspace/shared/components/button";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
|
||||
import { MAX_FILE_COMMENT_LENGTH } from "@docspace/shared/constants";
|
||||
// import infoPanel from "@docspace/common/components/Section/sub-components/info-panel";
|
||||
// import infoPanel from "@docspace/shared/components/section/sub-components/info-panel";
|
||||
|
||||
const CommentEditor = ({
|
||||
t,
|
||||
item,
|
||||
editing,
|
||||
setSelection,
|
||||
setInfoPanelSelection,
|
||||
fetchFileVersions,
|
||||
updateCommentVersion,
|
||||
|
||||
@ -61,7 +61,7 @@ const CommentEditor = ({
|
||||
setIsLoading(false);
|
||||
});
|
||||
|
||||
setSelection({ ...item, comment: inputValue });
|
||||
setInfoPanelSelection({ ...item, comment: inputValue });
|
||||
setIsEdit(false);
|
||||
setIsLoading(false);
|
||||
};
|
||||
@ -121,7 +121,7 @@ const CommentEditor = ({
|
||||
};
|
||||
|
||||
export default inject(({ auth, versionHistoryStore }) => {
|
||||
const { setSelection } = auth.infoPanelStore;
|
||||
const { setInfoPanelSelection } = auth.infoPanelStore;
|
||||
|
||||
const {
|
||||
fetchFileVersions,
|
||||
@ -136,7 +136,7 @@ export default inject(({ auth, versionHistoryStore }) => {
|
||||
const editing = isEditingVersion || isEditing;
|
||||
|
||||
return {
|
||||
setSelection,
|
||||
setInfoPanelSelection,
|
||||
fetchFileVersions,
|
||||
updateCommentVersion,
|
||||
|
||||
|
@ -16,7 +16,7 @@ import { decode } from "he";
|
||||
const AccountsItemTitle = ({
|
||||
t,
|
||||
isSeveralItems,
|
||||
selection,
|
||||
infoPanelSelection,
|
||||
getUserContextOptions,
|
||||
}) => {
|
||||
if (isSeveralItems) {
|
||||
@ -26,20 +26,23 @@ const AccountsItemTitle = ({
|
||||
const itemTitleRef = useRef();
|
||||
|
||||
const isPending =
|
||||
selection.statusType === "pending" || selection.statusType === "disabled";
|
||||
infoPanelSelection.statusType === "pending" ||
|
||||
infoPanelSelection.statusType === "disabled";
|
||||
|
||||
const getData = () => {
|
||||
const newOptions = selection.options?.filter(
|
||||
const newOptions = infoPanelSelection.options?.filter(
|
||||
(option) => option !== "details"
|
||||
);
|
||||
return getUserContextOptions(t, newOptions || [], selection);
|
||||
return getUserContextOptions(t, newOptions || [], infoPanelSelection);
|
||||
};
|
||||
const contextOptions = getData();
|
||||
|
||||
const userAvatar = selection.hasAvatar ? selection.avatar : DefaultUserPhoto;
|
||||
const isSSO = selection.isSSO || false;
|
||||
const displayName = selection.displayName
|
||||
? decode(selection.displayName).trim()
|
||||
const userAvatar = infoPanelSelection.hasAvatar
|
||||
? infoPanelSelection.avatar
|
||||
: DefaultUserPhoto;
|
||||
const isSSO = infoPanelSelection.isSSO || false;
|
||||
const displayName = infoPanelSelection.displayName
|
||||
? decode(infoPanelSelection.displayName).trim()
|
||||
: "";
|
||||
|
||||
return (
|
||||
@ -50,7 +53,7 @@ const AccountsItemTitle = ({
|
||||
>
|
||||
<Avatar
|
||||
className="avatar"
|
||||
role={selection.role ? selection.role : "user"}
|
||||
role={infoPanelSelection.role ? infoPanelSelection.role : "user"}
|
||||
size={"big"}
|
||||
source={userAvatar}
|
||||
/>
|
||||
@ -62,15 +65,18 @@ const AccountsItemTitle = ({
|
||||
title={displayName}
|
||||
truncate
|
||||
>
|
||||
{isPending || !displayName ? selection.email : displayName}
|
||||
{isPending || !displayName ? infoPanelSelection.email : displayName}
|
||||
</Text>
|
||||
{isPending && (
|
||||
<Badges withoutPaid={true} statusType={selection.statusType} />
|
||||
<Badges
|
||||
withoutPaid={true}
|
||||
statusType={infoPanelSelection.statusType}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{!isPending && !!displayName && (
|
||||
<Text className={"info-text__email"} title={selection.email}>
|
||||
{selection.email}
|
||||
<Text className={"info-text__email"} title={infoPanelSelection.email}>
|
||||
{infoPanelSelection.email}
|
||||
</Text>
|
||||
)}
|
||||
{isSSO && (
|
||||
|
@ -7,8 +7,6 @@ import { ContextMenuButton } from "@docspace/shared/components/context-menu-butt
|
||||
|
||||
const generalKeys = ["select", "show-info"];
|
||||
const roomKeys = ["separator0", "room-info"];
|
||||
const currentRoomKeys = ["pin-room", "unpin-room"];
|
||||
const currentFolderKeys = ["open", "separator0", "separator1"];
|
||||
|
||||
const StyledItemContextOptions = styled.div`
|
||||
height: 16px;
|
||||
@ -23,7 +21,6 @@ const RoomsContextBtn = ({
|
||||
|
||||
getItemContextOptionsKeys,
|
||||
getItemContextOptionsActions,
|
||||
|
||||
onSelectItem,
|
||||
}) => {
|
||||
const contextMenuRef = useRef();
|
||||
@ -54,10 +51,6 @@ const RoomsContextBtn = ({
|
||||
|
||||
generalKeys.forEach((key) => removeOptionByKey(key));
|
||||
if (selection.isRoom) roomKeys.forEach((key) => removeOptionByKey(key));
|
||||
if (selection.isSelectedFolder && selection.isRoom)
|
||||
currentRoomKeys.forEach((key) => removeOptionByKey(key));
|
||||
if (selection.isSelectedFolder && !selection.isRoom)
|
||||
currentFolderKeys.forEach((key) => removeOptionByKey(key));
|
||||
|
||||
options.forEach((item, index) => {
|
||||
const isSeparator = item.key.includes("separator");
|
||||
@ -76,10 +69,6 @@ const RoomsContextBtn = ({
|
||||
return options;
|
||||
};
|
||||
|
||||
// useEffect(() => {
|
||||
// contextMenuRef?.current.hide();
|
||||
// }, [selection]);
|
||||
|
||||
return (
|
||||
<StyledItemContextOptions>
|
||||
<ContextMenuButton
|
||||
|
@ -8,12 +8,16 @@ import { IconButton } from "@docspace/shared/components/icon-button";
|
||||
import { StyledTitle } from "../../../styles/common";
|
||||
import { RoomIcon } from "@docspace/shared/components/room-icon";
|
||||
import RoomsContextBtn from "./context-btn";
|
||||
import { RoomsType, ShareAccessRights } from "@docspace/shared/enums";
|
||||
import {
|
||||
FolderType,
|
||||
RoomsType,
|
||||
ShareAccessRights,
|
||||
} from "@docspace/shared/enums";
|
||||
|
||||
const RoomsItemHeader = ({
|
||||
t,
|
||||
selection,
|
||||
selectionParentRoom,
|
||||
infoPanelSelection,
|
||||
setIsMobileHidden,
|
||||
isGracePeriod,
|
||||
setInvitePanelOptions,
|
||||
@ -22,6 +26,7 @@ const RoomsItemHeader = ({
|
||||
roomsView,
|
||||
setSelected,
|
||||
setBufferSelection,
|
||||
isArchive,
|
||||
}) => {
|
||||
const itemTitleRef = useRef();
|
||||
|
||||
@ -30,7 +35,7 @@ const RoomsItemHeader = ({
|
||||
const icon = selection.icon;
|
||||
const isLoadedRoomIcon = !!selection.logo?.medium;
|
||||
const showDefaultRoomIcon = !isLoadedRoomIcon && selection.isRoom;
|
||||
const security = selectionParentRoom ? selectionParentRoom.security : {};
|
||||
const security = infoPanelSelection ? infoPanelSelection.security : {};
|
||||
const canInviteUserInRoomAbility = security?.EditAccess;
|
||||
const showInviteUserIcon = selection?.isRoom && roomsView === "info_members";
|
||||
|
||||
@ -41,7 +46,7 @@ const RoomsItemHeader = ({
|
||||
|
||||
const onClickInviteUsers = () => {
|
||||
setIsMobileHidden(true);
|
||||
const parentRoomId = selectionParentRoom.id;
|
||||
const parentRoomId = infoPanelSelection.id;
|
||||
|
||||
if (isGracePeriod) {
|
||||
setInviteUsersWarningDialogVisible(true);
|
||||
@ -65,7 +70,7 @@ const RoomsItemHeader = ({
|
||||
<RoomIcon
|
||||
color={selection.logo.color}
|
||||
title={selection.title}
|
||||
isArchive={selection.isArchive}
|
||||
isArchive={isArchive}
|
||||
/>
|
||||
) : (
|
||||
<img
|
||||
@ -103,30 +108,15 @@ const RoomsItemHeader = ({
|
||||
|
||||
export default inject(
|
||||
({ auth, dialogsStore, selectedFolderStore, filesStore }) => {
|
||||
const {
|
||||
selection: selectionItem,
|
||||
selectionParentRoom,
|
||||
getIsRooms,
|
||||
roomsView,
|
||||
} = auth.infoPanelStore;
|
||||
const { infoPanelSelection, roomsView } = auth.infoPanelStore;
|
||||
|
||||
const isShowParentRoom =
|
||||
getIsRooms() &&
|
||||
roomsView === "info_members" &&
|
||||
!selectionItem.isRoom &&
|
||||
!!selectionParentRoom;
|
||||
|
||||
const selection =
|
||||
selectionItem.length > 1
|
||||
? null
|
||||
: isShowParentRoom
|
||||
? selectionParentRoom
|
||||
: selectionItem;
|
||||
const selection = infoPanelSelection.length > 1 ? null : infoPanelSelection;
|
||||
const isArchive = selection?.rootFolderType === FolderType.Archive;
|
||||
|
||||
return {
|
||||
selection,
|
||||
roomsView,
|
||||
selectionParentRoom: auth.infoPanelStore.selectionParentRoom,
|
||||
infoPanelSelection: auth.infoPanelStore.infoPanelSelection,
|
||||
setIsMobileHidden: auth.infoPanelStore.setIsMobileHidden,
|
||||
|
||||
isGracePeriod: auth.currentTariffStatusStore.isGracePeriod,
|
||||
@ -137,11 +127,12 @@ export default inject(
|
||||
|
||||
isPublicRoomType:
|
||||
(selectedFolderStore.roomType ??
|
||||
auth.infoPanelStore.selectionParentRoom?.roomType) ===
|
||||
auth.infoPanelStore.infoPanelSelection?.roomType) ===
|
||||
RoomsType.PublicRoom,
|
||||
|
||||
setSelected: filesStore.setSelected,
|
||||
setBufferSelection: filesStore.setBufferSelection,
|
||||
isArchive,
|
||||
};
|
||||
}
|
||||
)(
|
||||
|
@ -5,7 +5,7 @@ import GalleryItemTitle from "./GalleryItemTitle";
|
||||
import RoomsItemHeader from "./Rooms";
|
||||
|
||||
const ItemTitle = ({
|
||||
selection,
|
||||
infoPanelSelection,
|
||||
gallerySelected,
|
||||
isNoItem,
|
||||
isAccounts,
|
||||
@ -16,13 +16,13 @@ const ItemTitle = ({
|
||||
getIcon,
|
||||
getUserContextOptions,
|
||||
}) => {
|
||||
if (!selection) return null;
|
||||
if (!infoPanelSelection) return null;
|
||||
if (isNoItem) return null;
|
||||
|
||||
if (isAccounts)
|
||||
return (
|
||||
<AccountsItemTitle
|
||||
selection={selection}
|
||||
infoPanelSelection={infoPanelSelection}
|
||||
isSeveralItems={isSeveralItems}
|
||||
getUserContextOptions={getUserContextOptions}
|
||||
selectionLength={selectionLength}
|
||||
|
@ -11,27 +11,29 @@ import { ComboBox } from "@docspace/shared/components/combobox";
|
||||
import { getUserStatus } from "SRC_DIR/helpers/people-helpers";
|
||||
import { StyledAccountContent } from "../../styles/accounts";
|
||||
|
||||
const Accounts = ({
|
||||
t,
|
||||
selection,
|
||||
isOwner,
|
||||
isAdmin,
|
||||
changeUserType,
|
||||
canChangeUserType,
|
||||
setSelection,
|
||||
getPeopleListItem,
|
||||
}) => {
|
||||
const Accounts = (props) => {
|
||||
const {
|
||||
t,
|
||||
infoPanelSelection,
|
||||
isOwner,
|
||||
isAdmin,
|
||||
changeUserType,
|
||||
canChangeUserType,
|
||||
setInfoPanelSelection,
|
||||
getPeopleListItem,
|
||||
} = props;
|
||||
|
||||
const [statusLabel, setStatusLabel] = React.useState("");
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
|
||||
const { role, id, isVisitor, isCollaborator } = selection;
|
||||
const { role, id, isVisitor, isCollaborator } = infoPanelSelection;
|
||||
|
||||
React.useEffect(() => {
|
||||
getStatusLabel();
|
||||
}, [selection, getStatusLabel]);
|
||||
}, [infoPanelSelection, getStatusLabel]);
|
||||
|
||||
const getStatusLabel = React.useCallback(() => {
|
||||
const status = getUserStatus(selection);
|
||||
const status = getUserStatus(infoPanelSelection);
|
||||
switch (status) {
|
||||
case "active":
|
||||
return setStatusLabel(t("Common:Active"));
|
||||
@ -42,7 +44,7 @@ const Accounts = ({
|
||||
default:
|
||||
return setStatusLabel(t("Common:Active"));
|
||||
}
|
||||
}, [selection]);
|
||||
}, [infoPanelSelection]);
|
||||
|
||||
const getUserTypeLabel = React.useCallback((role) => {
|
||||
switch (role) {
|
||||
@ -111,9 +113,9 @@ const Accounts = ({
|
||||
const items = [];
|
||||
users.map((u) => items.push(getPeopleListItem(u)));
|
||||
if (items.length === 1) {
|
||||
setSelection(getPeopleListItem(items[0]));
|
||||
setInfoPanelSelection(getPeopleListItem(items[0]));
|
||||
} else {
|
||||
setSelection(items);
|
||||
setInfoPanelSelection(items);
|
||||
}
|
||||
}
|
||||
setIsLoading(false);
|
||||
@ -122,11 +124,11 @@ const Accounts = ({
|
||||
const onTypeChange = React.useCallback(
|
||||
({ action }) => {
|
||||
setIsLoading(true);
|
||||
if (!changeUserType(action, [selection], onSuccess, onAbort)) {
|
||||
if (!changeUserType(action, [infoPanelSelection], onSuccess, onAbort)) {
|
||||
setIsLoading(false);
|
||||
}
|
||||
},
|
||||
[selection, changeUserType, t]
|
||||
[infoPanelSelection, changeUserType, t]
|
||||
);
|
||||
|
||||
const typeLabel = getUserTypeLabel(role);
|
||||
@ -165,9 +167,12 @@ const Accounts = ({
|
||||
</Text>
|
||||
);
|
||||
|
||||
const status = getUserStatus(selection);
|
||||
const status = getUserStatus(infoPanelSelection);
|
||||
|
||||
const canChange = canChangeUserType({ ...selection, statusType: status });
|
||||
const canChange = canChangeUserType({
|
||||
...infoPanelSelection,
|
||||
statusType: status,
|
||||
});
|
||||
|
||||
return canChange ? combobox : text;
|
||||
};
|
||||
@ -230,7 +235,7 @@ export default inject(({ auth, peopleStore, accessRightsStore }) => {
|
||||
const { changeType: changeUserType, usersStore } = peopleStore;
|
||||
const { canChangeUserType } = accessRightsStore;
|
||||
|
||||
const { setSelection } = auth.infoPanelStore;
|
||||
const { setInfoPanelSelection } = auth.infoPanelStore;
|
||||
|
||||
return {
|
||||
isOwner,
|
||||
@ -240,7 +245,7 @@ export default inject(({ auth, peopleStore, accessRightsStore }) => {
|
||||
canChangeUserType,
|
||||
loading: usersStore.operationRunning,
|
||||
getPeopleListItem: usersStore.getPeopleListItem,
|
||||
setSelection,
|
||||
setInfoPanelSelection,
|
||||
};
|
||||
})(
|
||||
withTranslation([
|
||||
|
@ -3,7 +3,7 @@ import { useNavigate } from "react-router-dom";
|
||||
import { inject } from "mobx-react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
|
||||
import { FileType } from "@docspace/shared/enums";
|
||||
import { FileType, FolderType } from "@docspace/shared/enums";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
|
||||
import DetailsHelper from "../../helpers/DetailsHelper.js";
|
||||
@ -21,6 +21,7 @@ const Details = ({
|
||||
isVisitor,
|
||||
isCollaborator,
|
||||
selectTag,
|
||||
isArchive,
|
||||
}) => {
|
||||
const [itemProperties, setItemProperties] = useState([]);
|
||||
|
||||
@ -61,7 +62,7 @@ const Details = ({
|
||||
}, [selection, createThumbnailAction]);
|
||||
|
||||
const currentIcon =
|
||||
!selection.isArchive && selection?.logo?.large
|
||||
!isArchive && selection?.logo?.large
|
||||
? selection?.logo?.large
|
||||
: getInfoPanelItemIcon(selection, 96);
|
||||
|
||||
@ -93,7 +94,7 @@ const Details = ({
|
||||
<RoomIcon
|
||||
color={selection.logo.color}
|
||||
title={selection.title}
|
||||
isArchive={selection.isArchive}
|
||||
isArchive={isArchive}
|
||||
size="96px"
|
||||
radius="16px"
|
||||
/>
|
||||
@ -101,7 +102,7 @@ const Details = ({
|
||||
<img
|
||||
className={`no-thumbnail-img ${selection.isRoom && "is-room"} ${
|
||||
selection.isRoom &&
|
||||
!selection.isArchive &&
|
||||
!isArchive &&
|
||||
selection.logo?.large &&
|
||||
"custom-logo"
|
||||
}`}
|
||||
@ -138,7 +139,8 @@ const Details = ({
|
||||
|
||||
export default inject(({ auth, filesStore, filesActionsStore }) => {
|
||||
const { userStore } = auth;
|
||||
const { selection, getInfoPanelItemIcon, openUser } = auth.infoPanelStore;
|
||||
const { infoPanelSelection, getInfoPanelItemIcon, openUser } =
|
||||
auth.infoPanelStore;
|
||||
const { createThumbnail } = filesStore;
|
||||
const { personal, culture } = auth.settingsStore;
|
||||
const { user } = userStore;
|
||||
@ -148,15 +150,18 @@ export default inject(({ auth, filesStore, filesActionsStore }) => {
|
||||
const isVisitor = user.isVisitor;
|
||||
const isCollaborator = user.isCollaborator;
|
||||
|
||||
const isArchive = infoPanelSelection?.rootFolderType === FolderType.Archive;
|
||||
|
||||
return {
|
||||
personal,
|
||||
culture,
|
||||
selection,
|
||||
selection: infoPanelSelection,
|
||||
createThumbnail,
|
||||
getInfoPanelItemIcon,
|
||||
openUser,
|
||||
isVisitor,
|
||||
isCollaborator,
|
||||
selectTag,
|
||||
isArchive,
|
||||
};
|
||||
})(withTranslation(["InfoPanel", "Common", "Translations", "Files"])(Details));
|
||||
|
@ -13,11 +13,10 @@ import { decode } from "he";
|
||||
|
||||
const HistoryBlock = ({
|
||||
t,
|
||||
selection,
|
||||
selectionIsFile,
|
||||
feed,
|
||||
selectedFolder,
|
||||
selectionParentRoom,
|
||||
infoPanelSelection,
|
||||
getInfoPanelItemIcon,
|
||||
checkAndOpenLocationAction,
|
||||
openUser,
|
||||
@ -72,9 +71,8 @@ const HistoryBlock = ({
|
||||
className="message"
|
||||
action={json}
|
||||
groupedActions={groupedFeeds}
|
||||
selection={selection}
|
||||
selectedFolder={selectedFolder}
|
||||
selectionParentRoom={selectionParentRoom}
|
||||
infoPanelSelection={infoPanelSelection}
|
||||
/>
|
||||
|
||||
{isItemAction && withFileList && (
|
||||
|
@ -10,9 +10,8 @@ const HistoryBlockMessage = ({
|
||||
t,
|
||||
action,
|
||||
groupedActions,
|
||||
selection,
|
||||
selectedFolder,
|
||||
selectionParentRoom,
|
||||
infoPanelSelection,
|
||||
}) => {
|
||||
const message = getBlockMessageTranslation(
|
||||
t,
|
||||
@ -31,7 +30,7 @@ const HistoryBlockMessage = ({
|
||||
|
||||
const itemLocationId = +action.ExtraLocation;
|
||||
if (selectedFolder?.id === itemLocationId) return "";
|
||||
if (selection?.isRoom && selectionParentRoom?.id === itemLocationId)
|
||||
if (infoPanelSelection?.isRoom && infoPanelSelection?.id === itemLocationId)
|
||||
return "";
|
||||
|
||||
const folderTitle = action.ExtraLocationTitle;
|
||||
|
@ -11,12 +11,11 @@ import NoHistory from "../NoItem/NoHistory";
|
||||
|
||||
const History = ({
|
||||
t,
|
||||
selection,
|
||||
historyWithFileList,
|
||||
selectedFolder,
|
||||
selectionHistory,
|
||||
setSelectionHistory,
|
||||
selectionParentRoom,
|
||||
infoPanelSelection,
|
||||
getInfoPanelItemIcon,
|
||||
getHistory,
|
||||
checkAndOpenLocationAction,
|
||||
@ -32,14 +31,15 @@ const History = ({
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const fetchHistory = async (item) => {
|
||||
if (!item?.id) return;
|
||||
if (isLoading) {
|
||||
abortControllerRef.current?.abort();
|
||||
abortControllerRef.current = new AbortController();
|
||||
} else setIsLoading(true);
|
||||
|
||||
let module = "files";
|
||||
if (selection.isRoom) module = "rooms";
|
||||
else if (selection.isFolder) module = "folders";
|
||||
if (infoPanelSelection.isRoom) module = "rooms";
|
||||
else if (infoPanelSelection.isFolder) module = "folders";
|
||||
|
||||
getHistory(
|
||||
module,
|
||||
@ -64,8 +64,8 @@ const History = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (!isMount.current) return;
|
||||
fetchHistory(selection);
|
||||
}, [selection.id]);
|
||||
fetchHistory(infoPanelSelection);
|
||||
}, [infoPanelSelection.id]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
@ -86,9 +86,8 @@ const History = ({
|
||||
key={feed.json.Id}
|
||||
t={t}
|
||||
feed={feed}
|
||||
selection={selection}
|
||||
selectedFolder={selectedFolder}
|
||||
selectionParentRoom={selectionParentRoom}
|
||||
infoPanelSelection={infoPanelSelection}
|
||||
getInfoPanelItemIcon={getInfoPanelItemIcon}
|
||||
checkAndOpenLocationAction={checkAndOpenLocationAction}
|
||||
openUser={openUser}
|
||||
@ -106,11 +105,10 @@ const History = ({
|
||||
export default inject(({ auth, filesStore, filesActionsStore }) => {
|
||||
const { userStore } = auth;
|
||||
const {
|
||||
selection,
|
||||
infoPanelSelection,
|
||||
selectionHistory,
|
||||
setSelectionHistory,
|
||||
historyWithFileList,
|
||||
selectionParentRoom,
|
||||
getInfoPanelItemIcon,
|
||||
openUser,
|
||||
} = auth.infoPanelStore;
|
||||
@ -126,11 +124,10 @@ export default inject(({ auth, filesStore, filesActionsStore }) => {
|
||||
return {
|
||||
personal,
|
||||
culture,
|
||||
selection,
|
||||
selectionHistory,
|
||||
setSelectionHistory,
|
||||
historyWithFileList,
|
||||
selectionParentRoom,
|
||||
infoPanelSelection,
|
||||
getInfoPanelItemIcon,
|
||||
getHistory,
|
||||
checkAndOpenLocationAction,
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import AtReactSvgUrl from "PUBLIC_DIR/images/@.react.svg?url";
|
||||
import { StyledUser } from "../../styles/members";
|
||||
import { Avatar } from "@docspace/shared/components/avatar";
|
||||
@ -17,62 +18,69 @@ import { IconButton } from "@docspace/shared/components/icon-button";
|
||||
const User = ({
|
||||
t,
|
||||
user,
|
||||
setMembers,
|
||||
isExpect,
|
||||
membersHelper,
|
||||
currentMember,
|
||||
updateRoomMemberRole,
|
||||
selectionParentRoom,
|
||||
setSelectionParentRoom,
|
||||
infoPanelSelection,
|
||||
changeUserType,
|
||||
setIsScrollLocked,
|
||||
isTitle,
|
||||
onRepeatInvitation,
|
||||
showInviteIcon,
|
||||
membersFilter,
|
||||
setMembersFilter,
|
||||
fetchMembers,
|
||||
hasNextPage,
|
||||
infoPanelMembers,
|
||||
setInfoPanelMembers,
|
||||
}) => {
|
||||
if (!selectionParentRoom) return null;
|
||||
if (!infoPanelSelection) return null;
|
||||
if (!user.displayName && !user.email) return null;
|
||||
|
||||
//const [userIsRemoved, setUserIsRemoved] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
//if (userIsRemoved) return null;
|
||||
|
||||
const security = infoPanelSelection ? infoPanelSelection.security : {};
|
||||
const isExpect = user.isExpect;
|
||||
const canInviteUserInRoomAbility = security?.EditAccess;
|
||||
const showInviteIcon = canInviteUserInRoomAbility && isExpect;
|
||||
const canChangeUserRole = user.canEditAccess;
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const fullRoomRoleOptions = membersHelper.getOptionsByRoomType(
|
||||
selectionParentRoom.roomType,
|
||||
infoPanelSelection.roomType,
|
||||
canChangeUserRole
|
||||
);
|
||||
|
||||
const userRole = membersHelper.getOptionByUserAccess(user.access, user);
|
||||
|
||||
const userRoleOptions = filterUserRoleOptions(fullRoomRoleOptions, user);
|
||||
|
||||
const onRepeatInvitation = async () => {
|
||||
resendEmailInvitations(infoPanelSelection.id, true)
|
||||
.then(() =>
|
||||
toastr.success(t("PeopleTranslations:SuccessSentMultipleInvitatios"))
|
||||
)
|
||||
.catch((err) => toastr.error(err));
|
||||
};
|
||||
|
||||
const updateRole = (option) => {
|
||||
return updateRoomMemberRole(selectionParentRoom.id, {
|
||||
return updateRoomMemberRole(infoPanelSelection.id, {
|
||||
invitations: [{ id: user.id, access: option.access }],
|
||||
notify: false,
|
||||
sharingMessage: "",
|
||||
})
|
||||
.then(async () => {
|
||||
setIsLoading(false);
|
||||
const users = selectionParentRoom.members.users;
|
||||
const administrators = selectionParentRoom.members.administrators;
|
||||
const expectedMembers = selectionParentRoom.members.expected;
|
||||
|
||||
if (option.key === "remove") {
|
||||
const newMembersFilter = JSON.parse(JSON.stringify(membersFilter));
|
||||
|
||||
const newMembers = {
|
||||
users: users?.filter((m) => m.id !== user.id),
|
||||
administrators: administrators?.filter((m) => m.id !== user.id),
|
||||
expected: expectedMembers?.filter((m) => m.id !== user.id),
|
||||
users: infoPanelMembers.users?.filter((m) => m.id !== user.id),
|
||||
administrators: infoPanelMembers.administrators?.filter(
|
||||
(m) => m.id !== user.id
|
||||
),
|
||||
expected: infoPanelMembers.expected?.filter(
|
||||
(m) => m.id !== user.id
|
||||
),
|
||||
};
|
||||
|
||||
const roomId = selectionParentRoom.id;
|
||||
const roomId = infoPanelSelection.id;
|
||||
const newUsers = newMembers.users.length > 1 ? newMembers?.users : [];
|
||||
const newAdministrators =
|
||||
newMembers.administrators.length > 1
|
||||
@ -81,7 +89,7 @@ const User = ({
|
||||
const newExpected =
|
||||
newMembers.expected.length > 1 ? newMembers?.expected : [];
|
||||
|
||||
setMembers({
|
||||
setInfoPanelMembers({
|
||||
roomId,
|
||||
users: newUsers,
|
||||
administrators: newAdministrators,
|
||||
@ -90,25 +98,12 @@ const User = ({
|
||||
|
||||
newMembersFilter.total -= 1;
|
||||
|
||||
setSelectionParentRoom({
|
||||
...selectionParentRoom,
|
||||
members: {
|
||||
users: newUsers,
|
||||
administrators: newAdministrators,
|
||||
expected: newExpected,
|
||||
},
|
||||
});
|
||||
|
||||
if (hasNextPage) {
|
||||
newMembersFilter.startIndex =
|
||||
(newMembersFilter.page + 1) * newMembersFilter.pageCount - 1;
|
||||
newMembersFilter.pageCount = 1;
|
||||
|
||||
const fetchedMembers = await fetchMembers(
|
||||
selectionParentRoom.id,
|
||||
false,
|
||||
newMembersFilter
|
||||
);
|
||||
const fetchedMembers = await fetchMembers(t, false);
|
||||
|
||||
const newMembers = {
|
||||
administrators: [
|
||||
@ -119,48 +114,26 @@ const User = ({
|
||||
expected: [...newExpected, ...fetchedMembers.expected],
|
||||
};
|
||||
|
||||
setMembers({
|
||||
roomId: selectionParentRoom.id,
|
||||
setInfoPanelMembers({
|
||||
roomId: infoPanelSelection.id,
|
||||
...newMembers,
|
||||
});
|
||||
|
||||
setSelectionParentRoom({
|
||||
...selectionParentRoom,
|
||||
members: newMembers,
|
||||
});
|
||||
}
|
||||
|
||||
setMembersFilter(newMembersFilter);
|
||||
|
||||
//setUserIsRemoved(true);
|
||||
} else {
|
||||
setMembers({
|
||||
roomId: selectionParentRoom.id,
|
||||
users: users?.map((m) =>
|
||||
setInfoPanelMembers({
|
||||
roomId: infoPanelSelection.id,
|
||||
users: infoPanelMembers.users?.map((m) =>
|
||||
m.id === user.id ? { ...m, access: option.access } : m
|
||||
),
|
||||
administrators: administrators?.map((m) =>
|
||||
administrators: infoPanelMembers.administrators?.map((m) =>
|
||||
m.id === user.id ? { ...m, access: option.access } : m
|
||||
),
|
||||
expected: expectedMembers?.map((m) =>
|
||||
expected: infoPanelMembers.expected?.map((m) =>
|
||||
m.id === user.id ? { ...m, access: option.access } : m
|
||||
),
|
||||
});
|
||||
|
||||
setSelectionParentRoom({
|
||||
...selectionParentRoom,
|
||||
members: {
|
||||
users: users?.map((m) =>
|
||||
m.id === user.id ? { ...m, access: option.access } : m
|
||||
),
|
||||
administrators: administrators?.map((m) =>
|
||||
m.id === user.id ? { ...m, access: option.access } : m
|
||||
),
|
||||
expected: expectedMembers?.map((m) =>
|
||||
m.id === user.id ? { ...m, access: option.access } : m
|
||||
),
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
@ -203,7 +176,7 @@ const User = ({
|
||||
};
|
||||
|
||||
const onToggle = (e, isOpen) => {
|
||||
setIsScrollLocked(isOpen);
|
||||
// setIsScrollLocked(isOpen);
|
||||
};
|
||||
|
||||
const userAvatar = user.hasAvatar ? user.avatar : DefaultUserPhotoUrl;
|
||||
@ -216,7 +189,7 @@ const User = ({
|
||||
user.isOwner ? t("Common:DocSpaceOwner") : t("Common:DocSpaceAdmin")
|
||||
}. ${t("Common:HasFullAccess")}`;
|
||||
|
||||
return isTitle ? (
|
||||
return user.isTitle ? (
|
||||
<StyledUserTypeHeader isExpect={isExpect}>
|
||||
<Text className="title">{user.displayName}</Text>
|
||||
|
||||
@ -282,4 +255,33 @@ const User = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default User;
|
||||
export default inject(({ auth, filesStore, peopleStore }) => {
|
||||
const {
|
||||
infoPanelSelection,
|
||||
setIsScrollLocked,
|
||||
infoPanelMembers,
|
||||
setInfoPanelMembers,
|
||||
fetchMembers,
|
||||
} = auth.infoPanelStore;
|
||||
const {
|
||||
updateRoomMemberRole,
|
||||
resendEmailInvitations,
|
||||
membersFilter,
|
||||
setMembersFilter,
|
||||
} = filesStore;
|
||||
|
||||
const { changeType: changeUserType } = peopleStore;
|
||||
|
||||
return {
|
||||
infoPanelSelection,
|
||||
setIsScrollLocked,
|
||||
updateRoomMemberRole,
|
||||
resendEmailInvitations,
|
||||
changeUserType,
|
||||
membersFilter,
|
||||
setMembersFilter,
|
||||
infoPanelMembers,
|
||||
setInfoPanelMembers,
|
||||
fetchMembers,
|
||||
};
|
||||
})(observer(User));
|
||||
|
@ -1,13 +1,9 @@
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
|
||||
import {
|
||||
EmployeeActivationStatus,
|
||||
RoomsType,
|
||||
ShareAccessRights,
|
||||
} from "@docspace/shared/enums";
|
||||
import { RoomsType, ShareAccessRights } from "@docspace/shared/enums";
|
||||
import { LINKS_LIMIT_COUNT } from "@docspace/shared/constants";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
import MembersHelper from "../../helpers/MembersHelper";
|
||||
@ -30,214 +26,60 @@ import LinkRow from "./sub-components/LinkRow";
|
||||
const Members = ({
|
||||
t,
|
||||
selfId,
|
||||
selection,
|
||||
|
||||
updateRoomMembers,
|
||||
setUpdateRoomMembers,
|
||||
|
||||
selectionParentRoom,
|
||||
setSelectionParentRoom,
|
||||
|
||||
infoPanelSelection,
|
||||
setIsScrollLocked,
|
||||
|
||||
getRoomMembers,
|
||||
getRoomLinks,
|
||||
updateRoomMemberRole,
|
||||
setView,
|
||||
roomsView,
|
||||
resendEmailInvitations,
|
||||
changeUserType,
|
||||
isPublicRoomType,
|
||||
|
||||
setExternalLinks,
|
||||
membersFilter,
|
||||
setMembersFilter,
|
||||
externalLinks,
|
||||
members,
|
||||
setMembersList,
|
||||
roomType,
|
||||
infoPanelMembers,
|
||||
setInfoPanelMembers,
|
||||
primaryLink,
|
||||
isArchiveFolder,
|
||||
isPublicRoom,
|
||||
|
||||
additionalLinks,
|
||||
setLinkParams,
|
||||
setEditLinkPanelIsVisible,
|
||||
getPrimaryLink,
|
||||
setExternalLink,
|
||||
withPublicRoomBlock,
|
||||
fetchMembers,
|
||||
membersIsLoading,
|
||||
}) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const membersHelper = new MembersHelper({ t });
|
||||
|
||||
const security = selectionParentRoom ? selectionParentRoom.security : {};
|
||||
|
||||
const fetchMembers = async (roomId, clearFilter = true) => {
|
||||
if (isLoading) return;
|
||||
const isPublic = selection?.roomType ?? selectionParentRoom?.roomType;
|
||||
const requests = [getRoomMembers(roomId, clearFilter)];
|
||||
|
||||
if (isPublic && clearFilter && withPublicRoomBlock) {
|
||||
requests.push(getRoomLinks(roomId));
|
||||
}
|
||||
|
||||
let timerId;
|
||||
if (clearFilter) timerId = setTimeout(() => setIsLoading(true), 300);
|
||||
|
||||
const [data, links] = await Promise.all(requests);
|
||||
clearFilter && setIsLoading(false);
|
||||
clearTimeout(timerId);
|
||||
|
||||
links && setExternalLinks(links);
|
||||
|
||||
const users = [];
|
||||
const administrators = [];
|
||||
const expectedMembers = [];
|
||||
data?.map((fetchedMember) => {
|
||||
const member = {
|
||||
access: fetchedMember.access,
|
||||
canEditAccess: fetchedMember.canEditAccess,
|
||||
...fetchedMember.sharedTo,
|
||||
};
|
||||
|
||||
if (member.activationStatus === EmployeeActivationStatus.Pending) {
|
||||
member.isExpect = true;
|
||||
expectedMembers.push(member);
|
||||
} else if (
|
||||
member.access === ShareAccessRights.FullAccess ||
|
||||
member.access === ShareAccessRights.RoomManager
|
||||
) {
|
||||
administrators.push(member);
|
||||
} else {
|
||||
users.push(member);
|
||||
}
|
||||
});
|
||||
|
||||
let hasPrevAdminsTitle =
|
||||
members?.roomId === roomId && !clearFilter
|
||||
? getHasPrevTitle(members?.administrators, "administration")
|
||||
: false;
|
||||
|
||||
if (administrators.length && !hasPrevAdminsTitle) {
|
||||
administrators.unshift({
|
||||
id: "administration",
|
||||
displayName: t("Administration"),
|
||||
isTitle: true,
|
||||
});
|
||||
}
|
||||
|
||||
let hasPrevUsersTitle =
|
||||
members?.roomId === roomId && !clearFilter
|
||||
? getHasPrevTitle(members?.users, "user")
|
||||
: false;
|
||||
|
||||
if (users.length && !hasPrevUsersTitle) {
|
||||
users.unshift({ id: "user", displayName: t("Users"), isTitle: true });
|
||||
}
|
||||
|
||||
let hasPrevExpectedTitle =
|
||||
members?.roomId === roomId && !clearFilter
|
||||
? getHasPrevTitle(members?.expected, "expected")
|
||||
: false;
|
||||
|
||||
if (expectedMembers.length && !hasPrevExpectedTitle) {
|
||||
expectedMembers.unshift({
|
||||
id: "expected",
|
||||
displayName: t("ExpectUsers"),
|
||||
isTitle: true,
|
||||
isExpect: true,
|
||||
});
|
||||
}
|
||||
|
||||
setUpdateRoomMembers(false);
|
||||
|
||||
return {
|
||||
users,
|
||||
administrators,
|
||||
expected: expectedMembers,
|
||||
roomId,
|
||||
};
|
||||
const updateInfoPanelMembers = async () => {
|
||||
if (!infoPanelSelection) return;
|
||||
const fetchedMembers = await fetchMembers(t);
|
||||
setInfoPanelMembers(fetchedMembers);
|
||||
};
|
||||
|
||||
const getHasPrevTitle = (array, type) => {
|
||||
return array.findIndex((x) => x.id === type) > -1;
|
||||
};
|
||||
|
||||
const updateSelectionParentRoomActionSelection = useCallback(async () => {
|
||||
if (!selection?.isRoom || selection.id === members?.roomId) return;
|
||||
|
||||
const fetchedMembers = await fetchMembers(selection.id);
|
||||
setMembersList(fetchedMembers);
|
||||
|
||||
setSelectionParentRoom({
|
||||
...selection,
|
||||
members: fetchedMembers,
|
||||
});
|
||||
if (roomsView === "info_members" && !selection?.security?.Read)
|
||||
setView("info_details");
|
||||
}, [selection]);
|
||||
|
||||
useEffect(() => {
|
||||
updateSelectionParentRoomActionSelection();
|
||||
}, [selection, updateSelectionParentRoomActionSelection]);
|
||||
|
||||
const updateMembersAction = useCallback(async () => {
|
||||
if (!updateRoomMembers) return;
|
||||
|
||||
const fetchedMembers = await fetchMembers(selection.id);
|
||||
|
||||
setSelectionParentRoom({
|
||||
...selectionParentRoom,
|
||||
members: fetchedMembers,
|
||||
});
|
||||
|
||||
setMembersList(fetchedMembers);
|
||||
}, [selectionParentRoom, selection?.id, updateRoomMembers]);
|
||||
|
||||
useEffect(() => {
|
||||
updateMembersAction();
|
||||
}, [
|
||||
selectionParentRoom,
|
||||
selection?.id,
|
||||
updateRoomMembers,
|
||||
updateMembersAction,
|
||||
]);
|
||||
|
||||
const onRepeatInvitation = async () => {
|
||||
resendEmailInvitations(selectionParentRoom.id, true)
|
||||
.then(() =>
|
||||
toastr.success(t("PeopleTranslations:SuccessSentMultipleInvitatios"))
|
||||
)
|
||||
.catch((err) => toastr.error(err));
|
||||
};
|
||||
updateInfoPanelMembers();
|
||||
}, [infoPanelSelection]);
|
||||
|
||||
const loadNextPage = async () => {
|
||||
const roomId = selectionParentRoom.id;
|
||||
const fetchedMembers = await fetchMembers(roomId, false);
|
||||
const roomId = infoPanelSelection.id;
|
||||
const fetchedMembers = await fetchMembers(t, false);
|
||||
const { users, administrators, expected } = fetchedMembers;
|
||||
|
||||
const newMembers = {
|
||||
roomId: roomId,
|
||||
administrators: [...members.administrators, ...administrators],
|
||||
users: [...members.users, ...users],
|
||||
expected: [...members.expected, ...expected],
|
||||
administrators: [...infoPanelMembers.administrators, ...administrators],
|
||||
users: [...infoPanelMembers.users, ...users],
|
||||
expected: [...infoPanelMembers.expected, ...expected],
|
||||
};
|
||||
|
||||
setMembersList(newMembers);
|
||||
setSelectionParentRoom({
|
||||
...selectionParentRoom,
|
||||
members: newMembers,
|
||||
});
|
||||
setInfoPanelMembers(newMembers);
|
||||
};
|
||||
|
||||
if (isLoading) return <Loaders.InfoPanelViewLoader view="members" />;
|
||||
else if (!members) return <></>;
|
||||
if (membersIsLoading) return <Loaders.InfoPanelViewLoader view="members" />;
|
||||
else if (!infoPanelMembers) return <></>;
|
||||
|
||||
const [currentMember] = members.administrators.filter(
|
||||
const [currentMember] = infoPanelMembers.administrators.filter(
|
||||
(member) => member.id === selfId
|
||||
);
|
||||
|
||||
const { administrators, users, expected } = members;
|
||||
const { administrators, users, expected } = infoPanelMembers;
|
||||
|
||||
const membersList = [...administrators, ...users, ...expected];
|
||||
|
||||
const adminsTitleCount = administrators.length ? 1 : 0;
|
||||
@ -245,18 +87,13 @@ const Members = ({
|
||||
const expectedTitleCount = expected.length ? 1 : 0;
|
||||
|
||||
const headersCount = adminsTitleCount + usersTitleCount + expectedTitleCount;
|
||||
const dataReadyMembersList = selection?.id === selectionParentRoom?.id;
|
||||
|
||||
if (!dataReadyMembersList) return <></>;
|
||||
|
||||
const canInviteUserInRoomAbility = security?.EditAccess;
|
||||
|
||||
const onAddNewLink = async () => {
|
||||
if (isPublicRoom || primaryLink) {
|
||||
setLinkParams({ isEdit: false });
|
||||
setEditLinkPanelIsVisible(true);
|
||||
} else {
|
||||
getPrimaryLink(selectionParentRoom.id).then((link) => {
|
||||
getPrimaryLink(infoPanelSelection.id).then((link) => {
|
||||
setExternalLink(link);
|
||||
copy(link.sharedTo.shareLink);
|
||||
toastr.success(t("Files:LinkSuccessfullyCreatedAndCopied"));
|
||||
@ -402,24 +239,8 @@ const Members = ({
|
||||
user={user}
|
||||
key={user.id}
|
||||
index={index + publicRoomItemsLength}
|
||||
security={security}
|
||||
membersHelper={membersHelper}
|
||||
currentMember={currentMember}
|
||||
updateRoomMemberRole={updateRoomMemberRole}
|
||||
roomId={selectionParentRoom.id}
|
||||
roomType={selectionParentRoom.roomType}
|
||||
selectionParentRoom={selectionParentRoom}
|
||||
setSelectionParentRoom={setSelectionParentRoom}
|
||||
changeUserType={changeUserType}
|
||||
setIsScrollLocked={setIsScrollLocked}
|
||||
isTitle={user.isTitle}
|
||||
isExpect={user.isExpect}
|
||||
showInviteIcon={canInviteUserInRoomAbility && user.isExpect}
|
||||
onRepeatInvitation={onRepeatInvitation}
|
||||
setMembers={setMembersList}
|
||||
membersFilter={membersFilter}
|
||||
setMembersFilter={setMembersFilter}
|
||||
fetchMembers={fetchMembers}
|
||||
hasNextPage={
|
||||
membersList.length - headersCount < membersFilter.total
|
||||
}
|
||||
@ -435,115 +256,50 @@ export default inject(
|
||||
({
|
||||
auth,
|
||||
filesStore,
|
||||
peopleStore,
|
||||
selectedFolderStore,
|
||||
publicRoomStore,
|
||||
treeFoldersStore,
|
||||
dialogsStore,
|
||||
}) => {
|
||||
const {
|
||||
selectionParentRoom,
|
||||
setSelectionParentRoom,
|
||||
setView,
|
||||
roomsView,
|
||||
|
||||
updateRoomMembers,
|
||||
setUpdateRoomMembers,
|
||||
|
||||
infoPanelSelection,
|
||||
setIsScrollLocked,
|
||||
membersList,
|
||||
setMembersList,
|
||||
selection: selectionItem,
|
||||
getIsRooms,
|
||||
infoPanelMembers,
|
||||
setInfoPanelMembers,
|
||||
fetchMembers,
|
||||
membersIsLoading,
|
||||
withPublicRoomBlock,
|
||||
} = auth.infoPanelStore;
|
||||
const {
|
||||
getRoomMembers,
|
||||
getRoomLinks,
|
||||
updateRoomMemberRole,
|
||||
resendEmailInvitations,
|
||||
membersFilter,
|
||||
setMembersFilter,
|
||||
selection,
|
||||
bufferSelection,
|
||||
} = filesStore;
|
||||
const { membersFilter } = filesStore;
|
||||
const { id: selfId } = auth.userStore.user;
|
||||
|
||||
const { changeType: changeUserType } = peopleStore;
|
||||
const {
|
||||
roomLinks,
|
||||
setExternalLinks,
|
||||
primaryLink,
|
||||
additionalLinks,
|
||||
setExternalLink,
|
||||
} = publicRoomStore;
|
||||
const { primaryLink, additionalLinks, setExternalLink } = publicRoomStore;
|
||||
const { isArchiveFolderRoot } = treeFoldersStore;
|
||||
const { setLinkParams, setEditLinkPanelIsVisible } = dialogsStore;
|
||||
|
||||
const roomType =
|
||||
selectedFolderStore.roomType ?? selectionParentRoom?.roomType;
|
||||
selectedFolderStore.roomType ?? infoPanelSelection?.roomType;
|
||||
|
||||
const isPublicRoomType =
|
||||
roomType === RoomsType.PublicRoom || roomType === RoomsType.CustomRoom;
|
||||
|
||||
const isPublicRoom = roomType === RoomsType.PublicRoom;
|
||||
|
||||
const room = selectionParentRoom
|
||||
? selectionParentRoom
|
||||
: selection.length
|
||||
? selection[0]
|
||||
: bufferSelection
|
||||
? bufferSelection
|
||||
: null;
|
||||
|
||||
const withPublicRoomBlock =
|
||||
room?.access === ShareAccessRights.RoomManager ||
|
||||
room?.access === ShareAccessRights.None;
|
||||
|
||||
const isShowParentRoom =
|
||||
getIsRooms() &&
|
||||
roomsView === "info_members" &&
|
||||
!selectionItem?.isRoom &&
|
||||
!!selectionParentRoom;
|
||||
|
||||
const infoSelection =
|
||||
selectionItem?.length > 1
|
||||
? null
|
||||
: isShowParentRoom
|
||||
? selectionParentRoom
|
||||
: selectionItem;
|
||||
infoPanelSelection?.length > 1 ? null : infoPanelSelection;
|
||||
|
||||
return {
|
||||
setView,
|
||||
roomsView,
|
||||
selection: infoSelection,
|
||||
selectionParentRoom,
|
||||
setSelectionParentRoom,
|
||||
|
||||
infoPanelSelection: infoSelection,
|
||||
setIsScrollLocked,
|
||||
|
||||
getRoomMembers,
|
||||
getRoomLinks,
|
||||
updateRoomMemberRole,
|
||||
|
||||
updateRoomMembers,
|
||||
setUpdateRoomMembers,
|
||||
|
||||
selfId,
|
||||
|
||||
resendEmailInvitations,
|
||||
changeUserType,
|
||||
isPublicRoomType,
|
||||
setExternalLinks,
|
||||
membersFilter,
|
||||
setMembersFilter,
|
||||
externalLinks: roomLinks,
|
||||
members: membersList,
|
||||
setMembersList,
|
||||
infoPanelMembers,
|
||||
setInfoPanelMembers,
|
||||
roomType,
|
||||
primaryLink,
|
||||
isArchiveFolder: isArchiveFolderRoot,
|
||||
isPublicRoom,
|
||||
|
||||
additionalLinks: additionalLinks,
|
||||
isArchiveFolder: isArchiveFolderRoot,
|
||||
setLinkParams,
|
||||
@ -552,6 +308,8 @@ export default inject(
|
||||
getPrimaryLink: filesStore.getPrimaryLink,
|
||||
setExternalLink,
|
||||
withPublicRoomBlock,
|
||||
fetchMembers,
|
||||
membersIsLoading,
|
||||
};
|
||||
}
|
||||
)(
|
||||
|
@ -259,7 +259,7 @@ const LinkRow = (props) => {
|
||||
|
||||
export default inject(
|
||||
({ auth, dialogsStore, publicRoomStore, treeFoldersStore }) => {
|
||||
const { selectionParentRoom } = auth.infoPanelStore;
|
||||
const { infoPanelSelection } = auth.infoPanelStore;
|
||||
const { theme } = auth.settingsStore;
|
||||
|
||||
const {
|
||||
@ -274,14 +274,14 @@ export default inject(
|
||||
return {
|
||||
setLinkParams,
|
||||
editExternalLink,
|
||||
roomId: selectionParentRoom.id,
|
||||
roomId: infoPanelSelection.id,
|
||||
setExternalLink,
|
||||
setEditLinkPanelIsVisible,
|
||||
setDeleteLinkDialogVisible,
|
||||
setEmbeddingPanelIsVisible,
|
||||
isArchiveFolder: isArchiveFolderRoot,
|
||||
theme,
|
||||
isPublicRoomType: selectionParentRoom.roomType === RoomsType.PublicRoom,
|
||||
isPublicRoomType: infoPanelSelection.roomType === RoomsType.PublicRoom,
|
||||
};
|
||||
}
|
||||
)(
|
||||
|
@ -2,7 +2,8 @@ import React, { useState, useCallback, useEffect, useRef, memo } from "react";
|
||||
import styled, { useTheme } from "styled-components";
|
||||
import { FixedSizeList as List, areEqual } from "react-window";
|
||||
import InfiniteLoader from "react-window-infinite-loader";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
import { RowLoader } from "@docspace/shared/skeletons/selector";
|
||||
|
||||
import { CustomScrollbarsVirtualList } from "@docspace/shared/components/scrollbar";
|
||||
import { isMobile } from "@docspace/shared/utils";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
@ -31,11 +32,7 @@ const Item = memo(({ data, index, style }) => {
|
||||
if (!item) {
|
||||
return (
|
||||
<div style={{ ...style, width: "calc(100% - 20px)", margin: "0 -16px" }}>
|
||||
<Loaders.SelectorRowLoader
|
||||
isMultiSelect={false}
|
||||
isContainer={true}
|
||||
isUser={true}
|
||||
/>
|
||||
<RowLoader isMultiSelect={false} isContainer={true} isUser={true} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,21 +1,15 @@
|
||||
import InfoPanelRoomEmptyScreenSvgUrl from "PUBLIC_DIR/images/empty_screen_corporate.svg?url";
|
||||
import InfoPanelRoomEmptyScreenDarkSvgUrl from "PUBLIC_DIR/images/empty_screen_corporate_dark.svg?url";
|
||||
|
||||
import React, { useEffect } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
|
||||
import { StyledNoItemContainer } from "../../styles/noItem";
|
||||
|
||||
const NoRoomItem = ({ t, theme, setMembersList }) => {
|
||||
const NoRoomItem = ({ t, theme }) => {
|
||||
const imageSrc = theme.isBase
|
||||
? InfoPanelRoomEmptyScreenSvgUrl
|
||||
: InfoPanelRoomEmptyScreenDarkSvgUrl;
|
||||
|
||||
useEffect(() => {
|
||||
setMembersList(null);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<StyledNoItemContainer className="info-panel_gallery-empty-screen">
|
||||
<div className="no-thumbnail-img-wrapper">
|
||||
@ -31,6 +25,5 @@ const NoRoomItem = ({ t, theme, setMembersList }) => {
|
||||
export default inject(({ auth }) => {
|
||||
return {
|
||||
theme: auth.settingsStore.theme,
|
||||
setMembersList: auth.infoPanelStore.setMembersList,
|
||||
};
|
||||
})(observer(NoRoomItem));
|
||||
|
@ -40,7 +40,7 @@ const SeveralItems = ({ isAccounts, theme, selectedItems }) => {
|
||||
};
|
||||
|
||||
export default inject(({ auth }) => {
|
||||
const selectedItems = auth.infoPanelStore.getSelectedItems();
|
||||
const selectedItems = auth.infoPanelStore.infoPanelSelectedItems;
|
||||
|
||||
return {
|
||||
theme: auth.settingsStore.theme,
|
||||
|
@ -21,7 +21,7 @@ const Share = (props) => {
|
||||
const {
|
||||
isRooms,
|
||||
setView,
|
||||
selection,
|
||||
infoPanelSelection,
|
||||
getPrimaryFileLink,
|
||||
getFileLinks,
|
||||
editFileLink,
|
||||
@ -35,14 +35,14 @@ const Share = (props) => {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [loadingLinks, setLoadingLinks] = useState([]);
|
||||
|
||||
const hideSharePanel = isRooms || !selection?.canShare;
|
||||
const hideSharePanel = isRooms || !infoPanelSelection?.canShare;
|
||||
|
||||
useEffect(() => {
|
||||
if (hideSharePanel) {
|
||||
setView("info_details");
|
||||
}
|
||||
fetchLinks();
|
||||
}, [selection]);
|
||||
}, [infoPanelSelection]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchLinks();
|
||||
@ -50,7 +50,7 @@ const Share = (props) => {
|
||||
}, [shareChanged]);
|
||||
|
||||
const fetchLinks = async () => {
|
||||
const res = await getFileLinks(selection.id);
|
||||
const res = await getFileLinks(infoPanelSelection.id);
|
||||
const primaryLink = res.items.filter(
|
||||
(item) => item.sharedTo.primary === true
|
||||
);
|
||||
@ -65,7 +65,7 @@ const Share = (props) => {
|
||||
|
||||
const addGeneralLink = async () => {
|
||||
addLoaderLink(true);
|
||||
const link = await getPrimaryFileLink(selection.id);
|
||||
const link = await getPrimaryFileLink(infoPanelSelection.id);
|
||||
setPrimaryFileLink([link]);
|
||||
copy(link.sharedTo.shareLink);
|
||||
toastr.success(t("SharingPanel:GeneralAccessLinkCopied"));
|
||||
@ -74,7 +74,7 @@ const Share = (props) => {
|
||||
const addAdditionalLinks = async () => {
|
||||
addLoaderLink(false);
|
||||
const newLink = await addFileLink(
|
||||
selection.id,
|
||||
infoPanelSelection.id,
|
||||
ShareAccessRights.ReadOnly,
|
||||
false,
|
||||
false
|
||||
@ -96,7 +96,7 @@ const Share = (props) => {
|
||||
setLoadingLinks([...loadingLinks, link.sharedTo.id]);
|
||||
|
||||
const res = await editFileLink(
|
||||
selection.id,
|
||||
infoPanelSelection.id,
|
||||
link.sharedTo.id,
|
||||
link.access,
|
||||
link.sharedTo.primary,
|
||||
@ -117,7 +117,7 @@ const Share = (props) => {
|
||||
setLoadingLinks([...loadingLinks, link.sharedTo.id]);
|
||||
|
||||
const res = await editFileLink(
|
||||
selection.id,
|
||||
infoPanelSelection.id,
|
||||
link.sharedTo.id,
|
||||
item.access,
|
||||
link.sharedTo.primary,
|
||||
@ -150,7 +150,7 @@ const Share = (props) => {
|
||||
setLoadingLinks([...loadingLinks, link.sharedTo.id]);
|
||||
|
||||
const res = await editFileLink(
|
||||
selection.id,
|
||||
infoPanelSelection.id,
|
||||
link.sharedTo.id,
|
||||
link.access,
|
||||
link.sharedTo.primary,
|
||||
@ -218,7 +218,9 @@ const Share = (props) => {
|
||||
changeShareOption={changeShareOption}
|
||||
changeAccessOption={changeAccessOption}
|
||||
changeExpirationOption={changeExpirationOption}
|
||||
availableExternalRights={selection.availableExternalRights}
|
||||
availableExternalRights={
|
||||
infoPanelSelection.availableExternalRights
|
||||
}
|
||||
loadingLinks={loadingLinks}
|
||||
/>
|
||||
</StyledLinks>
|
||||
@ -242,7 +244,9 @@ const Share = (props) => {
|
||||
changeShareOption={changeShareOption}
|
||||
changeAccessOption={changeAccessOption}
|
||||
changeExpirationOption={changeExpirationOption}
|
||||
availableExternalRights={selection.availableExternalRights}
|
||||
availableExternalRights={
|
||||
infoPanelSelection.availableExternalRights
|
||||
}
|
||||
loadingLinks={loadingLinks}
|
||||
/>
|
||||
</StyledLinks>
|
||||
|
@ -43,12 +43,12 @@ const InfoPanelHeaderContent = (props) => {
|
||||
const isAccounts = getIsAccounts();
|
||||
const isTrash = getIsTrash();
|
||||
|
||||
const isNoItem =
|
||||
selection?.isSelectedFolder && selection?.id === selection?.rootFolderId;
|
||||
const isRoot =
|
||||
selection?.isFolder && selection?.id === selection?.rootFolderId;
|
||||
const isSeveralItems = selection && Array.isArray(selection);
|
||||
|
||||
const withSubmenu =
|
||||
!isNoItem && !isSeveralItems && !isGallery && !isAccounts && !isTrash;
|
||||
!isRoot && !isSeveralItems && !isGallery && !isAccounts && !isTrash;
|
||||
|
||||
useEffect(() => {
|
||||
checkWidth();
|
||||
@ -94,9 +94,6 @@ const InfoPanelHeaderContent = (props) => {
|
||||
content: null,
|
||||
},
|
||||
];
|
||||
// const selectionRoomRights = selectionParentRoom
|
||||
// ? selectionParentRoom.security?.Read
|
||||
// : selection?.security?.Read;
|
||||
|
||||
const roomsSubmenu = [...submenuData];
|
||||
|
||||
@ -211,7 +208,7 @@ export default inject(({ auth, treeFoldersStore, pluginStore }) => {
|
||||
const { infoPanelItemsList } = pluginStore;
|
||||
|
||||
const {
|
||||
selection,
|
||||
infoPanelSelection,
|
||||
setIsVisible,
|
||||
roomsView,
|
||||
fileView,
|
||||
@ -222,7 +219,6 @@ export default inject(({ auth, treeFoldersStore, pluginStore }) => {
|
||||
getIsAccounts,
|
||||
getIsTrash,
|
||||
resetView,
|
||||
//selectionParentRoom,
|
||||
} = auth.infoPanelStore;
|
||||
|
||||
const { myRoomsId, archiveRoomsId } = treeFoldersStore;
|
||||
@ -230,7 +226,7 @@ export default inject(({ auth, treeFoldersStore, pluginStore }) => {
|
||||
const { enablePlugins } = auth.settingsStore;
|
||||
|
||||
return {
|
||||
selection,
|
||||
selection: infoPanelSelection,
|
||||
setIsVisible,
|
||||
roomsView,
|
||||
fileView,
|
||||
@ -247,10 +243,6 @@ export default inject(({ auth, treeFoldersStore, pluginStore }) => {
|
||||
archiveRoomsId,
|
||||
|
||||
enablePlugins,
|
||||
|
||||
// rootFolderType,
|
||||
|
||||
//selectionParentRoom,
|
||||
};
|
||||
})(
|
||||
withTranslation(["Common", "InfoPanel"])(
|
||||
|
@ -5,6 +5,8 @@ import { useNavigate, useLocation } from "react-router-dom";
|
||||
import queryString from "query-string";
|
||||
import MediaViewer from "@docspace/common/components/MediaViewer";
|
||||
import { PluginFileType } from "SRC_DIR/helpers/plugins/constants";
|
||||
import { MEDIA_VIEW_URL } from "@docspace/shared/constants";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
|
||||
const FilesMediaViewer = (props) => {
|
||||
const {
|
||||
@ -106,7 +108,8 @@ const FilesMediaViewer = (props) => {
|
||||
};
|
||||
|
||||
const onChangeUrl = (id) => {
|
||||
const url = "/products/files/#preview/" + id;
|
||||
const url = combineUrl(MEDIA_VIEW_URL, id);
|
||||
|
||||
setCurrentId(id);
|
||||
navigate(url);
|
||||
};
|
||||
|
@ -242,8 +242,6 @@ class FilesTableHeader extends React.Component {
|
||||
!splitColumns ||
|
||||
isFrame;
|
||||
|
||||
const tableColumns = columns.map((c) => c.enable && c.key);
|
||||
|
||||
if (isFrame && frameTableColumns) {
|
||||
const frameTableArray = frameTableColumns.split(",");
|
||||
|
||||
@ -253,6 +251,8 @@ class FilesTableHeader extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
const tableColumns = columns.map((c) => c.enable && c.key);
|
||||
|
||||
this.setTableColumns(tableColumns);
|
||||
if (fromUpdate) {
|
||||
this.setState({
|
||||
|
@ -8,7 +8,7 @@ import result from "lodash/result";
|
||||
|
||||
import { isTablet, isMobile } from "@docspace/shared/utils";
|
||||
import { RoomsTypeValues } from "@docspace/shared/utils/common";
|
||||
import FilterInput from "@docspace/common/components/FilterInput";
|
||||
import FilterInput from "@docspace/shared/components/filter";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
import { withLayoutSize } from "@docspace/shared/HOC/withLayoutSize";
|
||||
import { getUser } from "@docspace/shared/api/people";
|
||||
@ -43,6 +43,7 @@ import ViewRowsReactSvgUrl from "PUBLIC_DIR/images/view-rows.react.svg?url";
|
||||
import ViewTilesReactSvgUrl from "PUBLIC_DIR/images/view-tiles.react.svg?url";
|
||||
|
||||
import { getRoomInfo } from "@docspace/shared/api/rooms";
|
||||
import { FilterLoader } from "@docspace/shared/skeletons/filter";
|
||||
|
||||
const getAccountLoginType = (filterValues) => {
|
||||
const accountLoginType = result(
|
||||
@ -383,7 +384,7 @@ const SectionFilterContent = ({
|
||||
|
||||
newFilter.withSubfolders =
|
||||
withSubfolders === FilterKeys.excludeSubfolders ? null : "true";
|
||||
console.log(data);
|
||||
|
||||
newFilter.searchInContent = withContent === "true" ? "true" : null;
|
||||
|
||||
const path = location.pathname.split("/filter")[0];
|
||||
@ -1201,7 +1202,7 @@ const SectionFilterContent = ({
|
||||
isHeader: true,
|
||||
isLast: isLastTypeOptionsRooms,
|
||||
},
|
||||
...Object.values(RoomsTypeValues).map((roomType) => {
|
||||
...RoomsTypeValues.map((roomType) => {
|
||||
switch (roomType) {
|
||||
case RoomsType.FillingFormsRoom:
|
||||
return {
|
||||
@ -2031,11 +2032,10 @@ const SectionFilterContent = ({
|
||||
}
|
||||
};
|
||||
|
||||
if (showFilterLoader) return <Loaders.Filter />;
|
||||
if (showFilterLoader) return <FilterLoader />;
|
||||
|
||||
return (
|
||||
<FilterInput
|
||||
t={t}
|
||||
onFilter={onFilter}
|
||||
getFilterData={getFilterData}
|
||||
getSelectedFilterData={getSelectedFilterData}
|
||||
@ -2064,6 +2064,7 @@ const SectionFilterContent = ({
|
||||
setClearSearch={setClearSearch}
|
||||
onSortButtonClick={onSortButtonClick}
|
||||
currentDeviceType={currentDeviceType}
|
||||
userId={userId}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -930,6 +930,7 @@ const SectionHeaderContent = (props) => {
|
||||
: "",
|
||||
};
|
||||
|
||||
setSelected("none");
|
||||
setIsLoading(true);
|
||||
|
||||
window.DocSpace.navigate(`${path}?${filter.toUrlParams()}`, { state });
|
||||
|
@ -6,7 +6,7 @@ import { withTranslation } from "react-i18next";
|
||||
|
||||
import { showLoader, hideLoader } from "@docspace/shared/utils/common";
|
||||
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import SectionWrapper from "SRC_DIR/components/Section";
|
||||
import DragTooltip from "SRC_DIR/components/DragTooltip";
|
||||
|
||||
|
@ -4,6 +4,7 @@ import { Paging } from "@docspace/shared/components/paging";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { FilterLoader } from "@docspace/shared/skeletons/filter";
|
||||
|
||||
const SectionPagingContent = ({
|
||||
fetchPeople,
|
||||
@ -147,7 +148,7 @@ const SectionPagingContent = ({
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<Loaders.Filter />
|
||||
<FilterLoader />
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { useEffect } from "react";
|
||||
import Article from "@docspace/common/components/Article";
|
||||
import Article from "@docspace/shared/components/article";
|
||||
import { ArticleHeaderContent, ArticleBodyContent } from "./Article";
|
||||
import { SectionHeaderContent, SectionPagingContent } from "./Section";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import withLoading from "SRC_DIR/HOCs/withLoading";
|
||||
|
||||
import SectionWrapper from "SRC_DIR/components/Section";
|
||||
@ -11,10 +11,11 @@ import SectionWrapper from "SRC_DIR/components/Section";
|
||||
import { useParams } from "react-router-dom";
|
||||
import HistoryHeader from "../categories/developer-tools/Webhooks/WebhookHistory/sub-components/HistoryHeader";
|
||||
import DetailsNavigationHeader from "../categories/developer-tools/Webhooks/WebhookEventDetails/sub-components/DetailsNavigationHeader";
|
||||
import ArticleWrapper from "SRC_DIR/components/ArticleWrapper";
|
||||
|
||||
const ArticleSettings = React.memo(({ showArticleLoader }) => {
|
||||
return (
|
||||
<Article showArticleLoader={showArticleLoader}>
|
||||
<ArticleWrapper showArticleLoader={showArticleLoader}>
|
||||
<Article.Header>
|
||||
<ArticleHeaderContent />
|
||||
</Article.Header>
|
||||
@ -22,7 +23,7 @@ const ArticleSettings = React.memo(({ showArticleLoader }) => {
|
||||
<Article.Body>
|
||||
<ArticleBodyContent />
|
||||
</Article.Body>
|
||||
</Article>
|
||||
</ArticleWrapper>
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -14,8 +14,6 @@ import { setDocumentTitle } from "SRC_DIR/helpers/utils";
|
||||
import { DropDownItem } from "@docspace/shared/components/drop-down-item";
|
||||
import { DropDown } from "@docspace/shared/components/drop-down";
|
||||
|
||||
import HexColorPickerComponent from "./sub-components/hexColorPicker";
|
||||
|
||||
import Loader from "./sub-components/loaderAppearance";
|
||||
|
||||
import { StyledComponent, StyledTheme } from "./Appearance/StyledApperance.js";
|
||||
@ -25,6 +23,8 @@ import hexToRgba from "hex-to-rgba";
|
||||
import { isMobile } from "@docspace/shared/utils";
|
||||
import { DeviceType } from "@docspace/shared/enums";
|
||||
|
||||
import { ColorPicker } from "@docspace/shared/components/color-picker";
|
||||
|
||||
const Appearance = (props) => {
|
||||
const {
|
||||
appearanceTheme,
|
||||
@ -594,11 +594,13 @@ const Appearance = (props) => {
|
||||
clickOutsideAction={onCloseHexColorPickerButtons}
|
||||
>
|
||||
<DropDownItem className="drop-down-item-hex">
|
||||
<HexColorPickerComponent
|
||||
<ColorPicker
|
||||
id="buttons-hex"
|
||||
onCloseHexColorPicker={onCloseHexColorPickerButtons}
|
||||
onAppliedColor={onAppliedColorButtons}
|
||||
onClose={onCloseHexColorPickerButtons}
|
||||
onApply={onAppliedColorButtons}
|
||||
appliedColor={appliedColorButtons}
|
||||
applyButtonLabel={t("Common:ApplyButton")}
|
||||
cancelButtonLabel={t("Common:CancelButton")}
|
||||
/>
|
||||
</DropDownItem>
|
||||
</DropDown>
|
||||
@ -614,11 +616,13 @@ const Appearance = (props) => {
|
||||
clickOutsideAction={onCloseHexColorPickerAccent}
|
||||
>
|
||||
<DropDownItem className="drop-down-item-hex">
|
||||
<HexColorPickerComponent
|
||||
<ColorPicker
|
||||
id="accent-hex"
|
||||
onCloseHexColorPicker={onCloseHexColorPickerAccent}
|
||||
onAppliedColor={onAppliedColorAccent}
|
||||
onClose={onCloseHexColorPickerAccent}
|
||||
onApply={onAppliedColorAccent}
|
||||
appliedColor={appliedColorAccent}
|
||||
applyButtonLabel={t("Common:ApplyButton")}
|
||||
cancelButtonLabel={t("Common:CancelButton")}
|
||||
/>
|
||||
</DropDownItem>
|
||||
</DropDown>
|
||||
|
@ -29,7 +29,12 @@ const AuditContent = ({ sectionWidth, item, isSettingNotPaid, locale }) => {
|
||||
isSettingNotPaid={isSettingNotPaid}
|
||||
>
|
||||
<div className="user-container-wrapper">
|
||||
<Text fontWeight={600} fontSize="14px" isTextOverflow={true}>
|
||||
<Text
|
||||
fontWeight={600}
|
||||
fontSize="14px"
|
||||
isTextOverflow={true}
|
||||
className="settings_unavailable"
|
||||
>
|
||||
{item.user}
|
||||
</Text>
|
||||
</div>
|
||||
|
@ -25,9 +25,7 @@ const AuditTrail = (props) => {
|
||||
useEffect(() => {
|
||||
setDocumentTitle(t("AuditTrailNav"));
|
||||
|
||||
if (isAuditAvailable) {
|
||||
getAuditTrail();
|
||||
}
|
||||
getAuditTrail();
|
||||
|
||||
getLifetimeAuditSettings();
|
||||
}, []);
|
||||
@ -73,7 +71,7 @@ const AuditTrail = (props) => {
|
||||
securityLifetime={securityLifetime}
|
||||
lifetime={securityLifetime.auditTrailLifeTime}
|
||||
setLifetimeAuditSettings={setLifetimeAuditSettings}
|
||||
content={isAuditAvailable && getContent()}
|
||||
content={getContent()}
|
||||
downloadReport={t("DownloadReportBtnText")}
|
||||
downloadReportDescription={t("DownloadReportDescription")}
|
||||
getReport={getAuditTrailReport}
|
||||
|
@ -25,7 +25,12 @@ const HistoryContent = ({ sectionWidth, item, locale }) => {
|
||||
sectionWidth={sectionWidth}
|
||||
>
|
||||
<div className="user-container-wrapper">
|
||||
<Text fontWeight={600} fontSize="14px" isTextOverflow={true}>
|
||||
<Text
|
||||
fontWeight={600}
|
||||
fontSize="14px"
|
||||
isTextOverflow={true}
|
||||
className="settings_unavailable"
|
||||
>
|
||||
{item.user}
|
||||
</Text>
|
||||
</div>
|
||||
@ -36,10 +41,16 @@ const HistoryContent = ({ sectionWidth, item, locale }) => {
|
||||
fontWeight={600}
|
||||
truncate={true}
|
||||
color="#A3A9AE"
|
||||
className="settings_unavailable"
|
||||
>
|
||||
{dateStr}
|
||||
</Text>
|
||||
<Text fontSize="12px" as="div" fontWeight={600}>
|
||||
<Text
|
||||
fontSize="12px"
|
||||
as="div"
|
||||
fontWeight={600}
|
||||
className="settings_unavailable"
|
||||
>
|
||||
{item.action}
|
||||
</Text>
|
||||
</StyledRowContent>
|
||||
|
@ -46,6 +46,7 @@ const PeopleTableRow = (props) => {
|
||||
fontSize="12px"
|
||||
fontWeight={600}
|
||||
truncate
|
||||
className="settings_unavailable"
|
||||
>
|
||||
{item.user}
|
||||
</Text>
|
||||
@ -57,6 +58,7 @@ const PeopleTableRow = (props) => {
|
||||
fontSize="12px"
|
||||
fontWeight={600}
|
||||
truncate
|
||||
className="settings_unavailable"
|
||||
>
|
||||
{dateStr}
|
||||
</Text>
|
||||
@ -70,6 +72,7 @@ const PeopleTableRow = (props) => {
|
||||
fontWeight={600}
|
||||
onClick={onEmailClick}
|
||||
isTextOverflow
|
||||
className="settings_unavailable"
|
||||
>
|
||||
{item.action}
|
||||
</Text>
|
||||
|
@ -25,9 +25,7 @@ const LoginHistory = (props) => {
|
||||
useEffect(() => {
|
||||
setDocumentTitle(t("LoginHistoryTitle"));
|
||||
|
||||
if (isAuditAvailable) {
|
||||
getLoginHistory();
|
||||
}
|
||||
getLoginHistory();
|
||||
|
||||
getLifetimeAuditSettings();
|
||||
}, []);
|
||||
@ -73,7 +71,7 @@ const LoginHistory = (props) => {
|
||||
lifetime={securityLifetime.loginHistoryLifeTime}
|
||||
securityLifetime={securityLifetime}
|
||||
setLifetimeAuditSettings={setLifetimeAuditSettings}
|
||||
content={isAuditAvailable && getContent()}
|
||||
content={getContent()}
|
||||
downloadReport={t("DownloadReportBtnText")}
|
||||
downloadReportDescription={t("DownloadReportDescription")}
|
||||
getReport={getLoginHistoryReport}
|
||||
|
@ -5,7 +5,7 @@ import { Text } from "@docspace/shared/components/text";
|
||||
import { Link } from "@docspace/shared/components/link";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { Loader } from "@docspace/shared/components/loader";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import SectionWrapper from "SRC_DIR/components/Section";
|
||||
import { mobile, tablet } from "@docspace/shared/utils";
|
||||
import { I18nextProvider, Trans, withTranslation } from "react-i18next";
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import SectionWrapper from "SRC_DIR/components/Section";
|
||||
import { SectionHeaderContent, SectionBodyContent } from "./Section";
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { useLocation, Outlet } from "react-router-dom";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import SectionHeaderContent from "../Home/Section/Header";
|
||||
import SectionFilterContent from "../Home/Section/Filter";
|
||||
import FilesPanels from "../../components/FilesPanels";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { observer, inject } from "mobx-react";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import { Loader } from "@docspace/shared/components/loader";
|
||||
import { ValidationStatus } from "../../helpers/constants";
|
||||
import SectionWrapper from "SRC_DIR/components/Section";
|
||||
|
@ -4,7 +4,7 @@ import { useParams } from "react-router-dom";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { ColorTheme, ThemeId } from "@docspace/shared/components/color-theme";
|
||||
import AppLoader from "@docspace/common/components/AppLoader";
|
||||
import RoomSelector from "../../components/RoomSelector";
|
||||
import RoomSelector from "@docspace/shared/selectors/Room";
|
||||
import FilesSelector from "../../components/FilesSelector";
|
||||
import {
|
||||
frameCallEvent,
|
||||
@ -27,7 +27,7 @@ const Sdk = ({
|
||||
user,
|
||||
updateProfileCulture,
|
||||
getRoomsIcon,
|
||||
getPrimaryLink,
|
||||
fetchExternalLinks,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
window.addEventListener("message", handleMessage, false);
|
||||
@ -128,9 +128,23 @@ const Sdk = ({
|
||||
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;
|
||||
if (
|
||||
data[0].roomType === RoomsType.PublicRoom ||
|
||||
(data[0].roomType === RoomsType.CustomRoom && data[0].shared)
|
||||
) {
|
||||
const links = await fetchExternalLinks(data[0].id);
|
||||
|
||||
const requestTokens = links.map((link) => {
|
||||
const { id, title, requestToken } = link.sharedTo;
|
||||
|
||||
return {
|
||||
id,
|
||||
title,
|
||||
requestToken,
|
||||
};
|
||||
});
|
||||
|
||||
data[0].requestTokens = requestTokens;
|
||||
}
|
||||
|
||||
frameCallEvent({ event: "onSelectCallback", data });
|
||||
@ -193,28 +207,30 @@ const Sdk = ({
|
||||
return component;
|
||||
};
|
||||
|
||||
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, getRoomsIcon } = settingsStore;
|
||||
const { getPrimaryLink } = filesStore;
|
||||
export default inject(
|
||||
({ auth, settingsStore, peopleStore, publicRoomStore }) => {
|
||||
const { login, logout, userStore } = auth;
|
||||
const { theme, setFrameConfig, frameConfig, getSettings, isLoaded } =
|
||||
auth.settingsStore;
|
||||
const { loadCurrentUser, user } = userStore;
|
||||
const { updateProfileCulture } = peopleStore.targetUserStore;
|
||||
const { getIcon, getRoomsIcon } = settingsStore;
|
||||
const { fetchExternalLinks } = publicRoomStore;
|
||||
|
||||
return {
|
||||
theme,
|
||||
setFrameConfig,
|
||||
frameConfig,
|
||||
login,
|
||||
logout,
|
||||
getSettings,
|
||||
loadCurrentUser,
|
||||
getIcon,
|
||||
getRoomsIcon,
|
||||
isLoaded,
|
||||
updateProfileCulture,
|
||||
user,
|
||||
getPrimaryLink,
|
||||
};
|
||||
})(observer(Sdk));
|
||||
return {
|
||||
theme,
|
||||
setFrameConfig,
|
||||
frameConfig,
|
||||
login,
|
||||
logout,
|
||||
getSettings,
|
||||
loadCurrentUser,
|
||||
getIcon,
|
||||
getRoomsIcon,
|
||||
isLoaded,
|
||||
updateProfileCulture,
|
||||
user,
|
||||
fetchExternalLinks,
|
||||
};
|
||||
}
|
||||
)(observer(Sdk));
|
||||
|
@ -2,7 +2,7 @@ import { useState, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { getObjectByLocation } from "@docspace/shared/utils/common";
|
||||
import ErrorContainer from "@docspace/common/components/ErrorContainer";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import { RectangleSkeleton } from "@docspace/shared/skeletons";
|
||||
import { setDocumentTitle } from "SRC_DIR/helpers/utils";
|
||||
import SectionWrapper from "SRC_DIR/components/Section";
|
||||
|
@ -18,8 +18,12 @@ import { inject, observer } from "mobx-react";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { Encoder } from "@docspace/shared/utils/encoder";
|
||||
import { Base } from "@docspace/shared/themes";
|
||||
import { MAX_FILE_COMMENT_LENGTH } from "@docspace/shared/constants";
|
||||
import {
|
||||
MAX_FILE_COMMENT_LENGTH,
|
||||
MEDIA_VIEW_URL,
|
||||
} from "@docspace/shared/constants";
|
||||
import moment from "moment-timezone";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
|
||||
const StyledExternalLinkIcon = styled(ExternalLinkIcon)`
|
||||
${commonIconsStyles}
|
||||
@ -110,7 +114,7 @@ const VersionRow = (props) => {
|
||||
|
||||
if (MediaView || ImageView) {
|
||||
return window.open(
|
||||
"/products/files/#preview/" + info.id,
|
||||
combineUrl(MEDIA_VIEW_URL, info.id),
|
||||
window.DocSpaceConfig?.editor?.openOnNewPage ? "_blank" : "_self"
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Section from "@docspace/shared/components/section";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
import { withTranslation } from "react-i18next";
|
||||
|
||||
|
@ -26,8 +26,8 @@ const Wizard = loadable(() => import("../pages/Wizard"));
|
||||
const PreparationPortal = loadable(() => import("../pages/PreparationPortal"));
|
||||
const PortalUnavailable = loadable(() => import("../pages/PortalUnavailable"));
|
||||
const ErrorUnavailable = loadable(() => import("../pages/Errors/Unavailable"));
|
||||
const AccessRestricted = loadable(() =>
|
||||
import("../pages/Errors/AccessRestricted")
|
||||
const AccessRestricted = loadable(
|
||||
() => import("../pages/Errors/AccessRestricted")
|
||||
);
|
||||
|
||||
const Error401 = loadable(() => import("client/Error401"));
|
||||
@ -169,7 +169,7 @@ const ClientRoutes = [
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "products/files",
|
||||
path: "media/view/:id",
|
||||
element: (
|
||||
<PrivateRoute>
|
||||
<FilesView />
|
||||
|
@ -285,7 +285,7 @@ class ContextOptionsStore {
|
||||
|
||||
lockFile = (item, t) => {
|
||||
const { id, locked } = item;
|
||||
const { setSelection: setInfoPanelSelection } =
|
||||
const { setInfoPanelSelection: setInfoPanelSelection } =
|
||||
this.authStore.infoPanelStore;
|
||||
|
||||
this.filesActionsStore
|
||||
@ -620,10 +620,8 @@ class ContextOptionsStore {
|
||||
};
|
||||
|
||||
onShowInfoPanel = (item, view) => {
|
||||
const { setSelection, setIsVisible, setView } =
|
||||
this.authStore.infoPanelStore;
|
||||
const { setIsVisible, setView } = this.authStore.infoPanelStore;
|
||||
|
||||
setSelection(item);
|
||||
setIsVisible(true);
|
||||
view && setView(view);
|
||||
};
|
||||
@ -1166,6 +1164,8 @@ class ContextOptionsStore {
|
||||
) === -1;
|
||||
}
|
||||
|
||||
const isArchive = item.rootFolderType === FolderType.Archive;
|
||||
|
||||
const optionsModel = [
|
||||
{
|
||||
id: "option_select",
|
||||
@ -1286,9 +1286,7 @@ class ContextOptionsStore {
|
||||
icon: InvitationLinkReactSvgUrl,
|
||||
onClick: () => this.onCopyLink(item, t),
|
||||
disabled:
|
||||
(isPublicRoomType &&
|
||||
item.canCopyPublicLink &&
|
||||
!this.treeFoldersStore.isArchiveFolder) ||
|
||||
(isPublicRoomType && item.canCopyPublicLink && !isArchive) ||
|
||||
this.publicRoomStore.isPublicRoom,
|
||||
},
|
||||
{
|
||||
@ -1298,7 +1296,7 @@ class ContextOptionsStore {
|
||||
icon: TabletLinkReactSvgUrl,
|
||||
disabled:
|
||||
this.publicRoomStore.isPublicRoom ||
|
||||
this.treeFoldersStore.isArchiveFolder ||
|
||||
isArchive ||
|
||||
!item.canCopyPublicLink ||
|
||||
!isPublicRoomType,
|
||||
onClick: async () => {
|
||||
@ -1482,9 +1480,7 @@ class ContextOptionsStore {
|
||||
icon: LeaveRoomSvgUrl,
|
||||
onClick: this.onLeaveRoom,
|
||||
disabled:
|
||||
this.treeFoldersStore.isArchiveFolder ||
|
||||
!item.inRoom ||
|
||||
this.publicRoomStore.isPublicRoom,
|
||||
isArchive || !item.inRoom || this.publicRoomStore.isPublicRoom,
|
||||
},
|
||||
{
|
||||
id: "option_unarchive-room",
|
||||
|
@ -131,7 +131,7 @@ class DialogsStore {
|
||||
visible &&
|
||||
!this.filesStore.hasSelection &&
|
||||
!this.filesStore.hasBufferSelection &&
|
||||
!this.authStore.infoPanelStore.selection
|
||||
!this.authStore.infoPanelStore.infoPanelSelection
|
||||
)
|
||||
return;
|
||||
|
||||
@ -160,7 +160,7 @@ class DialogsStore {
|
||||
visible &&
|
||||
!this.filesStore.hasSelection &&
|
||||
!this.filesStore.hasBufferSelection &&
|
||||
!this.authStore.infoPanelStore.selection
|
||||
!this.authStore.infoPanelStore.infoPanelSelection
|
||||
) {
|
||||
console.log("No files selected");
|
||||
return;
|
||||
|
@ -55,6 +55,7 @@ import {
|
||||
getCategoryTypeByFolderType,
|
||||
getCategoryUrl,
|
||||
} from "SRC_DIR/helpers/utils";
|
||||
import { MEDIA_VIEW_URL } from "@docspace/shared/constants";
|
||||
|
||||
class FilesActionStore {
|
||||
authStore;
|
||||
@ -289,8 +290,8 @@ class FilesActionStore {
|
||||
let selection = newSelection
|
||||
? newSelection
|
||||
: this.filesStore.selection.length
|
||||
? this.filesStore.selection
|
||||
: [bufferSelection];
|
||||
? this.filesStore.selection
|
||||
: [bufferSelection];
|
||||
|
||||
selection = selection.filter((item) => item.security.Delete);
|
||||
|
||||
@ -996,7 +997,8 @@ class FilesActionStore {
|
||||
setPinAction = (action, id, t) => {
|
||||
const { pinRoom, unpinRoom, updateRoomPin, setSelected } = this.filesStore;
|
||||
|
||||
const { selection, setSelection } = this.authStore.infoPanelStore;
|
||||
const { infoPanelSelection, setInfoPanelSelection } =
|
||||
this.authStore.infoPanelStore;
|
||||
|
||||
const items = Array.isArray(id) ? id : [id];
|
||||
|
||||
@ -1013,8 +1015,8 @@ class FilesActionStore {
|
||||
return Promise.all(actions)
|
||||
.then(() => {
|
||||
this.updateCurrentFolder(null, items, null, operationId);
|
||||
if (selection) {
|
||||
setSelection({ ...selection, pinned: true });
|
||||
if (infoPanelSelection) {
|
||||
setInfoPanelSelection({ ...infoPanelSelection, pinned: true });
|
||||
}
|
||||
})
|
||||
.then(() => setSelected("close"))
|
||||
@ -1035,7 +1037,7 @@ class FilesActionStore {
|
||||
.then(() => {
|
||||
this.updateCurrentFolder(null, items, null, operationId);
|
||||
if (selection) {
|
||||
setSelection({ ...selection, pinned: false });
|
||||
setInfoPanelSelection({ ...selection, pinned: false });
|
||||
}
|
||||
})
|
||||
.then(() => setSelected("close"))
|
||||
@ -1731,9 +1733,10 @@ class FilesActionStore {
|
||||
|
||||
onShowInfoPanel = () => {
|
||||
const { selection } = this.filesStore;
|
||||
const { setSelection, setIsVisible } = this.authStore.infoPanelStore;
|
||||
const { setInfoPanelSelection, setIsVisible } =
|
||||
this.authStore.infoPanelStore;
|
||||
|
||||
setSelection([selection]);
|
||||
setInfoPanelSelection([selection]);
|
||||
setIsVisible(true);
|
||||
};
|
||||
|
||||
@ -2200,7 +2203,7 @@ class FilesActionStore {
|
||||
);
|
||||
setMediaViewerData({ visible: true, id });
|
||||
|
||||
const url = "/products/files/#preview/" + id;
|
||||
const url = combineUrl(MEDIA_VIEW_URL, id);
|
||||
|
||||
if (this.publicRoomStore.isPublicRoom) return;
|
||||
|
||||
@ -2230,7 +2233,9 @@ class FilesActionStore {
|
||||
onClickBack = () => {
|
||||
const { roomType, ...rest } = this.selectedFolderStore;
|
||||
const { setSelectedNode } = this.treeFoldersStore;
|
||||
const { clearFiles } = this.filesStore;
|
||||
const { clearFiles, setBufferSelection } = this.filesStore;
|
||||
|
||||
setBufferSelection(null);
|
||||
|
||||
const categoryType = getCategoryType(window.DocSpace.location);
|
||||
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
ShareAccessRights,
|
||||
} from "@docspace/shared/enums";
|
||||
|
||||
import { RoomsTypeValues } from "@docspace/shared/utils";
|
||||
import { RoomsTypes } from "@docspace/shared/utils";
|
||||
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
import { updateTempContent } from "@docspace/shared/utils/common";
|
||||
@ -219,7 +219,7 @@ class FilesStore {
|
||||
} else if (opt.cmd === "delete") {
|
||||
this.selectedFolderStore[opt.type + "sCount"]--;
|
||||
}
|
||||
this.authStore.infoPanelStore.reloadSelection();
|
||||
// this.authStore.infoPanelStore.updateInfoPanelSelection();
|
||||
});
|
||||
}
|
||||
|
||||
@ -1455,9 +1455,12 @@ class FilesStore {
|
||||
// Clear all selections
|
||||
this.setSelected("close");
|
||||
|
||||
// Restore not processed
|
||||
tempSelection.length && this.setSelection(tempSelection);
|
||||
tempBuffer && this.setBufferSelection(tempBuffer);
|
||||
// TODO: see bug 63479
|
||||
if (this.selectedFolderStore?.id === folderId) {
|
||||
// Restore not processed
|
||||
tempSelection.length && this.setSelection(tempSelection);
|
||||
tempBuffer && this.setBufferSelection(tempBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1498,6 +1501,9 @@ class FilesStore {
|
||||
canCopyPublicLink =
|
||||
room.access === ShareAccessRights.RoomManager ||
|
||||
room.access === ShareAccessRights.None;
|
||||
|
||||
room.canCopyPublicLink = canCopyPublicLink;
|
||||
this.authStore.infoPanelStore.setInfoPanelRoom(room);
|
||||
}
|
||||
|
||||
const { mute } = room;
|
||||
@ -1712,6 +1718,7 @@ class FilesStore {
|
||||
}
|
||||
}
|
||||
|
||||
this.authStore.infoPanelStore.setInfoPanelRoom(null);
|
||||
this.selectedFolderStore.setSelectedFolder({
|
||||
folders: data.folders,
|
||||
...data.current,
|
||||
@ -2952,7 +2959,7 @@ class FilesStore {
|
||||
const url = getCategoryUrl(this.categoryType, id);
|
||||
|
||||
if (canOpenPlayer) {
|
||||
return combineUrl(proxyURL, config.homepage, `${url}/#preview/${id}`);
|
||||
return combineUrl(proxyURL, config.homepage, url, id);
|
||||
}
|
||||
|
||||
if (isFolder) {
|
||||
@ -3227,8 +3234,8 @@ class FilesStore {
|
||||
|
||||
if (this.folders.length) {
|
||||
for (const item of this.folders) {
|
||||
if (item.roomType && RoomsTypeValues[item.roomType]) {
|
||||
cbMenu.push(`room-${RoomsTypeValues[item.roomType]}`);
|
||||
if (item.roomType && RoomsTypes[item.roomType]) {
|
||||
cbMenu.push(`room-${RoomsTypes[item.roomType]}`);
|
||||
} else {
|
||||
cbMenu.push(FilterType.FoldersOnly);
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import {
|
||||
isVideo,
|
||||
} from "@docspace/common/components/MediaViewer/helpers";
|
||||
import { thumbnailStatuses } from "SRC_DIR/helpers/filesConstants";
|
||||
import { MEDIA_VIEW_URL } from "@docspace/shared/constants";
|
||||
import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
|
||||
const FirstUrlKey = "isFirstUrl";
|
||||
|
||||
@ -76,7 +78,7 @@ class MediaViewerDataStore {
|
||||
changeUrl = (id) => {
|
||||
if (this.publicRoomStore.isPublicRoom) return;
|
||||
|
||||
const url = "/products/files/#preview/" + id;
|
||||
const url = combineUrl(MEDIA_VIEW_URL, id);
|
||||
window.DocSpace.navigate(url);
|
||||
};
|
||||
|
||||
|
@ -75,7 +75,7 @@ class OformsStore {
|
||||
|
||||
setGallerySelected = (gallerySelected) => {
|
||||
this.gallerySelected = gallerySelected;
|
||||
this.authStore.infoPanelStore.setSelection(gallerySelected);
|
||||
this.authStore.infoPanelStore.setInfoPanelSelection(gallerySelected);
|
||||
};
|
||||
|
||||
setOformLocales = (oformLocales) => (this.oformLocales = oformLocales);
|
||||
|
@ -15,7 +15,7 @@ import { combineUrl } from "@docspace/shared/utils/combineUrl";
|
||||
|
||||
import { isMobile } from "react-device-detect";
|
||||
|
||||
import { ZendeskAPI } from "@docspace/common/components/Zendesk";
|
||||
import { ZendeskAPI } from "@docspace/shared/components/zendesk";
|
||||
import { LIVE_CHAT_LOCAL_STORAGE_KEY } from "@docspace/shared/constants";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import { isDesktop, isTablet } from "@docspace/shared/utils";
|
||||
@ -124,7 +124,7 @@ class ProfileActionsStore {
|
||||
};
|
||||
|
||||
onSpacesClick = () => {
|
||||
this.selectedFolderStore.setSelectedFolder(null);
|
||||
// this.selectedFolderStore.setSelectedFolder(null);
|
||||
window.open(SPACES_URL, "_blank");
|
||||
};
|
||||
|
||||
|
@ -34,6 +34,7 @@ class SelectedFolderStore {
|
||||
security = null;
|
||||
type = null;
|
||||
inRoom = false;
|
||||
isFolder = true;
|
||||
|
||||
constructor(settingsStore) {
|
||||
makeAutoObservable(this);
|
||||
@ -70,6 +71,7 @@ class SelectedFolderStore {
|
||||
rootFolderId: this.rootFolderId,
|
||||
security: this.security,
|
||||
inRoom: this.inRoom,
|
||||
isFolder: this.isFolder,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -36,6 +36,7 @@ class SettingsStore {
|
||||
keepNewFileName = null;
|
||||
thumbnails1280x720 = window.DocSpaceConfig?.thumbnails1280x720 || false;
|
||||
chunkUploadSize = 1024 * 1023; // 1024 * 1023; //~0.999mb
|
||||
chunkUploadCount = 5;
|
||||
|
||||
settingsIsLoaded = false;
|
||||
|
||||
|
@ -31,8 +31,6 @@ import {
|
||||
getCategoryUrl,
|
||||
} from "SRC_DIR/helpers/utils";
|
||||
|
||||
const UPLOAD_LIMIT_AT_ONCE = 5;
|
||||
|
||||
class UploadDataStore {
|
||||
authStore;
|
||||
treeFoldersStore;
|
||||
@ -69,6 +67,7 @@ class UploadDataStore {
|
||||
uploadedFilesSize = 0;
|
||||
|
||||
isParallel = true;
|
||||
asyncUploadObj = {};
|
||||
|
||||
constructor(
|
||||
authStore,
|
||||
@ -147,6 +146,7 @@ class UploadDataStore {
|
||||
|
||||
this.isUploadingAndConversion = false;
|
||||
this.isUploading = false;
|
||||
this.asyncUploadObj = {};
|
||||
};
|
||||
|
||||
removeFileFromList = (id) => {
|
||||
@ -704,6 +704,7 @@ class UploadDataStore {
|
||||
this.files = [];
|
||||
this.filesToConversion = [];
|
||||
this.uploadedFilesSize = 0;
|
||||
this.asyncUploadObj = {};
|
||||
}
|
||||
|
||||
let newFiles = this.files;
|
||||
@ -904,100 +905,95 @@ class UploadDataStore {
|
||||
}
|
||||
};
|
||||
|
||||
uploadFileChunks = async (
|
||||
location,
|
||||
requestsDataArray,
|
||||
checkChunkUpload = (
|
||||
t,
|
||||
res,
|
||||
fileSize,
|
||||
index,
|
||||
indexOfFile,
|
||||
file,
|
||||
path,
|
||||
t
|
||||
length,
|
||||
resolve,
|
||||
reject,
|
||||
isAsyncUpload = false,
|
||||
isFinalize = false
|
||||
) => {
|
||||
const length = requestsDataArray.length;
|
||||
for (let index = 0; index < length; index++) {
|
||||
if (
|
||||
this.uploaded ||
|
||||
!this.files.some((f) => f.file === file) ||
|
||||
this.files[indexOfFile].cancel
|
||||
) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (!res.data.data && res.data.message) {
|
||||
return reject(res.data.message);
|
||||
}
|
||||
|
||||
const res = await uploadFile(location, requestsDataArray[index]);
|
||||
const { uploaded, id: fileId, file: fileInfo } = res.data.data;
|
||||
|
||||
//console.log(`Uploaded chunk ${index}/${length}`, res);
|
||||
let uploadedSize, newPercent;
|
||||
|
||||
//let isLatestFile = indexOfFile === newFilesLength - 1;
|
||||
if (!this.isParallel) {
|
||||
uploadedSize = uploaded
|
||||
? fileSize
|
||||
: index * this.settingsStore.chunkUploadSize;
|
||||
|
||||
if (!res.data.data && res.data.message) {
|
||||
return Promise.reject(res.data.message);
|
||||
}
|
||||
|
||||
const { uploaded, id: fileId, file: fileInfo } = res.data.data;
|
||||
|
||||
let uploadedSize, newPercent;
|
||||
|
||||
if (!this.isParallel) {
|
||||
uploadedSize = uploaded
|
||||
? fileSize
|
||||
: index * this.settingsStore.chunkUploadSize;
|
||||
|
||||
newPercent = this.getNewPercent(uploadedSize, indexOfFile);
|
||||
newPercent = this.getNewPercent(uploadedSize, indexOfFile);
|
||||
} else {
|
||||
if (!uploaded) {
|
||||
uploadedSize =
|
||||
fileSize <= this.settingsStore.chunkUploadSize
|
||||
? fileSize
|
||||
: this.settingsStore.chunkUploadSize;
|
||||
} else {
|
||||
if (!uploaded) {
|
||||
uploadedSize =
|
||||
fileSize <= this.settingsStore.chunkUploadSize
|
||||
? fileSize
|
||||
: this.settingsStore.chunkUploadSize;
|
||||
} else {
|
||||
uploadedSize = fileSize - index * this.settingsStore.chunkUploadSize;
|
||||
}
|
||||
newPercent = this.getFilesPercent(uploadedSize);
|
||||
uploadedSize = isFinalize
|
||||
? 0
|
||||
: fileSize <= this.settingsStore.chunkUploadSize
|
||||
? fileSize
|
||||
: fileSize - index * this.settingsStore.chunkUploadSize;
|
||||
}
|
||||
newPercent = this.getFilesPercent(uploadedSize);
|
||||
}
|
||||
|
||||
const percentCurrentFile = ((index + 1) / length) * 100;
|
||||
if (isAsyncUpload && !uploaded && newPercent >= 100) {
|
||||
newPercent = 99;
|
||||
}
|
||||
|
||||
const fileIndex = this.uploadedFilesHistory.findIndex(
|
||||
(f) => f.uniqueId === this.files[indexOfFile].uniqueId
|
||||
);
|
||||
if (fileIndex > -1)
|
||||
this.uploadedFilesHistory[fileIndex].percent = percentCurrentFile;
|
||||
const percentCurrentFile = ((index + 1) / length) * 100;
|
||||
|
||||
this.primaryProgressDataStore.setPrimaryProgressBarData({
|
||||
icon: "upload",
|
||||
percent: newPercent,
|
||||
visible: true,
|
||||
loadingFile: {
|
||||
uniqueId: this.files[indexOfFile].uniqueId,
|
||||
percent: percentCurrentFile,
|
||||
},
|
||||
const fileIndex = this.uploadedFilesHistory.findIndex(
|
||||
(f) => f.uniqueId === this.files[indexOfFile].uniqueId
|
||||
);
|
||||
if (fileIndex > -1)
|
||||
this.uploadedFilesHistory[fileIndex].percent = percentCurrentFile;
|
||||
|
||||
this.primaryProgressDataStore.setPrimaryProgressBarData({
|
||||
icon: "upload",
|
||||
percent: newPercent,
|
||||
visible: true,
|
||||
loadingFile: {
|
||||
uniqueId: this.files[indexOfFile].uniqueId,
|
||||
percent: percentCurrentFile,
|
||||
},
|
||||
});
|
||||
|
||||
if (uploaded) {
|
||||
runInAction(() => {
|
||||
this.files[indexOfFile].action = "uploaded";
|
||||
this.files[indexOfFile].fileId = fileId;
|
||||
this.files[indexOfFile].fileInfo = fileInfo;
|
||||
|
||||
if (!this.isParallel) this.percent = newPercent;
|
||||
|
||||
if (this.isParallel) {
|
||||
this.currentUploadNumber -= 1;
|
||||
|
||||
const nextFileIndex = this.files.findIndex((f) => !f.inAction);
|
||||
|
||||
if (nextFileIndex !== -1) {
|
||||
this.startSessionFunc(nextFileIndex, t);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (uploaded) {
|
||||
runInAction(() => {
|
||||
this.files[indexOfFile].action = "uploaded";
|
||||
this.files[indexOfFile].fileId = fileId;
|
||||
this.files[indexOfFile].fileInfo = fileInfo;
|
||||
|
||||
if (!this.isParallel) this.percent = newPercent;
|
||||
|
||||
if (this.isParallel) {
|
||||
this.currentUploadNumber -= 1;
|
||||
|
||||
const nextFileIndex = this.files.findIndex((f) => !f.inAction);
|
||||
|
||||
if (nextFileIndex !== -1) {
|
||||
this.startSessionFunc(nextFileIndex, t);
|
||||
}
|
||||
}
|
||||
if (fileInfo.version > 2) {
|
||||
this.filesStore.setHighlightFile({
|
||||
highlightFileId: fileInfo.id,
|
||||
isFileHasExst: !fileInfo.fileExst,
|
||||
});
|
||||
|
||||
if (fileInfo.version > 2) {
|
||||
this.filesStore.setHighlightFile({
|
||||
highlightFileId: fileInfo.id,
|
||||
isFileHasExst: !fileInfo.fileExst,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1005,7 +1001,7 @@ class UploadDataStore {
|
||||
|
||||
const currentFile = this.files[indexOfFile];
|
||||
currentFile.path = path;
|
||||
if (!currentFile) return Promise.resolve();
|
||||
if (!currentFile) return resolve();
|
||||
const { needConvert } = currentFile;
|
||||
|
||||
if (needConvert) {
|
||||
@ -1019,12 +1015,196 @@ class UploadDataStore {
|
||||
} else {
|
||||
this.filesToConversion.push(currentFile);
|
||||
}
|
||||
return Promise.resolve();
|
||||
return resolve();
|
||||
} else {
|
||||
if (currentFile.action === "uploaded") {
|
||||
this.refreshFiles(currentFile);
|
||||
}
|
||||
return Promise.resolve();
|
||||
if (!isAsyncUpload || res.status === 201) {
|
||||
return resolve();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
asyncUpload = async (t, chunkData, resolve, reject) => {
|
||||
const { operationId, file, fileSize, indexOfFile, path, length } =
|
||||
chunkData;
|
||||
|
||||
if (
|
||||
this.uploaded ||
|
||||
!this.files.some((f) => f.file === file) ||
|
||||
this.files[indexOfFile].cancel
|
||||
) {
|
||||
return resolve();
|
||||
}
|
||||
|
||||
if (!this.asyncUploadObj[operationId]) {
|
||||
return reject();
|
||||
}
|
||||
const chunkObjIndex = this.asyncUploadObj[
|
||||
operationId
|
||||
].chunksArray.findIndex((x) => !x.isActive && !x.isFinalize);
|
||||
|
||||
if (chunkObjIndex !== -1) {
|
||||
this.asyncUploadObj[operationId].chunksArray[chunkObjIndex].isActive =
|
||||
true;
|
||||
|
||||
try {
|
||||
const res =
|
||||
await this.asyncUploadObj[operationId].chunksArray[
|
||||
chunkObjIndex
|
||||
].onUpload();
|
||||
|
||||
this.asyncUploadObj[operationId].chunksArray[chunkObjIndex].isFinished =
|
||||
true;
|
||||
|
||||
if (!res.data.data && res.data.message) {
|
||||
delete this.asyncUploadObj[operationId];
|
||||
return reject(res.data.message);
|
||||
} else this.asyncUpload(t, chunkData, resolve, reject);
|
||||
|
||||
const activeLength = this.asyncUploadObj[operationId]
|
||||
? this.asyncUploadObj[operationId].chunksArray.filter(
|
||||
(x) => x.isActive
|
||||
).length - 1
|
||||
: 0;
|
||||
|
||||
this.checkChunkUpload(
|
||||
t,
|
||||
res,
|
||||
fileSize,
|
||||
activeLength,
|
||||
indexOfFile,
|
||||
path,
|
||||
length,
|
||||
resolve,
|
||||
reject,
|
||||
true
|
||||
);
|
||||
|
||||
const finalizeChunk = this.asyncUploadObj[
|
||||
operationId
|
||||
].chunksArray.findIndex((x) => !x.isFinished && !x.isFinalize);
|
||||
|
||||
if (finalizeChunk === -1) {
|
||||
const finalizeChunkIndex = this.asyncUploadObj[
|
||||
operationId
|
||||
].chunksArray.findIndex((x) => x.isFinalize);
|
||||
|
||||
if (finalizeChunkIndex > -1) {
|
||||
const finalizeIndex =
|
||||
this.asyncUploadObj[operationId].chunksArray.length - 1;
|
||||
|
||||
const finalizeRes =
|
||||
await this.asyncUploadObj[operationId].chunksArray[
|
||||
finalizeChunkIndex
|
||||
].onUpload();
|
||||
|
||||
this.checkChunkUpload(
|
||||
t,
|
||||
finalizeRes,
|
||||
fileSize,
|
||||
finalizeIndex,
|
||||
indexOfFile,
|
||||
path,
|
||||
length,
|
||||
resolve,
|
||||
reject,
|
||||
true, // isAsyncUpload
|
||||
true //isFinalize
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
return reject(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
uploadFileChunks = async (
|
||||
location,
|
||||
requestsDataArray,
|
||||
fileSize,
|
||||
indexOfFile,
|
||||
file,
|
||||
path,
|
||||
t,
|
||||
operationId,
|
||||
toFolderId
|
||||
) => {
|
||||
const { chunkUploadCount: asyncChunkUploadCount } = this.settingsStore;
|
||||
const length = requestsDataArray.length;
|
||||
|
||||
const isThirdPartyFolder = typeof toFolderId === "string";
|
||||
if (!isThirdPartyFolder) {
|
||||
const chunksArray = [];
|
||||
for (let index = 0; index < length; index++) {
|
||||
chunksArray.push({
|
||||
isActive: false,
|
||||
isFinished: false,
|
||||
isFinalize: false,
|
||||
onUpload: () =>
|
||||
uploadFile(
|
||||
location + `&chunkNumber=${index + 1}&upload=true`,
|
||||
requestsDataArray[index]
|
||||
),
|
||||
});
|
||||
}
|
||||
chunksArray.push({
|
||||
isActive: false,
|
||||
isFinished: false,
|
||||
isFinalize: true,
|
||||
onUpload: () => uploadFile(location + "&finalize=true"),
|
||||
});
|
||||
|
||||
if (!this.asyncUploadObj[operationId]) {
|
||||
this.asyncUploadObj[operationId] = { chunksArray: [] };
|
||||
this.asyncUploadObj[operationId].chunksArray = chunksArray;
|
||||
}
|
||||
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
let i =
|
||||
length <= asyncChunkUploadCount ? length : asyncChunkUploadCount;
|
||||
while (i !== 0) {
|
||||
this.asyncUpload(
|
||||
t,
|
||||
{ operationId, file, fileSize, indexOfFile, path, length },
|
||||
resolve,
|
||||
reject
|
||||
);
|
||||
i--;
|
||||
}
|
||||
});
|
||||
|
||||
await promise;
|
||||
} else {
|
||||
for (let index = 0; index < length; index++) {
|
||||
if (
|
||||
this.uploaded ||
|
||||
!this.files.some((f) => f.file === file) ||
|
||||
this.files[indexOfFile].cancel
|
||||
) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const res = await uploadFile(location, requestsDataArray[index]);
|
||||
const resolve = (res) => Promise.resolve(res);
|
||||
const reject = (err) => Promise.reject(err);
|
||||
|
||||
this.checkChunkUpload(
|
||||
t,
|
||||
res,
|
||||
fileSize,
|
||||
index,
|
||||
indexOfFile,
|
||||
path,
|
||||
length,
|
||||
resolve,
|
||||
reject
|
||||
);
|
||||
|
||||
//console.log(`Uploaded chunk ${index}/${length}`, res);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -1048,13 +1228,15 @@ class UploadDataStore {
|
||||
// console.log("IS PARALLEL");
|
||||
const notUploadedFiles = this.files.filter((f) => !f.inAction);
|
||||
|
||||
const { chunkUploadCount } = this.settingsStore;
|
||||
|
||||
const countFiles =
|
||||
notUploadedFiles.length >= UPLOAD_LIMIT_AT_ONCE
|
||||
? UPLOAD_LIMIT_AT_ONCE
|
||||
notUploadedFiles.length >= chunkUploadCount
|
||||
? chunkUploadCount
|
||||
: notUploadedFiles.length;
|
||||
|
||||
for (let i = 0; i < countFiles; i++) {
|
||||
if (this.currentUploadNumber <= UPLOAD_LIMIT_AT_ONCE) {
|
||||
if (this.currentUploadNumber <= chunkUploadCount) {
|
||||
const fileIndex = this.files.findIndex(
|
||||
(f) => f.uniqueId === notUploadedFiles[i].uniqueId
|
||||
);
|
||||
@ -1082,6 +1264,7 @@ class UploadDataStore {
|
||||
runInAction(() => {
|
||||
this.uploaded = true;
|
||||
this.isParallel = true;
|
||||
this.asyncUploadObj = {};
|
||||
});
|
||||
const uploadedFiles = this.files.filter((x) => x.action === "uploaded");
|
||||
const totalErrorsCount = sumBy(uploadedFiles, (f) => (f.error ? 1 : 0));
|
||||
@ -1103,6 +1286,7 @@ class UploadDataStore {
|
||||
if (!this.uploaded && this.files.length === 0) {
|
||||
this.uploaded = true;
|
||||
this.isParallel = true;
|
||||
this.asyncUploadObj = {};
|
||||
//setUploadData(uploadData);
|
||||
return;
|
||||
}
|
||||
@ -1145,6 +1329,7 @@ class UploadDataStore {
|
||||
.then((res) => {
|
||||
const location = res.data.location;
|
||||
const path = res.data.path;
|
||||
const operationId = res.data.id;
|
||||
|
||||
const requestsDataArray = [];
|
||||
|
||||
@ -1158,37 +1343,56 @@ class UploadDataStore {
|
||||
chunk++;
|
||||
}
|
||||
|
||||
return { location, requestsDataArray, fileSize, path };
|
||||
})
|
||||
.then(({ location, requestsDataArray, fileSize, path }) => {
|
||||
const fileIndex = this.uploadedFilesHistory.findIndex(
|
||||
(f) => f.uniqueId === this.files[indexOfFile].uniqueId
|
||||
);
|
||||
if (fileIndex > -1)
|
||||
this.uploadedFilesHistory[fileIndex].percent = chunks < 2 ? 50 : 0;
|
||||
|
||||
if (!this.isParallel) {
|
||||
this.primaryProgressDataStore.setPrimaryProgressBarData({
|
||||
icon: "upload",
|
||||
visible: true,
|
||||
percent: this.percent,
|
||||
loadingFile: {
|
||||
uniqueId: this.files[indexOfFile].uniqueId,
|
||||
percent: chunks < 2 ? 50 : 0,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return this.uploadFileChunks(
|
||||
return {
|
||||
location,
|
||||
requestsDataArray,
|
||||
fileSize,
|
||||
indexOfFile,
|
||||
file,
|
||||
path,
|
||||
t
|
||||
);
|
||||
operationId,
|
||||
toFolderId,
|
||||
};
|
||||
})
|
||||
.then(
|
||||
({
|
||||
location,
|
||||
requestsDataArray,
|
||||
fileSize,
|
||||
path,
|
||||
t,
|
||||
operationId,
|
||||
toFolderId,
|
||||
}) => {
|
||||
const fileIndex = this.uploadedFilesHistory.findIndex(
|
||||
(f) => f.uniqueId === this.files[indexOfFile].uniqueId
|
||||
);
|
||||
if (fileIndex > -1)
|
||||
this.uploadedFilesHistory[fileIndex].percent = chunks < 2 ? 50 : 0;
|
||||
|
||||
if (!this.isParallel) {
|
||||
this.primaryProgressDataStore.setPrimaryProgressBarData({
|
||||
icon: "upload",
|
||||
visible: true,
|
||||
percent: this.percent,
|
||||
loadingFile: {
|
||||
uniqueId: this.files[indexOfFile].uniqueId,
|
||||
percent: chunks < 2 ? 50 : 0,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return this.uploadFileChunks(
|
||||
location,
|
||||
requestsDataArray,
|
||||
fileSize,
|
||||
indexOfFile,
|
||||
file,
|
||||
path,
|
||||
t,
|
||||
operationId,
|
||||
toFolderId
|
||||
);
|
||||
}
|
||||
)
|
||||
.catch((error) => {
|
||||
if (this.files[indexOfFile] === undefined) {
|
||||
this.primaryProgressDataStore.setPrimaryProgressBarData({
|
||||
@ -1254,6 +1458,7 @@ class UploadDataStore {
|
||||
runInAction(() => {
|
||||
this.uploaded = true;
|
||||
this.isParallel = true;
|
||||
this.asyncUploadObj = {};
|
||||
});
|
||||
const uploadedFiles = this.files.filter(
|
||||
(x) => x.action === "uploaded"
|
||||
@ -1287,6 +1492,7 @@ class UploadDataStore {
|
||||
this.isParallel = true;
|
||||
this.converted = true;
|
||||
this.uploadedFilesSize = 0;
|
||||
this.asyncUploadObj = {};
|
||||
|
||||
for (let item of this.tempFiles) {
|
||||
const { uploadFiles, folderId, t } = item;
|
||||
@ -1314,6 +1520,7 @@ class UploadDataStore {
|
||||
this.isParallel = true;
|
||||
this.converted = true;
|
||||
this.uploadedFilesSize = 0;
|
||||
this.asyncUploadObj = {};
|
||||
|
||||
const uploadData = {
|
||||
filesSize: 0,
|
||||
|
@ -136,7 +136,8 @@ class UsersStore {
|
||||
throw new Error(e);
|
||||
}
|
||||
|
||||
await this.getUsersList(filter, true);
|
||||
// await this.getUsersList(filter, true); // accounts loader
|
||||
await this.getUsersList(filter); // rooms
|
||||
|
||||
if (users && !this.needResetUserSelection) {
|
||||
this.peopleStore.selectionStore.updateSelection(this.peopleList);
|
||||
|
@ -185,6 +185,7 @@ authStore.infoPanelStore.filesStore = filesStore;
|
||||
authStore.infoPanelStore.peopleStore = peopleStore;
|
||||
authStore.infoPanelStore.selectedFolderStore = selectedFolderStore;
|
||||
authStore.infoPanelStore.treeFoldersStore = treeFoldersStore;
|
||||
authStore.infoPanelStore.publicRoomStore = publicRoomStore;
|
||||
|
||||
const createEditRoomStore = new CreateEditRoomStore(
|
||||
filesStore,
|
||||
|
@ -308,9 +308,6 @@ module.exports = (env, argv) => {
|
||||
"./src/components/FilesSelector/FilesSelectorWrapper",
|
||||
"./SelectFolderDialog":
|
||||
"./src/components/FilesSelector/FilesSelectorWrapper",
|
||||
"./PeopleSelector": "./src/components/PeopleSelector",
|
||||
"./PeopleSelector/UserTooltip":
|
||||
"./src/components/PeopleSelector/sub-components/UserTooltip.js",
|
||||
"./BrandingPage":
|
||||
"./src/pages/PortalSettings/categories/common/branding.js",
|
||||
"./WhiteLabelPage":
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user