davidpomerenke's picture
Upload from GitHub Actions: Merge pull request #5 from datenlabor-bmz/jn-dev
abd65a6 verified
raw
history blame
15.1 kB
import { useState, useEffect } from 'react'
import { PrimeReactProvider } from 'primereact/api'
import 'primereact/resources/themes/lara-light-cyan/theme.css'
import ModelTable from './components/ModelTable'
import LanguageTable from './components/LanguageTable'
import DatasetTable from './components/DatasetTable'
import WorldMap from './components/WorldMap'
import AutoComplete from './components/AutoComplete'
import LanguagePlot from './components/LanguagePlot'
import SpeakerPlot from './components/SpeakerPlot'
import HistoryPlot from './components/HistoryPlot'
import CostPlot from './components/CostPlot'
import { Carousel } from 'primereact/carousel'
import { Dialog } from 'primereact/dialog'
import { Button } from 'primereact/button'
function App () {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const [selectedLanguages, setSelectedLanguages] = useState([])
const [dialogVisible, setDialogVisible] = useState(false)
const [aboutVisible, setAboutVisible] = useState(false)
const [contributeVisible, setContributeVisible] = useState(false)
useEffect(() => {
fetch('/api/data', {
method: 'POST',
body: JSON.stringify({ selectedLanguages })
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok')
}
return response.json()
})
.then(jsonData => {
setData(jsonData)
setLoading(false)
})
.catch(err => {
setError(err.message)
setLoading(false)
})
}, [selectedLanguages])
const [windowWidth, setWindowWidth] = useState(window.innerWidth)
const [windowHeight, setWindowHeight] = useState(window.innerHeight)
useEffect(() => {
const handleResize = () => {
setWindowWidth(window.innerWidth)
setWindowHeight(window.innerHeight)
}
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
return (
<PrimeReactProvider>
<div
style={{
minHeight: '100vh',
display: 'flex',
flexDirection: 'column',
width: '100vw'
}}
>
<div
style={{
backgroundColor: '#fff3cd',
color: '#856404',
padding: '1rem 1.5rem',
marginBottom: '1rem',
border: '1px solid #ffeeba',
borderRadius: '0.25rem',
textAlign: 'center',
lineHeight: '1.5',
position: 'relative'
}}
>
<strong>Work in Progress:</strong> This dashboard is currently under
active development. Evaluation results are not yet final. Note that the visualised results currently stem from sampling 10 instances per combination of model, task, and language. Only the top 100 languages by speaker count are included. More extensive evaluation runs will be released later this year.
</div>
<div
style={{
display: 'flex',
justifyContent: 'flex-end',
padding: '0 1.5rem',
marginBottom: '1rem'
}}
>
<a
href='https://github.com/datenlabor-bmz/ai-language-monitor'
target='_blank'
rel='noopener noreferrer'
style={{
textDecoration: 'none',
color: '#6c757d',
fontSize: '1rem',
fontWeight: '500',
padding: '0.5rem 1rem',
borderRadius: '0.375rem',
backgroundColor: '#f8f9fa',
border: '1px solid #e9ecef',
display: 'flex',
alignItems: 'center',
gap: '0.5rem',
transition: 'all 0.2s ease',
':hover': {
backgroundColor: '#e9ecef',
color: '#495057'
}
}}
>
<i className='pi pi-github' title='View on GitHub' />
GitHub
</a>
</div>
<header
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
padding: '5vh 5vw',
width: '100%',
maxWidth: '1400px',
margin: '0 auto'
}}
>
<div>
<span
role='img'
aria-label='Globe Emoji'
style={{ fontSize: '40px' }}
>
🌍
</span>
</div>
<h1
style={{
fontSize: '2.5rem',
fontWeight: '600',
margin: '1rem 0 0.5rem 0',
color: '#333',
letterSpacing: '-0.01em'
}}
>
AI Language Proficiency Monitor
</h1>
<p
style={{
fontSize: '1.1rem',
color: '#666',
margin: '0 0 2.5rem 0',
fontWeight: '400',
maxWidth: '700px',
lineHeight: '1.5'
}}
>
Comprehensive multilingual evaluation results for AI language models
</p>
<div
style={{
display: 'flex',
gap: '1rem',
marginBottom: '1.5rem',
flexWrap: 'wrap',
justifyContent: 'center'
}}
>
<Button
label='πŸ“š About this tool'
className='p-button-text'
onClick={() => setAboutVisible(true)}
style={{
color: '#666',
border: '1px solid #ddd',
padding: '0.5rem 1rem',
borderRadius: '4px',
fontSize: '0.9rem'
}}
/>
<Button
label='πŸš€ Add your model (soon)'
className='p-button-text'
onClick={() => setContributeVisible(true)}
tooltip='This feature is on our roadmap and will be available soon.'
tooltipOptions={{ position: 'bottom' }}
style={{
color: '#666',
border: '1px solid #ddd',
padding: '0.5rem 1rem',
borderRadius: '4px',
fontSize: '0.9rem'
}}
/>
</div>
{data && (
<AutoComplete
languages={data?.language_table}
onComplete={items => setSelectedLanguages(items)}
/>
)}
</header>
<main
style={{
display: 'flex',
flexDirection: 'column',
gap: '3rem',
width: '100%',
paddingBottom: '5vh',
padding: '1rem 15vw 5vh 15vw'
}}
>
{loading && (
<div style={{ width: '100%', textAlign: 'center' }}>
<i
className='pi pi-spinner pi-spin'
style={{ fontSize: '4rem' }}
/>
</div>
)}
{error && (
<div style={{ width: '100%', textAlign: 'center' }}>
<p>Error: {error}</p>
</div>
)}
{data && (
<>
<ModelTable
data={data.model_table}
selectedLanguages={selectedLanguages}
allLanguages={data.language_table || []}
/>
<LanguageTable
data={data.language_table}
selectedLanguages={selectedLanguages}
setSelectedLanguages={setSelectedLanguages}
totalModels={data.model_table?.length || 0}
/>
<DatasetTable data={data} />
<div
id='figure'
style={{
width: '100%',
position: 'relative'
}}
>
<Button
icon='pi pi-external-link'
className='p-button-text p-button-plain'
onClick={() => setDialogVisible(true)}
tooltip='Open in larger view'
style={{
position: 'absolute',
top: '10px',
right: '10px',
zIndex: 1,
color: '#666'
}}
/>
<Carousel
value={[
<WorldMap data={data.countries} />,
<LanguagePlot data={data} />,
<SpeakerPlot data={data} />,
<HistoryPlot data={data} />,
<CostPlot data={data} />
]}
numScroll={1}
numVisible={1}
itemTemplate={item => item}
circular
style={{ width: '100%', minHeight: '650px' }}
/>
</div>
</>
)}
</main>
{/* About Dialog */}
<Dialog
visible={aboutVisible}
onHide={() => setAboutVisible(false)}
style={{ width: '600px' }}
modal
header='About this tool'
>
<div>
<p>
The <i>AI Language Proficiency Monitor</i> presents comprehensive
multilingual evaluation results of AI language models.
</p>
<h4>Who is this for?</h4>
<ul>
<li>
<b>Practitioners</b> can pick the best model for a given
language.
</li>
<li>
<b>Policymakers and funders</b> can identify and prioritize
neglected languages.
</li>
<li>
<b>Model developers</b> can compete on our{' '}
<i>AI Language Proficiency</i> metric.
</li>
</ul>
<h4>⚑ Live Updates</h4>
<p>
Benchmark results automatically refresh every night and include
the most popular models from{' '}
<a
href='https://openrouter.ai'
target='_blank'
rel='noopener noreferrer'
>
OpenRouter
</a>
, plus community-submitted models.
</p>
<h4>Authors</h4>
<p>
The AI Language Proficiency Monitor is a collaboration between
BMZ's{' '}
<a
href='https://www.bmz-digital.global/en/overview-of-initiatives/the-bmz-data-lab/'
target='_blank'
rel='noopener noreferrer'
>
Data Lab
</a>
, the BMZ-Initiative{' '}
<a
href='https://www.bmz-digital.global/en/overview-of-initiatives/fair-forward/'
target='_blank'
rel='noopener noreferrer'
>
Fair Forward
</a>{' '}
(implemented by GIZ), and the{' '}
<a
href='https://www.dfki.de/en/web/research/research-departments/multilinguality-and-language-technology/ee-team'
target='_blank'
rel='noopener noreferrer'
>
E&E group
</a>{' '}
of DFKI's Multilinguality and Language Technology Lab.
</p>
<h4>πŸ”— Links</h4>
<p>
<a
href='https://github.com/datenlabor-bmz/ai-language-monitor'
target='_blank'
rel='noopener noreferrer'
style={{
color: '#666',
textDecoration: 'none',
display: 'inline-flex',
alignItems: 'center',
gap: '0.5rem'
}}
>
<i className='pi pi-github' style={{ fontSize: '1.2rem' }} />
View source code on GitHub
</a>
</p>
</div>
</Dialog>
{/* Contribute Dialog */}
<Dialog
visible={contributeVisible}
onHide={() => setContributeVisible(false)}
style={{ width: '600px' }}
modal
header='Add your model & Contribute'
>
<div>
<h4>πŸš€ Submit Your Model</h4>
<p>
Have a custom fine-tuned model you'd like to see on the
leaderboard?
</p>
<p>
<a
href='https://forms.gle/ckvY9pS7XLcHYnaV8'
target='_blank'
rel='noopener noreferrer'
style={{ color: '#28a745', fontWeight: 'bold' }}
>
β†’ Submit your model here
</a>
</p>
<h4>πŸ”§ Contribute to Development</h4>
<p>
Help us expand language coverage and add new evaluation tasks:
</p>
<p>
<a
href='https://github.com/datenlabor-bmz/ai-language-monitor/blob/main/CONTRIBUTING.md'
target='_blank'
rel='noopener noreferrer'
style={{ color: '#007bff', fontWeight: 'bold' }}
>
β†’ Contribution guidelines
</a>
</p>
</div>
</Dialog>
{/* Full-screen Dialog for Charts */}
<Dialog
visible={dialogVisible}
onHide={() => setDialogVisible(false)}
style={{ width: '90vw', height: '90vh' }}
maximizable
modal
header={null}
>
{data && (
<div style={{ width: '100%', height: '100%' }}>
<Carousel
value={[
<WorldMap
data={data.countries}
width={windowWidth * 0.7}
height={windowHeight * 0.6}
/>,
<LanguagePlot
data={data}
width={windowWidth * 0.7}
height={windowHeight * 0.6}
/>,
<SpeakerPlot
data={data}
width={windowWidth * 0.7}
height={windowHeight * 0.6}
/>,
<HistoryPlot
data={data}
width={windowWidth * 0.7}
height={windowHeight * 0.6}
/>,
<CostPlot data={data} />
]}
numScroll={1}
numVisible={1}
itemTemplate={item => item}
circular
style={{ width: '100%', height: 'calc(90vh - 120px)' }}
/>
</div>
)}
</Dialog>
</div>
</PrimeReactProvider>
)
}
export default App