Web:EmptyContainer Added rooms empty options

This commit is contained in:
Akmal Isomadinov 2024-08-09 17:17:27 +05:00
parent db10eccbfd
commit f1231446e2
10 changed files with 148 additions and 41 deletions

View File

@ -35,5 +35,10 @@
"UploadFromPortalDescription": "Upload any type files from Documents or Rooms",
"UploadFromPortalTitle": "Upload from {{productName}}",
"UploadPDFFormOptionDescription": "Select a ready PDF form available in {{productName}} and upload it to the room.",
"UserEmptyDescription": "Files and folders uploaded by admins will appeared here."
"UserEmptyDescription": "Files and folders uploaded by admins will appeared here.",
"InviteRootRoomDescription": "Send an invitation to add new members to your {{productName}}",
"MigrationDataTitle": "Migration Data",
"MigrationDataDescription": "Import data to your {{productName}} from ONLYOFFICE Workspace, Google Workspace, or Nextcloud.",
"EmptyRootRoomUserTitle": "There are no rooms here yet",
"EmptyRootRoomUserDescription": "The shared room will appear here."
}

View File

@ -2,6 +2,7 @@ import React from "react";
import { P, match } from "ts-pattern";
import {
EmployeeType,
FilesSelectorFilterTypes,
FilterType,
FolderType,
@ -13,6 +14,7 @@ import CreateNewFormIcon from "PUBLIC_DIR/images/emptyview/create.new.form.svg";
import CreateNewSpreadsheetIcon from "PUBLIC_DIR/images/emptyview/create.new.spreadsheet.svg";
import CreateNewPresentation from "PUBLIC_DIR/images/emptyview/create.new.presentation.svg";
import CreateRoom from "PUBLIC_DIR/images/emptyview/create.room.svg";
import InviteUserFormIcon from "PUBLIC_DIR/images/emptyview/invite.user.svg";
import SharedIcon from "PUBLIC_DIR/images/emptyview/share.svg";
@ -57,7 +59,7 @@ export const getDescription = (
): string => {
const isNotAdmin = isUser(access);
if (isRootEmptyPage) return getRootDesctiption(t, rootFolderType);
if (isRootEmptyPage) return getRootDesctiption(t, access, rootFolderType);
if (isFolder)
return getFolderDescription(
@ -85,7 +87,7 @@ export const getTitle = (
): string => {
const isNotAdmin = isUser(access);
if (isRootEmptyPage) return getRootTitle(t, rootFolderType);
if (isRootEmptyPage) return getRootTitle(t, access, rootFolderType);
if (isFolder)
return getFolderTitle(
@ -232,6 +234,28 @@ export const getOptions = (
disabled: false,
};
const inviteRootRoom = {
title: t("EmptyView:InviteNewUsers"),
description: t("EmptyView:InviteRootRoomDescription", {
productName: t("Common:ProductName"),
}),
icon: <InviteUserFormIcon />,
key: "invite-root-room",
onClick: () => actions.inviteRootUser(EmployeeType.Guest),
disabled: false,
};
const migrationData = {
title: t("EmptyView:MigrationDataTitle"),
description: t("EmptyView:MigrationDataDescription", {
productName: t("Common:ProductName"),
}),
icon: <InviteUserFormIcon />,
key: "migration-data",
onClick: () => actions.navigate("/portal-settings/data-import"),
disabled: false,
};
const createFile: EmptyViewItemType = {
title: t("EmptyView:CreateNewFileTitle"),
description: t("EmptyView:CreateNewFileDescription"),
@ -276,13 +300,13 @@ export const getOptions = (
if (isArchiveFolderRoot) return [];
if (isRootEmptyPage) {
switch (rootFolderType) {
case FolderType.Rooms:
return [createRoom];
default:
return [];
}
return match([rootFolderType, access])
.with([FolderType.Rooms, ShareAccessRights.None], () => [
createRoom,
inviteRootRoom,
migrationData,
])
.otherwise(() => []);
}
if (isFolder) {

View File

@ -2,6 +2,7 @@ import { useTheme } from "styled-components";
import { inject, observer } from "mobx-react";
import { useTranslation } from "react-i18next";
import React, { useMemo, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import {
Events,
@ -47,7 +48,10 @@ const EmptyViewContainer = observer(
onCreateAndCopySharedLink,
setSelectFileFormRoomDialogVisible,
setInviteUsersWarningDialogVisible,
inviteUser: inviteRootUser,
}: EmptyViewContainerProps) => {
const navigate = useNavigate();
const { t } = useTranslation([
"EmptyView",
"Files",
@ -189,6 +193,8 @@ const EmptyViewContainer = observer(
createAndCopySharedLink,
openInfoPanel,
onCreateRoom,
inviteRootUser,
navigate,
},
),
[
@ -209,6 +215,8 @@ const EmptyViewContainer = observer(
onCreate,
openInfoPanel,
onCreateRoom,
inviteRootUser,
navigate,
],
);
@ -237,7 +245,7 @@ const InjectedEmptyViewContainer = inject<
infoPanelStore,
currentTariffStatusStore,
}): InjectedEmptyViewContainerProps => {
const { onClickInviteUsers, onCreateAndCopySharedLink } =
const { onClickInviteUsers, onCreateAndCopySharedLink, inviteUser } =
contextOptionsStore;
const { isGracePeriod } = currentTariffStatusStore;
@ -270,6 +278,7 @@ const InjectedEmptyViewContainer = inject<
setInviteUsersWarningDialogVisible,
setVisibleInfoPanel,
setViewInfoPanel,
inviteUser,
};
},
)(EmptyViewContainer as React.FC<OutEmptyViewContainerProps>);

View File

@ -1,5 +1,5 @@
import type { TFolderSecurity } from "@docspace/shared/api/files/types";
import type { TRoomSecurity } from "@docspace/shared/api/rooms/types";
import type { NavigateFunction } from "react-router-dom";
import type {
FilesSelectorFilterTypes,
FilterType,
@ -41,27 +41,34 @@ export interface OutEmptyViewContainerProps {
isRootEmptyPage: boolean;
}
export interface InjectedEmptyViewContainerProps {
access: Nullable<ShareAccessRights>;
security: Nullable<TFolderSecurity | TRoomSecurity>;
selectedFolder?: ReturnType<
export interface InjectedEmptyViewContainerProps
extends Pick<
TStore["contextOptionsStore"],
"inviteUser" | "onCreateAndCopySharedLink" | "onClickInviteUsers"
>,
Pick<
TStore["dialogsStore"],
| "setSelectFileFormRoomDialogVisible"
| "setInviteUsersWarningDialogVisible"
>,
Pick<
TStore["selectedFolderStore"],
"access" | "security" | "rootFolderType"
> {
selectedFolder: ReturnType<
TStore["selectedFolderStore"]["getSelectedFolder"]
>;
isGracePeriod: boolean;
isVisibleInfoPanel: boolean;
rootFolderType: Nullable<FolderType>;
onClickInviteUsers: (folderId: string | number, roomType: RoomsType) => void;
onCreateAndCopySharedLink: TStore["contextOptionsStore"]["onCreateAndCopySharedLink"];
setSelectFileFormRoomDialogVisible: TStore["dialogsStore"]["setSelectFileFormRoomDialogVisible"];
setVisibleInfoPanel: (arg: boolean) => void;
setViewInfoPanel: TStore["infoPanelStore"]["setView"];
setInviteUsersWarningDialogVisible: TStore["dialogsStore"]["setInviteUsersWarningDialogVisible"];
}
export type EmptyViewContainerProps = OutEmptyViewContainerProps &
InjectedEmptyViewContainerProps;
export type OptionActions = {
navigate: NavigateFunction;
inviteUser: VoidFunction;
onCreate: (extension: ExtensiontionType, withoutDialog?: boolean) => void;
uploadFromDocspace: (
@ -72,4 +79,5 @@ export type OptionActions = {
createAndCopySharedLink: VoidFunction;
openInfoPanel: VoidFunction;
onCreateRoom: VoidFunction;
inviteRootUser: TStore["contextOptionsStore"]["inviteUser"];
};

View File

@ -34,6 +34,9 @@ import CreateNewFormIcon from "PUBLIC_DIR/images/emptyview/create.new.form.svg";
import EmptyRoomsRootDarkIcon from "PUBLIC_DIR/images/emptyview/empty.rooms.root.dark.svg";
import EmptyRoomsRootLightIcon from "PUBLIC_DIR/images/emptyview/empty.rooms.root.light.svg";
import EmptyRoomsRootUserDarkIcon from "PUBLIC_DIR/images/emptyview/empty.rooms.root.user.dark.svg";
import EmptyRoomsRootUserLightIcon from "PUBLIC_DIR/images/emptyview/empty.rooms.root.user.light.svg";
import EmptyFormRoomDarkIcon from "PUBLIC_DIR/images/emptyview/empty.form.room.dark.svg";
import EmptyFormRoomLightIcon from "PUBLIC_DIR/images/emptyview/empty.form.room.light.svg";
@ -88,6 +91,8 @@ import type {
} from "./EmptyViewContainer.types";
export const isUser = (access: AccessType) => {
console.log({ access });
return (
access !== ShareAccessRights.None &&
access !== ShareAccessRights.RoomManager &&
@ -155,14 +160,20 @@ export const getRoomDescription = (
export const getRootDesctiption = (
t: TTranslation,
access: AccessType,
rootFolderType: Nullable<FolderType>,
) => {
return match([rootFolderType])
.with([FolderType.Rooms], () => t("Files:RoomEmptyContainerDescription"))
.with([FolderType.USER], () => t("Test"))
.with([FolderType.Recent], () => t("Test"))
.with([FolderType.Archive], () => t("Test"))
.with([FolderType.TRASH], () => t("Test"))
return match([rootFolderType, access])
.with([FolderType.Rooms, ShareAccessRights.None], () =>
t("Files:RoomEmptyContainerDescription"),
)
.with([FolderType.Rooms, ShareAccessRights.DenyAccess], () =>
t("EmptyView:EmptyRootRoomUserDescription"),
)
.with([FolderType.USER, P._], () => t("Test"))
.with([FolderType.Recent, P._], () => t("Test"))
.with([FolderType.Archive, P._], () => t("Test"))
.with([FolderType.TRASH, P._], () => t("Test"))
.otherwise(() => "");
};
@ -234,18 +245,22 @@ export const getRoomTitle = (
export const getRootTitle = (
t: TTranslation,
access: AccessType,
rootFolderType: Nullable<FolderType>,
) => {
return match([rootFolderType])
.with([FolderType.Rooms], () =>
return match([rootFolderType, access])
.with([FolderType.Rooms, ShareAccessRights.None], () =>
t("Files:EmptyRootRoomHeader", {
productName: t("Common:ProductName"),
}),
)
.with([FolderType.USER], () => t("Test"))
.with([FolderType.Recent], () => t("Test"))
.with([FolderType.Archive], () => t("Test"))
.with([FolderType.TRASH], () => t("Test"))
.with([FolderType.Rooms, ShareAccessRights.DenyAccess], () =>
t("EmptyView:EmptyRootRoomUserTitle"),
)
.with([FolderType.USER, P._], () => t("Test"))
.with([FolderType.Recent, P._], () => t("Test"))
.with([FolderType.Archive, P._], () => t("Test"))
.with([FolderType.TRASH, P._], () => t("Test"))
.otherwise(() => "");
};
@ -363,9 +378,16 @@ export const getRootIcom = (
isBaseTheme: boolean,
) => {
return match([rootFolderType, access])
.with([FolderType.Rooms, P._], () =>
.with([FolderType.Rooms, ShareAccessRights.None], () =>
isBaseTheme ? <EmptyRoomsRootLightIcon /> : <EmptyRoomsRootDarkIcon />,
)
.with([FolderType.Rooms, ShareAccessRights.DenyAccess], () =>
isBaseTheme ? (
<EmptyRoomsRootUserLightIcon />
) : (
<EmptyRoomsRootUserDarkIcon />
),
)
.with([FolderType.USER, P._], () => <div />)
.with([FolderType.Recent, P._], () => <div />)
.with([FolderType.Archive, P._], () => <div />)

View File

@ -2098,12 +2098,14 @@ class ContextOptionsStore {
return newOptions;
};
onInvite = (e) => {
/**
* @param {EmployeeType} userType
* @returns {void}
*/
inviteUser = (userType) => {
const { setInviteUsersWarningDialogVisible, setInvitePanelOptions } =
this.dialogsStore;
const type = e.item["data-type"];
if (this.currentTariffStatusStore.isGracePeriod) {
setInviteUsersWarningDialogVisible(true);
return;
@ -2113,10 +2115,15 @@ class ContextOptionsStore {
visible: true,
roomId: -1,
hideSelector: true,
defaultAccess: type,
defaultAccess: userType,
});
};
onInvite = (e) => {
const type = e.item["data-type"];
this.inviteUser(type);
};
onInviteAgain = (t) => {
resendInvitesAgain()
.then(() =>

View File

@ -1,4 +1,4 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" rx="6" fill="#4781D1" fill-opacity="0.1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 14C10 12.3431 11.3431 11 13 11H22C23.6569 11 25 12.3431 25 14V23C25 24.6569 23.6569 26 22 26H13C11.3431 26 10 24.6569 10 23V14ZM13 13C12.4477 13 12 13.4477 12 14V23C12 23.5523 12.4477 24 13 24H22C22.5523 24 23 23.5523 23 23V14C23 13.4477 22.5523 13 22 13H13ZM14 16C14 15.4477 14.4477 15 15 15H16C16.5523 15 17 15.4477 17 16V17C17 17.5523 16.5523 18 16 18H15C14.4477 18 14 17.5523 14 17V16ZM15 19C14.4477 19 14 19.4477 14 20V21C14 21.5523 14.4477 22 15 22H16C16.5523 22 17 21.5523 17 21V20C17 19.4477 16.5523 19 16 19H15ZM18 16C18 15.4477 18.4477 15 19 15H20C20.5523 15 21 15.4477 21 16V17C21 17.5523 20.5523 18 20 18H19C18.4477 18 18 17.5523 18 17V16ZM19 19C18.4477 19 18 19.4477 18 20V21C18 21.5523 18.4477 22 19 22H20C20.5523 22 21 21.5523 21 21V20C21 19.4477 20.5523 19 20 19H19Z" fill="#4781D1"/>
<rect width="36" height="36" rx="6" fill="currentColor" fill-opacity="0.1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 14C10 12.3431 11.3431 11 13 11H22C23.6569 11 25 12.3431 25 14V23C25 24.6569 23.6569 26 22 26H13C11.3431 26 10 24.6569 10 23V14ZM13 13C12.4477 13 12 13.4477 12 14V23C12 23.5523 12.4477 24 13 24H22C22.5523 24 23 23.5523 23 23V14C23 13.4477 22.5523 13 22 13H13ZM14 16C14 15.4477 14.4477 15 15 15H16C16.5523 15 17 15.4477 17 16V17C17 17.5523 16.5523 18 16 18H15C14.4477 18 14 17.5523 14 17V16ZM15 19C14.4477 19 14 19.4477 14 20V21C14 21.5523 14.4477 22 15 22H16C16.5523 22 17 21.5523 17 21V20C17 19.4477 16.5523 19 16 19H15ZM18 16C18 15.4477 18.4477 15 19 15H20C20.5523 15 21 15.4477 21 16V17C21 17.5523 20.5523 18 20 18H19C18.4477 18 18 17.5523 18 17V16ZM19 19C18.4477 19 18 19.4477 18 20V21C18 21.5523 18.4477 22 19 22H20C20.5523 22 21 21.5523 21 21V20C21 19.4477 20.5523 19 20 19H19Z" fill="currentColor"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,4 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" rx="6" fill="currentColor" fill-opacity="0.1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.7071 10.2929C21.5196 10.1054 21.2652 10 21 10H15C13.8954 10 13 10.8954 13 12V15H15V12H20.5858L23 14.4142V24H15V21H13V24C13 25.1046 13.8954 26 15 26H23C24.1046 26 25 25.1046 25 24V14C25 13.7348 24.8946 13.4804 24.7071 13.2929L21.7071 10.2929ZM16.2929 15.7071L17.5858 17H11L11 19H17.5858L16.2929 20.2929L17.7071 21.7071L20.7071 18.7071C21.0976 18.3166 21.0976 17.6834 20.7071 17.2929L17.7071 14.2929L16.2929 15.7071Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 671 B

View File

@ -0,0 +1,14 @@
<svg width="200" height="140" viewBox="0 0 200 140" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M141.1 104.163H60V48C60 46.2909 61.1381 45 62.7516 45H92.0946C93.5955 45 94.8338 46.2321 94.9839 47.8219V51H139C140.051 51 141 51.8871 141 53L141.1 104.163Z" fill="#333333" stroke="#AAAAAA" stroke-width="2"/>
<path d="M140.622 112H59.545C58.1212 112 56.9347 110.896 56.8556 109.438L54.0005 66C53.8818 64.3838 55.4186 62.9606 57.0006 63H102.001L109.001 57H143.501C146.001 57 147.108 59.2575 146.95 60.8737L143.272 109.477C143.192 110.896 142.006 112 140.622 112Z" fill="#444444" stroke="#AAAAAA" stroke-width="2"/>
<path d="M84 85C84.4091 86.5 86.4545 88 88.5 88C90.5455 88 92.5909 86.5 93 85" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
<path d="M107 85C107.409 86.5 109.455 88 111.5 88C113.545 88 115.591 86.5 116 85" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
<circle cx="94.5" cy="97.5" r="2.5" fill="#AAAAAA"/>
<path d="M19.5 19H26.5L21 28H27.5" stroke="#9ADAF3" stroke-width="2" stroke-linecap="round"/>
<path d="M32 28H37.25L33.125 35H38" stroke="#9ADAF3" stroke-width="2" stroke-linecap="round"/>
<path d="M43 34H48.25L44.125 41H49" stroke="#9ADAF3" stroke-width="2" stroke-linecap="round"/>
<path d="M54.8822 84.9141C47.3076 93.7879 45.7174 100.522 50.1367 102.292C54.556 104.061 61.3433 100.42 64.1846 98.3776" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
<path d="M64.5078 98.1187C65.3667 98.4629 66.7057 98.4266 68.0331 97.5917" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
<path d="M145.621 85.5038C153.196 94.3776 153.836 100.703 149.417 102.473C144.998 104.242 138.21 100.601 135.369 98.5587" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
<path d="M135.045 98.2998C134.186 98.6441 132.847 98.6078 131.52 97.7729" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,14 @@
<svg width="200" height="140" viewBox="0 0 200 140" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M141.1 104.163H60V48C60 46.2909 61.1381 45 62.7516 45H92.0946C93.5955 45 94.8338 46.2321 94.9839 47.8219V51H139C140.051 51 141 51.8871 141 53L141.1 104.163Z" fill="#EFEFEF" stroke="#AAAAAA" stroke-width="2"/>
<path d="M140.622 112H59.545C58.1212 112 56.9347 110.896 56.8556 109.438L54.0005 66C53.8818 64.3838 55.4186 62.9606 57.0006 63H102.001L109.001 57H143.501C146.001 57 147.108 59.2575 146.95 60.8737L143.272 109.477C143.192 110.896 142.006 112 140.622 112Z" fill="#F9F9F9" stroke="#AAAAAA" stroke-width="2"/>
<path d="M84 85C84.4091 86.5 86.4545 88 88.5 88C90.5455 88 92.5909 86.5 93 85" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
<path d="M107 85C107.409 86.5 109.455 88 111.5 88C113.545 88 115.591 86.5 116 85" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
<circle cx="94.5" cy="97.5" r="2.5" fill="#AAAAAA"/>
<path d="M19.5 19H26.5L21 28H27.5" stroke="#9ADAF3" stroke-width="2" stroke-linecap="round"/>
<path d="M32 28H37.25L33.125 35H38" stroke="#9ADAF3" stroke-width="2" stroke-linecap="round"/>
<path d="M43 34H48.25L44.125 41H49" stroke="#9ADAF3" stroke-width="2" stroke-linecap="round"/>
<path d="M54.8822 84.9141C47.3076 93.7879 45.7174 100.522 50.1367 102.292C54.556 104.061 61.3433 100.42 64.1846 98.3776" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
<path d="M64.5078 98.1187C65.3667 98.4629 66.7057 98.4266 68.0331 97.5917" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
<path d="M145.621 85.5038C153.196 94.3776 153.836 100.703 149.417 102.473C144.998 104.242 138.21 100.601 135.369 98.5587" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
<path d="M135.045 98.2998C134.186 98.6441 132.847 98.6078 131.52 97.7729" stroke="#AAAAAA" stroke-width="2" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB