Web:Client:FilesSelector: add socket for create, update or delete file or folder inside tab
This commit is contained in:
parent
10c18125eb
commit
e5a4e57774
@ -41,6 +41,22 @@ export type useLoadersHelperProps = {
|
||||
items: Item[] | null;
|
||||
};
|
||||
|
||||
export type setItemsCallback = (value: Item[] | null) => Item[] | null;
|
||||
export type setBreadCrumbsCallback = (
|
||||
value: BreadCrumb[] | []
|
||||
) => BreadCrumb[] | [];
|
||||
export type setTotalCallback = (value: number) => number;
|
||||
|
||||
export type useSocketHelperProps = {
|
||||
socketHelper: any;
|
||||
socketSubscribersId: Set<string>;
|
||||
setItems: (callback: setItemsCallback) => void;
|
||||
setBreadCrumbs: (callback: setBreadCrumbsCallback) => void;
|
||||
setTotal: (callback: setTotalCallback) => void;
|
||||
disabledItems: string[] | number[];
|
||||
filterParam?: string;
|
||||
};
|
||||
|
||||
export type useRootHelperProps = {
|
||||
setBreadCrumbs: (items: BreadCrumb[]) => void;
|
||||
setIsBreadCrumbsLoading: (value: boolean) => void;
|
||||
@ -153,4 +169,7 @@ export type FilesSelectorProps = {
|
||||
setSelectedItems: () => void;
|
||||
|
||||
includeFolder?: boolean;
|
||||
|
||||
socketHelper: any;
|
||||
socketSubscribersId: Set<string>;
|
||||
};
|
||||
|
@ -171,7 +171,7 @@ const getIconUrl = (extension: string, isImage: boolean, isMedia: boolean) => {
|
||||
return iconSize32.get(path);
|
||||
};
|
||||
|
||||
const convertFoldersToItems = (
|
||||
export const convertFoldersToItems = (
|
||||
folders: any,
|
||||
disabledItems: any[],
|
||||
filterParam?: string
|
||||
@ -215,9 +215,17 @@ const convertFoldersToItems = (
|
||||
return items;
|
||||
};
|
||||
|
||||
const convertFilesToItems = (files: any, filterParam?: string) => {
|
||||
export const convertFilesToItems = (files: any, filterParam?: string) => {
|
||||
const items = files.map((file: any) => {
|
||||
const { id, title, security, parentId, rootFolderType, fileExst } = file;
|
||||
const {
|
||||
id,
|
||||
title,
|
||||
security,
|
||||
parentId,
|
||||
folderId,
|
||||
rootFolderType,
|
||||
fileExst,
|
||||
} = file;
|
||||
|
||||
const isImage = file.viewAccessability.ImageView;
|
||||
const isMedia = file.viewAccessability.MediaView;
|
||||
@ -231,9 +239,8 @@ const convertFilesToItems = (files: any, filterParam?: string) => {
|
||||
label: title.replace(fileExst, ""),
|
||||
title,
|
||||
icon,
|
||||
|
||||
security,
|
||||
parentId,
|
||||
parentId: parentId || folderId,
|
||||
rootFolderType,
|
||||
isFolder: false,
|
||||
isDisabled: !filterParam,
|
||||
|
@ -0,0 +1,220 @@
|
||||
import React from "react";
|
||||
|
||||
import { convertFilesToItems, convertFoldersToItems } from "./useFilesHelper";
|
||||
|
||||
import {
|
||||
Item,
|
||||
setItemsCallback,
|
||||
useSocketHelperProps,
|
||||
} from "../FilesSelector.types";
|
||||
|
||||
const useSocketHelper = ({
|
||||
socketHelper,
|
||||
socketSubscribersId,
|
||||
setItems,
|
||||
setBreadCrumbs,
|
||||
setTotal,
|
||||
disabledItems,
|
||||
filterParam,
|
||||
}: useSocketHelperProps) => {
|
||||
const subscribedId = React.useRef<null | number>(null);
|
||||
|
||||
const subscribe = (id: number) => {
|
||||
const roomParts = `DIR-${id}`;
|
||||
|
||||
if (socketSubscribersId.has(roomParts)) return (subscribedId.current = id);
|
||||
|
||||
if (subscribedId.current && !socketSubscribersId.has(roomParts)) {
|
||||
unsubscribe(subscribedId.current, false);
|
||||
}
|
||||
|
||||
socketHelper.emit({
|
||||
command: "subscribe",
|
||||
data: {
|
||||
roomParts: `DIR-${id}`,
|
||||
individual: true,
|
||||
},
|
||||
});
|
||||
|
||||
subscribedId.current = id;
|
||||
};
|
||||
|
||||
const unsubscribe = (id: number, clear = true) => {
|
||||
if (clear) {
|
||||
subscribedId.current = null;
|
||||
}
|
||||
|
||||
if (id && !socketSubscribersId.has(`DIR-${id}`)) {
|
||||
socketHelper.emit({
|
||||
command: "unsubscribe",
|
||||
data: {
|
||||
roomParts: `DIR-${id}`,
|
||||
individual: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const addItem = React.useCallback((opt: any) => {
|
||||
if (!opt?.data) return;
|
||||
|
||||
const data = JSON.parse(opt.data);
|
||||
|
||||
if (
|
||||
data.folderId
|
||||
? data.folderId !== subscribedId.current
|
||||
: data.parentId !== subscribedId.current
|
||||
)
|
||||
return;
|
||||
|
||||
let item: null | Item = null;
|
||||
|
||||
if (opt?.type === "file") {
|
||||
item = convertFilesToItems([data], filterParam)[0];
|
||||
} else if (opt?.type === "folder") {
|
||||
item = convertFoldersToItems([data], disabledItems, filterParam)[0];
|
||||
}
|
||||
|
||||
const callback: setItemsCallback = (value: Item[] | null) => {
|
||||
if (!item || !value) return value;
|
||||
|
||||
if (opt.type === "folder") {
|
||||
setTotal((value) => value + 1);
|
||||
|
||||
return [item, ...value];
|
||||
}
|
||||
|
||||
if (opt.type === "file") {
|
||||
let idx = 0;
|
||||
|
||||
for (let i = 0; i < value.length - 1; i++) {
|
||||
if (!value[i].isFolder) break;
|
||||
|
||||
idx = i + 1;
|
||||
}
|
||||
|
||||
const newValue = [...value];
|
||||
|
||||
newValue.splice(idx, 0, item);
|
||||
|
||||
setTotal((value) => value + 1);
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
setItems(callback);
|
||||
}, []);
|
||||
|
||||
const updateItem = React.useCallback((opt: any) => {
|
||||
if (!opt?.data) return;
|
||||
|
||||
const data = JSON.parse(opt.data);
|
||||
|
||||
if (
|
||||
data.folderId
|
||||
? data.folderId !== subscribedId.current
|
||||
: data.parentId !== subscribedId.current
|
||||
)
|
||||
return;
|
||||
|
||||
let item: null | Item = null;
|
||||
|
||||
if (opt?.type === "file") {
|
||||
item = convertFilesToItems([data], filterParam)[0];
|
||||
} else if (opt?.type === "folder") {
|
||||
item = convertFoldersToItems([data], disabledItems, filterParam)[0];
|
||||
}
|
||||
|
||||
const callback: setItemsCallback = (value: Item[] | null) => {
|
||||
if (!item || !value) return value;
|
||||
|
||||
if (opt.type === "folder") {
|
||||
const idx = value.findIndex((v) => v.id === item?.id && v.isFolder);
|
||||
|
||||
if (idx > -1) {
|
||||
const newValue = [...value];
|
||||
|
||||
newValue.splice(idx, 1, item);
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
setBreadCrumbs((breadCrumbsValue) => {
|
||||
if (breadCrumbsValue[breadCrumbsValue.length - 1].id === item?.id) {
|
||||
breadCrumbsValue[breadCrumbsValue.length - 1].label = item.label;
|
||||
}
|
||||
|
||||
return breadCrumbsValue;
|
||||
});
|
||||
}
|
||||
|
||||
if (opt.type === "file") {
|
||||
const idx = value.findIndex((v) => v.id === item?.id && !v.isFolder);
|
||||
|
||||
if (idx > -1) {
|
||||
const newValue = [...value];
|
||||
|
||||
newValue.splice(idx, 1, item);
|
||||
|
||||
return [...newValue];
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
setItems(callback);
|
||||
}, []);
|
||||
|
||||
const deleteItem = React.useCallback((opt: any) => {
|
||||
const callback: setItemsCallback = (value: Item[] | null) => {
|
||||
if (!value) return value;
|
||||
|
||||
if (opt.type === "folder") {
|
||||
const newValue = value.filter((v) => +v.id !== +opt?.id || !v.isFolder);
|
||||
|
||||
if (newValue.length !== value.length) {
|
||||
setTotal((value) => value - 1);
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
if (opt.type === "file") {
|
||||
const newValue = value.filter((v) => +v.id !== +opt?.id || v.isFolder);
|
||||
|
||||
if (newValue.length !== value.length) {
|
||||
setTotal((value) => value - 1);
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
setItems(callback);
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
socketHelper.on("s:modify-folder", async (opt: any) => {
|
||||
switch (opt?.cmd) {
|
||||
case "create":
|
||||
addItem(opt);
|
||||
break;
|
||||
case "update":
|
||||
updateItem(opt);
|
||||
break;
|
||||
case "delete":
|
||||
deleteItem(opt);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}, [addItem, updateItem, deleteItem]);
|
||||
|
||||
return { subscribe, unsubscribe };
|
||||
};
|
||||
|
||||
export default useSocketHelper;
|
@ -29,6 +29,7 @@ import useRoomsHelper from "./helpers/useRoomsHelper";
|
||||
import useLoadersHelper from "./helpers/useLoadersHelper";
|
||||
import useFilesHelper from "./helpers/useFilesHelper";
|
||||
import { getAcceptButtonLabel, getHeaderLabel, getIsDisabled } from "./utils";
|
||||
import useSocketHelper from "./helpers/useSocketHelper";
|
||||
|
||||
const FilesSelector = ({
|
||||
isPanelVisible = false,
|
||||
@ -84,6 +85,9 @@ const FilesSelector = ({
|
||||
setSelectedItems,
|
||||
|
||||
includeFolder,
|
||||
|
||||
socketHelper,
|
||||
socketSubscribersId,
|
||||
}: FilesSelectorProps) => {
|
||||
const { t } = useTranslation(["Files", "Common", "Translations"]);
|
||||
|
||||
@ -114,6 +118,16 @@ const FilesSelector = ({
|
||||
const [isRequestRunning, setIsRequestRunning] =
|
||||
React.useState<boolean>(false);
|
||||
|
||||
const { subscribe, unsubscribe } = useSocketHelper({
|
||||
socketHelper,
|
||||
socketSubscribersId,
|
||||
setItems,
|
||||
setBreadCrumbs,
|
||||
setTotal,
|
||||
disabledItems,
|
||||
filterParam,
|
||||
});
|
||||
|
||||
const {
|
||||
setIsBreadCrumbsLoading,
|
||||
isNextPageLoading,
|
||||
@ -194,6 +208,13 @@ const FilesSelector = ({
|
||||
}
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!selectedItemId) return;
|
||||
if (selectedItemId && isRoot) return unsubscribe(+selectedItemId);
|
||||
|
||||
subscribe(+selectedItemId);
|
||||
}, [selectedItemId, isRoot]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!withoutBasicSelection) {
|
||||
onSelectFolder && onSelectFolder(currentFolderId);
|
||||
@ -514,7 +535,12 @@ export default inject(
|
||||
}: any,
|
||||
{ isCopy, isRestoreAll, isMove, isPanelVisible, id, passedFoldersTree }: any
|
||||
) => {
|
||||
const { id: selectedId, parentId, rootFolderType } = selectedFolderStore;
|
||||
const {
|
||||
id: selectedId,
|
||||
parentId,
|
||||
rootFolderType,
|
||||
socketSubscribersId,
|
||||
} = selectedFolderStore;
|
||||
|
||||
const { setConflictDialogData, checkFileConflicts, setSelectedItems } =
|
||||
filesActionsStore;
|
||||
@ -550,10 +576,15 @@ export default inject(
|
||||
setIsFolderActions,
|
||||
} = dialogsStore;
|
||||
|
||||
const { theme } = auth.settingsStore;
|
||||
const { theme, socketHelper } = auth.settingsStore;
|
||||
|
||||
const { selection, bufferSelection, filesList, setMovingInProgress } =
|
||||
filesStore;
|
||||
const {
|
||||
selection,
|
||||
bufferSelection,
|
||||
filesList,
|
||||
|
||||
setMovingInProgress,
|
||||
} = filesStore;
|
||||
|
||||
const selections =
|
||||
isMove || isCopy || isRestoreAll
|
||||
@ -608,6 +639,8 @@ export default inject(
|
||||
setIsFolderActions,
|
||||
setSelectedItems,
|
||||
includeFolder,
|
||||
socketHelper,
|
||||
socketSubscribersId,
|
||||
};
|
||||
}
|
||||
)(observer(FilesSelector));
|
||||
|
@ -22,6 +22,7 @@ const compareFunction = (prevProps: ItemProps, nextProps: ItemProps) => {
|
||||
|
||||
return (
|
||||
prevItem?.id === nextItem?.id &&
|
||||
prevItem?.label === nextItem?.label &&
|
||||
prevItem?.isSelected === nextItem?.isSelected
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user