Skip to content

Commit 27451ab

Browse files
committed
Add Environments Table component
1 parent cc015e6 commit 27451ab

File tree

2 files changed

+145
-55
lines changed

2 files changed

+145
-55
lines changed
Lines changed: 49 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import React, { useState } from 'react';
2-
import { Table, Typography, Alert, Input, Button, Space, Empty } from 'antd';
3-
import { SearchOutlined, ReloadOutlined } from '@ant-design/icons';
4-
import { useHistory } from 'react-router-dom';
5-
import { useEnvironments } from './hooks/useEnvironments';
6-
import { Environment } from './types/environment.types';
1+
import React, { useState } from "react";
2+
import { Table, Typography, Alert, Input, Button, Space, Empty } from "antd";
3+
import { SearchOutlined, ReloadOutlined } from "@ant-design/icons";
4+
import { useHistory } from "react-router-dom";
5+
import { useEnvironments } from "./hooks/useEnvironments";
6+
import { Environment } from "./types/environment.types";
7+
import EnvironmentsTable from "./components/EnvironmentsTable";
78

89
const { Title } = Typography;
910

@@ -14,19 +15,19 @@ const { Title } = Typography;
1415
const EnvironmentsList: React.FC = () => {
1516
// Use our custom hook to get environments data and states
1617
const { environments, loading, error, refresh } = useEnvironments();
17-
18+
1819
// State for search input
19-
const [searchText, setSearchText] = useState('');
20-
20+
const [searchText, setSearchText] = useState("");
21+
2122
// Hook for navigation (using history instead of navigate)
2223
const history = useHistory();
2324

2425
// Filter environments based on search text
25-
const filteredEnvironments = environments.filter(env => {
26+
const filteredEnvironments = environments.filter((env) => {
2627
const searchLower = searchText.toLowerCase();
2728
return (
28-
(env.environmentName || '').toLowerCase().includes(searchLower) ||
29-
(env.environmentFrontendUrl || '').toLowerCase().includes(searchLower) ||
29+
(env.environmentName || "").toLowerCase().includes(searchLower) ||
30+
(env.environmentFrontendUrl || "").toLowerCase().includes(searchLower) ||
3031
env.environmentId.toLowerCase().includes(searchLower) ||
3132
env.environmentType.toLowerCase().includes(searchLower)
3233
);
@@ -35,64 +36,63 @@ const EnvironmentsList: React.FC = () => {
3536
// Define table columns - updated to match the actual data structure
3637
const columns = [
3738
{
38-
title: 'Name',
39-
dataIndex: 'environmentName',
40-
key: 'environmentName',
41-
render: (name: string) => name || 'Unnamed Environment',
39+
title: "Name",
40+
dataIndex: "environmentName",
41+
key: "environmentName",
42+
render: (name: string) => name || "Unnamed Environment",
4243
},
4344
{
44-
title: 'Domain',
45-
dataIndex: 'environmentFrontendUrl',
46-
key: 'environmentFrontendUrl',
47-
render: (url: string) => url || 'No URL',
45+
title: "Domain",
46+
dataIndex: "environmentFrontendUrl",
47+
key: "environmentFrontendUrl",
48+
render: (url: string) => url || "No URL",
4849
},
4950
{
50-
title: 'ID',
51-
dataIndex: 'environmentId',
52-
key: 'environmentId',
51+
title: "ID",
52+
dataIndex: "environmentId",
53+
key: "environmentId",
5354
},
5455
{
55-
title: 'Stage',
56-
dataIndex: 'environmentType',
57-
key: 'environmentType',
56+
title: "Stage",
57+
dataIndex: "environmentType",
58+
key: "environmentType",
5859
},
5960
{
60-
title: 'Master',
61-
dataIndex: 'isMaster',
62-
key: 'isMaster',
63-
render: (isMaster: boolean) => isMaster ? 'Yes' : 'No',
61+
title: "Master",
62+
dataIndex: "isMaster",
63+
key: "isMaster",
64+
render: (isMaster: boolean) => (isMaster ? "Yes" : "No"),
6465
},
6566
];
66-
67+
6768
// Handle row click to navigate to environment detail
6869
const handleRowClick = (record: Environment) => {
6970
history.push(`/home/settings/environments/${record.environmentId}`);
7071
};
7172

7273
return (
73-
<div className="environments-container" style={{ padding: '24px' }}>
74+
<div className="environments-container" style={{ padding: "24px" }}>
7475
{/* Header section with title and controls */}
75-
<div className="environments-header" style={{
76-
marginBottom: '24px',
77-
display: 'flex',
78-
justifyContent: 'space-between',
79-
alignItems: 'center'
80-
}}>
76+
<div
77+
className="environments-header"
78+
style={{
79+
marginBottom: "24px",
80+
display: "flex",
81+
justifyContent: "space-between",
82+
alignItems: "center",
83+
}}
84+
>
8185
<Title level={3}>Environments</Title>
8286
<Space>
8387
<Input
8488
placeholder="Search environments"
8589
value={searchText}
86-
onChange={e => setSearchText(e.target.value)}
90+
onChange={(e) => setSearchText(e.target.value)}
8791
style={{ width: 250 }}
8892
prefix={<SearchOutlined />}
8993
allowClear
9094
/>
91-
<Button
92-
icon={<ReloadOutlined />}
93-
onClick={refresh}
94-
loading={loading}
95-
>
95+
<Button icon={<ReloadOutlined />} onClick={refresh} loading={loading}>
9696
Refresh
9797
</Button>
9898
</Space>
@@ -105,7 +105,7 @@ const EnvironmentsList: React.FC = () => {
105105
description={error}
106106
type="error"
107107
showIcon
108-
style={{ marginBottom: '24px' }}
108+
style={{ marginBottom: "24px" }}
109109
/>
110110
)}
111111

@@ -117,20 +117,14 @@ const EnvironmentsList: React.FC = () => {
117117
/>
118118
) : (
119119
/* Table component */
120-
<Table
121-
dataSource={filteredEnvironments}
122-
columns={columns}
123-
rowKey="environmentId"
120+
<EnvironmentsTable
121+
environments={filteredEnvironments}
124122
loading={loading}
125-
pagination={{ pageSize: 10 }}
126-
onRow={(record) => ({
127-
onClick: () => handleRowClick(record),
128-
style: { cursor: 'pointer' }
129-
})}
123+
onRowClick={handleRowClick}
130124
/>
131125
)}
132126
</div>
133127
);
134128
};
135129

136-
export default EnvironmentsList;
130+
export default EnvironmentsList;
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import React from 'react';
2+
import { Table, Tag } from 'antd';
3+
import { Environment } from '../types/environment.types';
4+
5+
interface EnvironmentsTableProps {
6+
environments: Environment[];
7+
loading: boolean;
8+
onRowClick: (record: Environment) => void;
9+
}
10+
11+
/**
12+
* Table component for displaying environments
13+
*/
14+
const EnvironmentsTable: React.FC<EnvironmentsTableProps> = ({
15+
environments,
16+
loading,
17+
onRowClick
18+
}) => {
19+
// Get color for environment type/stage
20+
const getTypeColor = (type: string): string => {
21+
switch (type.toUpperCase()) {
22+
case 'DEV': return 'blue';
23+
case 'TEST': return 'orange';
24+
case 'PROD': return 'green';
25+
default: return 'default';
26+
}
27+
};
28+
29+
// Define table columns
30+
const columns = [
31+
{
32+
title: 'Name',
33+
dataIndex: 'environmentName',
34+
key: 'environmentName',
35+
render: (name: string) => name || 'Unnamed Environment',
36+
},
37+
{
38+
title: 'Domain',
39+
dataIndex: 'environmentFrontendUrl',
40+
key: 'environmentFrontendUrl',
41+
render: (url: string) => url || 'No URL',
42+
},
43+
{
44+
title: 'ID',
45+
dataIndex: 'environmentId',
46+
key: 'environmentId',
47+
},
48+
{
49+
title: 'Stage',
50+
dataIndex: 'environmentType',
51+
key: 'environmentType',
52+
render: (type: string) => (
53+
<Tag color={getTypeColor(type)}>
54+
{type.toUpperCase()}
55+
</Tag>
56+
),
57+
},
58+
{
59+
title: 'Master',
60+
dataIndex: 'isMaster',
61+
key: 'isMaster',
62+
render: (isMaster: boolean) => (
63+
<Tag color={isMaster ? 'green' : 'default'}>
64+
{isMaster ? 'Yes' : 'No'}
65+
</Tag>
66+
),
67+
},
68+
];
69+
70+
return (
71+
<Table
72+
dataSource={environments}
73+
columns={columns}
74+
rowKey="environmentId"
75+
loading={loading}
76+
pagination={{
77+
pageSize: 10,
78+
showSizeChanger: true,
79+
pageSizeOptions: ['10', '20', '50']
80+
}}
81+
onRow={(record) => ({
82+
onClick: () => onRowClick(record),
83+
style: {
84+
cursor: 'pointer',
85+
transition: 'background-color 0.3s',
86+
':hover': {
87+
backgroundColor: '#f5f5f5',
88+
}
89+
}
90+
})}
91+
rowClassName={() => 'environment-row'}
92+
/>
93+
);
94+
};
95+
96+
export default EnvironmentsTable;

0 commit comments

Comments
 (0)