feat: add simple select component
This commit is contained in:
@@ -8,6 +8,7 @@ import dayjs from 'dayjs';
|
||||
import React, { useEffect } from 'react';
|
||||
import { DASHBOARD_USAGE_API } from '../../apis';
|
||||
import { TableRow } from '../../config/types';
|
||||
import FilterBar from './filter-bar';
|
||||
import useUsageData from './use-usage-data';
|
||||
|
||||
const ExportData: React.FC<{
|
||||
@@ -17,7 +18,6 @@ const ExportData: React.FC<{
|
||||
const { open, onCancel } = props || {};
|
||||
const intl = useIntl();
|
||||
const {
|
||||
FilterBar,
|
||||
init,
|
||||
setResult,
|
||||
loading,
|
||||
@@ -25,7 +25,11 @@ const ExportData: React.FC<{
|
||||
userList,
|
||||
modelList,
|
||||
query,
|
||||
setQuery
|
||||
setQuery,
|
||||
handleExport,
|
||||
handleDateChange,
|
||||
handleUsersChange,
|
||||
handleModelsChange
|
||||
} = useUsageData<{
|
||||
items: TableRow[];
|
||||
}>({
|
||||
@@ -169,7 +173,16 @@ const ExportData: React.FC<{
|
||||
></ModalFooter>
|
||||
}
|
||||
>
|
||||
<FilterBar></FilterBar>
|
||||
<FilterBar
|
||||
disabledDate={false}
|
||||
url={DASHBOARD_USAGE_API}
|
||||
query={query}
|
||||
userList={userList}
|
||||
modelList={modelList}
|
||||
handleDateChange={handleDateChange}
|
||||
handleUsersChange={handleUsersChange}
|
||||
handleModelsChange={handleModelsChange}
|
||||
></FilterBar>
|
||||
<Table
|
||||
columns={exportTableColumns}
|
||||
tableLayout={'auto'}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
import SimpleSelect from '@/components/seal-form/simple-select';
|
||||
import { DownloadOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, DatePicker, Tooltip } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { DASHBOARD_STATS_API } from '../../apis';
|
||||
import useRangePickerPreset from '../../hooks/use-rangepicker-preset';
|
||||
|
||||
const DefaultDateConfig = {
|
||||
maxRange: 60,
|
||||
defaultRange: 29
|
||||
};
|
||||
|
||||
const FilterWrapper = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 0px;
|
||||
.selection {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.ant-select-selection-overflow-item > span {
|
||||
height: 24px;
|
||||
}
|
||||
`;
|
||||
|
||||
interface FilterBarProps {
|
||||
query: any;
|
||||
userList: any[];
|
||||
modelList: any[];
|
||||
handleDateChange: (dates: any, dateStrings: [string, string]) => void;
|
||||
handleUsersChange: (value: any) => void;
|
||||
handleModelsChange: (value: any) => void;
|
||||
handleExport?: () => void;
|
||||
url: string;
|
||||
disabledDate?: boolean;
|
||||
}
|
||||
|
||||
const FilterBar: React.FC<FilterBarProps> = (props) => {
|
||||
const {
|
||||
query,
|
||||
userList,
|
||||
modelList,
|
||||
handleDateChange,
|
||||
handleUsersChange,
|
||||
handleModelsChange,
|
||||
handleExport,
|
||||
url,
|
||||
disabledDate
|
||||
} = props;
|
||||
|
||||
const { disabledRangeDaysDate, rangePresets } = useRangePickerPreset({
|
||||
range: DefaultDateConfig.maxRange,
|
||||
disabledDate: disabledDate
|
||||
});
|
||||
|
||||
const intl = useIntl();
|
||||
|
||||
const filterOptions = (inputValue: any, option: any) => {
|
||||
return option.label?.toLowerCase().includes(inputValue.toLowerCase());
|
||||
};
|
||||
|
||||
return (
|
||||
<FilterWrapper>
|
||||
<div className="selection">
|
||||
<DatePicker.RangePicker
|
||||
maxDate={dayjs()}
|
||||
defaultValue={[
|
||||
dayjs().add(-DefaultDateConfig.defaultRange, 'd'),
|
||||
dayjs()
|
||||
]}
|
||||
disabledDate={disabledRangeDaysDate}
|
||||
presets={rangePresets}
|
||||
allowClear={false}
|
||||
style={{ width: 220 }}
|
||||
value={[dayjs(query.start_date), dayjs(query.end_date)]}
|
||||
onChange={handleDateChange}
|
||||
></DatePicker.RangePicker>
|
||||
<SimpleSelect
|
||||
allowClear
|
||||
showSearch
|
||||
mode="multiple"
|
||||
options={userList}
|
||||
maxTagCount={0}
|
||||
filterOption={filterOptions}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'dashboard.usage.selectuser'
|
||||
})}
|
||||
style={{ maxWidth: 200, minWidth: 160 }}
|
||||
value={query.user_ids}
|
||||
onChange={handleUsersChange}
|
||||
></SimpleSelect>
|
||||
<SimpleSelect
|
||||
allowClear
|
||||
showSearch
|
||||
mode="multiple"
|
||||
options={modelList}
|
||||
maxTagCount={0}
|
||||
filterOption={filterOptions}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'dashboard.usage.selectmodel'
|
||||
})}
|
||||
value={query.model_ids}
|
||||
style={{ maxWidth: 200, minWidth: 160 }}
|
||||
onChange={handleModelsChange}
|
||||
></SimpleSelect>
|
||||
{url === DASHBOARD_STATS_API && (
|
||||
<Tooltip title={intl.formatMessage({ id: 'common.button.export' })}>
|
||||
<Button icon={<DownloadOutlined />} onClick={handleExport}></Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
</FilterWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default FilterBar;
|
||||
@@ -8,6 +8,7 @@ import { baseColorMap } from '../../config';
|
||||
import { DashboardContext } from '../../config/dashboard-context';
|
||||
import { DashboardUsageData } from '../../config/types';
|
||||
import ExportData from './export-data';
|
||||
import FilterBar from './filter-bar';
|
||||
import RequestTokenInner from './request-token-inner';
|
||||
import TopUser from './top-user';
|
||||
import useUsageData from './use-usage-data';
|
||||
@@ -21,16 +22,27 @@ const UsageInner: FC<{ maxWidth: number }> = ({ maxWidth }) => {
|
||||
const intl = useIntl();
|
||||
const { model_usage } = useContext(DashboardContext);
|
||||
|
||||
const { usageData, handleOnCancel, handleExport, FilterBar, init, open } =
|
||||
useUsageData<DashboardUsageData>({
|
||||
url: DASHBOARD_STATS_API,
|
||||
disabledDate: true,
|
||||
defaultData: {
|
||||
api_request_history: [],
|
||||
completion_token_history: [],
|
||||
prompt_token_history: []
|
||||
}
|
||||
});
|
||||
const {
|
||||
usageData,
|
||||
query,
|
||||
userList,
|
||||
modelList,
|
||||
handleOnCancel,
|
||||
init,
|
||||
handleExport,
|
||||
handleDateChange,
|
||||
handleUsersChange,
|
||||
handleModelsChange,
|
||||
open
|
||||
} = useUsageData<DashboardUsageData>({
|
||||
url: DASHBOARD_STATS_API,
|
||||
disabledDate: true,
|
||||
defaultData: {
|
||||
api_request_history: [],
|
||||
completion_token_history: [],
|
||||
prompt_token_history: []
|
||||
}
|
||||
});
|
||||
|
||||
const topUserData = useMemo(() => {
|
||||
// top 10 users
|
||||
@@ -104,10 +116,19 @@ const UsageInner: FC<{ maxWidth: number }> = ({ maxWidth }) => {
|
||||
<TitleWrapper>
|
||||
{intl.formatMessage({ id: 'dashboard.usage' })}
|
||||
</TitleWrapper>
|
||||
<FilterBar></FilterBar>
|
||||
<FilterBar
|
||||
url={DASHBOARD_STATS_API}
|
||||
query={query}
|
||||
userList={userList}
|
||||
modelList={modelList}
|
||||
disabledDate={true}
|
||||
handleDateChange={handleDateChange}
|
||||
handleUsersChange={handleUsersChange}
|
||||
handleModelsChange={handleModelsChange}
|
||||
handleExport={handleExport}
|
||||
></FilterBar>
|
||||
</div>
|
||||
<RequestTokenInner
|
||||
onExport={handleExport}
|
||||
requestData={usageData?.requestTokenData.requestData}
|
||||
xAxisData={usageData?.requestTokenData.xAxisData}
|
||||
tokenData={usageData?.requestTokenData.tokenData}
|
||||
|
||||
@@ -27,7 +27,6 @@ const CardWrapperBox = styled.div`
|
||||
`;
|
||||
|
||||
interface RequestTokenInnerProps {
|
||||
onExport?: () => void;
|
||||
requestData: {
|
||||
name: string;
|
||||
color: string;
|
||||
|
||||
@@ -1,36 +1,11 @@
|
||||
import useSelectRender from '@/components/seal-form/hooks/use-select-render';
|
||||
import { queryModelsList } from '@/pages/llmodels/apis';
|
||||
import { ListItem as ModelListItem } from '@/pages/llmodels/config/types';
|
||||
import { queryUsersList } from '@/pages/users/apis';
|
||||
import { DownloadOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, DatePicker, Select, Tooltip } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import _ from 'lodash';
|
||||
import { useMemo, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
DASHBOARD_STATS_API,
|
||||
DASHBOARD_USAGE_API,
|
||||
queryDashboardUsageData
|
||||
} from '../../apis';
|
||||
import { DASHBOARD_USAGE_API, queryDashboardUsageData } from '../../apis';
|
||||
import { baseColorMap } from '../../config';
|
||||
import useRangePickerPreset from '../../hooks/use-rangepicker-preset';
|
||||
|
||||
const FilterWrapper = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 0px;
|
||||
.selection {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.ant-select-selection-overflow-item > span {
|
||||
height: 24px;
|
||||
}
|
||||
`;
|
||||
|
||||
interface RequestTokenData {
|
||||
requestData: {
|
||||
@@ -99,20 +74,8 @@ export default function useUseageData<T>(config: {
|
||||
defaultData?: T;
|
||||
disabledDate?: boolean;
|
||||
}) {
|
||||
const { url, defaultData, disabledDate = false } = config || {};
|
||||
const intl = useIntl();
|
||||
const { TagRender } = useSelectRender({
|
||||
maxTagWidth: 100,
|
||||
filled: true,
|
||||
style: {
|
||||
height: 24,
|
||||
lineHeight: '24px'
|
||||
}
|
||||
});
|
||||
const { disabledRangeDaysDate, rangePresets } = useRangePickerPreset({
|
||||
range: DefaultDateConfig.maxRange,
|
||||
disabledDate: disabledDate
|
||||
});
|
||||
const { url, defaultData } = config || {};
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [result, setResult] = useState<{
|
||||
start_date?: string;
|
||||
@@ -356,69 +319,6 @@ export default function useUseageData<T>(config: {
|
||||
fetchUsersList();
|
||||
};
|
||||
|
||||
const FilterBar = () => {
|
||||
const filterOptions = (inputValue: any, option: any) => {
|
||||
return option.label?.toLowerCase().includes(inputValue.toLowerCase());
|
||||
};
|
||||
return (
|
||||
<FilterWrapper>
|
||||
<div className="selection">
|
||||
<DatePicker.RangePicker
|
||||
maxDate={dayjs()}
|
||||
defaultValue={[
|
||||
dayjs().add(-DefaultDateConfig.defaultRange, 'd'),
|
||||
dayjs()
|
||||
]}
|
||||
disabledDate={disabledRangeDaysDate}
|
||||
presets={rangePresets}
|
||||
allowClear={false}
|
||||
style={{ width: 220 }}
|
||||
value={[dayjs(query.start_date), dayjs(query.end_date)]}
|
||||
onChange={handleDateChange}
|
||||
></DatePicker.RangePicker>
|
||||
<Select
|
||||
allowClear
|
||||
showSearch
|
||||
mode="multiple"
|
||||
options={userList}
|
||||
maxTagCount={1}
|
||||
filterOption={filterOptions}
|
||||
tagRender={TagRender}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'dashboard.usage.selectuser'
|
||||
})}
|
||||
style={{ maxWidth: 200, minWidth: 160 }}
|
||||
value={query.user_ids}
|
||||
onChange={handleUsersChange}
|
||||
></Select>
|
||||
<Select
|
||||
allowClear
|
||||
showSearch
|
||||
mode="multiple"
|
||||
options={modelList}
|
||||
maxTagCount={1}
|
||||
tagRender={TagRender}
|
||||
filterOption={filterOptions}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'dashboard.usage.selectmodel'
|
||||
})}
|
||||
value={query.model_ids}
|
||||
style={{ maxWidth: 200, minWidth: 160 }}
|
||||
onChange={handleModelsChange}
|
||||
></Select>
|
||||
{url === DASHBOARD_STATS_API && (
|
||||
<Tooltip title={intl.formatMessage({ id: 'common.button.export' })}>
|
||||
<Button
|
||||
icon={<DownloadOutlined />}
|
||||
onClick={handleExport}
|
||||
></Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
</FilterWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
usageData,
|
||||
result,
|
||||
@@ -430,8 +330,10 @@ export default function useUseageData<T>(config: {
|
||||
setQuery,
|
||||
init,
|
||||
setResult,
|
||||
FilterBar,
|
||||
handleOnCancel,
|
||||
handleExport
|
||||
handleExport,
|
||||
handleDateChange,
|
||||
handleUsersChange,
|
||||
handleModelsChange
|
||||
};
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ const SpinWrapper = styled.div`
|
||||
justify-content: center;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 400px;
|
||||
max-height: 400px;
|
||||
right: 0;
|
||||
`;
|
||||
|
||||
|
||||
@@ -551,7 +551,8 @@ export const useCheckCompatibility = () => {
|
||||
const gpuSelector = generateGPUIds(data.values);
|
||||
return await handleDoEvalute({
|
||||
...data.values,
|
||||
...gpuSelector
|
||||
...gpuSelector,
|
||||
replicas: allValues.replicas || 0
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user