Skip to content

Commit

Permalink
Merge pull request #872 from amitamrutiya/custom-formatters
Browse files Browse the repository at this point in the history
Create custom formatters and the resource data extract hooks for the resource detail view
  • Loading branch information
amitamrutiya authored Jan 8, 2025
2 parents e8f61e1 + 693950c commit 44c6e97
Show file tree
Hide file tree
Showing 15 changed files with 2,486 additions and 3 deletions.
552 changes: 549 additions & 3 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@
"access": "public"
},
"dependencies": {
"billboard.js": "^3.14.3",
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"react-share": "^5.1.0"
}
}
27 changes: 27 additions & 0 deletions src/custom/BBChart/BBChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ChartOptions, bb } from 'billboard.js';
import { memo, useEffect, useRef } from 'react';

interface BBChartProps {
options: ChartOptions;
}

const BBChart = ({ options }: BBChartProps) => {
const _chartRef = useRef<HTMLDivElement | null>(null);

useEffect(() => {
if (!_chartRef.current) return;

const chart = bb.generate({
bindto: _chartRef.current,
...options
});

return () => {
chart.destroy();
};
}, [options]);

return <div ref={_chartRef} onClickCapture={(e) => e.stopPropagation()} />;
};

export default memo(BBChart);
3 changes: 3 additions & 0 deletions src/custom/BBChart/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import BBChart from './BBChart';

export { BBChart };
168 changes: 168 additions & 0 deletions src/custom/ResourceDetailFormatters/Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import React from 'react';
import { Grid, IconButton, Typography } from '../../base';
import { iconSmall } from '../../constants/iconsSizes';
import { CopyIcon } from '../../icons';
import { useTheme } from '../../theme';
import { CustomTooltip } from './../CustomTooltip';
import { NumberState } from './Formatter';
import {
Details,
ElementDataWrap,
Heading,
KeyValueGrid,
KeyValueGridCell,
KeyValueGridTitle,
LongWrap,
StyledNumberBox,
Title,
VariableSubfield,
Wrap
} from './styles';
import {
ActionIconButtonProps,
CategoryProps,
CopyToClipboardProps,
EnvironmentVariablesProps,
KeyValueProps,
LongDetailsProps,
NumberStateFormatterProps,
PrimaryDetailsProps,
SectionHeadingProps
} from './types';
import { splitCamelCaseString } from './utils.js';

export const PrimaryDetails: React.FC<PrimaryDetailsProps> = ({ title, value, hide = false }) => {
const titleFormatted = splitCamelCaseString(title);
const show = hide === false ? hide : true;

if (!value || value === ` `) {
return null;
}

if (show) {
return (
<Details noPadding={true}>
<Wrap>
<Typography variant="body1">{titleFormatted}: </Typography>
<ElementDataWrap>{value}</ElementDataWrap>
</Wrap>
</Details>
);
}
return null;
};

export const CopyToClipboard: React.FC<CopyToClipboardProps> = ({ data }) => {
const theme = useTheme();
const copyToClipboard = () => {
navigator.clipboard.writeText(data);
};

return (
<span
style={{
display: 'flex',
alignItems: 'center',
cursor: 'pointer'
}}
>
<IconButton onClickCapture={copyToClipboard} style={{ paddingBlock: '4px' }}>
<CopyIcon height={20} width={20} fill={theme.palette.icon.secondary} />
</IconButton>
</span>
);
};

export const SectionHeading: React.FC<SectionHeadingProps> = ({ children }) => {
return <Typography variant="body1">{children + ':'}</Typography>;
};

export const LongDetails: React.FC<LongDetailsProps> = ({ title, value }) => {
const titleFormatted = splitCamelCaseString(title);

if (!value || value === ` `) {
return null;
}

return (
<Details noPadding={true}>
<LongWrap>
<SectionHeading>{titleFormatted}</SectionHeading>
{/* <CodeFormatter data={value} /> */}
</LongWrap>
</Details>
);
};

export const EnvironmentVariables: React.FC<EnvironmentVariablesProps> = ({ title, value }) => {
return (
<Details noPadding>
<LongWrap>
<VariableSubfield>
{title}:{value}
</VariableSubfield>
</LongWrap>
</Details>
);
};

export const Category: React.FC<CategoryProps> = ({ title, hide = false }) => {
const show = hide === false ? hide : true;

if (show) {
return (
<Heading>
<Title>{title}</Title>
</Heading>
);
}
return null;
};

export const NumberStateFormatter: React.FC<NumberStateFormatterProps> = ({ data }) => {
if (!data) {
return null;
}

return (
<StyledNumberBox>
{data.map((item) => (
<NumberState
key={item.title}
title={item.title}
value={item.value}
quantity={item.quantity}
/>
))}
</StyledNumberBox>
);
};

export const ActionIconButton: React.FC<ActionIconButtonProps> = ({ title, Icon, onClick }) => {
const theme = useTheme();
return (
<CustomTooltip title={title}>
<div>
<IconButton size="small" onClickCapture={onClick}>
<Icon {...iconSmall} fill={theme.palette.icon.default} />
</IconButton>
</div>
</CustomTooltip>
);
};

export const KeyValueInRow: React.FC<KeyValueProps> = ({ Key, Value }) => {
if (!Value || !Key) return null;
return (
<KeyValueGrid container>
<React.Fragment key={Key}>
<KeyValueGridCell item xs={3}>
<KeyValueGridTitle>{Key}</KeyValueGridTitle>
</KeyValueGridCell>
<Grid item xs={9}>
<div>{React.isValidElement(Value) ? Value : String(Value)}</div>
</Grid>
</React.Fragment>
</KeyValueGrid>
);
};
25 changes: 25 additions & 0 deletions src/custom/ResourceDetailFormatters/Details.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { OperatorDataContainer } from './styles';
import { isEmptyAtAllDepths } from './utils';

interface OperatorDataFormatterProps {
data: any;
FormatStructuredData: any;
propertyFormatter: any;
}

export const OperatorDataFormatter = ({
data,
FormatStructuredData,
propertyFormatter
}: OperatorDataFormatterProps) => {
if (!data || isEmptyAtAllDepths(data)) {
return null;
}

return (
<OperatorDataContainer>
<FormatStructuredData data={data} propertyFormatters={propertyFormatter} isLevel={false} />
</OperatorDataContainer>
);
};
19 changes: 19 additions & 0 deletions src/custom/ResourceDetailFormatters/ExpandArrow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { iconMedium } from '../../constants/iconsSizes';
import { useTheme } from '../../theme';

interface ExpandArrowProps {
expanded: boolean;
}

const ExpandArrow: React.FC<ExpandArrowProps> = ({ expanded }) => {
const theme = useTheme();
return expanded ? (
<ExpandLessIcon fill={theme.palette.icon.default} {...iconMedium} />
) : (
<ExpandMoreIcon fill={theme.palette.icon.default} {...iconMedium} />
);
};

export default ExpandArrow;
Loading

0 comments on commit 44c6e97

Please sign in to comment.