DashboardActivity.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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 * as React from "react";
  15. import { observer } from "mobx-react";
  16. import styled from "styled-components";
  17. import { Link } from "react-router-dom";
  18. import StatusIcon from "@src/components/ui/StatusComponents/StatusIcon";
  19. import StatusImage from "@src/components/ui/StatusComponents/StatusImage";
  20. import Button from "@src/components/ui/Button";
  21. import {
  22. InfoColumn,
  23. MainItemInfo,
  24. ItemTransferBadge,
  25. ItemTitle,
  26. ItemDescription,
  27. } from "@src/components/ui/Dropdowns/NotificationDropdown";
  28. import type { NotificationItemData } from "@src/@types/NotificationItem";
  29. import { ThemePalette, ThemeProps } from "@src/components/Theme";
  30. import transferImage from "./images/transfer.svg";
  31. const Wrapper = styled.div<any>`
  32. flex-grow: 1;
  33. `;
  34. const Title = styled.div<any>`
  35. font-size: 24px;
  36. font-weight: ${ThemeProps.fontWeights.light};
  37. margin-bottom: 12px;
  38. `;
  39. const Module = styled.div<any>`
  40. background: ${ThemePalette.grayscale[0]};
  41. display: flex;
  42. overflow: hidden;
  43. border-radius: ${ThemeProps.borderRadius};
  44. height: 273px;
  45. `;
  46. const LoadingWrapper = styled.div<any>`
  47. width: 100%;
  48. height: 100%;
  49. display: flex;
  50. justify-content: center;
  51. align-items: center;
  52. overflow: hidden;
  53. `;
  54. const List = styled.div<any>`
  55. width: 100%;
  56. display: flex;
  57. flex-direction: column;
  58. flex-wrap: wrap;
  59. `;
  60. const ListItem = styled(Link)`
  61. padding: 8px 16px 8px 16px;
  62. cursor: pointer;
  63. text-decoration: none;
  64. color: inherit;
  65. display: block;
  66. transition: all ${ThemeProps.animations.swift};
  67. &:hover {
  68. background: ${ThemePalette.grayscale[1]};
  69. }
  70. `;
  71. const NoItems = styled.div<any>`
  72. display: flex;
  73. flex-direction: column;
  74. align-items: center;
  75. width: 100%;
  76. `;
  77. const TransferImage = styled.div<any>`
  78. ${ThemeProps.exactSize("148px")}
  79. background: url('${transferImage}') center no-repeat;
  80. `;
  81. const Message = styled.div<any>`
  82. text-align: center;
  83. margin-bottom: 32px;
  84. `;
  85. type Props = {
  86. notificationItems: NotificationItemData[];
  87. style?: React.CSSProperties | null;
  88. loading?: boolean;
  89. large?: boolean;
  90. onNewClick?: () => void;
  91. };
  92. @observer
  93. class DashboardActivity extends React.Component<Props> {
  94. renderList() {
  95. return (
  96. <List>
  97. {this.props.notificationItems
  98. .filter((_, i) => i < (this.props.large ? 10 : 5))
  99. .map((item, i) => {
  100. const actionHref =
  101. item.type === "transfer"
  102. ? "transfers" : "deployments"
  103. const executionsHref =
  104. item.status === "RUNNING"
  105. ? item.type === "transfer"
  106. ? "/executions"
  107. : item.type === "deployment"
  108. ? "/tasks"
  109. : ""
  110. : "";
  111. return (
  112. <ListItem
  113. key={item.id}
  114. to={`/${actionHref}/${item.id}${executionsHref}`}
  115. style={{
  116. width: `calc(${this.props.large ? 50 : 100}% - 32px)`,
  117. paddingTop: i === 0 || i === 5 ? "16px" : "8px",
  118. }}
  119. >
  120. <InfoColumn>
  121. <MainItemInfo>
  122. <StatusIcon status={item.status} hollow />
  123. <ItemTransferBadge type={item.type}>
  124. {item.type === "transfer" ? "TR" : "DE"}
  125. </ItemTransferBadge>
  126. <ItemTitle nowrap>{item.name}</ItemTitle>
  127. </MainItemInfo>
  128. <ItemDescription>{item.description}</ItemDescription>
  129. </InfoColumn>
  130. </ListItem>
  131. );
  132. })}
  133. </List>
  134. );
  135. }
  136. renderNoItems() {
  137. return (
  138. <NoItems>
  139. <TransferImage />
  140. <Message>
  141. There is no recent activity
  142. <br />
  143. in this project.
  144. </Message>
  145. <Button hollow primary transparent onClick={this.props.onNewClick}>
  146. New Transfer
  147. </Button>
  148. </NoItems>
  149. );
  150. }
  151. renderLoading() {
  152. return (
  153. <LoadingWrapper>
  154. <StatusImage status="RUNNING" />
  155. </LoadingWrapper>
  156. );
  157. }
  158. render() {
  159. return (
  160. <Wrapper style={this.props.style}>
  161. <Title>Recent Activity</Title>
  162. <Module>
  163. {this.props.notificationItems.length === 0 && this.props.loading
  164. ? this.renderLoading()
  165. : this.props.notificationItems.length
  166. ? this.renderList()
  167. : this.renderNoItems()}
  168. </Module>
  169. </Wrapper>
  170. );
  171. }
  172. }
  173. export default DashboardActivity;