Hindawi Helpers
Utility HOCs
HOCs used for files drag and drop
Utility functions
Utility HOCs
withCountries
Injects countries and countryLabel as props.
withCountries props
| 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 '@hindawi/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
| 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 '@hindawi/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)
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:
| getSignedURL | (id: string) => Promise({signedURL: string}) | Async call that returns the securized S3 file url |
withFilePreviewProps
| 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 '@hindawi/ui'
const file = {
id: 'myfile',
name: 'myfile.pdf',
size: 100231,
}
const Wrapped = ({ previewFile }) => (
<div>
<FileItem item={file} onPreview={previewFile} />
</div>
)
export default withFilePreview(Wrapped)
Injects page, itemsPerPage, toFirst, nextPage, toLast, prevPage, changeItemsPerPage, hasMore, maxItems and paginatedItems as props.
| 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 '@hindawi/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
| roles | [{value: string, label: string}] | An array of user roles. |
import { Menu } from '@pubsweet/ui'
import { withRoles } from '@hindawi/ui'
const Wrapped = ({ roles }) => <Menu options={roles} />
export default withRoles(Wrapped)
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:
| 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 '@hindawi/ui'
const Wrapped = compose(
withProps({
files: [...],
listId: 'CoverLetter',
maxFiles: 3,
allowedFileExtensions: ['pdf'],
}),
withHandlers({
changeList: () => (fromListId, toListId, fileId) => {
}
}),
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:
| 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 '@hindawi/ui'
const Wrapped = compose(
withProps({
files: [...],
listId: 'CoverLetter',
maxFiles: 3,
allowedFileExtensions: ['pdf'],
}),
withHandlers({
onFileDrop: () => 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}`)
anAsyncOperation().catch(handleError(customErrorLogger))
anAsyncOperation().catch(err => {
setFetching(false)
handleError(customErrorLogger)(err)
})