Skip to content

Commit

Permalink
feat: MVP workflow for file uploads and running pipelines
Browse files Browse the repository at this point in the history
  • Loading branch information
PintoGideon committed Jul 18, 2024
1 parent 0b9ecd4 commit 5ffe982
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 19 deletions.
3 changes: 0 additions & 3 deletions src/components/NewLibrary/components/Cart.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,3 @@
display: none !important ;
}

.operation-cart .ant-spin-container {
display: none !important ;
}
24 changes: 23 additions & 1 deletion src/components/NewLibrary/components/Cart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useDispatch } from "react-redux";
import {
clearSelectFolder,
setToggleCart,
startAnonymize,
startDownload,
} from "../../../store/cart/actionts";
import type { SelectionPayload } from "../../../store/cart/types";
Expand All @@ -20,23 +21,44 @@ const Cart = () => {

return (
<Drawer
width={"500px"}
width={"600px"}
title={
<>
<Button
style={{
marginRight: "1em",
}}
size="sm"
>
Create Feed
</Button>
<Button
style={{
marginRight: "1em",
}}
onClick={() => {
dispatch(startDownload(selectedPaths));
}}
size="sm"
>
Download
</Button>

{(!isEmpty(fileUploadStatus) || !isEmpty(folderUploadStatus)) && (
<Button
size="sm"
onClick={() => {
dispatch(
startAnonymize({
fileUpload: fileUploadStatus,
folderUpload: folderUploadStatus,
}),
);
}}
>
Anonymize
</Button>
)}
</>
}
open={openCart}
Expand Down
11 changes: 6 additions & 5 deletions src/components/Store/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Client, { Plugin, PluginMeta } from "@fnndsc/chrisapi";
import Client, { type Plugin, type PluginMeta } from "@fnndsc/chrisapi";
import {
ActionGroup,
Badge,
Expand All @@ -11,7 +11,7 @@ import {
GridItem,
Icon,
MenuToggle,
MenuToggleElement,
type MenuToggleElement,
Modal,
PageSection,
Select,
Expand All @@ -30,7 +30,7 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Alert, Spin, Typography, notification } from "antd";
import { format } from "date-fns";
import { isEmpty } from "lodash";
import { Ref, useEffect, useState } from "react";
import { type Ref, useEffect, useState } from "react";
import { Cookies, useCookies } from "react-cookie";
import { useDispatch } from "react-redux";
import ChrisAPIClient from "../../api/chrisapiclient";
Expand All @@ -46,6 +46,7 @@ const { Paragraph } = Typography;

const Store = () => {
const isStaff = useTypedSelector((state) => state.user.isStaff);

const queryClient = useQueryClient();
const [_cookie, setCookie, removeCookie] = useCookies();
const [api, contextHolder] = notification.useNotification();
Expand Down Expand Up @@ -162,8 +163,6 @@ const Store = () => {
);
if (!adminURL)
throw new Error("Please provide a link to your chris-admin url");
if (!username || !password)
throw new Error("Please provide both username and password");

const client = ChrisAPIClient.getClient();
const adminCredentials = btoa(`${username.trim()}:${password.trim()}`); // Base64 encoding for Basic Auth
Expand Down Expand Up @@ -251,8 +250,10 @@ const Store = () => {
}

if (handleInstallMutation.isError) {
console.log();
api.error({
message: "Unable to install this plugin...",
description: handleInstallMutation.error.message,
});
}
}, [handleInstallMutation.isSuccess, handleInstallMutation.isError, api]);
Expand Down
13 changes: 13 additions & 0 deletions src/store/cart/actionts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,29 @@ export const setFolderDownloadStatus = (payload: {
export const startUpload = (payload: UploadPayload) =>
action(ICartActionTypes.START_UPLOAD, payload);

export const startAnonymize = (payload: {
fileUpload: FileUpload;
folderUpload: FolderUpload;
}) => action(ICartActionTypes.START_ANONYMIZE, payload);

export const setFileUploadStatus = (payload: {
step: string;
fileName: string;
progress: number;
controller: AbortController;
path: string;
type: string;
}) => action(ICartActionTypes.SET_FILE_UPLOAD_STATUS, payload);

export const setFolderUploadStatus = (payload: {
step: string;
fileName: string;
totalCount: number;
currentCount: number;
controller: AbortController;
path: string;
type: string;
}) => action(ICartActionTypes.SET_FOLDER_UPLOAD_STATUS, payload);

export const setBulkSelectPaths = (payload: SelectionPayload[]) =>
action(ICartActionTypes.SET_BULK_SELECTED_PATHS, payload);
26 changes: 23 additions & 3 deletions src/store/cart/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ const reducer: Reducer<ICartState> = (
selectedPaths: [...state.selectedPaths, action.payload],
};
}

case ICartActionTypes.SET_BULK_SELECTED_PATHS: {
return {
...state,
selectedPaths: [...state.selectedPaths, ...action.payload],
};
}

case ICartActionTypes.CLEAR_SELECTED_PATHS: {
const newSelectedPaths = state.selectedPaths.filter((pathObj) => {
return pathObj.path !== action.payload;
Expand Down Expand Up @@ -69,7 +77,8 @@ const reducer: Reducer<ICartState> = (
}

case ICartActionTypes.SET_FILE_UPLOAD_STATUS: {
const { step, fileName, progress, controller } = action.payload;
const { step, fileName, progress, controller, path, type } =
action.payload;

return {
...state,
Expand All @@ -79,14 +88,23 @@ const reducer: Reducer<ICartState> = (
currentStep: step,
progress,
controller,
path,
type,
},
},
};
}

case ICartActionTypes.SET_FOLDER_UPLOAD_STATUS: {
const { step, fileName, totalCount, currentCount, controller } =
action.payload;
const {
step,
fileName,
totalCount,
currentCount,
controller,
path,
type,
} = action.payload;
return {
...state,
folderUploadStatus: {
Expand All @@ -96,6 +114,8 @@ const reducer: Reducer<ICartState> = (
done: currentCount,
total: totalCount,
controller,
path,
type,
},
},
};
Expand Down
108 changes: 101 additions & 7 deletions src/store/cart/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import type {
FileBrowserFolder,
FileBrowserFolderFile,
FileBrowserFolderFileList,
FileBrowserFolderList,
ItemResource,
Pipeline,
PipelineList,
Plugin,
PluginInstance,
PluginInstanceList,
UserFile,
UserFileList,
} from "@fnndsc/chrisapi";
import { take, call, all, fork, put, takeEvery } from "redux-saga/effects";
import { type EventChannel, eventChannel, END } from "redux-saga";
Expand All @@ -22,8 +25,13 @@ import {
setFolderDownloadStatus,
setFileUploadStatus,
setFolderUploadStatus,
startDownload,
setSelectFolder,
setBulkSelectPaths,
} from "./actionts";
import {
type FileUpload,
type FolderUpload,
ICartActionTypes,
type SelectionPayload,
type UploadPayload,
Expand Down Expand Up @@ -213,7 +221,8 @@ function* uploadFile(
const url = `${import.meta.env.VITE_CHRIS_UI_URL}userfiles/`;
const formData = new FormData();
const name = isFolder ? file.webkitRelativePath : file.name;
formData.append("upload_path", `${currentPath}/${name}`);
const path = `${currentPath}/${name}`;
formData.append("upload_path", path);
formData.append("fname", file, file.name);

const config = {
Expand All @@ -239,6 +248,8 @@ function* uploadFile(
fileName: file.name,
progress,
controller,
path,
type: "file",
}),
);

Expand All @@ -249,33 +260,41 @@ function* uploadFile(
fileName: file.name,
progress,
controller,
path,
type: "file",
}),
);
}
} else {
if (progress === 100) {
const fileName = name.split("/")[0];
const nameSplit = name.split("/");
const fileName = nameSplit[0];
const folderPath = `${currentPath}/${fileName}`;

count[fileName] = count[fileName] ? count[fileName] + 1 : 1;

yield put(
setFolderUploadStatus({
step: "Uploading",
fileName: name.split("/")[0],
fileName,
totalCount: files.length,
currentCount: count[fileName],
controller,
path: folderPath,
type: "folder",
}),
);

if (count[fileName] === files.length) {
yield put(
setFolderUploadStatus({
step: "Upload Complete",
fileName: name.split("/")[0],
fileName,
totalCount: files.length,
currentCount: count[fileName],
controller,
path: folderPath,
type: "folder",
}),
);
delete count[fileName];
Expand Down Expand Up @@ -303,8 +322,6 @@ function* handleUpload(action: IActionTypeParam) {
const { files, isFolder, currentPath }: UploadPayload = action.payload;
const client = ChrisAPIClient.getClient();

console.log("HandleUpload", files, isFolder);

try {
yield all(
files.map((file: File) => {
Expand All @@ -325,6 +342,79 @@ function* handleUpload(action: IActionTypeParam) {
}
}

function* handleAnonymize(action: IActionTypeParam) {
const {
fileUpload,
folderUpload,
}: {
fileUpload: FileUpload;
folderUpload: FolderUpload;
} = action.payload;

const client = ChrisAPIClient.getClient();

const filePaths = Object.entries(fileUpload).map(([_name, status]) => {
return {
type: status.type,
path: status.path,
};
});

const folderPaths = Object.entries(folderUpload).map(([_name, status]) => {
return {
type: status.type,
path: status.path,
};
});

console.log("FolderPaths", folderPaths);

const createFileSelectionPayload: {
payload: UserFile;
type: string;
path: string;
}[] = yield all(
filePaths.map(async (file) => {
const userFileList: UserFileList = await client.getUserFiles({
fname_exact: file.path,
limit: 1,
});

const userFiles = userFileList.getItems() as UserFile[];

return {
payload: userFiles[0],
type: file.type,
path: file.path,
};
}),
);

const createFolderSelectionPayload: {
payload: FileBrowserFolder | FileBrowserFolderFile;
type: string;
path: string;
}[] = yield all(
folderPaths.map(async (folder) => {
const folderToAnon: FileBrowserFolder =
(await client.getFileBrowserFolderByPath(
folder.path,
)) as unknown as FileBrowserFolder;

return {
payload: folderToAnon,
type: folder.type,
path: folderToAnon.data.path,
};
}),
);

yield put(setBulkSelectPaths(createFolderSelectionPayload));
yield put(setBulkSelectPaths(createFileSelectionPayload));
yield put(startDownload(createFolderSelectionPayload));
yield put(startDownload(createFileSelectionPayload));
}

function* watchDownload() {
yield takeEvery(ICartActionTypes.START_DOWNLOAD, handleDownload);
}
Expand All @@ -333,6 +423,10 @@ function* watchUpload() {
yield takeEvery(ICartActionTypes.START_UPLOAD, handleUpload);
}

function* watchAnonymize() {
yield takeEvery(ICartActionTypes.START_ANONYMIZE, handleAnonymize);
}

export function* cartSaga() {
yield all([fork(watchDownload), fork(watchUpload)]);
yield all([fork(watchDownload), fork(watchUpload), fork(watchAnonymize)]);
}
Loading

0 comments on commit 5ffe982

Please sign in to comment.