Skip to content

Commit

Permalink
feat(ui): add workflow sharing modal (#375)
Browse files Browse the repository at this point in the history
Closes #651
  • Loading branch information
DaanRosendal authored and tiborsimko committed Sep 4, 2024
1 parent ea20030 commit 7722ff3
Show file tree
Hide file tree
Showing 12 changed files with 1,143 additions and 208 deletions.
1 change: 1 addition & 0 deletions reana-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"react-redux": "^8.1.3",
"react-router-dom": "^6.17.0",
"react-scripts": "^5.0.0",
"react-semantic-ui-datepickers": "^2.17.2",
"redux": "^4.0.4",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0",
Expand Down
108 changes: 108 additions & 0 deletions reana-ui/src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,23 @@ export const WORKFLOW_STOP_INIT = "Initialize workflow stopping";
export const WORKFLOW_STOPPED = "Workflow stopped";
export const OPEN_STOP_WORKFLOW_MODAL = "Open stop workflow modal";
export const CLOSE_STOP_WORKFLOW_MODAL = "Close stop workflow modal";
export const OPEN_SHARE_WORKFLOW_MODAL = "Open share workflow modal";
export const CLOSE_SHARE_WORKFLOW_MODAL = "Close share workflow modal";
export const WORKFLOW_LIST_REFRESH = "Refresh workflow list";
export const OPEN_INTERACTIVE_SESSION_MODAL = "Open interactive session modal";
export const CLOSE_INTERACTIVE_SESSION_MODAL =
"Close interactive session modal";
export const WORKFLOW_SHARE_STATUS_FETCH = "Fetch workflow share status";
export const WORKFLOW_SHARE_STATUS_RECEIVED = "Workflow share status received";
export const WORKFLOW_SHARE_STATUS_FETCH_ERROR =
"Fetch workflow share status error";
export const WORKFLOW_SHARE_INIT = "Initialise workflow sharing";
export const WORKFLOW_SHARED_SUCCESSFULLY = "Workflow shared successfully";
export const WORKFLOW_SHARED_ERROR = "Workflow shared error";
export const WORKFLOW_SHARE_FINISH = "Finish workflow sharing";
export const WORKFLOW_UNSHARE_INIT = "Initialise workflow unsharing";
export const WORKFLOW_UNSHARED = "Workflow unshared";
export const WORKFLOW_UNSHARE_ERROR = "Workflow unshare error";

export const USERS_SHARED_WITH_YOU_FETCH =
"Fetch users who shared workflows with you";
Expand Down Expand Up @@ -540,6 +553,14 @@ export function closeInteractiveSession(id) {
};
}

export function openShareWorkflowModal(workflow) {
return { type: OPEN_SHARE_WORKFLOW_MODAL, workflow };
}

export function closeShareWorkflowModal() {
return { type: CLOSE_SHARE_WORKFLOW_MODAL };
}

export function fetchUsersSharedWithYou() {
return async (dispatch) => {
dispatch({ type: USERS_SHARED_WITH_YOU_FETCH });
Expand Down Expand Up @@ -577,3 +598,90 @@ export function fetchUsersYouSharedWith() {
});
};
}

export function fetchWorkflowShareStatus(id) {
return async (dispatch) => {
dispatch({ type: WORKFLOW_SHARE_STATUS_FETCH });
return await client
.getWorkflowShareStatus(id)
.then((resp) => {
dispatch({
type: WORKFLOW_SHARE_STATUS_RECEIVED,
id,
workflow_share_status: resp.data.shared_with,
});
return resp;
})
.catch((err) => {
dispatch(errorActionCreator(err, WORKFLOW_SHARE_STATUS_FETCH_ERROR));
});
};
}

export function shareWorkflow(
id,
user_id,
user_emails_to_share_with,
valid_until,
) {
return async (dispatch) => {
dispatch({ type: WORKFLOW_SHARE_INIT });

const users_shared_with = [];
const users_not_shared_with = [];

for (const user_email_to_share_with of user_emails_to_share_with) {
await client
.shareWorkflow(id, {
user_id,
user_email_to_share_with,
valid_until,
})
.then(() => {
users_shared_with.push(user_email_to_share_with);
})
.catch((err) => {
const error_message = err.response.data.message;
users_not_shared_with.push({
user_email_to_share_with,
error_message,
});
});

if (users_shared_with.length > 0) {
dispatch({
type: WORKFLOW_SHARED_SUCCESSFULLY,
users_shared_with,
});
}

if (users_not_shared_with.length > 0) {
dispatch({
type: WORKFLOW_SHARED_ERROR,
users_not_shared_with,
});
}
}

dispatch({ type: WORKFLOW_SHARE_FINISH });
};
}

export function unshareWorkflow(id, user_id, user_email_to_unshare_with) {
return async (dispatch) => {
dispatch({ type: WORKFLOW_UNSHARE_INIT });

return await client
.unshareWorkflow(id, {
user_id,
user_email_to_unshare_with,
})
.then(() => {
dispatch({ type: WORKFLOW_UNSHARED, user_email_to_unshare_with });
})
.catch((err) => {
const error_message = err.response.data.message;
dispatch({ type: WORKFLOW_UNSHARE_ERROR, error_message });
});
};
}
23 changes: 23 additions & 0 deletions reana-ui/src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export const WORKFLOW_FILE_URL = (id, filename, preview = true) =>
)}`;
export const WORKFLOW_SET_STATUS_URL = (id, status) =>
`${api}/api/workflows/${id}/status?${stringifyQueryParams(status)}`;
export const WORKFLOW_SHARE_STATUS_URL = (id) =>
`${api}/api/workflows/${id}/share-status`;
export const WORKFLOW_SHARE_URL = (id) => `${api}/api/workflows/${id}/share`;
export const WORKFLOW_UNSHARE_URL = (id) =>
`${api}/api/workflows/${id}/unshare`;
export const INTERACTIVE_SESSIONS_OPEN_URL = (id, type = "jupyter") =>
`${api}/api/workflows/${id}/open/${type}`;
export const INTERACTIVE_SESSIONS_CLOSE_URL = (id) =>
Expand Down Expand Up @@ -226,6 +231,24 @@ class Client {
getUsersYouSharedWith() {
return this._request(USERS_YOU_SHARED_WITH_URL);
}

getWorkflowShareStatus(id) {
return this._request(WORKFLOW_SHARE_STATUS_URL(id));
}

shareWorkflow(id, data) {
return this._request(WORKFLOW_SHARE_URL(id), {
data,
method: "post",
});
}

unshareWorkflow(id, data) {
return this._request(WORKFLOW_UNSHARE_URL(id), {
data,
method: "post",
});
}
}

const client = new Client();
Expand Down
12 changes: 12 additions & 0 deletions reana-ui/src/components/WorkflowActionsPopup.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
openDeleteWorkflowModal,
openStopWorkflowModal,
openInteractiveSessionModal,
openShareWorkflowModal,
} from "~/actions";

import { JupyterNotebookIcon } from "~/components";
Expand Down Expand Up @@ -51,6 +52,17 @@ export default function WorkflowActionsPopup({ workflow, className }) {
});
}

menuItems.push({
key: "share",
content: "Share workflow",
icon: "share alternate",
onClick: (e) => {
dispatch(openShareWorkflowModal(workflow));
setOpen(false);
e.stopPropagation();
},
});

if (isSessionOpen) {
menuItems.push({
key: "closeNotebook",
Expand Down
Loading

0 comments on commit 7722ff3

Please sign in to comment.