QueryCard.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import { css } from '@emotion/css';
  2. import React from 'react';
  3. import { GrafanaTheme2 } from '@grafana/data';
  4. import { secondsToHms } from '@grafana/data/src/datetime/rangeutil';
  5. import { getDataSourceSrv } from '@grafana/runtime';
  6. import { useStyles2 } from '@grafana/ui';
  7. import { RecordedQuery } from '../types';
  8. interface Props {
  9. recordedQuery: RecordedQuery;
  10. buttons: JSX.Element[];
  11. }
  12. export const QueryCard = ({ recordedQuery, buttons }: Props) => {
  13. const styles = useStyles2(getStyles);
  14. const ds = getDataSourceSrv()?.getInstanceSettings(recordedQuery.queries[0]?.datasource);
  15. return (
  16. <div className={styles.alert}>
  17. {ds?.meta && <img className={styles.media} src={ds.meta.info.logos.small} />}
  18. <div className={styles.body}>
  19. <div className={styles.info}>
  20. <div>
  21. <h2 className={styles.heading}>{recordedQuery.name}</h2>
  22. <p className={styles.description}>{content(recordedQuery)}</p>
  23. </div>
  24. <div className={styles.buttonWrapper}>
  25. {buttons.map((b, i) => {
  26. return (
  27. <div key={`button-${i}`} className={styles.button}>
  28. {b}
  29. </div>
  30. );
  31. })}
  32. </div>
  33. </div>
  34. </div>
  35. </div>
  36. );
  37. };
  38. const content = (rq: RecordedQuery): string => {
  39. const content = [`Interval: ${secondsToHms(rq.interval)}`, `Range: Last ${secondsToHms(rq.range)}`];
  40. const ds = getDataSourceSrv()?.getInstanceSettings(rq.queries[0]?.datasource);
  41. if (ds !== undefined) {
  42. content.unshift(ds.name);
  43. }
  44. if (rq.description !== '') {
  45. content.push(`${rq.description}`);
  46. }
  47. return content.join(' | ');
  48. };
  49. const getStyles = (theme: GrafanaTheme2) => {
  50. const borderRadius = theme.shape.borderRadius();
  51. return {
  52. info: css`
  53. display: flex;
  54. flex-direction: row;
  55. justify-content: space-between;
  56. align-items: center;
  57. width: 100%;
  58. `,
  59. heading: css`
  60. display: flex;
  61. justify-content: space-between;
  62. align-items: center;
  63. width: 100%;
  64. margin-bottom: 0;
  65. font-size: ${theme.typography.size.md};
  66. letter-spacing: inherit;
  67. line-height: ${theme.typography.body.lineHeight};
  68. color: ${theme.colors.text.primary};
  69. font-weight: ${theme.typography.fontWeightMedium};
  70. `,
  71. description: css`
  72. width: 100%;
  73. margin: ${theme.spacing(1, 0, 0)};
  74. color: ${theme.colors.text.secondary};
  75. line-height: ${theme.typography.body.lineHeight};
  76. `,
  77. alert: css`
  78. flex-grow: 1;
  79. position: relative;
  80. border-radius: ${borderRadius};
  81. display: flex;
  82. flex-direction: row;
  83. align-items: center;
  84. background: ${theme.colors.background.secondary};
  85. box-shadow: ${theme.shadows.z1};
  86. margin-bottom: ${theme.spacing(1)};
  87. &:before {
  88. content: '';
  89. position: absolute;
  90. top: 0;
  91. left: 0;
  92. bottom: 0;
  93. right: 0;
  94. background: ${theme.colors.background.primary};
  95. z-index: -1;
  96. }
  97. `,
  98. body: css`
  99. color: ${theme.colors.text.secondary};
  100. padding: ${theme.spacing(2)};
  101. flex-grow: 1;
  102. display: flex;
  103. flex-direction: column;
  104. justify-content: center;
  105. overflow-wrap: break-word;
  106. word-break: break-word;
  107. `,
  108. content: css`
  109. color: ${theme.colors.text.secondary};
  110. padding-top: ${theme.spacing(1)};
  111. margin-left: 26px;
  112. `,
  113. media: css`
  114. margin-left: ${theme.spacing(2)};
  115. width: 40px;
  116. `,
  117. buttonWrapper: css`
  118. padding: ${theme.spacing(1)};
  119. background: none;
  120. display: flex;
  121. align-items: center;
  122. margin-right: ${theme.spacing()};
  123. `,
  124. button: css`
  125. margin-left: ${theme.spacing()};
  126. `,
  127. };
  128. };