Guest User

Untitled

a guest
Jan 17th, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.84 KB | None | 0 0
  1. import React from 'react'
  2. import DataLoader from 'core/DataLoader'
  3. import CRUDListContainer from 'core/common/CRUDListContainer'
  4. import requiresAuthentication from 'openstack/util/requiresAuthentication'
  5. import ListTable from 'core/common/list_table/ListTable'
  6. import createCRUDActions from 'core/helpers/createCRUDActions'
  7. import { compose } from 'core/fp'
  8. import { withAppContext } from 'core/AppContext'
  9. import { withRouter } from 'react-router-dom'
  10. import { withScopedPreferences } from 'core/PreferencesProvider'
  11.  
  12. /**
  13. * This helper removes a lot of boilerplate from standard CRUD operations.
  14. *
  15. * We separate them out into the following components:
  16. * - ListPage:
  17. * Responsible for fetching the data. A render prop that receives ({ ListContainer })
  18. * - ListContainer:
  19. * Responsible for handling CRUD operations (add, delete, update).
  20. * - List:
  21. * Responsible for specifying the columns and rendering the list.
  22. *
  23. * The reason for separating them into 3 different components is so that they
  24. * can be tested individually; mocks can be substituted for data loading and
  25. * actions.
  26. *
  27. * Please see CRUDListContainer and ListTable for a better understanding what
  28. * some of the `options` are.
  29. */
  30.  
  31. const createCRUDComponents = options => {
  32. const defaults = {
  33. columns: [],
  34. rowActions: () => [],
  35. uniqueIdentifier: 'id',
  36. }
  37.  
  38. const {
  39. actions,
  40. baseUrl,
  41. columns,
  42. dataKey,
  43. debug,
  44. deleteFn,
  45. loaderFn,
  46. name,
  47. rowActions,
  48. title,
  49. uniqueIdentifier,
  50. } = { ...defaults, ...options }
  51.  
  52. const crudActions = actions ? createCRUDActions(actions) : null
  53.  
  54. // List
  55. const List = withScopedPreferences(name)(({
  56. onAdd, onDelete, onEdit, rowActions, data,
  57. preferences: { visibleColumns, columnsOrder, rowsPerPage },
  58. updatePreferences
  59. }) => {
  60. if (!data || data.length === 0) {
  61. return <h1>No data found.</h1>
  62. }
  63. return (
  64. <ListTable
  65. title={title}
  66. columns={columns}
  67. data={data}
  68. onAdd={onAdd}
  69. onDelete={onDelete}
  70. onEdit={onEdit}
  71. rowActions={rowActions}
  72. searchTarget="name"
  73. uniqueIdentifier={uniqueIdentifier}
  74. visibleColumns={visibleColumns}
  75. columnsOrder={columnsOrder}
  76. rowsPerPage={rowsPerPage}
  77. onRowsPerPageChange={rowsPerPage => updatePreferences({ rowsPerPage })}
  78. onColumnsChange={updatePreferences}
  79. />
  80. )
  81. })
  82. List.displayName = `${name}List`
  83.  
  84. // ListContainer
  85. class ContainerBase extends React.Component {
  86. handleRemove = id => {
  87. const { context, setContext } = this.props
  88. return (deleteFn || crudActions.delete)({ id, context, setContext })
  89. }
  90.  
  91. render () {
  92. let moreProps = {}
  93. if (rowActions && rowActions.length > 0) {
  94. moreProps.rowActions = rowActions
  95. }
  96.  
  97. return (
  98. <CRUDListContainer
  99. items={this.props.data}
  100. addUrl={`${baseUrl}/add`}
  101. editUrl={`${baseUrl}/edit`}
  102. onRemove={this.handleRemove}
  103. uniqueIdentifier={uniqueIdentifier}
  104. >
  105. {handlers => <List data={this.props.data} {...handlers} {...moreProps} />}
  106. </CRUDListContainer>
  107. )
  108. }
  109. }
  110.  
  111. const ListContainer = compose(
  112. withAppContext,
  113. withRouter,
  114. )(ContainerBase)
  115.  
  116. ListContainer.displayName = `${name}ListContainer`
  117.  
  118. // ListPage
  119. const StandardListPage = () => (
  120. <DataLoader dataKey={dataKey} loaderFn={loaderFn || crudActions.list}>
  121. {({ data }) =>
  122. <React.Fragment>
  123. <ListContainer data={data} />
  124. {debug && <pre>{JSON.stringify(data, null, 4)}</pre>}
  125. </React.Fragment>
  126. }
  127. </DataLoader>
  128. )
  129. const ListPage = requiresAuthentication(options.ListPage({ ListContainer }) || StandardListPage)
  130. ListPage.displayName = `${name}ListPage`
  131.  
  132. return {
  133. ListPage,
  134. ListContainer,
  135. List,
  136. }
  137. }
  138.  
  139. export default createCRUDComponents
Add Comment
Please, Sign In to add comment