Skip to content

Commit

Permalink
Merge branch 'task/digital-rocks' into task/WC-166--sort-pub-requests
Browse files Browse the repository at this point in the history
  • Loading branch information
shayanaijaz authored Dec 10, 2024
2 parents 61273c3 + 7787b4a commit cdce886
Show file tree
Hide file tree
Showing 24 changed files with 473 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Button, Message } from '_common';
import { Modal, ModalHeader, ModalBody } from 'reactstrap';
import DataFilesProjectMembers from '../DataFilesProjectMembers/DataFilesProjectMembers';
import styles from './DataFilesManageProject.module.scss';
import { useAddonComponents } from 'hooks/datafiles';

const DataFilesManageProjectModal = () => {
const dispatch = useDispatch();
Expand Down Expand Up @@ -40,6 +41,12 @@ const DataFilesManageProjectModal = () => {
return projectSystem?.readOnly || !canEditSystem;
});

const portalName = useSelector((state) => state.workbench.portalName);

const { DataFilesManageProjectModalAddon } = useAddonComponents({
portalName,
});

const toggle = useCallback(() => {
setTransferMode(false);
dispatch({
Expand Down Expand Up @@ -154,6 +161,9 @@ const DataFilesManageProjectModal = () => {
</Button>
) : null}
</div>
{DataFilesManageProjectModalAddon && (
<DataFilesManageProjectModalAddon projectId={projectId} />
)}
</ModalBody>
</Modal>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const DataFilesProjectEditDescriptionModal = () => {
description: values.description || '',
metadata: DataFilesProjectEditDescriptionModalAddon ? values : null,
},
modal: 'editproject',
},
});
},
Expand Down Expand Up @@ -89,7 +90,7 @@ const DataFilesProjectEditDescriptionModal = () => {
{({ isValid, dirty }) => (
<Form>
<ModalHeader toggle={toggle} charCode="&#xe912;">
Edit Project
Edit Dataset
</ModalHeader>
<ModalBody className={styles['modal-body']}>
<FormField
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ const DataFilesProjectFileListing = ({ rootSystem, system, path }) => {
{canEditSystem ? (
<>
<Button type="link" onClick={onEdit}>
Edit Project
Edit Dataset
</Button>
<span className={styles.separator}>|</span>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
import React, { useState, useCallback, useEffect, useMemo } from 'react';
import * as Yup from 'yup';
import styles from './DataFilesManageProjectModalAddon.module.scss';
import { useDispatch, useSelector } from 'react-redux';
import { useSystemRole } from '../../../DataFiles/DataFilesProjectMembers/_cells/SystemRoleSelector';
import { Input, Label } from 'reactstrap';
import { FieldArray, Form, Formik, useFormikContext } from 'formik';
import {
Button,
FormField,
InfiniteScrollTable,
LoadingSpinner,
Section,
} from '_common';

const DataFilesManageProjectModalAddon = ({ projectId }) => {
const dispatch = useDispatch();

const { metadata } = useSelector((state) => state.projects);

const { loading, error } = useSelector((state) => {
if (
state.projects.operation &&
state.projects.operation.name === 'titleDescription'
) {
return state.projects.operation;
}
return {
loading: false,
error: false,
};
});

const authenticatedUser = useSelector(
(state) => state.authenticatedUser.user.username
);

const { query: authenticatedUserQuery } = useSystemRole(
projectId ?? null,
authenticatedUser ?? null
);

const canEditSystem = ['OWNER', 'ADMIN'].includes(
authenticatedUserQuery?.data?.role
);

const readOnlyTeam = useSelector((state) => {
const projectSystem = state.systems.storage.configuration.find(
(s) => s.scheme === 'projects'
);

return projectSystem?.readOnly || !canEditSystem;
});

const handleRemoveGuestUser = useCallback(
(email) => {
const updatedGuestUsers = metadata.guest_users.filter(
(user) => user.email !== email
);

dispatch({
type: 'PROJECTS_SET_TITLE_DESCRIPTION',
payload: {
projectId,
data: {
title: metadata.title,
description: metadata.description || '',
metadata: {
guest_users: updatedGuestUsers,
},
},
modal: '',
},
});
},
[metadata, dispatch, projectId] // Dependency array
);

const columns = [
{
Header: 'Guest Members',
accessor: (el) => el,
Cell: (el) => {
const { first_name, last_name, email } = el.value;
return (
<span>
<span
className={styles['printed-name']}
>{`${first_name} ${last_name}`}</span>
{` (${email})`}
</span>
);
},
},
{
Header: loading ? (
<LoadingSpinner
placement="inline"
className={styles['guest-members__loading']}
/>
) : (
''
),
accessor: 'email',
Cell: (el) => {
return !readOnlyTeam ? (
<Button
type="link"
onClick={() => handleRemoveGuestUser(el.value)}
disabled={loading}
>
Remove
</Button>
) : null;
},
},
];

const onSubmit = useCallback(
(values) => {
dispatch({
type: 'PROJECTS_SET_TITLE_DESCRIPTION',
payload: {
projectId,
data: {
title: metadata.title,
description: metadata.description || '',
metadata: {
guest_users: [...metadata.guest_users, ...values.guestUsers],
},
},
modal: '',
},
});
},
[projectId, dispatch, metadata]
);

const validationSchema = Yup.object().shape({
guestUsers: Yup.array().of(
Yup.object().shape({
first_name: Yup.string().required('First Name is required'),
last_name: Yup.string().required('Last Name is required'),
email: Yup.string()
.email('Invalid email address')
.required('Email is required'),
})
),
});

return (
<div className={styles.root}>
{metadata?.guest_users?.length > 0 && (
<InfiniteScrollTable
tableColumns={columns}
tableData={metadata.guest_users}
className={styles['guest-user-listing']}
columnMemoProps={[loading]}
/>
)}

{!readOnlyTeam && (
<>
<Label className="form-field__label" size="sm">
Add Guest Member
</Label>
<Formik
initialValues={{ guestUsers: [] }}
validationSchema={validationSchema}
onSubmit={onSubmit}
>
{({ values, isValid, resetForm }) => {
useEffect(() => {
resetForm();
}, [metadata, resetForm]);

return (
<Form>
<FieldArray name="guestUsers">
{({ remove, push }) => (
<>
{/* Render only if there are guest users */}
{values.guestUsers.length > 0 &&
values.guestUsers.map((_, index) => (
<Section
key={index}
contentClassName={`${styles['form-div']}`}
content={
<>
<FormField
name={`guestUsers.${index}.first_name`}
label="First Name"
required
/>
<FormField
name={`guestUsers.${index}.last_name`}
label="Last Name"
required
/>
<FormField
name={`guestUsers.${index}.email`}
label="Email"
required
/>
<Button
type="primary"
attr="submit"
className={styles['remove-button']}
isLoading={loading}
disabled={!isValid}
>
Add
</Button>
<Button
type="secondary"
onClick={() => remove(index)}
className={styles['remove-button']}
disabled={loading}
>
Remove
</Button>
</>
}
/>
))}

{/* Button to add a new guest user */}
<Button
type="secondary"
onClick={() =>
push({ first_name: '', last_name: '', email: '' })
}
iconNameBefore="add"
className={styles['button-full']}
>
Add Guest Member
</Button>
</>
)}
</FieldArray>
</Form>
);
}}
</Formik>
</>
)}
</div>
);
};

export default DataFilesManageProjectModalAddon;
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.form-div {
display: flex;
justify-content: space-between;
width: 100%;
// align-items: center;
}

.form-div > *:not(:nth-last-child(-n + 2)) {
width: 25%;
margin-bottom: 50px;
}

.remove-button {
align-self: center;
margin-bottom: 15px;
}

.button-full {
min-width: 100% !important;
margin-bottom: 30px;
}

.printed-name {
font-weight: bold;
}

.guest-user-listing {
/* title */
th:nth-child(1),
td:nth-child(1) {
width: 80%;
}
/* date */
th:nth-child(2),
td:nth-child(2) {
width: 20%;
}

padding-bottom: 10px;
}

.guest-members__loading {
font-size: 1em;
justify-content: flex-end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const DataFilesProjectPublish = ({ rootSystem, system }) => {
className={styles.root}
header={
<div className={styles.title}>
Request Project Publication | {metadata.title}
Request Dataset Publication | {metadata.title}
</div>
}
headerActions={
Expand All @@ -120,7 +120,7 @@ const DataFilesProjectPublish = ({ rootSystem, system }) => {
className="wb-link"
to={`${ROUTES.WORKBENCH}${ROUTES.DATA}/tapis/projects/${rootSystem}/${system}`}
>
Back to Project
Back to Dataset
</Link>
</>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@ const ProjectDescription = ({ project }) => {

return (
<SectionTableWrapper
header={<div className={styles.title}>Proofread Project</div>}
header={<div className={styles.title}>Proofread Dataset</div>}
headerActions={
<>
{canEdit && (
<div className={styles.controls}>
<>
<Button type="link" onClick={onEdit}>
Edit Project
Edit Dataset
</Button>
</>
</div>
Expand Down
Loading

0 comments on commit cdce886

Please sign in to comment.