kpfadnis's picture
chore (maintainance): Update depdencies, copyright and minimal support for chat template.
e23b66d
raw
history blame
4.91 kB
/**
*
* Copyright 2023-2025 InspectorRAGet Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
'use client';
import { useMemo } from 'react';
import {
DataTable,
TableContainer,
Table,
TableHead,
TableRow,
TableHeader,
TableBody,
TableCell,
} from '@carbon/react';
import { Metric, Annotation } from '@/src/types';
import {
extractMetricDisplayValue,
extractMetricDisplayName,
} from '@/src/utilities/metrics';
import classes from './AnnotationsTable.module.scss';
// ===================================================================================
// COMPUTE FUNCTIONS
// ===================================================================================
/**
* Helper function to compute annotations table headers and rows
* @param annotations full set of annotations
* @returns
*/
function populateTable(
annotations: {
[key: string]: { [key: string]: Annotation };
},
metrics: Metric[],
) {
// Step 0: Metric names
const metricNames = metrics.map((metric) => metric.name);
// Step 1: Identify headers
const headers: { key: string; header: string }[] = [
{
key: 'annotator',
header: 'Annotator',
},
];
metrics.forEach((metric) => {
headers.push({
key: metric.name,
header: extractMetricDisplayName(metric),
});
});
// Step 2: Build rows
// Step 2.a: Collect metrics per annotator
const MetricsPerAnnotator: {
[key: string]: { [key: string]: string | number };
} = {};
for (const [metricName, annotators] of Object.entries(annotations)) {
if (metricNames.includes(metricName)) {
for (const [annotator, entry] of Object.entries(annotators)) {
if (MetricsPerAnnotator.hasOwnProperty(annotator)) {
MetricsPerAnnotator[annotator][metricName] = entry.value;
} else {
MetricsPerAnnotator[annotator] = { [metricName]: entry.value };
}
}
}
}
// Step 2.a: Formulate rows
const rows: { [key: string]: any }[] = [];
for (const [annotator, metricNames] of Object.entries(MetricsPerAnnotator)) {
const row = { id: annotator, annotator: annotator };
for (const [metricName, value] of Object.entries(metricNames)) {
row[metricName] = extractMetricDisplayValue(
value,
metrics.find((metric) => metric.name === metricName)?.values,
);
}
rows.push(row);
}
return [headers, rows];
}
// ===================================================================================
// MAIN FUNCTION
// ===================================================================================
export default function AnnotationsTable({
annotations,
metrics,
}: {
annotations: {
[key: string]: { [key: string]: Annotation };
};
metrics: Metric[];
}) {
// Step 1: Run effects
// Step 1.a: Populate table header and rows
const [headers, rows] = useMemo(
() => populateTable(annotations, metrics),
[annotations, metrics],
);
return (
<>
{headers && rows && (
<div>
<DataTable rows={rows} headers={headers}>
{({
rows,
headers,
getTableProps,
getHeaderProps,
getRowProps,
}) => (
<TableContainer className={classes.table}>
<Table {...getTableProps()}>
<TableHead>
<TableRow>
{headers.map((header, index) => (
<TableHeader
key={'header--' + index}
{...getHeaderProps({ header })}
>
{header.header}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, index) => (
<TableRow key={'row--' + index} {...getRowProps({ row })}>
{row.cells.map((cell) => (
<TableCell key={cell.id}>{cell.value}</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
)}
</DataTable>
</div>
)}
</>
);
}