plugin-postgresql-connector
Version:
NocoBase plugin for connecting to external PostgreSQL databases
129 lines • 10.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConnectionManager = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const antd_1 = require("antd");
const icons_1 = require("@ant-design/icons");
const ConnectionForm_1 = require("../components/ConnectionForm");
const client_1 = require("@nocobase/client");
const { Title, Text } = antd_1.Typography;
const { Search } = antd_1.Input;
const ConnectionManager = () => {
const [createModalVisible, setCreateModalVisible] = (0, react_1.useState)(false);
const [editModalVisible, setEditModalVisible] = (0, react_1.useState)(false);
const [selectedConnection, setSelectedConnection] = (0, react_1.useState)(null);
const [searchText, setSearchText] = (0, react_1.useState)('');
// Fetch connections
const { data: connectionsData, loading: loadingConnections, run: refreshConnections } = (0, client_1.useRequest)({
url: '/postgresql-connections',
});
// Delete connection
const { run: deleteConnection, loading: deletingConnection } = (0, client_1.useRequest)((id) => ({
url: `/postgresql-connections/${id}`,
method: 'DELETE',
}), {
manual: true,
onSuccess: () => {
antd_1.message.success('Xóa kết nối thành công!');
refreshConnections();
},
onError: (error) => {
antd_1.message.error(`Xóa kết nối thất bại: ${error.message}`);
},
});
// Test connection
const { run: testConnection, loading: testingConnection } = (0, client_1.useRequest)((id) => ({
url: `/postgresql-connections/${id}/test`,
method: 'POST',
}), {
manual: true,
onSuccess: () => {
antd_1.message.success('Kết nối hoạt động bình thường!');
},
onError: (error) => {
antd_1.message.error(`Kết nối thất bại: ${error.message}`);
},
});
const connections = connectionsData?.data || [];
const activeConnections = connections.filter((conn) => conn.isActive);
const totalConnections = connections.length;
// Filter connections based on search
const filteredConnections = connections.filter((conn) => conn.name.toLowerCase().includes(searchText.toLowerCase()) ||
conn.host.toLowerCase().includes(searchText.toLowerCase()) ||
conn.database.toLowerCase().includes(searchText.toLowerCase()));
const handleCreateSuccess = () => {
setCreateModalVisible(false);
refreshConnections();
};
const handleEditSuccess = () => {
setEditModalVisible(false);
setSelectedConnection(null);
refreshConnections();
};
const handleEdit = (connection) => {
setSelectedConnection(connection);
setEditModalVisible(true);
};
const handleDelete = (connectionId) => {
deleteConnection(connectionId);
};
const handleTest = (connectionId) => {
testConnection(connectionId);
};
const columns = [
{
title: 'Tên kết nối',
dataIndex: 'name',
key: 'name',
render: (text, record) => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(Text, { strong: true, children: text }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsxs)(Text, { type: "secondary", style: { fontSize: 12 }, children: [record.host, ":", record.port] })] })),
},
{
title: 'Database',
dataIndex: 'database',
key: 'database',
render: (text) => ((0, jsx_runtime_1.jsx)(antd_1.Tag, { icon: (0, jsx_runtime_1.jsx)(icons_1.DatabaseOutlined, {}), color: "blue", children: text })),
},
{
title: 'Username',
dataIndex: 'username',
key: 'username',
},
{
title: 'SSL',
dataIndex: 'ssl',
key: 'ssl',
render: (ssl) => ((0, jsx_runtime_1.jsx)(antd_1.Tag, { color: ssl ? 'green' : 'default', children: ssl ? 'SSL' : 'No SSL' })),
},
{
title: 'Trạng thái',
dataIndex: 'isActive',
key: 'isActive',
render: (isActive) => ((0, jsx_runtime_1.jsx)(antd_1.Tag, { icon: isActive ? (0, jsx_runtime_1.jsx)(icons_1.CheckCircleOutlined, {}) : (0, jsx_runtime_1.jsx)(icons_1.CloseCircleOutlined, {}), color: isActive ? 'success' : 'error', children: isActive ? 'Active' : 'Inactive' })),
},
{
title: 'Thao tác',
key: 'actions',
render: (record) => ((0, jsx_runtime_1.jsxs)(antd_1.Space, { children: [(0, jsx_runtime_1.jsx)(antd_1.Tooltip, { title: "Test k\u1EBFt n\u1ED1i", children: (0, jsx_runtime_1.jsx)(antd_1.Button, { size: "small", icon: (0, jsx_runtime_1.jsx)(icons_1.CheckCircleOutlined, {}), onClick: () => handleTest(record.id), loading: testingConnection }) }), (0, jsx_runtime_1.jsx)(antd_1.Tooltip, { title: "Ch\u1EC9nh s\u1EEDa", children: (0, jsx_runtime_1.jsx)(antd_1.Button, { size: "small", icon: (0, jsx_runtime_1.jsx)(icons_1.EditOutlined, {}), onClick: () => handleEdit(record) }) }), (0, jsx_runtime_1.jsx)(antd_1.Popconfirm, { title: "B\u1EA1n c\u00F3 ch\u1EAFc ch\u1EAFn mu\u1ED1n x\u00F3a k\u1EBFt n\u1ED1i n\u00E0y?", description: "Thao t\u00E1c n\u00E0y kh\u00F4ng th\u1EC3 ho\u00E0n t\u00E1c.", onConfirm: () => handleDelete(record.id), okText: "X\u00F3a", cancelText: "H\u1EE7y", okType: "danger", children: (0, jsx_runtime_1.jsx)(antd_1.Tooltip, { title: "X\u00F3a", children: (0, jsx_runtime_1.jsx)(antd_1.Button, { size: "small", icon: (0, jsx_runtime_1.jsx)(icons_1.DeleteOutlined, {}), danger: true, loading: deletingConnection }) }) })] })),
},
];
return ((0, jsx_runtime_1.jsxs)("div", { style: { padding: 24 }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: 24 }, children: [(0, jsx_runtime_1.jsxs)(Title, { level: 2, style: { margin: 0, display: 'flex', alignItems: 'center', gap: 12 }, children: [(0, jsx_runtime_1.jsx)(icons_1.DatabaseOutlined, {}), "Qu\u1EA3n l\u00FD k\u1EBFt n\u1ED1i PostgreSQL"] }), (0, jsx_runtime_1.jsx)(Text, { type: "secondary", children: "T\u1EA1o v\u00E0 qu\u1EA3n l\u00FD c\u00E1c k\u1EBFt n\u1ED1i \u0111\u1EBFn PostgreSQL databases" })] }), (0, jsx_runtime_1.jsxs)(antd_1.Row, { gutter: 16, style: { marginBottom: 24 }, children: [(0, jsx_runtime_1.jsx)(antd_1.Col, { span: 6, children: (0, jsx_runtime_1.jsx)(antd_1.Card, { children: (0, jsx_runtime_1.jsx)(antd_1.Statistic, { title: "T\u1ED5ng k\u1EBFt n\u1ED1i", value: totalConnections, prefix: (0, jsx_runtime_1.jsx)(icons_1.DatabaseOutlined, {}) }) }) }), (0, jsx_runtime_1.jsx)(antd_1.Col, { span: 6, children: (0, jsx_runtime_1.jsx)(antd_1.Card, { children: (0, jsx_runtime_1.jsx)(antd_1.Statistic, { title: "K\u1EBFt n\u1ED1i ho\u1EA1t \u0111\u1ED9ng", value: activeConnections.length, prefix: (0, jsx_runtime_1.jsx)(icons_1.CheckCircleOutlined, {}), valueStyle: { color: '#3f8600' } }) }) }), (0, jsx_runtime_1.jsx)(antd_1.Col, { span: 6, children: (0, jsx_runtime_1.jsx)(antd_1.Card, { children: (0, jsx_runtime_1.jsx)(antd_1.Statistic, { title: "K\u1EBFt n\u1ED1i SSL", value: connections.filter((c) => c.ssl).length, prefix: (0, jsx_runtime_1.jsx)(icons_1.CheckCircleOutlined, {}), valueStyle: { color: '#1890ff' } }) }) }), (0, jsx_runtime_1.jsx)(antd_1.Col, { span: 6, children: (0, jsx_runtime_1.jsx)(antd_1.Card, { children: (0, jsx_runtime_1.jsx)(antd_1.Statistic, { title: "K\u1EBFt n\u1ED1i kh\u00F4ng ho\u1EA1t \u0111\u1ED9ng", value: totalConnections - activeConnections.length, prefix: (0, jsx_runtime_1.jsx)(icons_1.CloseCircleOutlined, {}), valueStyle: { color: '#cf1322' } }) }) })] }), (0, jsx_runtime_1.jsx)(antd_1.Card, { style: { marginBottom: 16 }, children: (0, jsx_runtime_1.jsxs)(antd_1.Row, { justify: "space-between", align: "middle", children: [(0, jsx_runtime_1.jsx)(antd_1.Col, { children: (0, jsx_runtime_1.jsxs)(antd_1.Space, { children: [(0, jsx_runtime_1.jsx)(antd_1.Button, { type: "primary", icon: (0, jsx_runtime_1.jsx)(icons_1.PlusOutlined, {}), onClick: () => setCreateModalVisible(true), size: "large", children: "T\u1EA1o k\u1EBFt n\u1ED1i m\u1EDBi" }), (0, jsx_runtime_1.jsx)(antd_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.ReloadOutlined, {}), onClick: refreshConnections, loading: loadingConnections, children: "Refresh" })] }) }), (0, jsx_runtime_1.jsx)(antd_1.Col, { children: (0, jsx_runtime_1.jsx)(Search, { placeholder: "T\u00ECm ki\u1EBFm k\u1EBFt n\u1ED1i...", value: searchText, onChange: (e) => setSearchText(e.target.value), style: { width: 300 }, prefix: (0, jsx_runtime_1.jsx)(icons_1.SearchOutlined, {}) }) })] }) }), (0, jsx_runtime_1.jsx)(antd_1.Card, { children: (0, jsx_runtime_1.jsx)(antd_1.Table, { columns: columns, dataSource: filteredConnections, rowKey: "id", loading: loadingConnections, pagination: {
pageSize: 10,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total) => `Tổng ${total} kết nối`,
}, scroll: { x: true } }) }), (0, jsx_runtime_1.jsx)(antd_1.Modal, { title: "T\u1EA1o k\u1EBFt n\u1ED1i PostgreSQL m\u1EDBi", open: createModalVisible, onCancel: () => setCreateModalVisible(false), footer: null, width: 700, destroyOnClose: true, children: (0, jsx_runtime_1.jsx)(ConnectionForm_1.ConnectionForm, { onSuccess: handleCreateSuccess, mode: "create" }) }), (0, jsx_runtime_1.jsx)(antd_1.Modal, { title: "Ch\u1EC9nh s\u1EEDa k\u1EBFt n\u1ED1i PostgreSQL", open: editModalVisible, onCancel: () => {
setEditModalVisible(false);
setSelectedConnection(null);
}, footer: null, width: 700, destroyOnClose: true, children: selectedConnection && ((0, jsx_runtime_1.jsx)(ConnectionForm_1.ConnectionForm, { onSuccess: handleEditSuccess, mode: "edit", connectionId: selectedConnection.id, initialValues: {
name: selectedConnection.name,
host: selectedConnection.host,
port: selectedConnection.port,
database: selectedConnection.database,
username: selectedConnection.username,
ssl: selectedConnection.ssl,
} })) })] }));
};
exports.ConnectionManager = ConnectionManager;
exports.default = exports.ConnectionManager;
//# sourceMappingURL=ConnectionManager.js.map