Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion factsheet/frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ function App() {
}
if (!loading) {
if (resource === 'scenario-bundles' && route === 'compare') {
return <ComparisonBoardMain params={route} />
const uidString = window.location.pathname.split('/')[3] || '';
const uids = uidString.split('&'); // ✅ split into array
return <ComparisonBoardMain params={uids} />
}
// now matches both '/scenario-bundles/id/new' and '/scenario-bundles/id/<uuid>'
if (resource === 'scenario-bundles' && route === 'id' && idOrNew) {
Expand Down
149 changes: 88 additions & 61 deletions factsheet/frontend/src/components/comparisonBoardItems.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
import Typography from '@mui/material/Typography';
import Chip from '@mui/material/Chip';
Expand All @@ -7,7 +7,7 @@ import palette from '../styles/oep-theme/palette.js';
import variables from '../styles/oep-theme/variables.js';
import StudyKeywords from './scenarioBundleUtilityComponents/StudyDescriptors';
import handleOpenURL from './scenarioBundleUtilityComponents/handleOnClickTableIRI.jsx';
import HtmlTooltip from '../styles/oep-theme/components/tooltipStyles'
import HtmlTooltip from '../styles/oep-theme/components/tooltipStyles';

const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
Expand All @@ -21,7 +21,7 @@ const aspectStyle = {
padding: variables.spacing[3],
color: palette.text.primary,
fontSize: variables.fontSize.sm,
lineHeight: variables.lineHeight.sm
lineHeight: variables.lineHeight.sm,
};

const getItemStyle = (isDragging, draggableStyle, index) => ({
Expand All @@ -38,78 +38,105 @@ const getItemStyle = (isDragging, draggableStyle, index) => ({
...draggableStyle,
});

const getListStyle = isDraggingOver => ({
const getListStyle = (isDraggingOver) => ({
background: isDraggingOver ? 'white' : 'white',
display: 'flex',
overflow: 'auto',
width: '100%',
minHeight: '20rem',
});

export default function ComparisonBoardItems (props) {
export default function ComparisonBoardItems(props) {
const { elements, c_aspects } = props;
const [state, setState] = useState({ items : elements });

function onDragEnd(result) {
if (!result.destination) {
return;
}
if (result.destination.index === result.source.index) {
return;
}
const newItems = reorder(
state.items,
result.source.index,
result.destination.index
);
setState({
items: newItems,
});
}
const [state, setState] = useState({ items: elements });
const [mounted, setMounted] = useState(false);

const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
useEffect(() => {
setState({ items: elements });
}, [elements]);

useEffect(() => {
const timer = setTimeout(() => setMounted(true), 30); // allow DOM to stabilize
return () => clearTimeout(timer);
}, []);

const onDragEnd = (result) => {
if (!result.destination || result.destination.index === result.source.index) return;

const newItems = reorder(state.items, result.source.index, result.destination.index);
setState({ items: newItems });
};

if (!mounted || !state.items?.length) return null;

return (
<div style={{ overflow: 'auto', marginBottom: variables.spacing[6] }}>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable
droppableId="droppable"
direction="horizontal"
>
{(provided, snapshot) => (
<Droppable droppableId="droppable-scenarios" direction="horizontal">
{(provided, snapshot) => (
<div
ref={provided.innerRef}
style={getListStyle(snapshot.isDraggingOver)}
{...provided.droppableProps}
style={getListStyle(snapshot.isDraggingOver)}
>
{state.items.map((item, index) => (
<Draggable key={item.data.uid} draggableId={item.data.uid} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style,
index
)
}
>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent:'center', height: '4rem', marginBottom: variables.spacing[3], backgroundColor: index === 0 ? palette.background.highlight : palette.background.lighter, color: index === 0 ? palette.primary.contrastText : palette.text.primary }} >

<Typography variant="h6">
{ index === 0 ? <b>{item.acronym}</b> : item.acronym }
</Typography>
<Typography variant="caption">
{ index === 0 ? 'Base scenario' : '' }
</Typography>
</div>
{state.items.map((item, index) => {
const uid = String(item?.data?.uid);
if (!uid) return null;

<div style={{ height: '60vh',overflow: 'auto', }}>
return (
<Draggable key={uid} draggableId={uid} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style,
index
)}
>
{/* --- DRAGGABLE CONTENT HERE --- */}
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
height: '4rem',
marginBottom: variables.spacing[3],
backgroundColor:
index === 0
? palette.background.highlight
: palette.background.lighter,
color:
index === 0
? palette.primary.contrastText
: palette.text.primary,
}}
>
<Typography variant="h6">
{index === 0 ? <b>{item.acronym}</b> : item.acronym}
</Typography>
<Typography variant="caption">
{index === 0 ? 'Base scenario' : ''}
</Typography>
</div>

<div style={{ height: '60vh', overflow: 'auto' }}>
{c_aspects.includes('Study name') && (
<div style={aspectStyle}>
<Typography variant="subtitle2" gutterBottom>
<b>Study name:</b>
</Typography>
<Typography variant="body2">
{item.data.study_label}
</Typography>
</div>
)}

{c_aspects.includes("Study name") && <div style= {aspectStyle} >
{c_aspects.includes("Study name") && <div style= {aspectStyle} >
<Typography variant="subtitle2" gutterBottom component="div">
<b>Study name:</b>
</Typography>
Expand Down Expand Up @@ -277,13 +304,13 @@ export default function ComparisonBoardItems (props) {
</HtmlTooltip>
))}
</div>}

</div>

</div>
)}
</Draggable>
))}
</div>
</div>
)}
</Draggable>
);
})}
{provided.placeholder}
</div>
)}
</Droppable>
Expand Down
50 changes: 29 additions & 21 deletions factsheet/frontend/src/components/comparisonBoardMain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ const ComparisonBoardMain = (props) => {

const { params } = props;
const [scenarios, setScenarios] = useState([]);
const scenarios_uid = params.split('#');
const scenarios_uid = params;
// console.log(scenarios_uid);
const scenarios_uid_json = JSON.stringify(scenarios_uid);
// console.log(scenarios_uid_json);
const [selectedCriteria, setselectedCriteria] = useState(['Study descriptors', 'Scenario types', 'Study name']);
const [alignment, setAlignment] = React.useState('Qualitative');
const [sparqOutput, setSparqlOutput] = useState([]);
Expand Down Expand Up @@ -198,12 +200,13 @@ const ComparisonBoardMain = (props) => {
});
}, []);

const handleChangeView = (
newAlignment,
) => {
newAlignment !== null && setAlignment(newAlignment);
const handleChangeView = (event, newAlignment) => {
if (newAlignment !== null) {
setAlignment(newAlignment);
}
};


// 'http://oevkg:8080/sparql'

const Criteria = [
Expand Down Expand Up @@ -259,7 +262,7 @@ const ComparisonBoardMain = (props) => {
const categorieIDs = [];
for (let key in category_disctionary) {
if (selectedCategories.includes(category_disctionary[key])) {
categorieIDs.push('http://openenergy-platform.org/ontology/oeo/' + key);
categorieIDs.push('https://openenergyplatform.org/ontology/oeo/' + key);
}
}

Expand Down Expand Up @@ -837,7 +840,7 @@ const sendQuery = async (index) => {
const categorieIDs = [];
for (let key in category_disctionary) {
if (selectedCategories.includes(category_disctionary[key])) {
categorieIDs.push('http://openenergy-platform.org/ontology/oeo/' + key);
categorieIDs.push('https://openenergyplatform.org/ontology/oeo/' + key);
}
}

Expand Down Expand Up @@ -1171,29 +1174,34 @@ const sendQuery = async (index) => {
</Toolbar>
{/* <ComparisonControl /> */}

{alignment == "Qualitative" &&
{alignment === "Qualitative" && scenarios.length > 0 && (
<Grid item xs={12}>
<OptionBox>
<h2>Criteria</h2>
<FormGroup>
<div >
{
Criteria.map((item) => <FormControlLabel control={<Checkbox size="medium" color="primary" />} checked={selectedCriteria.includes(item)} onChange={handleCriteria} label={item} name={item} />)
}
<div>
{Criteria.map((item) => (
<FormControlLabel
key={item}
control={<Checkbox size="medium" color="primary" />}
checked={selectedCriteria.includes(item)}
onChange={handleCriteria}
label={item}
name={item}
/>
))}
</div>
</FormGroup>
{/* <MultipleSelectChip
sx={{ mt: 2, width: "100%" }}
options={['Scenario 1', 'Scenario 2', 'Scenario 3']}
label="Scenarios to be compared"
disabled={true}
/> */}
</OptionBox>
<ComparisonBoardItems elements={scenarios} c_aspects={selectedCriteria} />
<ComparisonBoardItems
key={`qualitative-${scenarios.map(s => s.data.uid).join(',')}`}
elements={scenarios}
c_aspects={selectedCriteria}
/>
</Grid>
}
{alignment == "Quantitative" &&
)}

{alignment === "Quantitative" &&
<Grid container spacing={2}>
<Grid item lg={6} sx={{ borderLeft: variables.border.light, px: 2 }}>

Expand Down
24 changes: 12 additions & 12 deletions factsheet/frontend/src/components/customTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ function EnhancedTableToolbar(props) {
onClick={handleReset}>Reset</Button>
<Tooltip title="Compare">

{numSelected > 1 ? <Link to={`scenario-bundles/compare/${[...selected].join('#')}`} onClick={() => this.forceUpdate} style={{ color: 'white' }}>
{numSelected > 1 ? <Link to={`scenario-bundles/compare/${[...selected].join('&')}`} onClick={() => this.forceUpdate} style={{ color: 'white' }}>
<Button size="small"
style={{ 'marginLeft': '5px', 'color': 'white', 'textTransform': 'none' }}
variant="contained"
Expand Down Expand Up @@ -645,14 +645,14 @@ export default function CustomTable(props) {
const emptyRows =
page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0;

const visibleRows = React.useMemo(
() =>
stableSort(rows, getComparator(order, orderBy)).slice(
page * rowsPerPage,
page * rowsPerPage + rowsPerPage,
),
[order, orderBy, page, rowsPerPage],
);
const visibleRows = React.useMemo(() => {
const finalRows = filteredFactsheets.length === 0 ? factsheets : filteredFactsheets;
return stableSort(finalRows, getComparator(order, orderBy)).slice(
page * rowsPerPage,
page * rowsPerPage + rowsPerPage,
);
}, [filteredFactsheets, factsheets, order, orderBy, page, rowsPerPage]);



const scenarioAspects = [
Expand All @@ -665,13 +665,13 @@ export default function CustomTable(props) {
];

const renderRows = (rs) => {
const rowsToRender = filteredFactsheets.length == 0 ? factsheets : filteredFactsheets;
// const rowsToRender = filteredFactsheets.length == 0 ? factsheets : filteredFactsheets;
return <TableBody >
{rowsToRender.map((row, index) => {
{rs.map((row, index) => {
const isItemSelected = isSelected(row.study_name);
const labelId = `enhanced-table-checkbox-${index}`;
return (
<React.Fragment key={row.study_name}>
<React.Fragment key={row.uid}>
<StyledTableRow
hover
role="checkbox"
Expand Down
5 changes: 3 additions & 2 deletions factsheet/frontend/src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ const container = document.getElementById('root');
const root = createRoot(container);

root.render(
<React.StrictMode>
// StrictMode currently breaks DND in qualitative comparison
// <React.StrictMode>
<CacheProvider value={cache}>
<ThemeProvider theme={theme}>
<CssBaseline />
Expand All @@ -36,5 +37,5 @@ root.render(
</LocalizationProvider>
</ThemeProvider>
</CacheProvider>
</React.StrictMode>
// </React.StrictMode>
);
Loading