diff --git a/common/ASC.Core.Common/GeolocationHelper.cs b/common/ASC.Core.Common/GeolocationHelper.cs index afe0c7e84f..8bfeaf4141 100644 --- a/common/ASC.Core.Common/GeolocationHelper.cs +++ b/common/ASC.Core.Common/GeolocationHelper.cs @@ -68,7 +68,7 @@ public class GeolocationHelper try { var location = await GetIPGeolocationAsync(IPAddress.Parse(ip)); - if (string.IsNullOrEmpty(location.Key)) + if (string.IsNullOrEmpty(location.Key) || (location.Key == "ZZ")) { return new string[] { string.Empty, string.Empty }; } @@ -96,7 +96,7 @@ public class GeolocationHelper var addrType = address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ? "ipv4" : "ipv6"; var result = await Queries.IpGeolocationInfoAsync(dbContext, addrType, address.GetAddressBytes()); - + if (result != null) { _cache.Insert(cacheKey, result, TimeSpan.FromSeconds(15)); diff --git a/packages/client/src/components/GlobalEvents/CreateRoomEvent.js b/packages/client/src/components/GlobalEvents/CreateRoomEvent.js index 9fded01a34..b7ee57afc7 100644 --- a/packages/client/src/components/GlobalEvents/CreateRoomEvent.js +++ b/packages/client/src/components/GlobalEvents/CreateRoomEvent.js @@ -38,7 +38,7 @@ const CreateRoomEvent = ({ ) { setCreateRoomConfirmDialogVisible(true); } else { - onCreateRoom(); + onCreateRoom(false, t); } }; diff --git a/packages/client/src/store/ContextOptionsStore.js b/packages/client/src/store/ContextOptionsStore.js index 7edfb42ae8..caad9c1c92 100644 --- a/packages/client/src/store/ContextOptionsStore.js +++ b/packages/client/src/store/ContextOptionsStore.js @@ -34,6 +34,7 @@ import CopyToReactSvgUrl from "PUBLIC_DIR/images/copyTo.react.svg?url"; import MailReactSvgUrl from "PUBLIC_DIR/images/mail.react.svg?url"; import RoomArchiveSvgUrl from "PUBLIC_DIR/images/room.archive.svg?url"; import LeaveRoomSvgUrl from "PUBLIC_DIR/images/logout.react.svg?url"; +import CatalogRoomsReactSvgUrl from "PUBLIC_DIR/images/catalog.rooms.react.svg?url"; import { makeAutoObservable } from "mobx"; import copy from "copy-to-clipboard"; @@ -52,6 +53,7 @@ import { getContextMenuItems } from "SRC_DIR/helpers/plugins"; import { connectedCloudsTypeTitleTranslation } from "@docspace/client/src/helpers/filesUtils"; import { getOAuthToken } from "@docspace/common/utils"; import api from "@docspace/common/api"; +import { FolderType } from "@docspace/common/constants"; const LOADER_TIMER = 500; let loadingTime; @@ -163,10 +165,8 @@ class ContextOptionsStore { }; onClickMakeForm = (item, t) => { - const { - setConvertPasswordDialogVisible, - setFormCreationInfo, - } = this.dialogsStore; + const { setConvertPasswordDialogVisible, setFormCreationInfo } = + this.dialogsStore; const { title, id, folderId, fileExst } = item; const newTitle = @@ -229,10 +229,8 @@ class ContextOptionsStore { }; showVersionHistory = (id, security) => { - const { - fetchFileVersions, - setIsVerHistoryPanel, - } = this.versionHistoryStore; + const { fetchFileVersions, setIsVerHistoryPanel } = + this.versionHistoryStore; if (this.treeFoldersStore.isRecycleBinFolder) return; @@ -262,9 +260,8 @@ class ContextOptionsStore { lockFile = (item, t) => { const { id, locked } = item; - const { - setSelection: setInfoPanelSelection, - } = this.authStore.infoPanelStore; + const { setSelection: setInfoPanelSelection } = + this.authStore.infoPanelStore; this.filesActionsStore .lockFileAction(id, !locked) @@ -410,6 +407,12 @@ class ContextOptionsStore { this.dialogsStore.setDownloadDialogVisible(true); }; + onClickCreateRoom = () => { + this.filesActionsStore.setProcessCreatingRoomFromData(true); + const event = new Event(Events.ROOM_CREATE); + window.dispatchEvent(event); + }; + onDuplicate = (item, t) => { this.filesActionsStore .duplicateAction(item, t("Common:CopyOperation")) @@ -439,19 +442,13 @@ class ContextOptionsStore { }; onClickDeleteSelectedFolder = (t, isRoom) => { - const { - setIsFolderActions, - setDeleteDialogVisible, - setIsRoomDelete, - } = this.dialogsStore; + const { setIsFolderActions, setDeleteDialogVisible, setIsRoomDelete } = + this.dialogsStore; const { confirmDelete } = this.settingsStore; const { deleteAction, deleteRoomsAction } = this.filesActionsStore; const { id: selectedFolderId } = this.selectedFolderStore; - const { - isThirdPartySelection, - getFolderInfo, - setBufferSelection, - } = this.filesStore; + const { isThirdPartySelection, getFolderInfo, setBufferSelection } = + this.filesStore; setIsFolderActions(true); @@ -493,10 +490,8 @@ class ContextOptionsStore { onClickDelete = (item, t) => { const { id, title, providerKey, rootFolderId, isFolder, isRoom } = item; - const { - setRemoveItem, - setDeleteThirdPartyDialogVisible, - } = this.dialogsStore; + const { setRemoveItem, setDeleteThirdPartyDialogVisible } = + this.dialogsStore; if (id === this.selectedFolderStore.id) { this.onClickDeleteSelectedFolder(t, isRoom); @@ -1202,6 +1197,14 @@ class ContextOptionsStore { "data-action": "remove", action: "remove", }, + { + id: "option_create_room", + key: "create-room", + label: t("Files:CreateRoom"), + icon: CatalogRoomsReactSvgUrl, + onClick: this.onClickCreateRoom, + disabled: this.selectedFolderStore.rootFolderType !== FolderType.USER, + }, { id: "option_download", key: "download", @@ -1338,11 +1341,8 @@ class ContextOptionsStore { const { personal } = this.authStore.settingsStore; const { selection, allFilesIsEditing } = this.filesStore; const { setDeleteDialogVisible } = this.dialogsStore; - const { - isRecycleBinFolder, - isRoomsFolder, - isArchiveFolder, - } = this.treeFoldersStore; + const { isRecycleBinFolder, isRoomsFolder, isArchiveFolder } = + this.treeFoldersStore; const { pinRooms, unpinRooms, deleteRooms } = this.filesActionsStore; @@ -1504,6 +1504,14 @@ class ContextOptionsStore { "data-action": "remove", action: "remove", }, + { + id: "create_room", + key: "create-room", + label: t("Files:CreateRoom"), + icon: CatalogRoomsReactSvgUrl, + onClick: this.onClickCreateRoom, + disabled: this.selectedFolderStore.rootFolderType !== FolderType.USER, + }, { key: "download", label: t("Common:Download"), diff --git a/packages/client/src/store/CreateEditRoomStore.js b/packages/client/src/store/CreateEditRoomStore.js index 73d0a29ff2..781f1042af 100644 --- a/packages/client/src/store/CreateEditRoomStore.js +++ b/packages/client/src/store/CreateEditRoomStore.js @@ -64,12 +64,17 @@ class CreateEditRoomStore { this.onClose = onClose; }; - onCreateRoom = async (withConfirm = false) => { + onCreateRoom = async (withConfirm = false, t) => { const roomParams = this.roomParams; const { createTag } = this.tagsStore; const { id: currentFolderId } = this.selectedFolderStore; - const { updateCurrentFolder } = this.filesActionsStore; + const { + updateCurrentFolder, + processCreatingRoomFromData, + setProcessCreatingRoomFromData, + setSelectedItems, + } = this.filesActionsStore; const { deleteThirdParty } = this.thirdPartyStore; const { withPaging } = this.settingsStore; const { @@ -80,6 +85,8 @@ class CreateEditRoomStore { uploadRoomLogo, addLogoToRoom, } = this.filesStore; + const { preparingDataForCopyingToRoom } = + this.filesActionsStore.uploadDataStore; const createRoomData = { roomType: roomParams.type, @@ -148,6 +155,11 @@ class CreateEditRoomStore { }); } else !withPaging && this.onOpenNewRoom(room); + if (processCreatingRoomFromData) { + setSelectedItems(); + preparingDataForCopyingToRoom(room.id, t); + } + this.roomIsCreated = true; } catch (err) { toastr.error(err); @@ -157,6 +169,7 @@ class CreateEditRoomStore { this.onClose(); this.roomIsCreated = true; } finally { + processCreatingRoomFromData && setProcessCreatingRoomFromData(false); if (withPaging) await updateCurrentFolder(null, currentFolderId); } }; diff --git a/packages/client/src/store/FilesActionsStore.js b/packages/client/src/store/FilesActionsStore.js index dc0fe334c7..9f4f4be914 100644 --- a/packages/client/src/store/FilesActionsStore.js +++ b/packages/client/src/store/FilesActionsStore.js @@ -8,6 +8,7 @@ import PinReactSvgUrl from "PUBLIC_DIR/images/pin.react.svg?url"; import UnpinReactSvgUrl from "PUBLIC_DIR/images/unpin.react.svg?url"; import RoomArchiveSvgUrl from "PUBLIC_DIR/images/room.archive.svg?url"; import DeleteReactSvgUrl from "PUBLIC_DIR/images/delete.react.svg?url"; +import CatalogRoomsReactSvgUrl from "PUBLIC_DIR/images/catalog.rooms.react.svg?url"; import { checkFileConflicts, deleteFile, @@ -43,7 +44,7 @@ import RoomsFilter from "@docspace/common/api/rooms/filter"; import AccountsFilter from "@docspace/common/api/people/filter"; import { RoomSearchArea } from "@docspace/common/constants"; import { getObjectByLocation } from "@docspace/common/utils"; - +import { Events } from "@docspace/common/constants"; import uniqueid from "lodash/uniqueId"; import FilesFilter from "@docspace/common/api/files/filter"; import { @@ -68,6 +69,7 @@ class FilesActionStore { isLoadedSearchFiles = false; isGroupMenuBlocked = false; emptyTrashInProgress = false; + processCreatingRoomFromData = false; constructor( authStore, @@ -1579,6 +1581,10 @@ class FilesActionStore { const canDelete = selection.every((s) => s.security?.Delete); return !allFilesIsEditing && canDelete && hasSelection; + case "create-room": + const canCreateRoom = rootFolderType === FolderType.USER; + + return canCreateRoom; } }; @@ -1710,6 +1716,16 @@ class FilesActionStore { setIsVisible(true); }; + setProcessCreatingRoomFromData = (processCreatingRoomFromData) => { + this.processCreatingRoomFromData = processCreatingRoomFromData; + }; + + onClickCreateRoom = () => { + this.setProcessCreatingRoomFromData(true); + const event = new Event(Events.ROOM_CREATE); + window.dispatchEvent(event); + }; + getOption = (option, t) => { const { setSharingPanelVisible, @@ -1740,6 +1756,16 @@ class FilesActionStore { iconUrl: CopyToReactSvgUrl, }; + case "create-room": + if (!this.isAvailableOption("create-room")) return null; + else + return { + id: "menu-create-room", + label: t("Files:CreateRoom"), + onClick: this.onClickCreateRoom, + iconUrl: CatalogRoomsReactSvgUrl, + }; + case "download": if (!this.isAvailableOption("download")) return null; else @@ -1879,6 +1905,7 @@ class FilesActionStore { }; getAnotherFolderOptions = (itemsCollection, t) => { + const createRoom = this.getOption("create-room", t); const download = this.getOption("download", t); const downloadAs = this.getOption("downloadAs", t); const moveTo = this.getOption("moveTo", t); @@ -1887,6 +1914,7 @@ class FilesActionStore { const showInfo = this.getOption("showInfo", t); itemsCollection + .set("createRoom", createRoom) .set("download", download) .set("downloadAs", downloadAs) .set("moveTo", moveTo) diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index c574b28187..83c5236246 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -1069,7 +1069,6 @@ class FilesStore { }; setSelection = (selection) => { - // console.log("setSelection", selection); this.selection = selection; }; @@ -1869,6 +1868,7 @@ class FilesStore { "mark-read", // "mark-as-favorite", // "remove-from-favorites", + "create-room", "download", "download-as", "convert", @@ -2208,6 +2208,7 @@ class FilesStore { // "link-for-portal-users", "separator1", "open-location", + "create-room", "download", "move", //category "move-to", @@ -3020,12 +3021,8 @@ class FilesStore { } get cbMenuItems() { - const { - isDocument, - isPresentation, - isSpreadsheet, - isArchive, - } = this.filesSettingsStore; + const { isDocument, isPresentation, isSpreadsheet, isArchive } = + this.filesSettingsStore; let cbMenu = ["all"]; const filesItems = [...this.files, ...this.folders]; diff --git a/packages/client/src/store/UploadDataStore.js b/packages/client/src/store/UploadDataStore.js index cb793caa0a..b7e3c68c54 100644 --- a/packages/client/src/store/UploadDataStore.js +++ b/packages/client/src/store/UploadDataStore.js @@ -1485,6 +1485,45 @@ class UploadDataStore { ); }; + preparingDataForCopyingToRoom = (destFolderId, t) => { + const { selection, bufferSelection } = this.filesStore; + let fileIds = []; + let folderIds = []; + + const selections = + selection.length > 0 && selection[0] != null + ? selection + : bufferSelection != null + ? [bufferSelection] + : []; + + if (!selections.length) return; + + for (let item of selections) { + if (item.fileExst || item.contentLength) { + fileIds.push(item.id); + } else { + folderIds.push(item.id); + } + } + + this.filesStore.setSelection([]); + this.filesStore.setBufferSelection(null); + + const operationData = { + destFolderId, + folderIds, + fileIds, + deleteAfter: false, + isCopy: true, + translations: { + copy: t("Common:CopyOperation"), + }, + }; + + this.itemOperationToFolder(operationData); + }; + loopFilesOperations = async (data, pbData, isDownloadAction) => { const { clearSecondaryProgressData, setSecondaryProgressBarData } = this.secondaryProgressDataStore;