StatusIndicator.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import React, { Component } from "react";
  2. import styled from "styled-components";
  3. import loading from "assets/loading.gif";
  4. type PropsType = {
  5. status: string;
  6. controllers: Record<string, Record<string, any>>;
  7. margin_left: string;
  8. };
  9. type StateType = {};
  10. // Manages a tab selector and renders the associated view
  11. export default class StatusIndicator extends Component<PropsType, StateType> {
  12. renderStatus = (status: string) => {
  13. if (status == "loading") {
  14. return (
  15. <div>
  16. <Spinner src={loading} />
  17. </div>
  18. );
  19. }
  20. return (
  21. <div>
  22. <StatusColor status={status} />
  23. </div>
  24. );
  25. };
  26. getChartStatus = (chartStatus: string) => {
  27. if (chartStatus === "deployed") {
  28. for (var uid in this.props.controllers) {
  29. let value = this.props.controllers[uid];
  30. let available = this.getAvailability(value.metadata.kind, value);
  31. let progressing = true;
  32. this.props.controllers[uid]?.status?.conditions?.forEach(
  33. (condition: any) => {
  34. if (
  35. condition.type == "Progressing" &&
  36. condition.status == "False" &&
  37. condition.reason == "ProgressDeadlineExceeded"
  38. ) {
  39. progressing = false;
  40. }
  41. }
  42. );
  43. if (!available && progressing) {
  44. return "loading";
  45. } else if (!available && !progressing) {
  46. return "failed";
  47. }
  48. }
  49. return "deployed";
  50. }
  51. return chartStatus;
  52. };
  53. getAvailability = (kind: string, c: any) => {
  54. switch (kind?.toLowerCase()) {
  55. case "deployment":
  56. case "replicaset":
  57. return c.status.availableReplicas == c.status.replicas;
  58. case "statefulset":
  59. return c.status.readyReplicas == c.status.replicas;
  60. case "daemonset":
  61. return c.status.numberAvailable == c.status.desiredNumberScheduled;
  62. case "cronjob":
  63. return 1;
  64. }
  65. };
  66. render() {
  67. let status = this.getChartStatus(this.props.status);
  68. return (
  69. <Status margin_left={this.props.margin_left}>
  70. {this.renderStatus(status)}
  71. {status}
  72. </Status>
  73. );
  74. }
  75. }
  76. const Spinner = styled.img`
  77. width: 15px;
  78. height: 15px;
  79. margin-right: 15px;
  80. margin-bottom: -3px;
  81. `;
  82. const StatusColor = styled.div`
  83. margin-top: 1px;
  84. width: 8px;
  85. height: 8px;
  86. background: ${(props: { status: string }) =>
  87. props.status === "deployed"
  88. ? "#4797ff"
  89. : props.status === "failed"
  90. ? "#ed5f85"
  91. : props.status === "completed"
  92. ? "#00d12a"
  93. : "#f5cb42"};
  94. border-radius: 20px;
  95. margin-left: 3px;
  96. margin-right: 16px;
  97. `;
  98. const Status = styled.div`
  99. display: flex;
  100. height: 20px;
  101. font-size: 13px;
  102. flex-direction: row;
  103. text-transform: capitalize;
  104. align-items: center;
  105. font-family: "Work Sans", sans-serif;
  106. color: #aaaabb;
  107. animation: fadeIn 0.5s;
  108. margin-left: ${(props: { margin_left: string }) => props.margin_left};
  109. @keyframes fadeIn {
  110. from {
  111. opacity: 0;
  112. }
  113. to {
  114. opacity: 1;
  115. }
  116. }
  117. `;