Skip to content

Commit

Permalink
* create UploadDropZone and ProjectImport compomnents
Browse files Browse the repository at this point in the history
* render ProjectImport in Modal
* add dropzone styles
* fix gettext statements
* add constants
  • Loading branch information
CalamityC committed Apr 18, 2024
1 parent adfe836 commit dc15009
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 18 deletions.
38 changes: 38 additions & 0 deletions rdmo/core/assets/js/components/UploadDropZone.js
@@ -0,0 +1,38 @@
import React, { useState } from 'react'
import PropTypes from 'prop-types'
import { useDropzone } from 'react-dropzone'

const UploadDropZone = ({ acceptedTypes, onImportFile }) => {
const [errorMessage, setErrorMessage] = useState('')

const { getRootProps, getInputProps } = useDropzone({
accept: acceptedTypes,
onDropAccepted: acceptedFiles => {
if (acceptedFiles.length > 0) {
onImportFile(acceptedFiles[0])
setErrorMessage('')
}
},
onDropRejected: rejectedFiles => {
console.log(rejectedFiles)
setErrorMessage(interpolate(gettext('%s has unsupported file type'), [rejectedFiles[0].path]))
}
})

return (
<section className="dropzone-container">
<div {...getRootProps({className: 'dropzone'})}>
<input {...getInputProps()} />
<p>{gettext('Drag and drop a file here or click to select a file')}</p>
{errorMessage && <div className="alert alert-danger mt-2">{errorMessage}</div>}
</div>
</section>
)
}

UploadDropZone.propTypes = {
acceptedTypes: PropTypes.arrayOf(PropTypes.string),
onImportFile: PropTypes.func.isRequired,
}

export default UploadDropZone
1 change: 1 addition & 0 deletions rdmo/core/assets/js/components/index.js
Expand Up @@ -2,4 +2,5 @@ export { default as FileUploadButton } from './FileUploadButton'
export { default as Link } from './Link'
export { default as LinkButton } from './LinkButton'
export { default as Modal } from './Modal'
export { default as UploadDropZone } from './UploadDropZone'
export * from './SearchAndFilter'
@@ -1,5 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
import { ROLE_LABELS } from '../../utils'

const PendingInvitations = ({ invitations }) => {
const baseUrl = window.location.origin
Expand All @@ -11,7 +12,7 @@ const PendingInvitations = ({ invitations }) => {
<b>{item.title}</b>
</div>
<div className="w-50">
{gettext(item.role).charAt(0).toUpperCase() + gettext(item.role).slice(1)}
{ROLE_LABELS[item.role]}
</div>
<div className="w-25 align-right">
<button className="btn btn-xs btn-success ml-10" onClick={() => { window.location.href = `${baseUrl}/projects/join/${item.token}` }}>{gettext('Accept')}</button>
Expand Down
24 changes: 24 additions & 0 deletions rdmo/projects/assets/js/components/helper/ProjectImport.js
@@ -0,0 +1,24 @@
import React from 'react'
import PropTypes from 'prop-types'

import { UploadDropZone } from 'rdmo/core/assets/js/components'

const ProjectImport = ({ allowedTypes, handleImport}) => {
return (
<>
<UploadDropZone
acceptedTypes={allowedTypes}
onImportFile={handleImport} />
<hr />
<h2>{gettext('Direct import')}</h2>
to do: display links
</>
)
}

ProjectImport.propTypes = {
allowedTypes: PropTypes.arrayOf(PropTypes.string),
handleImport: PropTypes.func.isRequired,
}

export default ProjectImport
1 change: 1 addition & 0 deletions rdmo/projects/assets/js/components/helper/index.js
@@ -1,3 +1,4 @@
export { default as PendingInvitations } from './PendingInvitations'
export { default as ProjectFilters } from './ProjectFilters'
export { default as ProjectImport } from './ProjectImport'
export { default as Table } from './Table'
39 changes: 27 additions & 12 deletions rdmo/projects/assets/js/components/main/Projects.js
@@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import { PendingInvitations, ProjectFilters, Table } from '../helper'
import { FileUploadButton, Link, Modal, SearchField } from 'rdmo/core/assets/js/components'
import { PendingInvitations, ProjectFilters, ProjectImport, Table } from '../helper'
import { Link, Modal, SearchField } from 'rdmo/core/assets/js/components'
import { useFormattedDateTime, useModal, useScrollToTop } from 'rdmo/core/assets/js/hooks'
import useDatePicker from '../../hooks/useDatePicker'
import { language } from 'rdmo/core/assets/js/utils'
Expand All @@ -14,8 +14,21 @@ const Projects = ({ config, configActions, currentUserObject, projectsActions, p
const { myProjects } = config

const { showTopButton, scrollToTop } = useScrollToTop()
const { show, open, close } = useModal()
const modalProps = {title: gettext('Pending invitations'), show: show, onClose: close }

const { show: showInvitations, open: openInvitations, close: closeInvitations } = useModal()
const { show: showImport, open: openImport, close: closeImport } = useModal()

const invitationsModalProps = {
title: gettext('Pending invitations'),
show: showInvitations,
onClose: closeInvitations
}

const importModalProps = {
title: gettext('Import project'),
show: showImport,
onClose: closeImport
}

const { setStartDate, setEndDate } = useDatePicker()

Expand Down Expand Up @@ -136,7 +149,7 @@ const Projects = ({ config, configActions, currentUserObject, projectsActions, p
<h1>{headline}</h1>
<div className="icon-container">
{!isEmpty(invites) && myProjects &&
<button className="btn btn-link mr-10" onClick={open}>
<button className="btn btn-link mr-10" onClick={openInvitations}>
<span className="badge badge-primary badge-invitations">
{invites.length}
</span>
Expand All @@ -151,12 +164,9 @@ const Projects = ({ config, configActions, currentUserObject, projectsActions, p
<button className="btn btn-link mr-10" onClick={handleNew}>
<i className="fa fa-plus" aria-hidden="true"></i> {gettext('New project')}
</button>
<FileUploadButton
acceptedTypes={allowedTypes}
buttonProps={{'className': 'btn btn-link'}}
buttonLabel={gettext('Import project')}
onImportFile={handleImport}
/>
<button className="btn btn-link mr-10" onClick={openImport}>
<i className="fa fa-download" aria-hidden="true"></i> {gettext('Import project')}
</button>
</div>
</div>
<div className="panel">
Expand Down Expand Up @@ -203,9 +213,14 @@ const Projects = ({ config, configActions, currentUserObject, projectsActions, p
sortableColumns={SORTABLE_COLUMNS}
visibleColumns={visibleColumns}
/>
<Modal {...modalProps}>
<Modal {...invitationsModalProps}>
<PendingInvitations invitations={invites} />
</Modal>
<Modal {...importModalProps}>
<ProjectImport
allowedTypes={allowedTypes}
handleImport={handleImport} />
</Modal>
</div>
)
}
Expand Down
7 changes: 7 additions & 0 deletions rdmo/projects/assets/js/utils/constants.js
Expand Up @@ -11,3 +11,10 @@ export const HEADER_FORMATTERS = {
updated: {render: () => gettext('Last changed')},
actions: {render: () => null},
}
// project roles
export const ROLE_LABELS = {
author: gettext('Author'),
guest: gettext('Guest'),
manager: gettext('Manager'),
owner: gettext('Owner')
}
12 changes: 7 additions & 5 deletions rdmo/projects/assets/js/utils/getUserRoles.js
@@ -1,13 +1,15 @@
import { ROLE_LABELS } from './constants'

export const getUserRoles = (row, currentUserId, arraysToSearch) => {
if (!arraysToSearch || !arraysToSearch.length) {
arraysToSearch = ['authors', 'guests', 'managers', 'owners']
}

const roleDefinitions = {
authors: { roleLabel: 'Author', roleBoolean: 'isProjectAuthor' },
guests: { roleLabel: 'Guest', roleBoolean: 'isProjectGuest' },
managers: { roleLabel: 'Manager', roleBoolean: 'isProjectManager' },
owners: { roleLabel: 'Owner', roleBoolean: 'isProjectOwner' }
authors: { roleLabel: ROLE_LABELS.author, roleBoolean: 'isProjectAuthor' },
guests: { roleLabel: ROLE_LABELS.guest, roleBoolean: 'isProjectGuest' },
managers: { roleLabel: ROLE_LABELS.manager, roleBoolean: 'isProjectManager' },
owners: { roleLabel: ROLE_LABELS.owner, roleBoolean: 'isProjectOwner' }
}

let rolesFound = []
Expand All @@ -21,7 +23,7 @@ export const getUserRoles = (row, currentUserId, arraysToSearch) => {
arraysToSearch.forEach(arrayName => {
if (row[arrayName].some(item => item.id === currentUserId)) {
const { roleLabel, roleBoolean } = roleDefinitions[arrayName]
rolesFound.push(gettext(roleLabel))
rolesFound.push(roleLabel)
roleBooleans[roleBoolean] = true
}
})
Expand Down
27 changes: 27 additions & 0 deletions rdmo/projects/assets/scss/projects.scss
Expand Up @@ -332,3 +332,30 @@ a.disabled {
outline:0;
}
}

.dropzone-container {
width: 100%;
padding: 20px;
}

.dropzone {
border: 2px dashed #cccccc;
border-radius: 5px;
padding: 20px;
text-align: center;
transition: border .24s ease-in-out;
}

.dropzone:focus {
border-color: #2196f3;
}

/* Add additional styling for when files are being dragged over the dropzone */
.dropzone.drag-active {
border-color: #2196f3;
}

/* Add styles for when the dropzone is disabled */
.dropzone.disabled {
opacity: 0.6;
}

0 comments on commit dc15009

Please sign in to comment.