diff --git a/ee/tabby-ui/app/(dashboard)/reports/components/report.tsx b/ee/tabby-ui/app/(dashboard)/reports/components/report.tsx index b3590339ea52..5d957710d28a 100644 --- a/ee/tabby-ui/app/(dashboard)/reports/components/report.tsx +++ b/ee/tabby-ui/app/(dashboard)/reports/components/report.tsx @@ -15,6 +15,7 @@ import { DailyStatsQuery, Language } from '@/lib/gql/generates/graphql' +import { toProgrammingLanguageDisplayName } from '@/lib/language-utils' import { queryDailyStats, queryDailyStatsInPastYear } from '@/lib/tabby/query' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import DatePickerWithRange from '@/components/ui/date-range-picker' @@ -282,7 +283,7 @@ export function Report() { .sort((_, b) => (b[1] === Language.Other ? -1 : 0)) .map(([key, value]) => ( - {key} + {toProgrammingLanguageDisplayName(value)} ))} diff --git a/ee/tabby-ui/app/(home)/components/completion-charts.tsx b/ee/tabby-ui/app/(home)/components/completion-charts.tsx index 30ff44badb1a..9cf47af293c0 100644 --- a/ee/tabby-ui/app/(home)/components/completion-charts.tsx +++ b/ee/tabby-ui/app/(home)/components/completion-charts.tsx @@ -22,7 +22,7 @@ export type LanguageStats = Record< { selects: number completions: number - name: string + name: Language } > diff --git a/ee/tabby-ui/app/(home)/components/stats.tsx b/ee/tabby-ui/app/(home)/components/stats.tsx index 377bfd891b8c..bb5fba4efaac 100644 --- a/ee/tabby-ui/app/(home)/components/stats.tsx +++ b/ee/tabby-ui/app/(home)/components/stats.tsx @@ -28,6 +28,7 @@ import { Language } from '@/lib/gql/generates/graphql' import { useMe } from '@/lib/hooks/use-me' +import { toProgrammingLanguageDisplayName } from '@/lib/language-utils' import { QueryVariables } from '@/lib/tabby/gql' import { queryDailyStats, queryDailyStatsInPastYear } from '@/lib/tabby/query' import { Card, CardContent } from '@/components/ui/card' @@ -40,10 +41,9 @@ import { CompletionCharts, type LanguageStats } from './completion-charts' const DATE_RANGE = 6 type LanguageData = { - name: string + name: Language | 'NONE' selects: number completions: number - label: string }[] // Find auto-completion stats of each language @@ -83,7 +83,7 @@ function useLanguageStats({ newLanguageStats[language] = newLanguageStats[language] || { selects: 0, completions: 0, - name: Object.keys(Language)[lanIdx] + name: Object.values(Language)[lanIdx] } newLanguageStats[language].selects += sum( data.dailyStats.map(stats => stats.selects) @@ -150,13 +150,12 @@ const LanguageLabel: React.FC< LabelProps & { languageData: LanguageData; theme?: string } > = props => { const { x, y, value, languageData, theme } = props - const myLanguageData = languageData.find(data => data.label === value) + const myLanguageData = languageData.find(data => data.name === value) if (!myLanguageData || myLanguageData.completions === 0) { return null } - const padding = 5 return ( - {value} + {toProgrammingLanguageDisplayName(value as Language)} ) } @@ -180,16 +179,16 @@ function LanguageTooltip({ payload?: { name: string payload: { - label: string + name: Language | 'NONE' completions: number selects: number } }[] }) { if (active && payload && payload.length) { - const { completions, selects, label } = payload[0].payload + const { completions, selects, name } = payload[0].payload const activities = completions + selects - if (!activities) return null + if (!activities || name === 'NONE') return null return ( @@ -197,7 +196,9 @@ function LanguageTooltip({ Completions: {completions}

-

{label}

+

+ {toProgrammingLanguageDisplayName(name)} +

) @@ -314,33 +315,31 @@ export default function Stats() { end: moment(endDate).toDate(), users: data?.me?.id }) - let languageData: LanguageData | undefined + + let languageData: LanguageData | [] if (sample) { const rng = seedrandom(data?.me.id) const rustCompletion = Math.ceil(rng() * 40) const pythonCompletion = Math.ceil(rng() * 25) languageData = [ { - name: 'rust', - label: 'Rust', + name: Language.Rust, completions: rustCompletion, selects: rustCompletion }, { - name: 'python', - label: 'Python', + name: Language.Python, completions: pythonCompletion, selects: pythonCompletion } ] } else { languageData = Object.entries(languageStats) - .map(([key, stats]) => { + .map(([_, stats]) => { return { - name: key, + name: stats.name, selects: stats.selects, - completions: stats.completions, - label: stats.name + completions: stats.completions } }) .filter(item => item.completions) @@ -351,10 +350,9 @@ export default function Stats() { // Placeholder when there is no completions languageData = [ { - name: 'none', + name: 'NONE', selects: 0, - completions: 0.01, - label: 'None' + completions: 0.01 } ] } @@ -410,7 +408,7 @@ export default function Stats() { > {languageData.map((entry, index) => { - const lanColor = colorMap[entry.label.toLocaleLowerCase()] + const lanColor = colorMap[entry.name.toLocaleLowerCase()] const color = lanColor ? lanColor : theme === 'dark' diff --git a/ee/tabby-ui/app/(home)/language-colors.json b/ee/tabby-ui/app/(home)/language-colors.json index 997f9f13c264..287f5e2a2fae 100644 --- a/ee/tabby-ui/app/(home)/language-colors.json +++ b/ee/tabby-ui/app/(home)/language-colors.json @@ -113,7 +113,7 @@ "Arduino": "#bd79d1", "FLUX": "#88ccff", "NetLogo": "#ff6375", - "C Sharp": "#178600", + "CSharp": "#178600", "CSS": "#563d7c", "Emacs Lisp": "#c065db", "Stan": "#b2011d", diff --git a/ee/tabby-ui/app/files/components/source-code-browser.tsx b/ee/tabby-ui/app/files/components/source-code-browser.tsx index c8c758c586b3..7af9757bc9d5 100644 --- a/ee/tabby-ui/app/files/components/source-code-browser.tsx +++ b/ee/tabby-ui/app/files/components/source-code-browser.tsx @@ -7,8 +7,8 @@ import { toast } from 'sonner' import { SWRResponse } from 'swr' import useSWRImmutable from 'swr/immutable' -import filename2prism from '@/lib/filename2prism' import useRouterStuff from '@/lib/hooks/use-router-stuff' +import { filename2prism } from '@/lib/language-utils' import fetcher from '@/lib/tabby/fetcher' import type { ResolveEntriesResponse, TFile } from '@/lib/types' import { cn } from '@/lib/utils' diff --git a/ee/tabby-ui/app/files/components/text-file-view.tsx b/ee/tabby-ui/app/files/components/text-file-view.tsx index 117a66729adf..114f1c230a0a 100644 --- a/ee/tabby-ui/app/files/components/text-file-view.tsx +++ b/ee/tabby-ui/app/files/components/text-file-view.tsx @@ -1,7 +1,7 @@ import React, { Suspense, useContext } from 'react' -import filename2prism from '@/lib/filename2prism' import useRouterStuff from '@/lib/hooks/use-router-stuff' +import { filename2prism } from '@/lib/language-utils' import { cn } from '@/lib/utils' import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs' import { ListSkeleton } from '@/components/skeleton' diff --git a/ee/tabby-ui/lib/filename2prism/index.ts b/ee/tabby-ui/lib/filename2prism/index.ts deleted file mode 100644 index d6396da7b1b4..000000000000 --- a/ee/tabby-ui/lib/filename2prism/index.ts +++ /dev/null @@ -1,40 +0,0 @@ -// Fork from -// https://github.com/TomerAberbach/filename2prism/ - -import path from 'path' -import { has } from 'lodash-es' - -import languages from './languages' - -const filenames: Record = {} -const extnames: Record = {} - -for (const [alias, associations] of Object.entries(languages)) { - for (const filename of associations.filenames) { - if (!has(filenames, filename)) { - filenames[filename] = [] - } - - filenames[filename].push(alias) - } - - for (const extname of associations.extnames) { - if (!has(extnames, extname)) { - extnames[extname] = [] - } - - extnames[extname].push(alias) - } -} - -const filename2prism: (filename: string) => Array = filename => { - const result: string[] = [] - return result - .concat( - filenames[path.basename(filename)], - extnames[path.extname(filename).substring(1)] - ) - .filter(Boolean) -} - -export default filename2prism diff --git a/ee/tabby-ui/lib/language-utils/index.ts b/ee/tabby-ui/lib/language-utils/index.ts new file mode 100644 index 000000000000..e16c135a47fd --- /dev/null +++ b/ee/tabby-ui/lib/language-utils/index.ts @@ -0,0 +1,55 @@ +import path from 'path' +import { has } from 'lodash-es' + +import { Language as ProgrammingLanguage } from '@/lib/gql/generates/graphql' + +import languages from './languages' + +// Fork from +// https://github.com/TomerAberbach/filename2prism/ +export const filename2prism: (filename: string) => Array = filename => { + const filenames: Record = {} + const extnames: Record = {} + + for (const [alias, associations] of Object.entries(languages)) { + for (const filename of associations.filenames) { + if (!has(filenames, filename)) { + filenames[filename] = [] + } + + filenames[filename].push(alias) + } + + for (const extname of associations.extnames) { + if (!has(extnames, extname)) { + extnames[extname] = [] + } + + extnames[extname].push(alias) + } + } + + const result: string[] = [] + return result + .concat( + filenames[path.basename(filename)], + extnames[path.extname(filename).substring(1)] + ) + .filter(Boolean) +} + +export const toProgrammingLanguageDisplayName = ( + lan: ProgrammingLanguage +): string => { + const displayName = + Object.keys(ProgrammingLanguage)[ + Object.values(ProgrammingLanguage).indexOf(lan) + ] || '' + const mapping: Record = { + csharp: 'C#', + cpp: 'C++', + javascript: 'JavaScript', + typescript: 'TypeScript' + } + return mapping[displayName.toLocaleLowerCase()] || displayName +} diff --git a/ee/tabby-ui/lib/filename2prism/languages.ts b/ee/tabby-ui/lib/language-utils/languages.ts similarity index 100% rename from ee/tabby-ui/lib/filename2prism/languages.ts rename to ee/tabby-ui/lib/language-utils/languages.ts