index.jsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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. // @flow
  15. import React from 'react'
  16. import { observer } from 'mobx-react'
  17. import styled from 'styled-components'
  18. import type { MainItem } from '../../../types/MainItem'
  19. import type { Execution } from '../../../types/Execution'
  20. import StatusPill from '../../atoms/StatusPill'
  21. import Button from '../../atoms/Button'
  22. import Palette from '../../styleUtils/Palette'
  23. import StyleProps from '../../styleUtils/StyleProps'
  24. import backArrowImage from './images/back-arrow.svg'
  25. const Wrapper = styled.div`
  26. background: ${Palette.grayscale[0]};
  27. height: 96px;
  28. display: flex;
  29. align-items: center;
  30. justify-content: center;
  31. margin-left: -72px;
  32. `
  33. const BackButton = styled.div`
  34. ${StyleProps.exactSize('33px')}
  35. background: url('${backArrowImage}') no-repeat center;
  36. cursor: pointer;
  37. margin-right: 32px;
  38. `
  39. const TypeImage = styled.div`
  40. min-width: 64px;
  41. height: 64px;
  42. background: url('${props => props.image}') no-repeat center;
  43. margin-right: 64px;
  44. `
  45. const Title = styled.div`
  46. display: flex;
  47. align-items: center;
  48. ${StyleProps.exactWidth(StyleProps.contentWidth)}
  49. `
  50. const Text = styled.div`
  51. font-size: 30px;
  52. font-weight: ${StyleProps.fontWeights.light};
  53. white-space: nowrap;
  54. overflow: hidden;
  55. text-overflow: ellipsis;
  56. `
  57. const Status = styled.div`
  58. flex-grow: 1;
  59. `
  60. const StatusPills = styled.div`
  61. display: flex;
  62. margin-top: 5px;
  63. & > div {
  64. margin-right: 16px;
  65. }
  66. `
  67. const Description = styled.div`
  68. color: ${Palette.grayscale[4]};
  69. margin-top: 3px;
  70. `
  71. const MockButton = styled.div`
  72. ${StyleProps.exactWidth(`${StyleProps.inputSizes.regular.width}px`)}
  73. `
  74. type Props = {
  75. onBackButonClick: () => void,
  76. onActionButtonClick?: () => void,
  77. onCancelClick?: (?Execution | ?MainItem) => void,
  78. typeImage?: string,
  79. buttonLabel?: string,
  80. statusLabel?: string,
  81. item: ?MainItem,
  82. alertInfoPill?: boolean,
  83. primaryInfoPill?: boolean,
  84. alertButton?: boolean,
  85. hollowButton?: boolean,
  86. actionButtonDisabled?: boolean,
  87. }
  88. @observer
  89. class DetailsContentHeader extends React.Component<Props> {
  90. getLastExecution(): ?MainItem | ?Execution {
  91. if (this.props.item && this.props.item.executions && this.props.item.executions.length) {
  92. return this.props.item.executions[this.props.item.executions.length - 1]
  93. } else if (this.props.item && typeof this.props.item.executions === 'undefined') {
  94. return this.props.item
  95. }
  96. return null
  97. }
  98. getStatus() {
  99. let lastExecution = this.getLastExecution()
  100. if (lastExecution) {
  101. return lastExecution.status
  102. }
  103. return null
  104. }
  105. renderStatusPill() {
  106. if (!this.getStatus()) {
  107. return null
  108. }
  109. let statusLabel = this.getStatus()
  110. if (this.props.statusLabel) {
  111. statusLabel = this.props.statusLabel
  112. }
  113. return (
  114. <StatusPills>
  115. <StatusPill
  116. status="INFO"
  117. label={this.props.item ? this.props.item.type && this.props.item.type.toUpperCase() : ''}
  118. alert={this.props.alertInfoPill}
  119. primary={this.props.primaryInfoPill}
  120. />
  121. <StatusPill
  122. data-test-id={`mainStatusPill-${statusLabel || ''}`}
  123. status={this.getStatus()}
  124. label={statusLabel || ''}
  125. />
  126. </StatusPills>
  127. )
  128. }
  129. renderButton() {
  130. if (!this.props.onActionButtonClick && this.getStatus() !== 'RUNNING') {
  131. return <MockButton />
  132. }
  133. if (this.getStatus() === 'RUNNING') {
  134. return (
  135. <Button
  136. secondary
  137. onClick={() => {
  138. // $FlowIssue
  139. if (this.props.onCancelClick) this.props.onCancelClick(this.getLastExecution())
  140. }}
  141. >Cancel</Button>
  142. )
  143. }
  144. return (
  145. <Button
  146. secondary={!this.props.alertButton}
  147. alert={this.props.alertButton}
  148. hollow={this.props.hollowButton}
  149. onClick={this.props.onActionButtonClick}
  150. disabled={this.props.actionButtonDisabled}
  151. >{this.props.buttonLabel}</Button>
  152. )
  153. }
  154. renderDescription() {
  155. if (!this.props.item || !this.props.item.description) {
  156. return null
  157. }
  158. return (
  159. <Description>{this.props.item.description}</Description>
  160. )
  161. }
  162. render() {
  163. let title = this.props.item ? (this.props.item.instances && this.props.item.instances[0]) || this.props.item.name : ''
  164. return (
  165. <Wrapper>
  166. <BackButton onClick={this.props.onBackButonClick} />
  167. <TypeImage image={this.props.typeImage} />
  168. <Title>
  169. <Status>
  170. <Text>{title}</Text>
  171. {this.renderStatusPill()}
  172. {this.renderDescription()}
  173. </Status>
  174. {this.renderButton()}
  175. </Title>
  176. </Wrapper>
  177. )
  178. }
  179. }
  180. export default DetailsContentHeader