SmallLoading.jsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. Copyright (C) 2018 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, { css } from 'styled-components'
  18. import StyleProps from '../../styleUtils/StyleProps'
  19. import Palette from '../../styleUtils/Palette'
  20. const Wrapper = styled.div`
  21. position: relative;
  22. ${StyleProps.exactSize('28px')}
  23. background-repeat: no-repeat;
  24. background-position: center;
  25. `
  26. const ProgressSvgWrapper = styled.svg`
  27. ${StyleProps.exactSize('100%')}
  28. transform: rotate(-90deg);
  29. ${props => props.spinning ? css`animation: rotate 1s linear infinite;` : ''}
  30. @keyframes rotate {
  31. 0% {transform: rotate(0deg);}
  32. 100% {transform: rotate(360deg);}
  33. }
  34. `
  35. const ProgressText = styled.div`
  36. color: ${Palette.primary};
  37. font-size: 9px;
  38. font-weight: ${StyleProps.fontWeights.medium};
  39. top: 9px;
  40. position: absolute;
  41. width: 100%;
  42. text-align: center;
  43. `
  44. const CircleProgressBar = styled.circle``
  45. export const TEST_ID = 'smallLoading'
  46. export type Props = {
  47. loadingProgress: number,
  48. }
  49. @observer
  50. class SmallLoading extends React.Component<Props> {
  51. renderProgressImage() {
  52. let progress = this.props.loadingProgress > -1 ? this.props.loadingProgress : 25
  53. return (
  54. <ProgressSvgWrapper
  55. id="svg"
  56. width="28"
  57. height="28"
  58. viewPort="0 0 28 28"
  59. spinning={this.props.loadingProgress === -1}
  60. version="1.1"
  61. xmlns="http://www.w3.org/2000/svg"
  62. >
  63. <g strokeWidth="2">
  64. <circle
  65. r="13"
  66. cx="14"
  67. cy="14"
  68. fill="transparent"
  69. stroke={Palette.grayscale[2]}
  70. />
  71. <CircleProgressBar
  72. data-test-id="statusImage-progressBar"
  73. r="13"
  74. cx="14"
  75. cy="14"
  76. fill="transparent"
  77. stroke={Palette.primary}
  78. strokeDasharray="100 100"
  79. strokeDashoffset={300 - ((progress / 100) * 82)}
  80. />
  81. </g>
  82. </ProgressSvgWrapper>
  83. )
  84. }
  85. renderProgressText() {
  86. if (this.props.loadingProgress === -1) {
  87. return null
  88. }
  89. return (
  90. <ProgressText
  91. data-test-id={`${TEST_ID}-progressText`}
  92. >{this.props.loadingProgress ? this.props.loadingProgress.toFixed(0) : 0}%</ProgressText>
  93. )
  94. }
  95. render() {
  96. return (
  97. <Wrapper>
  98. {this.renderProgressImage()}
  99. {this.renderProgressText()}
  100. </Wrapper>
  101. )
  102. }
  103. }
  104. export default SmallLoading