Skip to content

Commit b933f00

Browse files
authored
Merge pull request #33 from MichaelPesce/add-logo-dropdown
Add dropdown on logo for switching project versions
2 parents b7021cd + 7c01bb3 commit b933f00

10 files changed

Lines changed: 140 additions & 27 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# idaes-flowsheet-processor-ui
22

33
This repository is for work on the user interface (UI) for the IDAES Flowsheet Processor.
4-
The UI installer can be downloaded from our homepage at: https://prommis.github.io/
4+
The UI installer can be downloaded from our [download site](https://prommis.github.io/idaes-flowsheet-processor-ui/docs/Download/watertap).
55

6-
[Documentation website](https://prommis.github.io/idaes-flowsheet-processor-ui/)
6+
For information on using the UI, check out our [Documentation website](https://prommis.github.io/idaes-flowsheet-processor-ui/).
77

88
## Getting started (developer)
99

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ dependencies:
66
- pip
77
- nodejs=22.3.0
88
- pip:
9+
- .
910
- -r backend/requirements.txt

frontend/src/App.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ function App() {
6161

6262
const changeTheme = (new_theme) => {
6363
localStorage.setItem("theme", new_theme)
64-
window.location.reload()
64+
window.location.hash = "#/flowsheets";
65+
window.location.reload();
6566
}
6667

6768
const subProcState = {value: numberOfSubprocesses, setValue: setNumberOfSubprocesses}

frontend/src/components/Boilerplate/Header/Header.js

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import './Header.css';
2-
import React from 'react';
2+
import React, { useState } from 'react';
33
import LoggingPanel from '../../LoggingPanel/LoggingPanel';
44
import {useNavigate} from "react-router-dom";
55
import {Menu, MenuItem, IconButton} from '@mui/material';
@@ -8,23 +8,38 @@ import {themes} from '../../../theme';
88

99
export default function Header({theme, changeTheme}) {
1010
let navigate = useNavigate();
11-
const [showLogs, setShowLogs] = React.useState(false)
12-
const [actionsList, setActionsList] = React.useState(false)
13-
const [anchorEl, setAnchorEl] = React.useState(null);
11+
const [showLogs, setShowLogs] = useState(false);
12+
const [menuActionsList, setMenuActionsList] = useState(false);
13+
const [menuAnchorEl, setMenuAnchorEl] = useState(null);
14+
const [logoMenuAnchor, setLogoMenuAnchor] = useState(null);
15+
const [logoActionsList, setLogoActionsList] = useState(false);
16+
const [current_theme, setCurrentTheme] = useState(localStorage.getItem("theme"));
1417

1518
const handleNavigateHome = () => {
16-
// setActionsList(!actionsList)
1719
navigate("/flowsheets", {replace: true})
1820
}
1921

2022
const handleShowLogs = () => {
2123
setShowLogs(!showLogs)
22-
setActionsList(false)
24+
setMenuActionsList(false)
2325
}
2426

2527
const handleShowActions = (event) => {
26-
setActionsList(!actionsList)
27-
setAnchorEl(event.currentTarget);
28+
setMenuActionsList(!menuActionsList)
29+
setMenuAnchorEl(event.currentTarget);
30+
}
31+
32+
const handleShowLogoActions = (event) => {
33+
if (process.env.NODE_ENV === 'development') {
34+
setLogoActionsList(!logoActionsList)
35+
setLogoMenuAnchor(event.currentTarget);
36+
}
37+
}
38+
39+
const getLogoStyle = () => {
40+
const logoStyle = {color: theme.header.color}
41+
if (process.env.NODE_ENV === 'development') logoStyle.cursor = 'pointer';
42+
return logoStyle;
2843
}
2944

3045
return (
@@ -37,25 +52,38 @@ export default function Header({theme, changeTheme}) {
3752
}} onClick={handleNavigateHome}>
3853
<img data-testid="project-logo" src={theme.logoOnly} alt={`${theme.project} logo`}/>
3954
</div>
40-
<div id="titlebar-name" style={{color: theme.header.color}}>
55+
<div id="titlebar-name" style={getLogoStyle()} onClick={handleShowLogoActions}>
4156
{theme.projectTitle}
57+
<Menu
58+
id="actions-list"
59+
anchorEl={logoMenuAnchor}
60+
open={logoActionsList}
61+
onClose={() => setLogoActionsList(false)}
62+
>
63+
{process.env.NODE_ENV === 'development' && (
64+
Object.keys(themes).map((key, idx) => {
65+
if (key !== current_theme && key !== "watertap") return (
66+
<MenuItem key={`logo_${key}`} className="change_theme" onClick={() => changeTheme(key)}>Switch to {key.replace("nawi", "watertap")}</MenuItem>
67+
)
68+
})
69+
)}
70+
</Menu>
4271
</div>
4372
<div className="right">
4473
<IconButton className="header-actions" style={{color: theme.menuButton.color}} onClick={handleShowActions}>
4574
<ListIcon/>
4675
</IconButton>
4776
<Menu
4877
id="actions-list"
49-
anchorEl={anchorEl}
50-
open={actionsList}
51-
onClose={() => setActionsList(false)}
78+
anchorEl={menuAnchorEl}
79+
open={menuActionsList}
80+
onClose={() => setMenuActionsList(false)}
5281
>
5382
<MenuItem className="view-logs" onClick={handleShowLogs}>View Logs</MenuItem>
5483
{process.env.NODE_ENV === 'development' && (
5584
Object.keys(themes).map((key, idx) => {
56-
let current_theme = localStorage.getItem("theme")
5785
if (key !== current_theme && key !== "watertap") return (
58-
<MenuItem key={key} className="change_theme" onClick={() => changeTheme(key)}>Switch to {key.replace("nawi", "watertap")}</MenuItem>
86+
<MenuItem key={`menu_${key}`} className="change_theme" onClick={() => changeTheme(key)}>Switch to {key.replace("nawi", "watertap")}</MenuItem>
5987
)
6088
})
6189
)}

frontend/src/components/FlowsheetsListTable/FlowsheetsListTable.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ export default function FlowsheetsListTable(props) {
6868
tempRows.push(fs)
6969
}
7070
}
71-
console.log('setting table rows: ')
72-
console.log(tempRows)
71+
// console.log('setting table rows: ')
72+
// console.log(tempRows)
7373
setTableRows(tempRows)
7474
} catch (e) {
7575
setTableRows([...props.rows])
@@ -89,7 +89,7 @@ export default function FlowsheetsListTable(props) {
8989

9090
const handleFlowsheetClick = (id, built, options) => {
9191
let hasOptions = false
92-
if (Object.keys(options).length > 1) hasOptions = true
92+
if (Object.keys(options).length >= 1) hasOptions = true
9393
navigate("/flowsheet/" + id + "/config", {
9494
replace: true,
9595
state: {built: built, hasOptions: hasOptions}
@@ -212,7 +212,7 @@ export default function FlowsheetsListTable(props) {
212212
</TableHead>
213213
<TableBody>
214214
{Object.keys(CATEGORIES).map((key) => {
215-
console.log('FlowsheetListTable key=', key);
215+
// console.log('FlowsheetListTable key=', key);
216216
let result = null;
217217
if ((key === 'Custom Flowsheets' && checkForCustomFlowsheets()) ||
218218
CATEGORIES[key].length > 0) {

website/docs/HowTo/how_to_use_ui.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import HowToUseAbout from '@site/src/components/HowToContent/HowToUseAbout';
77
import HowToRunOptimization from '@site/src/components/HowToContent/HowToRunOptimization';
88
import HowToRunSensitivityAnalysis from '@site/src/components/HowToContent/HowToRunSensitivityAnalysis';
99
import HowToUploadFlowsheet from '@site/src/components/HowToContent/HowToUploadFlowsheet';
10+
import HowToSwitchVersion from '@site/src/components/HowToContent/HowToSwitchVersion';
1011
import Troubleshooting from '@site/src/components/HowToContent/Troubleshooting';
1112

1213

@@ -23,5 +24,8 @@ import Troubleshooting from '@site/src/components/HowToContent/Troubleshooting';
2324
### Upload a flowsheet{#upload-a-flowsheet}
2425
<HowToUploadFlowsheet/>
2526

27+
### Switch UI Project Version{#switch-version}
28+
<HowToSwitchVersion/>
29+
2630
### Troubleshooting{#troubleshooting}
2731
<Troubleshooting/>

website/src/components/AboutContent/AboutContent.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const styles = {
1515
width: 'calc(33.33% - 20px)',
1616
display: 'inline-block',
1717
verticalAlign: 'top',
18-
'@media (max-width: 768px)': {
18+
'@media (maxWidth: 768px)': {
1919
width: '100%',
2020
margin: 10,
2121
},
@@ -52,7 +52,7 @@ function AboutContent() {
5252
<h3>Screenshots</h3>
5353
{
5454
screenshots.map((screenshot) => (
55-
<div style={styles.screenshotContainer}>
55+
<div style={styles.screenshotContainer} key={screenshot.description}>
5656
<img src={screenshot.src} alt={screenshot.description} style={{ width: '100%', height: 'auto' }} />
5757
</div>
5858
))
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const styles = {
2+
container: {
3+
margin: '40px auto',
4+
padding: 20,
5+
backgroundColor: '#f9f9f9',
6+
border: '1px solid #ddd',
7+
borderRadius: 10,
8+
boxShadow: '0 0 10px rgba(0, 0, 0, 0.1)',
9+
width: '100%'
10+
},
11+
imageContainer: {
12+
margin: 10,
13+
width: '50%',
14+
textAlign: 'center',
15+
},
16+
image: {
17+
boxShadow: '0 0 10px rgba(0, 0, 0, 0.4)',
18+
borderRadius: 10,
19+
padding: 20,
20+
marginTop: 10
21+
}
22+
};
23+
24+
function HowToSwitchVersion() {
25+
26+
27+
return (
28+
<div style={{marginTop: '20px'}}>
29+
<p>
30+
If you would like to switch project versions (eg. from WaterTAP to PrOMMIS), click on the project name in the top left:
31+
<img
32+
style={styles.image}
33+
src={require('@site/static/img/switch-project-version.png').default}
34+
/>
35+
<i>Note: This feature is only availabe in development mode and in the generic release of the Flowsheet Processor UI.</i>
36+
</p>
37+
</div>
38+
39+
);
40+
}
41+
42+
export default HowToSwitchVersion;

website/src/components/InstallerTable/InstallerTable.js

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,39 @@ function InstallerTable({owner, repo}) {
5656
const [releases, setReleases] = useState([]);
5757
const [loading, setLoading] = useState(true);
5858
const [error, setError] = useState(false);
59+
const project = repo === "idaes-pse" ? "idaes" : repo.toLowerCase();
60+
61+
const fetchElectronBuildReleases = async () => {
62+
// if the project repository has no releases with UIs, we check the idaes-electron-build repo for releases
63+
try {
64+
const response = await fetch(`https://api.github.com/repos/prommis/idaes-electron-build/releases`);
65+
if (!response.ok) {
66+
throw new Error(`Failed to fetch releases: ${response.status}`);
67+
}
68+
const releasesData = await response.json();
69+
formatElectronBuildReleaseData(releasesData)
70+
71+
} catch (error) {
72+
setError(true);
73+
setLoading(false);
74+
}
75+
}
76+
77+
const formatElectronBuildReleaseData = (data) => {
78+
let releasesWithInstaller = []
79+
for (let release of data) {
80+
if (release.assets?.length > 0) {
81+
for (let asset of release.assets) {
82+
if (asset.name.toLowerCase().includes(project) && (asset.name.endsWith(".exe") || asset.name.endsWith(".dmg"))) {
83+
releasesWithInstaller.push(release)
84+
break
85+
}
86+
}
87+
}
88+
}
89+
setReleases(releasesWithInstaller)
90+
setLoading(false);
91+
}
5992

6093
useEffect(() => {
6194
const fetchReleases = async () => {
@@ -89,8 +122,12 @@ function InstallerTable({owner, repo}) {
89122
}
90123
}
91124
}
92-
setReleases(releasesWithInstaller)
93-
setLoading(false);
125+
if (releasesWithInstaller.length > 0) {
126+
setReleases(releasesWithInstaller)
127+
setLoading(false);
128+
} else // check idaes-electron-build repo for releases
129+
fetchElectronBuildReleases()
130+
94131
}
95132

96133
const populateTable = () => {
@@ -108,8 +145,8 @@ function InstallerTable({owner, repo}) {
108145
const version = release.tag_name;
109146
if (version.toLowerCase().includes('rc')) return null;
110147

111-
const windowsLink = release.assets.find(asset => asset.name.endsWith(".exe"));
112-
const macLink = release.assets.find(asset => asset.name.endsWith(".dmg"));
148+
const windowsLink = release.assets.find(asset => asset.name.toLowerCase().includes(project) && asset.name.endsWith(".exe"));
149+
const macLink = release.assets.find(asset => asset.name.toLowerCase().includes(project) && asset.name.endsWith(".dmg"));
113150

114151
return (
115152
<tr key={version} style={index === 0 ? { ...styles.td, ...styles.stableReleaseTd } : styles.td}>
320 KB
Loading

0 commit comments

Comments
 (0)