Skip to content

Commit 3564a41

Browse files
authored
Merge pull request #815 from devtron-labs/feat/revamp-chart-store-details
feat: Illustration Component, Improve Table Component typings
2 parents 2df774c + 1639cad commit 3564a41

32 files changed

Lines changed: 654 additions & 165 deletions

.eslintrc.cjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ module.exports = {
151151
group: ['IconBase'],
152152
message: 'Please use "Icon" component instead.',
153153
},
154+
{
155+
group: ['IllustrationBase'],
156+
message: 'Please use "Illustration" component instead.',
157+
},
154158
],
155159
},
156160
],

.husky/pre-commit

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
echo "Running pre-commit hook..."
2121

2222
# Check for changes in the Icon folder
23-
CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep -E 'IconV2/|generate-icon.cjs' || true)
23+
ICON_CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep -E 'IconV2/|generate-icon.cjs' || true)
2424

25-
if [ -n "$CHANGED_FILES" ]; then
25+
if [ -n "$ICON_CHANGED_FILES" ]; then
2626
echo "Changes detected in the Icon folder or icon generation script. Running icon generation script..."
2727

2828
if ! npm run generate-icon; then
@@ -36,6 +36,23 @@ else
3636
echo "No changes in the IconsV2 folder. Skipping icon generation."
3737
fi
3838

39+
# Check for changes in the Illustration folder
40+
ILLUSTRATION_CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep -E 'Illustration/|generate-illustration.cjs' || true)
41+
42+
if [ -n "$ILLUSTRATION_CHANGED_FILES" ]; then
43+
echo "Changes detected in the Illustration folder or illustration generation script. Running illustration generation script..."
44+
45+
if ! npm run generate-illustration; then
46+
echo "Error: Illustration generation script failed."
47+
exit 1
48+
fi
49+
50+
echo "Illustration.tsx updated. Adding to commit."
51+
git add src/Shared/Components/Illustration/Illustration.tsx
52+
else
53+
echo "No changes in the Illustration folder. Skipping illustration generation."
54+
fi
55+
3956
# TypeScript check
4057
if ! npx tsc --noEmit; then
4158
echo "Error: TypeScript check failed."

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devtron-labs/devtron-fe-common-lib",
3-
"version": "1.17.0-pre-11",
3+
"version": "1.17.0-pre-12",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",
@@ -33,7 +33,8 @@
3333
"preview": "vite preview",
3434
"lint-staged": "lint-staged",
3535
"postinstall": "patch-package",
36-
"generate-icon": "node ./scripts/generate-icon.cjs"
36+
"generate-icon": "node ./scripts/generate-icon.cjs",
37+
"generate-illustration": "node ./scripts/generate-illustration.cjs"
3738
},
3839
"devDependencies": {
3940
"@esbuild-plugins/node-globals-polyfill": "0.2.3",

scripts/generate-illustration.cjs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const fs = require('fs')
2+
const path = require('path')
3+
const { execFile } = require('child_process')
4+
5+
// Base path relative to the current script
6+
const basePath = path.resolve(__dirname, '../src')
7+
8+
// Directory containing SVG, Webp illustrations and the output file
9+
const illustrationsDir = path.join(basePath, 'Assets', 'Illustration')
10+
const outputFile = path.join(basePath, 'Shared', 'Components', 'Illustration', 'Illustration.tsx')
11+
12+
const runESLint = (filePath) => {
13+
execFile('npx', ['eslint', filePath, '--fix'], (error, stdout, stderr) => {
14+
if (error) {
15+
console.error(`Error running ESLint: ${error.message}`)
16+
return
17+
}
18+
if (stderr) {
19+
console.error(`ESLint stderr: ${stderr}`)
20+
}
21+
if (stdout) {
22+
console.log(`ESLint output:\n${stdout}`)
23+
}
24+
console.log('ESLint completed successfully.')
25+
})
26+
}
27+
28+
const generateIllustrationComponent = () => {
29+
// Read all files in the illustrations directory
30+
const files = fs.readdirSync(illustrationsDir)
31+
32+
// Filter for SVG files
33+
const svgFiles = files.filter((file) => file.endsWith('.svg'))
34+
// Filter for WEBP files
35+
const webpFiles = files.filter((file) => file.endsWith('.webp'))
36+
37+
// Generate import statements and the illustration map
38+
const imports = []
39+
const illustrationMapEntries = []
40+
41+
svgFiles.forEach((file) => {
42+
// Remove the .svg extension
43+
const illustrationName = path.basename(file, '.svg')
44+
// Convert illustration-name to IllustrationName for importName
45+
const importName = illustrationName
46+
.split('-')
47+
.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
48+
.join('')
49+
// Push imports statement
50+
imports.push(`import { ReactComponent as ${importName} } from '@Illustrations/${file}'`)
51+
// Push illustrations to illustrationMap
52+
illustrationMapEntries.push(`["${illustrationName}"]: ${importName},`)
53+
})
54+
55+
webpFiles.forEach((file) => {
56+
// Remove the .webp extension
57+
const illustrationName = path.basename(file, '.webp')
58+
// Convert illustration-name to IllustrationName for importName
59+
const importName = illustrationName.replace(/(^\w|-\w)/g, (match) => match.replace('-', '').toUpperCase())
60+
// Push imports statement
61+
imports.push(`import ${importName} from '@Illustrations/${file}'`)
62+
// Push illustrations to illustrationMap
63+
illustrationMapEntries.push(`["${illustrationName}"]: ${importName},`)
64+
})
65+
66+
// Generate the Illustration.tsx content
67+
const content = `
68+
// NOTE: This file is auto-generated. Do not edit directly. Run the script \`npm run generate-illustration\` to update.
69+
70+
${imports.join('\n')}
71+
72+
// eslint-disable-next-line no-restricted-imports
73+
import { IllustrationBase } from './IllustrationBase';
74+
import { IllustrationBaseProps } from './types';
75+
76+
export const illustrationMap = {
77+
${illustrationMapEntries.join('\n')}
78+
};
79+
80+
export type IllustrationName = keyof typeof illustrationMap;
81+
82+
export interface IllustrationProps extends Omit<IllustrationBaseProps, 'name' | 'illustrationMap'> {
83+
/**
84+
* The name of the illustration to render.
85+
* @note The component will return either an img component or an SVG component based on the type of illustration (.svg, .webp)
86+
*/
87+
name: keyof typeof illustrationMap;
88+
}
89+
90+
export const Illustration = (props: IllustrationProps) => {
91+
return <IllustrationBase {...props} illustrationMap={illustrationMap} />;
92+
};
93+
`
94+
95+
// Write the content to the Illustration.tsx file
96+
fs.writeFileSync(outputFile, content.trim(), 'utf-8')
97+
console.log(`Illustration component file generated at: ${outputFile}`)
98+
99+
// Run ESLint on the generated file
100+
runESLint(outputFile)
101+
}
102+
103+
// Run the script
104+
generateIllustrationComponent()
Lines changed: 4 additions & 0 deletions
Loading
30.9 KB
Loading
43 KB
Loading
39.3 KB
Loading

src/Common/EmptyState/GenericEmptyState.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17+
import { Illustration } from '@Shared/Components'
18+
1719
import AppNotDeployed from '../../Assets/Img/app-not-deployed.svg'
1820
import { GenericEmptyStateType, ImageType } from '../Types'
1921

@@ -35,6 +37,7 @@ const GenericEmptyState = ({
3537
layout = 'column',
3638
contentClassName = '',
3739
imageStyles = {},
40+
imgName,
3841
}: GenericEmptyStateType): JSX.Element => {
3942
const isRowLayout = layout === 'row'
4043

@@ -54,7 +57,20 @@ const GenericEmptyState = ({
5457
data-testid="generic-empty-state"
5558
>
5659
{!SvgImage ? (
57-
!noImage && (
60+
!noImage &&
61+
(imgName ? (
62+
<Illustration
63+
name={imgName}
64+
imageProps={{
65+
alt: 'empty-state',
66+
style: {
67+
width: `${getImageSize().width}`,
68+
height: `${getImageSize().height}`,
69+
...imageStyles,
70+
},
71+
}}
72+
/>
73+
) : (
5874
<img
5975
className={imageClassName || ''}
6076
src={image || AppNotDeployed}
@@ -65,7 +81,7 @@ const GenericEmptyState = ({
6581
}}
6682
alt="empty-state"
6783
/>
68-
)
84+
))
6985
) : (
7086
<SvgImage
7187
style={{

0 commit comments

Comments
 (0)