new-api/web/src/components/table/channels/ChannelsTabs.jsx

89 lines
2.4 KiB
React
Raw Normal View History

/*
Copyright (C) 2025 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import React from 'react';
import { Tabs, TabPane, Tag } from '@douyinfe/semi-ui';
import { CHANNEL_OPTIONS } from '../../../constants/index.js';
import { getChannelIcon } from '../../../helpers/index.js';
const ChannelsTabs = ({
enableTagMode,
activeTypeKey,
setActiveTypeKey,
channelTypeCounts,
availableTypeKeys,
loadChannels,
activePage,
pageSize,
idSort,
setActivePage,
t
}) => {
if (enableTagMode) return null;
const handleTabChange = (key) => {
setActiveTypeKey(key);
setActivePage(1);
loadChannels(1, pageSize, idSort, enableTagMode, key);
};
return (
<Tabs
activeKey={activeTypeKey}
type="card"
collapsible
onChange={handleTabChange}
♻️ refactor: restructure LogsTable into modular component architecture Refactor the monolithic LogsTable component (1453 lines) into a modular, maintainable architecture following the channels table pattern. ## What Changed ### 🏗️ Architecture - Split single large file into focused, single-responsibility components - Introduced custom hook `useLogsData` for centralized state management - Created dedicated column definitions file for better organization - Implemented modal components for user interactions ### 📁 New Structure ``` web/src/components/table/usage-logs/ ├── index.jsx # Main page component orchestrator ├── LogsTable.jsx # Pure table rendering component ├── LogsActions.jsx # Actions area (stats + compact mode) ├── LogsFilters.jsx # Search form component ├── LogsColumnDefs.js # Column definitions and renderers └── modals/ ├── ColumnSelectorModal.jsx # Column visibility settings └── UserInfoModal.jsx # User information display web/src/hooks/logs/ └── useLogsData.js # Custom hook for state & logic ``` ### 🎯 Key Improvements - **Maintainability**: Clear separation of concerns, easier to understand - **Reusability**: Modular components can be reused independently - **Performance**: Optimized with `useMemo` for column rendering - **Testing**: Single-responsibility components easier to test - **Developer Experience**: Better code organization and readability ### 🔧 Technical Details - Preserved all existing functionality and user experience - Maintained backward compatibility through existing import path - Centralized all business logic in `useLogsData` custom hook - Extracted column definitions to separate module with render functions - Split complex UI into focused components (table, actions, filters, modals) ### 🐛 Fixes - Fixed Semi UI component import issues (`Typography.Paragraph`) - Resolved module export dependencies - Maintained consistent prop passing patterns ## Breaking Changes None - all existing imports and functionality preserved.
2025-07-18 22:04:54 +08:00
className="mb-2"
>
<TabPane
itemKey="all"
tab={
<span className="flex items-center gap-2">
{t('全部')}
<Tag color={activeTypeKey === 'all' ? 'red' : 'grey'} shape='circle'>
{channelTypeCounts['all'] || 0}
</Tag>
</span>
}
/>
{CHANNEL_OPTIONS.filter((opt) => availableTypeKeys.includes(String(opt.value))).map((option) => {
const key = String(option.value);
const count = channelTypeCounts[option.value] || 0;
return (
<TabPane
key={key}
itemKey={key}
tab={
<span className="flex items-center gap-2">
{getChannelIcon(option.value)}
{option.label}
<Tag color={activeTypeKey === key ? 'red' : 'grey'} shape='circle'>
{count}
</Tag>
</span>
}
/>
);
})}
</Tabs>
);
};
export default ChannelsTabs;