🔖 chore: Model price page add toolbar(#196)

This commit is contained in:
MartialBE 2024-05-19 22:41:54 +08:00
parent 96f19fb35f
commit 6081cc27fa
No known key found for this signature in database
GPG Key ID: 27C0267EC84B0A5C
3 changed files with 116 additions and 89 deletions

View File

@ -1,39 +0,0 @@
import PropTypes from 'prop-types';
import { TableRow, TableCell } from '@mui/material';
import Label from 'ui-component/Label';
import { copy } from 'utils/common';
export default function PricesTableRow({ item }) {
return (
<>
<TableRow tabIndex={item.model}>
<TableCell>
<Label
variant="outlined"
color="primary"
key={item.model}
onClick={() => {
copy(item.model, '模型名称');
}}
>
{item.model}
</Label>
</TableCell>
<TableCell>{item.type}</TableCell>
<TableCell>{item.channel_type}</TableCell>
<TableCell>{item.input}</TableCell>
<TableCell>{item.output}</TableCell>
</TableRow>
</>
);
}
PricesTableRow.propTypes = {
item: PropTypes.object,
userModelList: PropTypes.object,
ownedby: PropTypes.array
};

View File

@ -1,14 +1,15 @@
import { useState, useEffect, useCallback } from 'react'; import { useState, useEffect, useCallback, useMemo } from 'react';
import Table from '@mui/material/Table'; import { Card, Stack, Typography } from '@mui/material';
import TableBody from '@mui/material/TableBody'; import {
import TableContainer from '@mui/material/TableContainer'; DataGrid,
import PerfectScrollbar from 'react-perfect-scrollbar'; GridToolbarContainer,
GridToolbarColumnsButton,
import { Card } from '@mui/material'; GridToolbarFilterButton,
import PricesTableRow from './component/TableRow'; GridToolbarQuickFilter,
import TableNoData from 'ui-component/TableNoData'; GridToolbarDensitySelector
import KeywordTableHead from 'ui-component/TableHead'; } from '@mui/x-data-grid';
import { zhCN } from '@mui/x-data-grid/locales';
import { API } from 'utils/api'; import { API } from 'utils/api';
import { showError } from 'utils/common'; import { showError } from 'utils/common';
import { ValueFormatter, priceType } from 'views/Pricing/component/util'; import { ValueFormatter, priceType } from 'views/Pricing/component/util';
@ -77,18 +78,20 @@ export default function ModelPrice() {
} }
let newRows = []; let newRows = [];
userModelList.forEach((model) => { userModelList.forEach((model, index) => {
const price = prices[model.id]; const price = prices[model.id];
const type_label = priceType.find((pt) => pt.value === price?.type); // const type_label = priceType.find((pt) => pt.value === price?.type);
const channel_label = ownedby.find((ob) => ob.value === price?.channel_type); // const channel_label = ownedby.find((ob) => ob.value === price?.channel_type);
newRows.push({ newRows.push({
id: index + 1,
model: model.id, model: model.id,
type: type_label?.label || '未知', type: price?.type,
channel_type: channel_label?.label || '未知', channel_type: price?.channel_type,
input: ValueFormatter(price?.input !== undefined && price?.input !== null ? price.input : 30), input: price?.input !== undefined && price?.input !== null ? price.input : 30,
output: ValueFormatter(price?.output !== undefined && price?.output !== null ? price.output : 30) output: price?.output !== undefined && price?.output !== null ? price.output : 30
}); });
}); });
console.log(newRows);
setRows(newRows); setRows(newRows);
}, [userModelList, ownedby, prices]); }, [userModelList, ownedby, prices]);
@ -105,31 +108,81 @@ export default function ModelPrice() {
fetchData(); fetchData();
}, [fetchOwnedby, fetchUserModelList, fetchPrices]); }, [fetchOwnedby, fetchUserModelList, fetchPrices]);
const modelRatioColumns = useMemo(
() => [
{
field: 'model',
sortable: true,
headerName: '模型名称',
minWidth: 220,
flex: 1
},
{
field: 'type',
sortable: true,
headerName: '类型',
flex: 0.5,
minWidth: 100,
type: 'singleSelect',
valueOptions: priceType
},
{
field: 'channel_type',
sortable: true,
headerName: '供应商',
flex: 0.5,
minWidth: 100,
type: 'singleSelect',
valueOptions: ownedby
},
{
field: 'input',
sortable: true,
headerName: '输入倍率',
flex: 0.8,
minWidth: 150,
type: 'number',
valueFormatter: (params) => ValueFormatter(params.value)
},
{
field: 'output',
sortable: true,
headerName: '输出倍率',
flex: 0.8,
minWidth: 150,
type: 'number',
valueFormatter: (params) => ValueFormatter(params.value)
}
],
[ownedby]
);
function EditToolbar() {
return (
<GridToolbarContainer>
<GridToolbarColumnsButton />
<GridToolbarFilterButton />
<GridToolbarDensitySelector />
<GridToolbarQuickFilter />
</GridToolbarContainer>
);
}
return ( return (
<> <>
<Stack direction="row" alignItems="center" justifyContent="space-between" mb={5}>
<Typography variant="h4">可用模型</Typography>
</Stack>
<Card> <Card>
<PerfectScrollbar component="div"> <DataGrid
<TableContainer sx={{ overflow: 'unset' }}> rows={rows}
<Table sx={{ minWidth: 800 }}> columns={modelRatioColumns}
<KeywordTableHead initialState={{ pagination: { paginationModel: { pageSize: 20 } } }}
headLabel={[ pageSizeOptions={[20, 30, 50, 100]}
{ id: 'model', label: '模型名称', disableSort: true }, disableRowSelectionOnClick
{ id: 'type', label: '类型', disableSort: true }, slots={{ toolbar: EditToolbar }}
{ id: 'channel_type', label: '供应商', disableSort: true }, localeText={zhCN.components.MuiDataGrid.defaultProps.localeText}
{ id: 'input', label: '输入(/1k tokens)', disableSort: true }, />
{ id: 'output', label: '输出(/1k tokens)', disableSort: true }
]}
/>
<TableBody>
{rows.length === 0 ? (
<TableNoData message="无可用模型" />
) : (
rows.map((row) => <PricesTableRow item={row} key={row.model} />)
)}
</TableBody>
</Table>
</TableContainer>
</PerfectScrollbar>
</Card> </Card>
</> </>
); );

View File

@ -1,6 +1,17 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useState, useEffect, useMemo, useCallback } from 'react'; import { useState, useEffect, useMemo, useCallback } from 'react';
import { GridRowModes, DataGrid, GridToolbarContainer, GridActionsCellItem } from '@mui/x-data-grid'; import {
GridRowModes,
DataGrid,
GridToolbarContainer,
GridActionsCellItem,
GridToolbarExport,
GridToolbarColumnsButton,
GridToolbarFilterButton,
GridToolbarQuickFilter,
GridToolbarDensitySelector
} from '@mui/x-data-grid';
import { zhCN } from '@mui/x-data-grid/locales';
import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material'; import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material';
import AddIcon from '@mui/icons-material/Add'; import AddIcon from '@mui/icons-material/Add';
import EditIcon from '@mui/icons-material/Edit'; import EditIcon from '@mui/icons-material/Edit';
@ -58,6 +69,11 @@ function EditToolbar({ setRows, setRowModesModel }) {
<Button color="primary" startIcon={<AddIcon />} onClick={handleClick}> <Button color="primary" startIcon={<AddIcon />} onClick={handleClick}>
新增 新增
</Button> </Button>
<GridToolbarColumnsButton />
<GridToolbarFilterButton />
<GridToolbarDensitySelector />
<GridToolbarExport printOptions={{ disableToolbarButton: true }} csvOptions={{ utf8WithBom: true }} />
<GridToolbarQuickFilter />
</GridToolbarContainer> </GridToolbarContainer>
); );
} }
@ -185,8 +201,7 @@ const Single = ({ ownedby, prices, reloadData }) => {
headerName: '模型名称', headerName: '模型名称',
minWidth: 220, minWidth: 220,
flex: 1, flex: 1,
editable: true, editable: true
hideable: false
}, },
{ {
field: 'type', field: 'type',
@ -196,8 +211,7 @@ const Single = ({ ownedby, prices, reloadData }) => {
minWidth: 100, minWidth: 100,
type: 'singleSelect', type: 'singleSelect',
valueOptions: priceType, valueOptions: priceType,
editable: true, editable: true
hideable: false
}, },
{ {
field: 'channel_type', field: 'channel_type',
@ -207,8 +221,7 @@ const Single = ({ ownedby, prices, reloadData }) => {
minWidth: 100, minWidth: 100,
type: 'singleSelect', type: 'singleSelect',
valueOptions: ownedby, valueOptions: ownedby,
editable: true, editable: true
hideable: false
}, },
{ {
field: 'input', field: 'input',
@ -218,8 +231,7 @@ const Single = ({ ownedby, prices, reloadData }) => {
minWidth: 150, minWidth: 150,
type: 'number', type: 'number',
editable: true, editable: true,
valueFormatter: (params) => ValueFormatter(params.value), valueFormatter: (params) => ValueFormatter(params.value)
hideable: false
}, },
{ {
field: 'output', field: 'output',
@ -229,8 +241,7 @@ const Single = ({ ownedby, prices, reloadData }) => {
minWidth: 150, minWidth: 150,
type: 'number', type: 'number',
editable: true, editable: true,
valueFormatter: (params) => ValueFormatter(params.value), valueFormatter: (params) => ValueFormatter(params.value)
hideable: false
}, },
{ {
field: 'actions', field: 'actions',
@ -241,6 +252,7 @@ const Single = ({ ownedby, prices, reloadData }) => {
// width: 100, // width: 100,
cellClassName: 'actions', cellClassName: 'actions',
hideable: false, hideable: false,
disableExport: true,
getActions: ({ id }) => { getActions: ({ id }) => {
const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;
@ -338,6 +350,7 @@ const Single = ({ ownedby, prices, reloadData }) => {
onRowModesModelChange={handleRowModesModelChange} onRowModesModelChange={handleRowModesModelChange}
processRowUpdate={processRowUpdate} processRowUpdate={processRowUpdate}
onProcessRowUpdateError={handleProcessRowUpdateError} onProcessRowUpdateError={handleProcessRowUpdateError}
localeText={zhCN.components.MuiDataGrid.defaultProps.localeText}
// onCellDoubleClick={(params, event) => { // onCellDoubleClick={(params, event) => {
// event.defaultMuiPrevented = true; // event.defaultMuiPrevented = true;
// }} // }}