Skip to content
Snippets Groups Projects
Demetriad Sinzeanu's avatar
e7dd4cf4

Hindawi Helpers

Utility HOCs

HOCs used for files drag and drop

Utility functions

Utility HOCs

withCountries

Injects countries and countryLabel as props.

withCountries props

Name Type Description
countries [{value: string, label: string}] the list of countries
countryLabel (code: string) => string get the name of the country with the specified code
import { Menu } from '@pubsweet/ui'
import { withCountries } from 'pubsweet-component-faraday-ui'

const Wrapped = ({ countries, countryLabel }) => (
  <div>
    <Menu options={countries} placeholder="Select a country" />

    <span>Selected country: {countryLabel('RO')}</span>
  </div>
)

export default withCountries(Wrapped)

withFetching

Injects isFetching, fetchingError, setFetching, toggleFetching, setError and clearError as props.

withFetching props

Name Type Description
isFetching bool Pending async operation sattus
fetchingError fetchingError Value representing the error
setFetching (value: bool) => any Function for setting the isFetching value
toggleFetching (value: bool) => any Function that toggles the current value of isFetching
setError (error: string) => any Function that sets fetchingError
clearError () => any Function that resets fetchingError to it's original value
import { withFetching } from 'pubsweet-component-faraday-ui'

const Wrapped = ({ isFetching, fetchingError, setFetching, toggleFetching }) => (
  <div>
    {isFetching && <span>I am fetching</span>}
    <span>{`The error: ${fetchingError}`</span>
    <button onClick={() => setFetching(true)}>Set fetching true</button>
    <button onClick={() => setFetching(false)}>Set fetching false</button>
    <button onClick={toggleFetching}>Toggle fetching</button>
  </div>
)

export default withFetching(Wrapped)

withFileDownload

Injects downloadFile as a prop.

withFileDownload props

Name Type Description
downloadFile (file: {id: string, name: string}) => any Downloads the file specified as a parameter. The wrapped component should have the authentication token in a prop called token in order for this to work.
import { FileItem, withFileDownload } from 'pubsweet-component-faraday-ui'

const file = {
  id: 'myfile',
  name: 'myfile.pdf',
  size: 100231,
}

const Wrapped = ({ downloadFile }) => (
  <div>
    <FileItem item={file} onDownload={downloadfile} />
  </div>
)

export default withFileDownload(Wrapped)

withFilePreview

Generate a securized file URL and preview it in a new tab. Injects previewFile as a prop.

This HOC assumes the following props are present on the wrapped component:

Name Type Description
getSignedURL (id: string) => Promise({signedURL: string}) Async call that returns the securized S3 file url

withFilePreviewProps

Name Type Description
previewFile (file: {id: string, ...}) => any Opens the file preview in a new tab (only possible for PDF files and images)
import { withProps } from 'recompose'
import { FileItem, withFilePreview Wrapped} from 'pubsweet-component-faraday-ui'

const file = {
  id: 'myfile',
  name: 'myfile.pdf',
  size: 100231,
}

const Wrapped = ({ previewFile }) => (
  <div>
    <FileItem item={file} onPreview={previewFile} />
  </div>
)

export default withFilePreview(Wrapped)

withPagination

Injects page, itemsPerPage, toFirst, nextPage, toLast, prevPage, changeItemsPerPage, hasMore, maxItems and paginatedItems as props.

withPagination props

Name Type Description
page number Current page.
itemsPerPage number Number of items to be shown per page.
maxItems number Total number of items.
maxItems number Total number of items.
hasMore bool If we're not at the last page yet.
paginatedItems [any] Slice of the original items.
toFirst () => { page: number } Go to the first page.
toLast () => { page: number } Go to the last page.
nextPage () => { page: number } Move to the next page.
prevPage () => { page: number } Move to the previous page.
changeItemsPerPage e: HTMLInputEvent => {page: number, itemsPerPage: number} Change the number of items per page.
import { withPagination } from 'pubsweet-component-faraday-ui'

const Wrapped = ({ page, nextPage, prevPage, paginatedItems, changeItemsPerPage }) => (
  <div>
    <span>Page {page}</span>
    <button onClick={prevPage}>Prev page</button>
    <button onClick={nextPage}>Next page</button>
    <input type="text" onChange={changeItemsPerPage} />
    <div>
    {
      paginatedItems.map(p => <span>{p}<span>)
    }
    </div>
  </div>
)

export default withPagination(Wrapped)

withRoles

Injects the roles array as a prop. The roles are parsed from the journal config files.

withRoles props

Name Type Description
roles [{value: string, label: string}] An array of user roles.
import { Menu } from '@pubsweet/ui'
import { withRoles } from 'pubsweet-component-faraday-ui'

const Wrapped = ({ roles }) => <Menu options={roles} />

export default withRoles(Wrapped)

withZipDownload

Downloads all the files of a fragment as a zip archive. Injects the downloadFiles function as a prop.

This HOCs assumes the following props are present on the wrapped component:

Name Type Description
token string Authentication token (used to authorize this request).
isReviewer bool If the user is reviewer.
fragmentId string Id of the fragment whose files we want to download.
setFetching (value: bool) => any Callback to set a fetching status.
archiveName string Name of the outputted archive file.

withZipDownload props

Name Type Description
downloadFiles strin() => anyg Download all the fragment's file as a zip.

Files drag and drop

withFileSectionDrop

HOC used to provide drop functionality to the FileSection component. It's main purpose is to change a file from one list to another. This is usually done in a callback called changeList that should be provided to the wrapped component.

This HOC assumes the wrapped component has the following props:

Name Type Description
files [{id: string, ...}] List of files passed to the wrapped component.
setError (error: string) => any Error setting callback.
listId string Current list id.
allowedFileExtensions [string] Allowed file types.
maxFiles number Maximum number of files allowed.
changeList (fromListId: string, toListId: string: fileId: string) => any Callback fired when moving the file to a new list.
import { compose, withHandler, withProps } from 'recompose'
import { FileSection, withFileSectionDrop } from 'pubsweet-component-faraday-ui'

const Wrapped = compose(
  withProps({
    files: [...],
    listId: 'CoverLetter',
    maxFiles: 3,
    allowedFileExtensions: ['pdf'],
  }),
  withHandlers({
    changeList: () => (fromListId, toListId, fileId) => {
      // do the actual change here
    }
  }),
  withFileSectionDrop,
)(FileSection)

export default Wrapped

withNativeFileDrop

HOC used to provide native file drop functionality to the FileSection component. It's purpose is to do something when dragging files from the computer's hard drive into the app. This HOC allows only single items! Dragging multiple items into the wrapped component will only handle the first item!

This HOC assumes the wrapped component has the following props:

Name Type Description
files [{id: string, ...}] List of files passed to the wrapped component.
setError (error: string) => any Error setting callback.
allowedFileExtensions [string] Allowed file types.
maxFiles number Maximum number of files allowed.
onFileDrop (file: File) => any Callback fired when a valid file is dropped.
import { compose, withHandler, withProps } from 'recompose'
import { FileSection, withNativeFileDrop } from 'pubsweet-component-faraday-ui'

const Wrapped = compose(
  withProps({
    files: [...],
    listId: 'CoverLetter',
    maxFiles: 3,
    allowedFileExtensions: ['pdf'],
  }),
  withHandlers({
    onFileDrop: () => file => {
      // do something with the dropped file
    }
  }),
  withNativeFileDrop,
)(FileSection)

export default Wrapped

Utility functions

handleError

Function that parses the server error. Calls the passed function with the parsed error.

Has the following signature: (callbackFn: (parsedError) => any) => (e: Error) => any

const customErrorLogger = parsedError =>
  console.error(`This is very handled: ${parsedError}`)

// point free notation
anAsyncOperation().catch(handleError(customErrorLogger))

// can be used besides other function calls

anAsyncOperation().catch(err => {
  setFetching(false)
  handleError(customErrorLogger)(err)
})