project-list-root.tsx 5.6 KB

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