File size: 3,067 Bytes
b034029
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Card } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { Select } from '@/components/ui/Select';
import styles from '@/pages/UsagePage.module.scss';

const formatDisplayName = (value: string, allTrafficLabel: string): string => {
  const normalized = value.trim();
  if (!normalized) return '-';
  if (normalized === 'all') return allTrafficLabel;
  return normalized;
};

export interface ChartLineSelectorProps {
  chartLines: string[];
  modelNames: string[];
  maxLines?: number;
  onChange: (lines: string[]) => void;
}

export function ChartLineSelector({
  chartLines,
  modelNames,
  maxLines = 9,
  onChange
}: ChartLineSelectorProps) {
  const { t } = useTranslation();

  const handleAdd = () => {
    if (chartLines.length >= maxLines) return;
    const unusedModel = modelNames.find((m) => !chartLines.includes(m));
    if (unusedModel) {
      onChange([...chartLines, unusedModel]);
    } else {
      onChange([...chartLines, 'all']);
    }
  };

  const handleRemove = (index: number) => {
    if (chartLines.length <= 1) return;
    const newLines = [...chartLines];
    newLines.splice(index, 1);
    onChange(newLines);
  };

  const handleChange = (index: number, value: string) => {
    const newLines = [...chartLines];
    newLines[index] = value;
    onChange(newLines);
  };

  const allTrafficLabel = t('usage_stats.chart_line_all_traffic');
  const options = useMemo(
    () => [
      { value: 'all', label: allTrafficLabel },
      ...modelNames.map((name) => ({ value: name, label: formatDisplayName(name, allTrafficLabel) }))
    ],
    [allTrafficLabel, modelNames]
  );

  return (
    <Card
      title={t('usage_stats.chart_line_title')}
      extra={
        <div className={styles.chartLineHeader}>
          <span className={styles.chartLineCount}>
            {chartLines.length}/{maxLines}
          </span>
          <Button
            variant="secondary"
            size="sm"
            onClick={handleAdd}
            disabled={chartLines.length >= maxLines}
          >
            {t('usage_stats.chart_line_add')}
          </Button>
        </div>
      }
    >
      <div className={styles.chartLineList}>
        {chartLines.map((line, index) => (
          <div key={index} className={styles.chartLineItem}>
            <span className={styles.chartLineLabel}>
              {t('usage_stats.chart_line_label', { index: index + 1 })}
            </span>
            <Select
              value={line}
              options={options}
              onChange={(value) => handleChange(index, value)}
            />
            {chartLines.length > 1 && (
              <Button variant="danger" size="sm" onClick={() => handleRemove(index)}>
                {t('usage_stats.chart_line_delete')}
              </Button>
            )}
          </div>
        ))}
      </div>
      <p className={styles.chartLineHint}>
        {t('usage_stats.chart_line_hint')}
      </p>
    </Card>
  );
}