Mirror of https://github.com/roostorg/osprey
github.com/roostorg/osprey
1import * as React from 'react';
2import moment from 'moment-timezone';
3
4import { QueryRecord } from '../../types/QueryTypes';
5import Expand, { ExpandButton } from '../../uikit/Expand';
6import OverflowTooltip from '../../uikit/OverflowTooltip';
7import Text, { TextSizes, TextColors } from '../../uikit/Text';
8import { localizeAndFormatTimestamp } from '../../utils/DateUtils';
9import QueryFilter from './QueryFilter';
10
11import { DATE_FORMAT } from '../../Constants';
12import styles from './QueryCards.module.css';
13
14interface QueryCardActionDataProps {
15 user: string;
16 action: string;
17 timestamp: number;
18}
19
20export const QueryCardActionData = ({ user, action, timestamp }: QueryCardActionDataProps) => {
21 return (
22 <Text size={TextSizes.SMALL} color={TextColors.LIGHT_SECONDARY}>
23 <b>{user}</b> {action} {moment.unix(timestamp).format(DATE_FORMAT)}
24 </Text>
25 );
26};
27
28interface QueryCardHeaderProps {
29 children: React.ReactNode;
30 isCompact?: boolean;
31}
32
33export const QueryCardHeader = ({ children, isCompact = false }: QueryCardHeaderProps) => {
34 return <div className={isCompact ? styles.cardHeaderCompact : styles.cardHeader}>{children}</div>;
35};
36
37interface QueryCardBodyProps {
38 query: QueryRecord;
39 queryFilterPlaceholder?: React.ReactNode;
40 intervalCopy: string;
41 isCompact?: boolean;
42}
43
44export const QueryCardBody = ({
45 query,
46 queryFilterPlaceholder = null,
47 intervalCopy,
48 isCompact = false,
49}: QueryCardBodyProps) => {
50 const getOverflowTooltipContent = (content: React.ReactNode) => {
51 const topNTables =
52 query.top_n.length === 0 ? null : (
53 <>
54 <div>Top N Tables:</div>
55 <ul className={styles.overflowTopNList}>
56 {query.top_n.map((table) => table.dimension && <li key={table.dimension}>{table.dimension}</li>)}
57 </ul>
58 </>
59 );
60
61 return (
62 <>
63 {content}
64 {topNTables}
65 </>
66 );
67 };
68
69 const renderQueryFilter = () => {
70 if (query.query_filter === '') {
71 return queryFilterPlaceholder;
72 }
73
74 return (
75 <>
76 <Expand className={styles.queryFilterExpand} rowHeight={20}>
77 <QueryFilter queryFilter={query.query_filter} />
78 </Expand>
79 <ExpandButton />
80 {isCompact ? null : <div className={styles.divider} />}
81 </>
82 );
83 };
84
85 const renderQueryInfo = () => {
86 const delimiter = ' • ';
87 const dateRange = `${localizeAndFormatTimestamp(query.date_range.start)} - ${localizeAndFormatTimestamp(
88 query.date_range.end
89 )}`;
90 const additionalQueryInfo = [
91 `${localizeAndFormatTimestamp(query.date_range.start)} - ${localizeAndFormatTimestamp(query.date_range.end)}`,
92 ];
93
94 if (intervalCopy !== '') {
95 additionalQueryInfo.unshift(intervalCopy);
96 }
97
98 if (query.top_n.length > 0) {
99 additionalQueryInfo.push(`Top N: ${query.top_n.join(', ')}`);
100 }
101
102 return (
103 <OverflowTooltip className={styles.additionalInfo} tooltipContent={getOverflowTooltipContent(dateRange)}>
104 {additionalQueryInfo.join(delimiter)}
105 </OverflowTooltip>
106 );
107 };
108
109 return (
110 <div className={styles.cardBody}>
111 {renderQueryFilter()}
112 {renderQueryInfo()}
113 </div>
114 );
115};