fix: deleted tag
This commit is contained in:
@@ -28,6 +28,20 @@ const ControlLabel = styled.span`
|
||||
margin-right: 8px;
|
||||
`;
|
||||
|
||||
function getColorForIndex(index: number) {
|
||||
const hue = (index * 137.5) % 360;
|
||||
return `oklch(70% 0.12 ${hue})`;
|
||||
}
|
||||
|
||||
const colors = [
|
||||
baseColorMap.base,
|
||||
baseColorMap.baseR3,
|
||||
baseColorMap.baseL1,
|
||||
baseColorMap.baseR1,
|
||||
baseColorMap.baseR2,
|
||||
baseColorMap.baseL2
|
||||
];
|
||||
|
||||
interface DailyUsageProps {
|
||||
timeSeriesData: TimeSeriesData | null;
|
||||
metric: string;
|
||||
@@ -60,22 +74,33 @@ const DailyUsage: React.FC<DailyUsageProps> = (props) => {
|
||||
}
|
||||
|
||||
const series = timeSeriesData.series;
|
||||
const xAxis = series[0]?.timeline?.map((item) => item.date) || [];
|
||||
const dateSet = new Set<string>();
|
||||
|
||||
const colors = [
|
||||
baseColorMap.base,
|
||||
baseColorMap.baseR3,
|
||||
baseColorMap.baseL1,
|
||||
baseColorMap.baseR1,
|
||||
baseColorMap.baseR2,
|
||||
baseColorMap.baseL2
|
||||
];
|
||||
for (const item of series) {
|
||||
for (const point of item.timeline) {
|
||||
dateSet.add(point.date);
|
||||
}
|
||||
}
|
||||
|
||||
const chartSeries = series.map((item, index) => ({
|
||||
name: item.label,
|
||||
data: item.timeline.map((t) => ({ time: t.date, value: t.value })),
|
||||
color: colors[index % colors.length]
|
||||
}));
|
||||
// sort dates in ascending order
|
||||
const xAxis = Array.from(dateSet).sort(
|
||||
(a, b) => dayjs(a).valueOf() - dayjs(b).valueOf()
|
||||
);
|
||||
|
||||
const chartSeries = series.map((item, index) => {
|
||||
const timelineMap = new Map(
|
||||
item.timeline.map((point) => [
|
||||
point.date,
|
||||
{ time: point.date, value: point.value }
|
||||
])
|
||||
);
|
||||
|
||||
return {
|
||||
name: item.label,
|
||||
data: xAxis.map((date) => timelineMap.get(date) ?? null),
|
||||
color: colors[index % colors.length]
|
||||
};
|
||||
});
|
||||
|
||||
// API requests use line chart, tokens use bar chart
|
||||
return {
|
||||
|
||||
@@ -84,7 +84,8 @@ const ExportData: React.FC<{
|
||||
}) => {
|
||||
fetchExportData({
|
||||
...pageParams,
|
||||
granularity: nextChartFilters.granularity,
|
||||
granularity: 'day',
|
||||
sort_by: '-date',
|
||||
group_by: ['date', 'user', 'model', 'api_key'],
|
||||
filters: nextFilters,
|
||||
scope: initialScope,
|
||||
@@ -221,9 +222,10 @@ const ExportData: React.FC<{
|
||||
...pageParams,
|
||||
page,
|
||||
perPage: pageSize,
|
||||
granularity,
|
||||
granularity: 'day',
|
||||
group_by: ['date', 'user', 'model', 'api_key'],
|
||||
filters,
|
||||
sort_by: '-date',
|
||||
scope: initialScope,
|
||||
start_date: commonFilters.start_date,
|
||||
end_date: commonFilters.end_date
|
||||
@@ -239,9 +241,10 @@ const ExportData: React.FC<{
|
||||
setPageParams(INITIAL_PAGE_PARAMS);
|
||||
fetchExportData({
|
||||
...INITIAL_PAGE_PARAMS,
|
||||
granularity,
|
||||
granularity: 'day',
|
||||
group_by: ['date', 'user', 'model', 'api_key'],
|
||||
filters,
|
||||
sort_by: '-date',
|
||||
scope: initialScope,
|
||||
start_date: commonFilters.start_date,
|
||||
end_date: commonFilters.end_date
|
||||
@@ -263,7 +266,7 @@ const ExportData: React.FC<{
|
||||
closable: false
|
||||
}}
|
||||
keyboard={false}
|
||||
width={1200}
|
||||
width={1280}
|
||||
style={{
|
||||
top: '10%'
|
||||
}}
|
||||
|
||||
@@ -7,7 +7,7 @@ import ProviderLogo from '@/pages/maas-provider/components/provider-logo';
|
||||
import { useModel } from '@@/plugin-model';
|
||||
import { DownloadOutlined, SyncOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, DatePicker, Dropdown, MenuProps, Segmented } from 'antd';
|
||||
import { Button, DatePicker, Dropdown, MenuProps } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import React from 'react';
|
||||
import { GroupOption } from '../config';
|
||||
@@ -120,8 +120,6 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
||||
}
|
||||
]
|
||||
});
|
||||
// const [activeModels, setActiveModels] = React.useState<valueType[][]>([]);
|
||||
// const [activeApiKeys, setActiveApiKeys] = React.useState<valueType[][]>([]);
|
||||
|
||||
const initialInfo = useModel('@@initialState');
|
||||
const { initialState } = initialInfo || {};
|
||||
@@ -149,8 +147,15 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
||||
}
|
||||
];
|
||||
|
||||
const renderTag = (tag: string) => {
|
||||
return (
|
||||
<span className="text-tertiary" style={{ fontSize: 12, marginRight: 4 }}>
|
||||
[{tag}]
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const handleOnModelsChange = (value: valueType[][], selectedOptions: any) => {
|
||||
// setActiveModels(value);
|
||||
const selectedValues: string[] = value.map((item) => {
|
||||
if (Array.isArray(item)) {
|
||||
return item[item.length - 1] as string; // Get the last value in the array
|
||||
@@ -165,7 +170,6 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
||||
value: valueType[][],
|
||||
selectedOptions: any
|
||||
) => {
|
||||
// setActiveApiKeys(value);
|
||||
const selectedValues: string[] = value.map((item) => {
|
||||
if (Array.isArray(item)) {
|
||||
return item[item.length - 1] as string; // Get the last value in the array
|
||||
@@ -194,10 +198,14 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
||||
|
||||
const optionRender = (option: any) => {
|
||||
const { data } = option;
|
||||
console.log('optionRender', option);
|
||||
|
||||
if (!data.isParent) {
|
||||
return <AutoTooltip ghost>{data.label}</AutoTooltip>;
|
||||
return (
|
||||
<span className="flex-center gap-4">
|
||||
<AutoTooltip ghost>{data.label}</AutoTooltip>
|
||||
{data.deleted &&
|
||||
renderTag(intl.formatMessage({ id: 'usage.table.deleted' }))}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (data.type === 'deployments') {
|
||||
@@ -221,6 +229,36 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
const apiKeyOptionRender = (option: any) => {
|
||||
const { data } = option;
|
||||
if (!data.isParent) {
|
||||
return (
|
||||
<span className="flex-center gap-4">
|
||||
<AutoTooltip ghost>{data.label}</AutoTooltip>
|
||||
{data.deleted &&
|
||||
renderTag(intl.formatMessage({ id: 'usage.table.deleted' }))}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<AutoTooltip ghost>
|
||||
<span>{data.label}</span>
|
||||
</AutoTooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const singleOptionRender = (option: any) => {
|
||||
const { data } = option;
|
||||
return (
|
||||
<span className="flex-center gap-4">
|
||||
<AutoTooltip ghost>{data.label}</AutoTooltip>
|
||||
{data.deleted &&
|
||||
renderTag(intl.formatMessage({ id: 'usage.table.deleted' }))}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const onPickerChange = (picker: DateType) => {
|
||||
handleOnPickerChange(picker);
|
||||
handlePickerChange(picker);
|
||||
@@ -231,57 +269,15 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
||||
? normalizeRangeValue(startDate, endDate, picker)
|
||||
: [dayjs().add(-DefaultDateConfig.defaultRange, 'd'), dayjs()];
|
||||
|
||||
const renderFooter = () => {
|
||||
return (
|
||||
<Segmented
|
||||
size="middle"
|
||||
shape="round"
|
||||
value={picker}
|
||||
styles={{
|
||||
root: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
marginBlock: 8
|
||||
},
|
||||
item: {
|
||||
flex: 1
|
||||
},
|
||||
label: {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
flex: 1
|
||||
}
|
||||
}}
|
||||
onChange={onPickerChange}
|
||||
options={[
|
||||
{
|
||||
label: 'Day',
|
||||
value: 'date'
|
||||
},
|
||||
{
|
||||
label: 'Month',
|
||||
value: 'month'
|
||||
},
|
||||
{
|
||||
label: 'Week',
|
||||
value: 'week'
|
||||
}
|
||||
]}
|
||||
></Segmented>
|
||||
);
|
||||
};
|
||||
|
||||
const userOptionRender = (option: any) => {
|
||||
const { data } = option;
|
||||
return (
|
||||
<span className="flex-center gap-8">
|
||||
<span>{data.label}</span>
|
||||
{data.isCurrent && (
|
||||
<span className="text-tertiary">
|
||||
{' '}
|
||||
[{intl.formatMessage({ id: 'usage.user.currentAccount' })}]
|
||||
</span>
|
||||
)}
|
||||
<span className="flex-center gap-4">
|
||||
<AutoTooltip ghost>{data.label}</AutoTooltip>
|
||||
{data.isCurrent &&
|
||||
renderTag(intl.formatMessage({ id: 'usage.user.currentAccount' }))}
|
||||
{data.deleted &&
|
||||
renderTag(intl.formatMessage({ id: 'usage.table.deleted' }))}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
@@ -394,6 +390,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
||||
options={apiKeyOptions}
|
||||
showCheckedStrategy="SHOW_CHILD"
|
||||
value={activeApiKeys}
|
||||
optionNode={apiKeyOptionRender}
|
||||
onChange={handleOnApiKeysChange}
|
||||
getPopupContainer={(triggerNode) => triggerNode.parentNode}
|
||||
></SealCascader>
|
||||
@@ -412,6 +409,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
|
||||
wrapper: { flex: 1, maxWidth: 240, minWidth: 100 }
|
||||
}}
|
||||
value={selectedApiKeys}
|
||||
optionRender={singleOptionRender}
|
||||
onChange={onApiKeysChange}
|
||||
/>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user