DashboardContent.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. Copyright (C) 2017 Cloudbase Solutions SRL
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. import React from "react";
  15. import { observer } from "mobx-react";
  16. import styled from "styled-components";
  17. import autobind from "autobind-decorator";
  18. import DashboardInfoCount from "@src/components/modules/DashboardModule/DashboardInfoCount";
  19. import DashboardLicence from "@src/components/modules/DashboardModule/DashboardLicence";
  20. import DashboardActivity from "@src/components/modules/DashboardModule/DashboardActivity";
  21. import DashboardTopEndpoints from "@src/components/modules/DashboardModule/DashboardTopEndpoints";
  22. import DashboardExecutions from "@src/components/modules/DashboardModule/DashboardExecutions";
  23. import { ThemePalette } from "@src/components/Theme";
  24. import type { Endpoint } from "@src/@types/Endpoint";
  25. import type { Project } from "@src/@types/Project";
  26. import type { User } from "@src/@types/User";
  27. import type { Licence, LicenceServerStatus } from "@src/@types/Licence";
  28. import type { NotificationItemData } from "@src/@types/NotificationItem";
  29. import { TransferItem, DeploymentItem } from "@src/@types/MainItem";
  30. const MIDDLE_WIDTHS = ["264px", "264px", "264px"];
  31. const Wrapper = styled.div<any>`
  32. margin-bottom: 64px;
  33. `;
  34. const RowLayout = styled.div<any>`
  35. display: flex;
  36. flex-wrap: wrap;
  37. margin-bottom: 40px;
  38. margin-left: -32px;
  39. & > div {
  40. margin-top: 40px;
  41. margin-left: 32px;
  42. }
  43. `;
  44. const MiddleMobileLayout = styled.div<any>`
  45. margin: 40px 0;
  46. `;
  47. type Props = {
  48. transfers: TransferItem[];
  49. deployments: DeploymentItem[];
  50. endpoints: Endpoint[];
  51. projects: Project[];
  52. transfersLoading: boolean;
  53. deploymentsLoading: boolean;
  54. endpointsLoading: boolean;
  55. usersLoading: boolean;
  56. projectsLoading: boolean;
  57. licenceLoading: boolean;
  58. notificationItemsLoading: boolean;
  59. users: User[];
  60. licence: Licence | null;
  61. licenceServerStatus: LicenceServerStatus | null;
  62. licenceError: string | null;
  63. notificationItems: NotificationItemData[];
  64. isAdmin: boolean;
  65. onNewTransferClick: () => void;
  66. onNewEndpointClick: () => void;
  67. onAddLicenceClick: () => void;
  68. };
  69. type State = {
  70. useMobileLayout: boolean;
  71. useLargeActivity: boolean;
  72. };
  73. @observer
  74. class DashboardContent extends React.Component<Props, State> {
  75. state = {
  76. useMobileLayout: false,
  77. useLargeActivity: false,
  78. };
  79. UNSAFE_componentWillMount() {
  80. this.handleResize();
  81. window.addEventListener("resize", this.handleResize);
  82. }
  83. componentWillUnmount() {
  84. window.removeEventListener("resize", this.handleResize, false);
  85. }
  86. @autobind
  87. handleResize() {
  88. if (window.innerWidth < 1120 && !this.state.useMobileLayout) {
  89. this.setState({ useMobileLayout: true });
  90. } else if (window.innerWidth >= 1120 && this.state.useMobileLayout) {
  91. this.setState({ useMobileLayout: false });
  92. }
  93. if (window.innerWidth >= 2100 && !this.state.useLargeActivity) {
  94. this.setState({ useLargeActivity: true });
  95. } else if (window.innerWidth < 2100 && this.state.useLargeActivity) {
  96. this.setState({ useLargeActivity: false });
  97. }
  98. }
  99. renderMiddleModules() {
  100. const modules = [
  101. <DashboardActivity
  102. key="activity"
  103. large={this.state.useMobileLayout || this.state.useLargeActivity}
  104. notificationItems={this.props.notificationItems}
  105. loading={this.props.notificationItemsLoading}
  106. style={
  107. this.state.useMobileLayout
  108. ? null
  109. : {
  110. minWidth: MIDDLE_WIDTHS[0],
  111. width: MIDDLE_WIDTHS[0],
  112. }
  113. }
  114. onNewClick={this.props.onNewTransferClick}
  115. />,
  116. <DashboardTopEndpoints
  117. key="top-endpoints"
  118. transfers={this.props.transfers}
  119. endpoints={this.props.endpoints}
  120. loading={
  121. this.props.transfersLoading ||
  122. this.props.deploymentsLoading ||
  123. this.props.endpointsLoading
  124. }
  125. style={{
  126. minWidth: MIDDLE_WIDTHS[1],
  127. width: MIDDLE_WIDTHS[1],
  128. }}
  129. onNewClick={this.props.onNewEndpointClick}
  130. />,
  131. <DashboardLicence
  132. key="licence"
  133. licence={this.props.licence}
  134. loading={this.props.licenceLoading}
  135. licenceServerStatus={this.props.licenceServerStatus}
  136. licenceError={this.props.licenceError}
  137. onAddClick={this.props.onAddLicenceClick}
  138. style={{
  139. minWidth: MIDDLE_WIDTHS[2],
  140. width: MIDDLE_WIDTHS[2],
  141. }}
  142. />,
  143. ];
  144. if (this.state.useMobileLayout) {
  145. return (
  146. <MiddleMobileLayout>
  147. {modules[0]}
  148. <RowLayout>
  149. {modules[1]}
  150. {modules[2]}
  151. </RowLayout>
  152. </MiddleMobileLayout>
  153. );
  154. }
  155. return (
  156. <RowLayout>
  157. {modules[0]}
  158. {modules[1]}
  159. {modules[2]}
  160. </RowLayout>
  161. );
  162. }
  163. getReplicas() {
  164. return this.props.transfers.filter(
  165. (r: TransferItem) => r.scenario === "replica");
  166. }
  167. getLiveMigrations() {
  168. return this.props.transfers.filter(
  169. (r: TransferItem) => r.scenario === "live_migration");
  170. }
  171. render() {
  172. let infoCountData = [
  173. {
  174. label: "Replicas",
  175. value: this.getReplicas().length,
  176. color: ThemePalette.alert,
  177. link: "/transfers",
  178. loading: this.props.transfersLoading,
  179. },
  180. {
  181. label: "Migrations",
  182. value: this.getLiveMigrations().length,
  183. link: "/transfers",
  184. loading: this.props.transfersLoading,
  185. },
  186. {
  187. label: "Endpoints",
  188. value: this.props.endpoints.length,
  189. color: ThemePalette.black,
  190. link: "/endpoints",
  191. loading: this.props.endpointsLoading,
  192. },
  193. ];
  194. if (this.props.isAdmin) {
  195. infoCountData = infoCountData.concat([
  196. {
  197. label: "Users",
  198. value: this.props.users.length,
  199. color: ThemePalette.grayscale[3],
  200. link: "/users",
  201. loading: this.props.usersLoading,
  202. },
  203. {
  204. label: "Projects",
  205. value: this.props.projects.length,
  206. color: ThemePalette.grayscale[3],
  207. link: "/projects",
  208. loading: this.props.projectsLoading,
  209. },
  210. ]);
  211. }
  212. return (
  213. <Wrapper>
  214. <DashboardInfoCount data={infoCountData} />
  215. {this.renderMiddleModules()}
  216. <DashboardExecutions
  217. replicas={this.getReplicas()}
  218. migrations={this.getLiveMigrations()}
  219. loading={this.props.transfersLoading || this.props.deploymentsLoading}
  220. />
  221. </Wrapper>
  222. );
  223. }
  224. }
  225. export default DashboardContent;