project-list-root.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import {
  2. ProjectListProvider,
  3. useProjectListContext,
  4. } from '../context/project-list-context'
  5. import { Col, Row } from 'react-bootstrap'
  6. import { useTranslation } from 'react-i18next'
  7. import useWaitForI18n from '../../../shared/hooks/use-wait-for-i18n'
  8. import CurrentPlanWidget from './current-plan-widget/current-plan-widget'
  9. import NewProjectButton from './new-project-button'
  10. import ProjectListTable from './table/project-list-table'
  11. import SidebarFilters from './sidebar/sidebar-filters'
  12. import SurveyWidget from './survey-widget'
  13. import WelcomeMessage from './welcome-message'
  14. import LoadingBranded from '../../../shared/components/loading-branded'
  15. import UserNotifications from './notifications/user-notifications'
  16. import SearchForm from './search-form'
  17. import ProjectsDropdown from './dropdown/projects-dropdown'
  18. import SortByDropdown from './dropdown/sort-by-dropdown'
  19. import ProjectTools from './table/project-tools/project-tools'
  20. import LoadMore from './load-more'
  21. function ProjectListRoot() {
  22. const { isReady } = useWaitForI18n()
  23. return isReady ? (
  24. <ProjectListProvider>
  25. <ProjectListPageContent />
  26. </ProjectListProvider>
  27. ) : null
  28. }
  29. function ProjectListPageContent() {
  30. const {
  31. totalProjectsCount,
  32. error,
  33. isLoading,
  34. loadProgress,
  35. searchText,
  36. setSearchText,
  37. selectedProjects,
  38. } = useProjectListContext()
  39. return isLoading ? (
  40. <div className="loading-container">
  41. <LoadingBranded loadProgress={loadProgress} />
  42. </div>
  43. ) : (
  44. <div className="project-list-row fill">
  45. <div className="project-list-wrapper clearfix">
  46. {error ? <DashApiError /> : ''}
  47. {totalProjectsCount > 0 ? (
  48. <>
  49. <div className="project-list-sidebar-wrapper hidden-xs">
  50. <aside className="project-list-sidebar">
  51. <NewProjectButton id="new-project-button-sidebar" />
  52. <SidebarFilters />
  53. </aside>
  54. <SurveyWidget />
  55. </div>
  56. <div className="project-list-main">
  57. <Row>
  58. <Col xs={12}>
  59. <UserNotifications />
  60. </Col>
  61. </Row>
  62. <Row>
  63. <Col md={7} className="hidden-xs">
  64. <SearchForm
  65. inputValue={searchText}
  66. setInputValue={setSearchText}
  67. />
  68. </Col>
  69. <Col md={5}>
  70. <div className="project-tools">
  71. <div className="hidden-xs">
  72. {selectedProjects.length === 0 ? (
  73. <CurrentPlanWidget />
  74. ) : (
  75. <ProjectTools />
  76. )}
  77. </div>
  78. <div className="visible-xs">
  79. <CurrentPlanWidget />
  80. </div>
  81. </div>
  82. </Col>
  83. </Row>
  84. <div className="visible-xs mt-1">
  85. <div role="toolbar" className="projects-toolbar">
  86. <ProjectsDropdown />
  87. <SortByDropdown />
  88. </div>
  89. </div>
  90. <Row className="row-spaced">
  91. <Col xs={12}>
  92. <div className="card project-list-card">
  93. <div className="visible-xs pt-2 pb-3">
  94. <div className="clearfix">
  95. <NewProjectButton
  96. id="new-project-button-projects-table"
  97. className="pull-left me-2"
  98. />
  99. <SearchForm
  100. inputValue={searchText}
  101. setInputValue={setSearchText}
  102. className="overflow-hidden"
  103. formGroupProps={{ className: 'mb-0' }}
  104. />
  105. </div>
  106. </div>
  107. <ProjectListTable />
  108. </div>
  109. </Col>
  110. </Row>
  111. <Row className="row-spaced">
  112. <Col xs={12}>
  113. <LoadMore />
  114. </Col>
  115. </Row>
  116. </div>
  117. </>
  118. ) : (
  119. <Row className="row-spaced">
  120. <Col
  121. xs={8}
  122. xsOffset={2}
  123. md={8}
  124. mdOffset={2}
  125. className="project-list-empty-col"
  126. >
  127. <WelcomeMessage />
  128. </Col>
  129. </Row>
  130. )}
  131. </div>
  132. </div>
  133. )
  134. }
  135. function DashApiError() {
  136. const { t } = useTranslation()
  137. return (
  138. <Row className="row-spaced">
  139. <Col xs={8} xsOffset={2} aria-live="polite" className="text-center">
  140. <div className="alert alert-danger">
  141. {t('generic_something_went_wrong')}
  142. </div>
  143. </Col>
  144. </Row>
  145. )
  146. }
  147. export default ProjectListRoot