Client:Store: create structure of files stores, init files socket stores
This commit is contained in:
parent
925cc648f5
commit
fc3593eab1
0
packages/client/src/store/FilesFilterStore.ts
Normal file
0
packages/client/src/store/FilesFilterStore.ts
Normal file
14
packages/client/src/store/FilesListStore.ts
Normal file
14
packages/client/src/store/FilesListStore.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { TFile, TFolder } from "@docspace/shared/api/files/types";
|
||||
import { makeAutoObservable } from "mobx";
|
||||
|
||||
class FilesSelectionStore {
|
||||
files: TFile[] = [];
|
||||
|
||||
folders: TFolder[] = [];
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
}
|
||||
|
||||
export default FilesSelectionStore;
|
35
packages/client/src/store/FilesSelectionStore.ts
Normal file
35
packages/client/src/store/FilesSelectionStore.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { makeAutoObservable } from "mobx";
|
||||
|
||||
import { TFile, TFolder } from "@docspace/shared/api/files/types";
|
||||
import { TRoom } from "@docspace/shared/api/rooms/types";
|
||||
import { Nullable } from "@docspace/shared/types";
|
||||
|
||||
export type TSelection = (TFile | TFolder | TRoom)[];
|
||||
export type TBufferSelection = Nullable<TFile | TFolder | TRoom>;
|
||||
export type TSelected = "close" | "none";
|
||||
|
||||
class FilesSelectionStore {
|
||||
selection: TSelection = [];
|
||||
|
||||
bufferSelection: TBufferSelection = null;
|
||||
|
||||
selected: TSelected = "close";
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
setSelection = (selection: TSelection) => {
|
||||
this.selection = selection;
|
||||
};
|
||||
|
||||
setBufferSelection = (bufferSelection: TBufferSelection) => {
|
||||
this.bufferSelection = bufferSelection;
|
||||
};
|
||||
|
||||
setSelected = (selected: TSelected) => {
|
||||
this.selected = selected;
|
||||
};
|
||||
}
|
||||
|
||||
export default FilesSelectionStore;
|
562
packages/client/src/store/FilesSocketStore.ts
Normal file
562
packages/client/src/store/FilesSocketStore.ts
Normal file
@ -0,0 +1,562 @@
|
||||
/* eslint-disable no-console */
|
||||
import { makeAutoObservable, runInAction } from "mobx";
|
||||
import merge from "lodash/merge";
|
||||
import cloneDeep from "lodash/cloneDeep";
|
||||
import debounce from "lodash/debounce";
|
||||
|
||||
import api from "@docspace/shared/api";
|
||||
import { TFile } from "@docspace/shared/api/files/types";
|
||||
import { TOptSocket } from "@docspace/shared/utils/socket";
|
||||
import { SettingsStore } from "@docspace/shared/store/SettingsStore";
|
||||
import { UserStore } from "@docspace/shared/store/UserStore";
|
||||
import { Events, FileStatus } from "@docspace/shared/enums";
|
||||
import { PDF_FORM_DIALOG_KEY } from "@docspace/shared/constants";
|
||||
|
||||
import FilesStore from "./FilesStore";
|
||||
import ClientLoadingStore from "./ClientLoadingStore";
|
||||
import SelectedFolderStore from "./SelectedFolderStore";
|
||||
import TreeFoldersStore from "./TreeFoldersStore";
|
||||
import InfoPanelStore from "./InfoPanelStore";
|
||||
|
||||
class FilesSocketStore {
|
||||
constructor(
|
||||
private settingsStore: Readonly<SettingsStore>,
|
||||
private clientLoadingStore: Readonly<ClientLoadingStore>,
|
||||
private selectedFolderStore: Readonly<SelectedFolderStore>,
|
||||
private treeFoldersStore: Readonly<TreeFoldersStore>,
|
||||
private infoPanelStore: Readonly<InfoPanelStore>,
|
||||
private userStore: Readonly<UserStore>,
|
||||
|
||||
private filesStore: Readonly<FilesStore>,
|
||||
) {
|
||||
makeAutoObservable(this);
|
||||
|
||||
const { socketHelper } = settingsStore;
|
||||
|
||||
socketHelper.on("s:modify-folder", async (opt) => {
|
||||
const { socketSubscribers } = socketHelper;
|
||||
|
||||
if (opt && typeof opt !== "string" && opt.data) {
|
||||
const data = JSON.parse(opt.data);
|
||||
|
||||
const pathParts = data.folderId
|
||||
? `DIR-${data.folderId}`
|
||||
: `DIR-${data.parentId}`;
|
||||
|
||||
if (
|
||||
!socketSubscribers.has(pathParts) &&
|
||||
!socketSubscribers.has(`DIR-${data.id}`)
|
||||
) {
|
||||
console.log("[WS] s:modify-folder: SKIP UNSUBSCRIBED", { data });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("[WS] s:modify-folder", opt);
|
||||
|
||||
if (
|
||||
!(this.clientLoadingStore.isLoading || this.filesStore.operationAction)
|
||||
) {
|
||||
switch (typeof opt !== "string" && opt?.cmd) {
|
||||
case "create":
|
||||
this.wsModifyFolderCreate(opt);
|
||||
break;
|
||||
case "update":
|
||||
this.wsModifyFolderUpdate(opt);
|
||||
break;
|
||||
case "delete":
|
||||
this.wsModifyFolderDelete(opt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
typeof opt !== "string" &&
|
||||
opt?.cmd &&
|
||||
opt.id &&
|
||||
(opt.type === "file" || opt.type === "folder") &&
|
||||
(opt.cmd === "create" || opt.cmd === "delete")
|
||||
) {
|
||||
if (opt.type === "file") {
|
||||
if (opt.cmd === "create") {
|
||||
this.selectedFolderStore.increaseFilesCount();
|
||||
} else {
|
||||
this.selectedFolderStore.decreaseFilesCount();
|
||||
}
|
||||
} else if (opt.type === "folder")
|
||||
if (opt.cmd === "create") {
|
||||
this.selectedFolderStore.increaseFoldersCount();
|
||||
} else {
|
||||
this.selectedFolderStore.decreaseFoldersCount();
|
||||
}
|
||||
}
|
||||
|
||||
this.treeFoldersStore.updateTreeFoldersItem(opt);
|
||||
});
|
||||
|
||||
socketHelper.on("s:update-history", (opt) => {
|
||||
if (typeof opt === "string") return;
|
||||
|
||||
const { infoPanelSelection, fetchHistory } = this.infoPanelStore;
|
||||
|
||||
const { id, type } = opt;
|
||||
|
||||
let infoPanelSelectionType = "file";
|
||||
if (infoPanelSelection?.isRoom || infoPanelSelection?.isFolder)
|
||||
infoPanelSelectionType = "folder";
|
||||
|
||||
if (id === infoPanelSelection?.id && type === infoPanelSelectionType) {
|
||||
console.log("[WS] s:update-history", id);
|
||||
fetchHistory();
|
||||
}
|
||||
});
|
||||
|
||||
socketHelper.on("refresh-folder", (id) => {
|
||||
const { socketSubscribers } = socketHelper;
|
||||
const pathParts = `DIR-${id}`;
|
||||
|
||||
if (!socketSubscribers.has(pathParts)) return;
|
||||
|
||||
if (!id || this.clientLoadingStore.isLoading) return;
|
||||
|
||||
if (
|
||||
this.selectedFolderStore.id?.toString() === id.toString() &&
|
||||
this.settingsStore.withPaging // TODO: no longer deletes the folder in other tabs
|
||||
) {
|
||||
console.log("[WS] refresh-folder", id);
|
||||
this.filesStore.fetchFiles(id, this.filesStore.filter);
|
||||
}
|
||||
});
|
||||
|
||||
socketHelper.on("s:markasnew-folder", (opt) => {
|
||||
if (typeof opt === "string") return;
|
||||
|
||||
const { socketSubscribers } = socketHelper;
|
||||
|
||||
const { folderId, count } = opt;
|
||||
const pathParts = `DIR-${folderId}`;
|
||||
|
||||
if (!socketSubscribers.has(pathParts)) return;
|
||||
|
||||
console.log(`[WS] markasnew-folder ${folderId}:${count}`);
|
||||
|
||||
const foundIndex =
|
||||
folderId && this.filesStore.folders.findIndex((x) => x.id === folderId);
|
||||
if (foundIndex === -1 || !foundIndex) return;
|
||||
|
||||
runInAction(() => {
|
||||
this.filesStore.folders[foundIndex].new =
|
||||
typeof count !== "undefined" && Number(count) >= 0 ? count : 0;
|
||||
this.treeFoldersStore.fetchTreeFolders();
|
||||
});
|
||||
});
|
||||
|
||||
socketHelper.on("s:markasnew-file", (opt) => {
|
||||
if (typeof opt === "string") return;
|
||||
const { fileId, count } = opt;
|
||||
|
||||
const { socketSubscribers } = socketHelper;
|
||||
const pathParts = `FILE-${fileId}`;
|
||||
|
||||
if (!socketSubscribers.has(pathParts)) return;
|
||||
|
||||
console.log(`[WS] markasnew-file ${fileId}:${count}`);
|
||||
|
||||
const foundIndex =
|
||||
fileId && this.filesStore.files.findIndex((x) => x.id === fileId);
|
||||
|
||||
this.treeFoldersStore.fetchTreeFolders();
|
||||
|
||||
if (foundIndex === -1 || !foundIndex) return;
|
||||
|
||||
this.filesStore.updateFileStatus(
|
||||
foundIndex,
|
||||
typeof count !== "undefined" && Number(count) > 0
|
||||
? this.filesStore.files[foundIndex].fileStatus | FileStatus.IsNew
|
||||
: this.filesStore.files[foundIndex].fileStatus & ~FileStatus.IsNew,
|
||||
);
|
||||
});
|
||||
|
||||
// WAIT FOR RESPONSES OF EDITING FILE
|
||||
socketHelper.on("s:start-edit-file", (id) => {
|
||||
const { socketSubscribers } = socketHelper;
|
||||
const pathParts = `FILE-${id}`;
|
||||
|
||||
if (!socketSubscribers.has(pathParts)) return;
|
||||
|
||||
const foundIndex = this.filesStore.files.findIndex((x) => x.id === id);
|
||||
if (foundIndex === -1) return;
|
||||
|
||||
console.log(
|
||||
`[WS] s:start-edit-file`,
|
||||
id,
|
||||
this.filesStore.files[foundIndex].title,
|
||||
);
|
||||
|
||||
this.filesStore.updateSelectionStatus(
|
||||
id,
|
||||
this.filesStore.files[foundIndex].fileStatus | FileStatus.IsEditing,
|
||||
true,
|
||||
);
|
||||
|
||||
this.filesStore.updateFileStatus(
|
||||
foundIndex,
|
||||
this.filesStore.files[foundIndex].fileStatus | FileStatus.IsEditing,
|
||||
);
|
||||
});
|
||||
|
||||
socketHelper.on("s:modify-room", (option) => {
|
||||
if (typeof option === "string") return;
|
||||
switch (option.cmd) {
|
||||
case "create-form":
|
||||
this.wsCreatedPDFForm(option);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
socketHelper.on("s:stop-edit-file", (id) => {
|
||||
const { socketSubscribers } = socketHelper;
|
||||
const pathParts = `FILE-${id}`;
|
||||
|
||||
const { isVisible, infoPanelSelection, setInfoPanelSelection } =
|
||||
this.infoPanelStore;
|
||||
|
||||
if (!socketSubscribers.has(pathParts)) return;
|
||||
|
||||
const foundIndex = this.filesStore.files.findIndex((x) => x.id === id);
|
||||
if (foundIndex == -1) return;
|
||||
|
||||
console.log(
|
||||
`[WS] s:stop-edit-file`,
|
||||
id,
|
||||
this.filesStore.files[foundIndex].title,
|
||||
);
|
||||
|
||||
this.filesStore.updateSelectionStatus(
|
||||
id,
|
||||
this.filesStore.files[foundIndex].fileStatus & ~FileStatus.IsEditing,
|
||||
false,
|
||||
);
|
||||
|
||||
this.filesStore.updateFileStatus(
|
||||
foundIndex,
|
||||
this.filesStore.files[foundIndex].fileStatus & ~FileStatus.IsEditing,
|
||||
);
|
||||
|
||||
this.filesStore.getFileInfo(id).then((file) => {
|
||||
if (
|
||||
isVisible &&
|
||||
file.id === infoPanelSelection?.id &&
|
||||
infoPanelSelection?.fileExst === file.fileExst
|
||||
) {
|
||||
setInfoPanelSelection(merge(cloneDeep(infoPanelSelection), file));
|
||||
}
|
||||
});
|
||||
|
||||
this.filesStore.createThumbnail(this.filesStore.files[foundIndex]);
|
||||
});
|
||||
|
||||
this.filesStore.createNewFilesQueue.on(
|
||||
"resolve",
|
||||
this.filesStore.onResolveNewFile,
|
||||
);
|
||||
}
|
||||
|
||||
wsModifyFolderCreate = async (opt: TOptSocket | string) => {
|
||||
if (typeof opt === "string") return;
|
||||
|
||||
if (opt?.type === "file" && opt?.id && opt.data) {
|
||||
const foundIndex = this.filesStore.files.findIndex(
|
||||
(x) => x.id === opt?.id,
|
||||
);
|
||||
|
||||
const file = JSON.parse(opt?.data);
|
||||
|
||||
if (this.selectedFolderStore.id !== file.folderId) {
|
||||
const movedToIndex = this.filesStore.getFolderIndex(file.folderId);
|
||||
if (movedToIndex > -1)
|
||||
this.filesStore.folders[movedToIndex].filesCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
// To update a file version
|
||||
if (foundIndex > -1 && !this.settingsStore.withPaging) {
|
||||
if (
|
||||
this.filesStore.files[foundIndex].version !== file.version ||
|
||||
this.filesStore.files[foundIndex].versionGroup !== file.versionGroup
|
||||
) {
|
||||
this.filesStore.files[foundIndex].version = file.version;
|
||||
this.filesStore.files[foundIndex].versionGroup = file.versionGroup;
|
||||
}
|
||||
this.filesStore.checkSelection(file);
|
||||
}
|
||||
|
||||
if (foundIndex > -1) return;
|
||||
|
||||
setTimeout(() => {
|
||||
const foundIndex = this.filesStore.files.findIndex(
|
||||
(x) => x.id === file.id,
|
||||
);
|
||||
if (foundIndex > -1) {
|
||||
// console.log("Skip in timeout");
|
||||
return null;
|
||||
}
|
||||
|
||||
this.filesStore.createNewFilesQueue.enqueue(() => {
|
||||
const foundIndex = this.filesStore.files.findIndex(
|
||||
(x) => x.id === file.id,
|
||||
);
|
||||
if (foundIndex > -1) {
|
||||
// console.log("Skip in queue");
|
||||
return null;
|
||||
}
|
||||
|
||||
return api.files.getFileInfo(file.id);
|
||||
});
|
||||
}, 300);
|
||||
} else if (opt?.type === "folder" && opt?.id) {
|
||||
const foundIndex = this.filesStore.folders.findIndex(
|
||||
(x) => x.id === opt?.id,
|
||||
);
|
||||
|
||||
if (foundIndex > -1) return;
|
||||
|
||||
const folder = JSON.parse(opt?.data);
|
||||
|
||||
if (this.selectedFolderStore.id != folder.parentId) {
|
||||
const movedToIndex = this.filesStore.getFolderIndex(folder.parentId);
|
||||
if (movedToIndex > -1)
|
||||
this.filesStore.folders[movedToIndex].foldersCount++;
|
||||
}
|
||||
|
||||
if (
|
||||
this.selectedFolderStore.id !== folder.parentId ||
|
||||
(folder.roomType &&
|
||||
folder.createdBy.id === this.userStore?.user?.id &&
|
||||
this.filesStore.roomCreated)
|
||||
) {
|
||||
return (this.filesStore.roomCreated = false);
|
||||
}
|
||||
|
||||
const folderInfo = await api.files.getFolderInfo(folder.id);
|
||||
|
||||
console.log("[WS] create new folder", folderInfo.id, folderInfo.title);
|
||||
|
||||
const newFolders = [folderInfo, ...this.filesStore.folders];
|
||||
|
||||
if (
|
||||
newFolders.length > this.filesStore.filter.pageCount &&
|
||||
this.settingsStore.withPaging
|
||||
) {
|
||||
newFolders.pop(); // Remove last
|
||||
}
|
||||
|
||||
const newFilter = this.filesStore.filter;
|
||||
newFilter.total += 1;
|
||||
|
||||
runInAction(() => {
|
||||
this.filesStore.setFilter(newFilter);
|
||||
this.filesStore.setFolders(newFolders);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
wsModifyFolderUpdate = (opt: TOptSocket | string) => {
|
||||
if (typeof opt === "string") return;
|
||||
|
||||
if (opt?.type === "file" && opt?.data) {
|
||||
const file = JSON.parse(opt?.data);
|
||||
if (!file || !file.id) return;
|
||||
|
||||
this.filesStore.getFileInfo(file.id); // this.setFile(file);
|
||||
console.log("[WS] update file", file.id, file.title);
|
||||
|
||||
this.filesStore.checkSelection(file);
|
||||
} else if (opt?.type === "folder" && opt?.data) {
|
||||
const folder = JSON.parse(opt?.data);
|
||||
if (!folder || !folder.id) return;
|
||||
|
||||
api.files
|
||||
.getFolderInfo(folder.id)
|
||||
.then(this.filesStore.setFolder)
|
||||
.catch(() => {
|
||||
// console.log("Folder deleted")
|
||||
});
|
||||
|
||||
console.log("[WS] update folder", folder.id, folder.title);
|
||||
|
||||
if (this.filesStore.selection?.length) {
|
||||
const foundIndex = this.filesStore.selection?.findIndex(
|
||||
(x) => x.id === folder.id,
|
||||
);
|
||||
if (foundIndex > -1) {
|
||||
runInAction(() => {
|
||||
this.filesStore.selection[foundIndex] = folder;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.filesStore.bufferSelection) {
|
||||
const foundIndex = [this.filesStore.bufferSelection].findIndex(
|
||||
(x) => x.id === folder.id,
|
||||
);
|
||||
if (foundIndex > -1) {
|
||||
runInAction(() => {
|
||||
this.filesStore.bufferSelection[foundIndex] = folder;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (folder.id === this.selectedFolderStore.id) {
|
||||
this.selectedFolderStore.setSelectedFolder({ ...folder });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
wsModifyFolderDelete = (opt: TOptSocket | string) => {
|
||||
if (typeof opt === "string") return;
|
||||
|
||||
if (opt?.type === "file" && opt?.id) {
|
||||
const foundIndex = this.filesStore.files.findIndex(
|
||||
(x) => x.id === opt?.id,
|
||||
);
|
||||
if (foundIndex === -1) return;
|
||||
|
||||
console.log(
|
||||
"[WS] delete file",
|
||||
this.filesStore.files[foundIndex].id,
|
||||
this.filesStore.files[foundIndex].title,
|
||||
);
|
||||
|
||||
const tempActionFilesIds = JSON.parse(
|
||||
JSON.stringify(this.filesStore.tempActionFilesIds),
|
||||
);
|
||||
tempActionFilesIds.push(this.filesStore.files[foundIndex].id);
|
||||
|
||||
this.filesStore.setTempActionFilesIds(tempActionFilesIds);
|
||||
|
||||
this.debounceRemoveFiles();
|
||||
|
||||
// Hide pagination when deleting files
|
||||
runInAction(() => {
|
||||
this.filesStore.isHidePagination = true;
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
if (
|
||||
this.filesStore.files.length === 0 &&
|
||||
this.filesStore.folders.length === 0 &&
|
||||
this.filesStore.pageItemsLength > 1
|
||||
) {
|
||||
this.filesStore.isLoadingFilesFind = true;
|
||||
}
|
||||
});
|
||||
} else if (opt?.type === "folder" && opt?.id) {
|
||||
const foundIndex = this.filesStore.folders.findIndex(
|
||||
(x) => x.id === opt?.id,
|
||||
);
|
||||
if (foundIndex == -1) return;
|
||||
|
||||
console.log(
|
||||
"[WS] delete folder",
|
||||
this.filesStore.folders[foundIndex].id,
|
||||
this.filesStore.folders[foundIndex].title,
|
||||
);
|
||||
|
||||
const tempActionFoldersIds = JSON.parse(
|
||||
JSON.stringify(this.filesStore.tempActionFoldersIds),
|
||||
);
|
||||
tempActionFoldersIds.push(this.filesStore.folders[foundIndex].id);
|
||||
|
||||
this.filesStore.setTempActionFoldersIds(tempActionFoldersIds);
|
||||
this.debounceRemoveFolders();
|
||||
|
||||
runInAction(() => {
|
||||
this.filesStore.isHidePagination = true;
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
if (
|
||||
this.filesStore.files.length === 0 &&
|
||||
this.filesStore.folders.length === 0 &&
|
||||
this.filesStore.pageItemsLength > 1
|
||||
) {
|
||||
this.filesStore.isLoadingFilesFind = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
wsCreatedPDFForm = (option: TOptSocket) => {
|
||||
if (!option.data) return;
|
||||
|
||||
const file = JSON.parse(option.data);
|
||||
|
||||
if (this.selectedFolderStore.id !== file.folderId) return;
|
||||
|
||||
const localKey = `${PDF_FORM_DIALOG_KEY}-${this.userStore?.user?.id}`;
|
||||
|
||||
const isFirst = JSON.parse(localStorage.getItem(localKey) ?? "true");
|
||||
|
||||
const event = new CustomEvent(Events.CREATE_PDF_FORM_FILE, {
|
||||
detail: {
|
||||
file,
|
||||
isFill: !option.isOneMember,
|
||||
isFirst,
|
||||
},
|
||||
});
|
||||
|
||||
if (isFirst) localStorage.setItem(localKey, "false");
|
||||
|
||||
window?.dispatchEvent(event);
|
||||
};
|
||||
|
||||
onResolveNewFile = (fileInfo: TFile) => {
|
||||
if (!fileInfo) return;
|
||||
|
||||
if (this.filesStore.files.findIndex((x) => x.id === fileInfo.id) > -1)
|
||||
return;
|
||||
|
||||
if (this.selectedFolderStore.id !== fileInfo.folderId) return;
|
||||
|
||||
console.log("[WS] create new file", { fileInfo });
|
||||
|
||||
const newFiles = [fileInfo, ...this.filesStore.files];
|
||||
|
||||
if (
|
||||
newFiles.length > this.filesStore.filter.pageCount &&
|
||||
this.settingsStore.withPaging
|
||||
) {
|
||||
newFiles.pop(); // Remove last
|
||||
}
|
||||
|
||||
const newFilter = this.filesStore.filter;
|
||||
newFilter.total += 1;
|
||||
|
||||
runInAction(() => {
|
||||
this.filesStore.setFilter(newFilter);
|
||||
this.filesStore.setFiles(newFiles);
|
||||
});
|
||||
|
||||
this.debounceFetchTreeFolders();
|
||||
};
|
||||
|
||||
debounceFetchTreeFolders = debounce(() => {
|
||||
this.treeFoldersStore.fetchTreeFolders();
|
||||
}, 1000);
|
||||
|
||||
debounceRemoveFiles = debounce(() => {
|
||||
this.filesStore.removeFiles(this.filesStore.tempActionFilesIds);
|
||||
}, 1000);
|
||||
|
||||
debounceRemoveFolders = debounce(() => {
|
||||
this.filesStore.removeFiles(null, this.filesStore.tempActionFoldersIds);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
export default FilesSocketStore;
|
@ -26,8 +26,6 @@
|
||||
|
||||
import axios from "axios";
|
||||
import { makeAutoObservable, runInAction } from "mobx";
|
||||
import merge from "lodash/merge";
|
||||
import cloneDeep from "lodash/cloneDeep";
|
||||
|
||||
import api from "@docspace/shared/api";
|
||||
import {
|
||||
@ -68,10 +66,9 @@ import { isDesktop, isMobile } from "@docspace/shared/utils";
|
||||
import { PluginFileType } from "SRC_DIR/helpers/plugins/enums";
|
||||
|
||||
import { CategoryType } from "SRC_DIR/helpers/constants";
|
||||
import debounce from "lodash.debounce";
|
||||
|
||||
import clone from "lodash/clone";
|
||||
import Queue from "queue-promise";
|
||||
import { parseHistory } from "SRC_DIR/pages/Home/InfoPanel/Body/helpers/HistoryHelper";
|
||||
|
||||
const { FilesFilter, RoomsFilter } = api;
|
||||
const storageViewAs = localStorage.getItem("viewAs");
|
||||
@ -225,490 +222,8 @@ class FilesStore {
|
||||
|
||||
this.roomsController = new AbortController();
|
||||
this.filesController = new AbortController();
|
||||
const { socketHelper } = settingsStore;
|
||||
|
||||
socketHelper.on("s:modify-folder", async (opt) => {
|
||||
const { socketSubscribers } = socketHelper;
|
||||
|
||||
if (opt && opt.data) {
|
||||
const data = JSON.parse(opt.data);
|
||||
|
||||
const pathParts = data.folderId
|
||||
? `DIR-${data.folderId}`
|
||||
: `DIR-${data.parentId}`;
|
||||
|
||||
if (
|
||||
!socketSubscribers.has(pathParts) &&
|
||||
!socketSubscribers.has(`DIR-${data.id}`)
|
||||
) {
|
||||
console.log("[WS] s:modify-folder: SKIP UNSUBSCRIBED", { data });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("[WS] s:modify-folder", opt);
|
||||
|
||||
if (!(this.clientLoadingStore.isLoading || this.operationAction))
|
||||
switch (opt?.cmd) {
|
||||
case "create":
|
||||
this.wsModifyFolderCreate(opt);
|
||||
break;
|
||||
case "update":
|
||||
this.wsModifyFolderUpdate(opt);
|
||||
break;
|
||||
case "delete":
|
||||
this.wsModifyFolderDelete(opt);
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
opt?.cmd &&
|
||||
opt.id &&
|
||||
(opt.type === "file" || opt.type === "folder") &&
|
||||
(opt.cmd === "create" || opt.cmd === "delete")
|
||||
) {
|
||||
runInAction(() => {
|
||||
if (opt.cmd === "create") {
|
||||
this.selectedFolderStore[opt.type + "sCount"]++;
|
||||
} else if (opt.cmd === "delete") {
|
||||
this.selectedFolderStore[opt.type + "sCount"]--;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.treeFoldersStore.updateTreeFoldersItem(opt);
|
||||
});
|
||||
|
||||
socketHelper.on("s:update-history", ({ id, type }) => {
|
||||
const { infoPanelSelection, fetchHistory } = this.infoPanelStore;
|
||||
|
||||
let infoPanelSelectionType = "file";
|
||||
if (infoPanelSelection?.isRoom || infoPanelSelection?.isFolder)
|
||||
infoPanelSelectionType = "folder";
|
||||
|
||||
if (id === infoPanelSelection?.id && type === infoPanelSelectionType) {
|
||||
console.log("[WS] s:update-history", id);
|
||||
fetchHistory();
|
||||
}
|
||||
});
|
||||
|
||||
socketHelper.on("refresh-folder", (id) => {
|
||||
const { socketSubscribers } = socketHelper;
|
||||
const pathParts = `DIR-${id}`;
|
||||
|
||||
if (!socketSubscribers.has(pathParts)) return;
|
||||
|
||||
if (!id || this.clientLoadingStore.isLoading) return;
|
||||
|
||||
//console.log(
|
||||
// `selected folder id ${this.selectedFolderStore.id} an changed folder id ${id}`
|
||||
//);
|
||||
|
||||
if (
|
||||
this.selectedFolderStore.id == id &&
|
||||
this.settingsStore.withPaging //TODO: no longer deletes the folder in other tabs
|
||||
) {
|
||||
console.log("[WS] refresh-folder", id);
|
||||
this.fetchFiles(id, this.filter);
|
||||
}
|
||||
});
|
||||
|
||||
socketHelper.on("s:markasnew-folder", ({ folderId, count }) => {
|
||||
const { socketSubscribers } = socketHelper;
|
||||
const pathParts = `DIR-${folderId}`;
|
||||
|
||||
if (!socketSubscribers.has(pathParts)) return;
|
||||
|
||||
console.log(`[WS] markasnew-folder ${folderId}:${count}`);
|
||||
|
||||
const foundIndex =
|
||||
folderId && this.folders.findIndex((x) => x.id === folderId);
|
||||
if (foundIndex == -1) return;
|
||||
|
||||
runInAction(() => {
|
||||
this.folders[foundIndex].new = count >= 0 ? count : 0;
|
||||
this.treeFoldersStore.fetchTreeFolders();
|
||||
});
|
||||
});
|
||||
|
||||
socketHelper.on("s:markasnew-file", ({ fileId, count }) => {
|
||||
const { socketSubscribers } = socketHelper;
|
||||
const pathParts = `FILE-${fileId}`;
|
||||
|
||||
if (!socketSubscribers.has(pathParts)) return;
|
||||
|
||||
console.log(`[WS] markasnew-file ${fileId}:${count}`);
|
||||
|
||||
const foundIndex = fileId && this.files.findIndex((x) => x.id === fileId);
|
||||
|
||||
this.treeFoldersStore.fetchTreeFolders();
|
||||
|
||||
if (foundIndex == -1) return;
|
||||
|
||||
this.updateFileStatus(
|
||||
foundIndex,
|
||||
count > 0
|
||||
? this.files[foundIndex].fileStatus | FileStatus.IsNew
|
||||
: this.files[foundIndex].fileStatus & ~FileStatus.IsNew,
|
||||
);
|
||||
});
|
||||
|
||||
//WAIT FOR RESPONSES OF EDITING FILE
|
||||
socketHelper.on("s:start-edit-file", (id) => {
|
||||
const { socketSubscribers } = socketHelper;
|
||||
const pathParts = `FILE-${id}`;
|
||||
|
||||
if (!socketSubscribers.has(pathParts)) return;
|
||||
|
||||
const foundIndex = this.files.findIndex((x) => x.id === id);
|
||||
if (foundIndex == -1) return;
|
||||
|
||||
console.log(`[WS] s:start-edit-file`, id, this.files[foundIndex].title);
|
||||
|
||||
this.updateSelectionStatus(
|
||||
id,
|
||||
this.files[foundIndex].fileStatus | FileStatus.IsEditing,
|
||||
true,
|
||||
);
|
||||
|
||||
this.updateFileStatus(
|
||||
foundIndex,
|
||||
this.files[foundIndex].fileStatus | FileStatus.IsEditing,
|
||||
);
|
||||
});
|
||||
|
||||
socketHelper.on("s:modify-room", (option) => {
|
||||
switch (option.cmd) {
|
||||
case "create-form":
|
||||
this.wsCreatedPDFForm(option);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
socketHelper.on("s:stop-edit-file", (id) => {
|
||||
const { socketSubscribers } = socketHelper;
|
||||
const pathParts = `FILE-${id}`;
|
||||
|
||||
const { isVisible, infoPanelSelection, setInfoPanelSelection } =
|
||||
this.infoPanelStore;
|
||||
|
||||
if (!socketSubscribers.has(pathParts)) return;
|
||||
|
||||
const foundIndex = this.files.findIndex((x) => x.id === id);
|
||||
if (foundIndex == -1) return;
|
||||
|
||||
console.log(`[WS] s:stop-edit-file`, id, this.files[foundIndex].title);
|
||||
|
||||
this.updateSelectionStatus(
|
||||
id,
|
||||
this.files[foundIndex].fileStatus & ~FileStatus.IsEditing,
|
||||
false,
|
||||
);
|
||||
|
||||
this.updateFileStatus(
|
||||
foundIndex,
|
||||
this.files[foundIndex].fileStatus & ~FileStatus.IsEditing,
|
||||
);
|
||||
|
||||
this.getFileInfo(id).then((file) => {
|
||||
if (
|
||||
isVisible &&
|
||||
file.id === infoPanelSelection?.id &&
|
||||
infoPanelSelection?.fileExst === file.fileExst
|
||||
) {
|
||||
setInfoPanelSelection(merge(cloneDeep(infoPanelSelection), file));
|
||||
}
|
||||
});
|
||||
|
||||
this.createThumbnail(this.files[foundIndex]);
|
||||
});
|
||||
|
||||
this.createNewFilesQueue.on("resolve", this.onResolveNewFile);
|
||||
}
|
||||
|
||||
onResolveNewFile = (fileInfo) => {
|
||||
if (!fileInfo) return;
|
||||
|
||||
//console.log("onResolveNewFiles", { fileInfo });
|
||||
|
||||
if (this.files.findIndex((x) => x.id === fileInfo.id) > -1) return;
|
||||
|
||||
if (this.selectedFolderStore.id !== fileInfo.folderId) return;
|
||||
|
||||
console.log("[WS] create new file", { fileInfo });
|
||||
|
||||
const newFiles = [fileInfo, ...this.files];
|
||||
|
||||
if (
|
||||
newFiles.length > this.filter.pageCount &&
|
||||
this.settingsStore.withPaging
|
||||
) {
|
||||
newFiles.pop(); // Remove last
|
||||
}
|
||||
|
||||
const newFilter = this.filter;
|
||||
newFilter.total += 1;
|
||||
|
||||
runInAction(() => {
|
||||
this.setFilter(newFilter);
|
||||
this.setFiles(newFiles);
|
||||
});
|
||||
|
||||
this.debouncefetchTreeFolders();
|
||||
};
|
||||
|
||||
debouncefetchTreeFolders = debounce(() => {
|
||||
this.treeFoldersStore.fetchTreeFolders();
|
||||
}, 1000);
|
||||
|
||||
debounceRemoveFiles = debounce(() => {
|
||||
this.removeFiles(this.tempActionFilesIds);
|
||||
}, 1000);
|
||||
|
||||
debounceRemoveFolders = debounce(() => {
|
||||
this.removeFiles(null, this.tempActionFoldersIds);
|
||||
}, 1000);
|
||||
|
||||
wsModifyFolderCreate = async (opt) => {
|
||||
if (opt?.type === "file" && opt?.id) {
|
||||
const foundIndex = this.files.findIndex((x) => x.id === opt?.id);
|
||||
|
||||
const file = JSON.parse(opt?.data);
|
||||
|
||||
if (this.selectedFolderStore.id !== file.folderId) {
|
||||
const movedToIndex = this.getFolderIndex(file.folderId);
|
||||
if (movedToIndex > -1) this.folders[movedToIndex].filesCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
//To update a file version
|
||||
if (foundIndex > -1 && !this.settingsStore.withPaging) {
|
||||
if (
|
||||
this.files[foundIndex].version !== file.version ||
|
||||
this.files[foundIndex].versionGroup !== file.versionGroup
|
||||
) {
|
||||
this.files[foundIndex].version = file.version;
|
||||
this.files[foundIndex].versionGroup = file.versionGroup;
|
||||
}
|
||||
this.checkSelection(file);
|
||||
}
|
||||
|
||||
if (foundIndex > -1) return;
|
||||
|
||||
setTimeout(() => {
|
||||
const foundIndex = this.files.findIndex((x) => x.id === file.id);
|
||||
if (foundIndex > -1) {
|
||||
//console.log("Skip in timeout");
|
||||
return null;
|
||||
}
|
||||
|
||||
this.createNewFilesQueue.enqueue(() => {
|
||||
const foundIndex = this.files.findIndex((x) => x.id === file.id);
|
||||
if (foundIndex > -1) {
|
||||
//console.log("Skip in queue");
|
||||
return null;
|
||||
}
|
||||
|
||||
return api.files.getFileInfo(file.id);
|
||||
});
|
||||
}, 300);
|
||||
} else if (opt?.type === "folder" && opt?.id) {
|
||||
const foundIndex = this.folders.findIndex((x) => x.id == opt?.id);
|
||||
|
||||
if (foundIndex > -1) return;
|
||||
|
||||
const folder = JSON.parse(opt?.data);
|
||||
|
||||
if (this.selectedFolderStore.id != folder.parentId) {
|
||||
const movedToIndex = this.getFolderIndex(folder.parentId);
|
||||
if (movedToIndex > -1) this.folders[movedToIndex].foldersCount++;
|
||||
}
|
||||
|
||||
if (
|
||||
this.selectedFolderStore.id != folder.parentId ||
|
||||
(folder.roomType &&
|
||||
folder.createdBy.id === this.userStore.user.id &&
|
||||
this.roomCreated)
|
||||
) {
|
||||
return (this.roomCreated = false);
|
||||
}
|
||||
|
||||
const folderInfo = await api.files.getFolderInfo(folder.id);
|
||||
|
||||
console.log("[WS] create new folder", folderInfo.id, folderInfo.title);
|
||||
|
||||
const newFolders = [folderInfo, ...this.folders];
|
||||
|
||||
if (
|
||||
newFolders.length > this.filter.pageCount &&
|
||||
this.settingsStore.withPaging
|
||||
) {
|
||||
newFolders.pop(); // Remove last
|
||||
}
|
||||
|
||||
const newFilter = this.filter;
|
||||
newFilter.total += 1;
|
||||
|
||||
runInAction(() => {
|
||||
this.setFilter(newFilter);
|
||||
this.setFolders(newFolders);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
wsModifyFolderUpdate = (opt) => {
|
||||
if (opt?.type === "file" && opt?.data) {
|
||||
const file = JSON.parse(opt?.data);
|
||||
if (!file || !file.id) return;
|
||||
|
||||
this.getFileInfo(file.id); //this.setFile(file);
|
||||
console.log("[WS] update file", file.id, file.title);
|
||||
|
||||
this.checkSelection(file);
|
||||
} else if (opt?.type === "folder" && opt?.data) {
|
||||
const folder = JSON.parse(opt?.data);
|
||||
if (!folder || !folder.id) return;
|
||||
|
||||
api.files
|
||||
.getFolderInfo(folder.id)
|
||||
.then(this.setFolder)
|
||||
.catch(() => {
|
||||
// console.log("Folder deleted")
|
||||
});
|
||||
|
||||
console.log("[WS] update folder", folder.id, folder.title);
|
||||
|
||||
if (this.selection?.length) {
|
||||
const foundIndex = this.selection?.findIndex((x) => x.id === folder.id);
|
||||
if (foundIndex > -1) {
|
||||
runInAction(() => {
|
||||
this.selection[foundIndex] = folder;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.bufferSelection) {
|
||||
const foundIndex = [this.bufferSelection].findIndex(
|
||||
(x) => x.id === folder.id,
|
||||
);
|
||||
if (foundIndex > -1) {
|
||||
runInAction(() => {
|
||||
this.bufferSelection[foundIndex] = folder;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (folder.id === this.selectedFolderStore.id) {
|
||||
this.selectedFolderStore.setSelectedFolder({ ...folder });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
wsModifyFolderDelete = (opt) => {
|
||||
if (opt?.type === "file" && opt?.id) {
|
||||
const foundIndex = this.files.findIndex((x) => x.id === opt?.id);
|
||||
if (foundIndex == -1) return;
|
||||
|
||||
console.log(
|
||||
"[WS] delete file",
|
||||
this.files[foundIndex].id,
|
||||
this.files[foundIndex].title,
|
||||
);
|
||||
|
||||
// this.setFiles(
|
||||
// this.files.filter((_, index) => {
|
||||
// return index !== foundIndex;
|
||||
// })
|
||||
// );
|
||||
|
||||
// const newFilter = this.filter.clone();
|
||||
// newFilter.total -= 1;
|
||||
// this.setFilter(newFilter);
|
||||
|
||||
const tempActionFilesIds = JSON.parse(
|
||||
JSON.stringify(this.tempActionFilesIds),
|
||||
);
|
||||
tempActionFilesIds.push(this.files[foundIndex].id);
|
||||
|
||||
this.setTempActionFilesIds(tempActionFilesIds);
|
||||
|
||||
this.debounceRemoveFiles();
|
||||
|
||||
// Hide pagination when deleting files
|
||||
runInAction(() => {
|
||||
this.isHidePagination = true;
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
if (
|
||||
this.files.length === 0 &&
|
||||
this.folders.length === 0 &&
|
||||
this.pageItemsLength > 1
|
||||
) {
|
||||
this.isLoadingFilesFind = true;
|
||||
}
|
||||
});
|
||||
} else if (opt?.type === "folder" && opt?.id) {
|
||||
const foundIndex = this.folders.findIndex((x) => x.id === opt?.id);
|
||||
if (foundIndex == -1) return;
|
||||
|
||||
console.log(
|
||||
"[WS] delete folder",
|
||||
this.folders[foundIndex].id,
|
||||
this.folders[foundIndex].title,
|
||||
);
|
||||
|
||||
const tempActionFoldersIds = JSON.parse(
|
||||
JSON.stringify(this.tempActionFoldersIds),
|
||||
);
|
||||
tempActionFoldersIds.push(this.folders[foundIndex].id);
|
||||
|
||||
this.setTempActionFoldersIds(tempActionFoldersIds);
|
||||
this.debounceRemoveFolders();
|
||||
|
||||
runInAction(() => {
|
||||
this.isHidePagination = true;
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
if (
|
||||
this.files.length === 0 &&
|
||||
this.folders.length === 0 &&
|
||||
this.pageItemsLength > 1
|
||||
) {
|
||||
this.isLoadingFilesFind = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
wsCreatedPDFForm = (option) => {
|
||||
if (!option.data) return;
|
||||
|
||||
const file = JSON.parse(option.data);
|
||||
|
||||
if (this.selectedFolderStore.id !== file.folderId) return;
|
||||
|
||||
const localKey = `${PDF_FORM_DIALOG_KEY}-${this.userStore.user.id}`;
|
||||
|
||||
const isFirst = JSON.parse(localStorage.getItem(localKey) ?? "true");
|
||||
|
||||
const event = new CustomEvent(Events.CREATE_PDF_FORM_FILE, {
|
||||
detail: {
|
||||
file,
|
||||
isFill: !option.isOneMember,
|
||||
isFirst,
|
||||
},
|
||||
});
|
||||
|
||||
if (isFirst) localStorage.setItem(localKey, "false");
|
||||
|
||||
window?.dispatchEvent(event);
|
||||
};
|
||||
|
||||
setIsErrorRoomNotAvailable = (state) => {
|
||||
this.isErrorRoomNotAvailable = state;
|
||||
};
|
||||
|
@ -349,6 +349,22 @@ class SelectedFolderStore {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
increaseFilesCount = () => {
|
||||
this.filesCount += 1;
|
||||
};
|
||||
|
||||
decreaseFilesCount = () => {
|
||||
this.filesCount -= 1;
|
||||
};
|
||||
|
||||
increaseFoldersCount = () => {
|
||||
this.foldersCount += 1;
|
||||
};
|
||||
|
||||
decreaseFoldersCount = () => {
|
||||
this.foldersCount -= 1;
|
||||
};
|
||||
}
|
||||
|
||||
export default SelectedFolderStore;
|
||||
|
@ -82,6 +82,7 @@ import InfoPanelStore from "./InfoPanelStore";
|
||||
import CampaignsStore from "./CampaignsStore";
|
||||
|
||||
import OAuthStore from "./OAuthStore";
|
||||
import FilesSocketStore from "./FilesSocketStore";
|
||||
|
||||
const oauthStore = new OAuthStore(userStore);
|
||||
|
||||
@ -157,6 +158,16 @@ const filesStore = new FilesStore(
|
||||
settingsStore,
|
||||
);
|
||||
|
||||
const filesSocketStore = new FilesSocketStore(
|
||||
settingsStore,
|
||||
clientLoadingStore,
|
||||
selectedFolderStore,
|
||||
treeFoldersStore,
|
||||
infoPanelStore,
|
||||
userStore,
|
||||
filesStore,
|
||||
);
|
||||
|
||||
const mediaViewerDataStore = new MediaViewerDataStore(
|
||||
filesStore,
|
||||
publicRoomStore,
|
||||
@ -324,6 +335,7 @@ const store = {
|
||||
profileActionsStore,
|
||||
|
||||
filesStore,
|
||||
filesSocketStore,
|
||||
|
||||
filesSettingsStore,
|
||||
mediaViewerDataStore,
|
||||
|
@ -54,7 +54,10 @@ export type TOptSocket = {
|
||||
data?: string;
|
||||
type?: "folder" | "file";
|
||||
id?: string;
|
||||
cmd?: "create" | "update" | "delete";
|
||||
cmd?: "create" | "update" | "delete" | "create-form";
|
||||
folderId?: string | number;
|
||||
fileId?: string | number;
|
||||
count?: string | number;
|
||||
} & TOptQuota;
|
||||
|
||||
export type TEmit = {
|
||||
@ -172,7 +175,7 @@ class SocketIOHelper {
|
||||
}
|
||||
};
|
||||
|
||||
on = (eventName: string, callback: (value: TOptSocket) => void) => {
|
||||
on = (eventName: string, callback: (value: TOptSocket | string) => void) => {
|
||||
if (!this.isEnabled) {
|
||||
callbacks.push({ eventName, callback });
|
||||
return;
|
||||
|
55
yarn.lock
55
yarn.lock
@ -2742,48 +2742,6 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@docspace/common@workspace:packages/common":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@docspace/common@workspace:packages/common"
|
||||
dependencies:
|
||||
"@babel/runtime": "npm:^7.21.0"
|
||||
"@loadable/component": "npm:^5.15.3"
|
||||
"@types/crypto-js": "npm:^4.2.1"
|
||||
"@welldone-software/why-did-you-render": "npm:^6.2.3"
|
||||
axios: "npm:^0.22.0"
|
||||
cross-fetch: "npm:3.1.5"
|
||||
fast-deep-equal: "npm:^3.1.3"
|
||||
global: "npm:^4.4.0"
|
||||
i18next: "npm:^20.6.1"
|
||||
mobx: "npm:^6.8.0"
|
||||
mobx-react: "npm:^7.6.0"
|
||||
moment: "npm:^2.29.4"
|
||||
moment-timezone: "npm:^0.5.43"
|
||||
prop-types: "npm:^15.8.1"
|
||||
query-string: "npm:7.1.3"
|
||||
re-resizable: "npm:^6.9.9"
|
||||
react: "npm:^18.2.0"
|
||||
react-autosize-textarea: "npm:^7.1.0"
|
||||
react-content-loader: "npm:^5.1.4"
|
||||
react-dom: "npm:^18.2.0"
|
||||
react-hammerjs: "npm:^1.0.1"
|
||||
react-i18next: "npm:^13.2.1"
|
||||
react-player: "npm:^1.15.3"
|
||||
react-router: "npm:^6.10.0"
|
||||
react-router-dom: "npm:^6.10.0"
|
||||
react-tooltip: "npm:^5.23.0"
|
||||
react-viewer: "npm:^3.2.2"
|
||||
react-virtualized-auto-sizer: "npm:^1.0.7"
|
||||
react-window: "npm:^1.8.8"
|
||||
react-window-infinite-loader: "npm:^1.0.8"
|
||||
screenfull: "npm:^5.2.0"
|
||||
sjcl: "npm:^1.0.8"
|
||||
socket.io-client: "npm:^4.6.1"
|
||||
styled-components: "npm:^5.3.9"
|
||||
workbox-window: "npm:^6.5.4"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@docspace/doceditor@workspace:packages/doceditor":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@docspace/doceditor@workspace:packages/doceditor"
|
||||
@ -9411,17 +9369,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@welldone-software/why-did-you-render@npm:^6.2.3":
|
||||
version: 6.2.3
|
||||
resolution: "@welldone-software/why-did-you-render@npm:6.2.3"
|
||||
dependencies:
|
||||
lodash: "npm:^4"
|
||||
peerDependencies:
|
||||
react: ^16 || ^17
|
||||
checksum: 10/7255723b0d6790f273e353449bf047fbbeaaf8fc0abcca0e8cd7dd9a0cce5a4da5bc9d055117b49d2ff7bfe9a0737faf0a268630e4a72722bc14de0b29714809
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@wojtekmaj/enzyme-adapter-react-17@npm:^0.4.1":
|
||||
version: 0.4.1
|
||||
resolution: "@wojtekmaj/enzyme-adapter-react-17@npm:0.4.1"
|
||||
@ -19403,7 +19350,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash@npm:4.17.21, lodash@npm:^4, lodash@npm:^4.0.1, lodash@npm:^4.17.13, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21":
|
||||
"lodash@npm:4.17.21, lodash@npm:^4.0.1, lodash@npm:^4.17.13, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21":
|
||||
version: 4.17.21
|
||||
resolution: "lodash@npm:4.17.21"
|
||||
checksum: 10/c08619c038846ea6ac754abd6dd29d2568aa705feb69339e836dfa8d8b09abbb2f859371e86863eda41848221f9af43714491467b5b0299122431e202bb0c532
|
||||
|
Loading…
Reference in New Issue
Block a user