diff --git a/.github/workflows/electron-build.yml b/.github/workflows/electron-build.yml index 987a70d8..adee7f41 100644 --- a/.github/workflows/electron-build.yml +++ b/.github/workflows/electron-build.yml @@ -3,7 +3,7 @@ name: App build on: push: branches: - - "1.1rc0" + - "build" defaults: run: @@ -49,16 +49,19 @@ jobs: - name: Install Watertap locally working-directory: ../ - run: git clone https://github.com/watertap-org/watertap.git && cd watertap && git fetch --all --tags && git checkout 1.1.0 && pip install --progress-bar off . - - - name: Transfer Entry points - run: | - npm --prefix electron run move-entrypoints + run: git clone https://github.com/watertap-org/watertap.git && cd watertap && pip install --progress-bar off . + # - name: Install Prommis + # run: pip install --progress-bar off prommis + - name: Install watertap-ui Python package run: | pip install --progress-bar off . + - name: Transfer Entry points + run: | + python move_entrypoints.py -p watertap + - name: Build Backend run: npm --prefix electron run build-backend @@ -70,7 +73,7 @@ jobs: - name: Sign Windows Distribution run: | - AzureSignTool sign -kvu "${{ secrets.AZURE_KEY_VAULT_URI }}" -kvi "${{ secrets.AZURE_CLIENT_ID }}" -kvt "${{ secrets.AZURE_TENANT_ID }}" -kvs "${{ secrets.AZURE_CLIENT_SECRET }}" -kvc ${{ secrets.AZURE_CERT_NAME }} -tr http://timestamp.digicert.com -v electron/dist/WaterTAP-UI_24.10.11_win64.exe + AzureSignTool sign -kvu "${{ secrets.AZURE_KEY_VAULT_URI }}" -kvi "${{ secrets.AZURE_CLIENT_ID }}" -kvt "${{ secrets.AZURE_TENANT_ID }}" -kvs "${{ secrets.AZURE_CLIENT_SECRET }}" -kvc ${{ secrets.AZURE_CERT_NAME }} -tr http://timestamp.digicert.com -v electron/dist/WaterTAP-UI_24.11.20_win64.exe - name: Upload artifact for windows build @@ -79,4 +82,4 @@ jobs: with: name: windows-dist path: | - electron/dist/WaterTAP-UI_24.10.11_win64.exe + electron/dist/WaterTAP-UI_24.11.20_win64.exe diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 235b41c6..a6af1b2b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -50,9 +50,9 @@ jobs: run: | echo REACT_APP_THEME=watertap >> .env - - name: Install Electron JS dependencies - run: | - npm --prefix electron clean-install + # - name: Install Electron JS dependencies + # run: | + # npm --prefix electron clean-install - name: Install frontend JS dependencies run: | @@ -135,7 +135,10 @@ jobs: - name: Rename conda package cache if: runner.os == 'Windows' shell: bash - run: mv "${CONDA_PKGS_DIR}" "${CONDA_PKGS_DIR}_do_not_cache" + run: | # Try renaming hardcoded directory + if [ -d C:\\Users\\runneradmin\\conda_pkgs_dir ]; then + mv C:\\Users\\runneradmin\\conda_pkgs_dir C:\\Users\\runneradmin\\conda_pkgs_dir_do_not_cache + fi pytest: name: pytest (${{ matrix.os }}) @@ -162,6 +165,10 @@ jobs: activate-environment: watertap-ui-env miniforge-version: latest + # Set project as environment variable. This can also be set by the frontend. + - name: Set env + run: echo "project=nawi" >> $GITHUB_ENV + - name: Install watertap-ui Python package run: | pip install --progress-bar off . diff --git a/.gitignore b/.gitignore index 2dbe3892..671a9f94 100644 --- a/.gitignore +++ b/.gitignore @@ -148,4 +148,5 @@ get-idaes-extensions-dist/ cert/ extensions/ setup-extensions-dist/ -sweep_outputs/ \ No newline at end of file +sweep_outputs/ +math.nist.gov/ \ No newline at end of file diff --git a/backend/app/internal/flowsheet_manager.py b/backend/app/internal/flowsheet_manager.py index 4646bd71..fd34e483 100644 --- a/backend/app/internal/flowsheet_manager.py +++ b/backend/app/internal/flowsheet_manager.py @@ -24,7 +24,7 @@ import tinydb # JSON single-file 'database' # package-local -from app.internal.settings import AppSettings +from app.internal.settings import Deployment, AppSettings from watertap.ui.fsapi import FlowsheetInterface import idaes.logger as idaeslog @@ -73,12 +73,28 @@ def __init__(self, **kwargs): Args: **kwargs: Passed as keywords to :class:`AppSettings`. """ - self.app_settings = AppSettings(**kwargs) - self._objs, self._flowsheets = {}, {} + current_project = os.environ.get("project", None) + if current_project: + self.set_project(current_project) self.startup_time = time.time() + + + def set_project(self, project: str): + os.environ["project"] = project + self._objs, self._flowsheets = {}, {} + self.project = project + self._dpy = Deployment(project) + + # Set App Settings + self.app_settings = AppSettings( + packages = list(self._dpy.package), + log_dir = self._dpy.data_basedir / "logs", + custom_flowsheets_dir = self._dpy.data_basedir / "custom_flowsheets", + data_basedir = self._dpy.data_basedir, + ) # Add custom flowsheets path to the system path - self.custom_flowsheets_path = self.app_settings.data_basedir / "custom_flowsheets" + self.custom_flowsheets_path = self.app_settings.custom_flowsheets_dir sys.path.append(str(self.custom_flowsheets_path)) for package in self.app_settings.packages: @@ -98,6 +114,10 @@ def __init__(self, **kwargs): path = self.app_settings.data_basedir / self.HISTORY_DB_FILE self._histdb = tinydb.TinyDB(path) + ## set last run + self.set_last_run_dictionary() + + def set_last_run_dictionary(self): # check for (and set if necessary) the last_run dictionary query = tinydb.Query() last_run_dict = self._histdb.search( @@ -570,6 +590,8 @@ def add_custom_flowsheets(self): try: _log.info(f"adding imported flowsheet module: {f}") module_name = f.replace(".py", "") + if module_name in sys.modules: + sys.modules.pop(module_name) custom_module = importlib.import_module(module_name) fsi = self._get_flowsheet_interface(custom_module) self.add_flowsheet_interface(module_name, fsi, custom=True) @@ -613,7 +635,7 @@ def set_number_of_subprocesses(self, value): def get_logs_path(self): """Return logs path.""" - return self.app_settings.log_dir / "nawi-ui_backend_logs.log" + return self.app_settings.log_dir / "ui_backend_logs.log" @staticmethod def _get_flowsheet_interface(module: ModuleType) -> Optional[FlowsheetInterface]: diff --git a/backend/app/internal/settings.py b/backend/app/internal/settings.py index bc301a74..7939ef49 100644 --- a/backend/app/internal/settings.py +++ b/backend/app/internal/settings.py @@ -5,6 +5,7 @@ import os from pathlib import Path import logging +from logging import handlers as logging_handlers from typing import List, Union from pydantic import field_validator from pydantic_settings import BaseSettings @@ -17,7 +18,6 @@ _log.addHandler(h) _log.setLevel(logging.WARNING) - class Deployment: """Values related to the deployment context of the UI, e.g., NAWI WaterTAP, PROMMIS, or IDAES. @@ -32,13 +32,7 @@ class Deployment: } DEFAULT_PROJ = "nawi" - def __init__(self): - try: - project = os.environ[self.PROJECT_ENV].lower() - except KeyError: - project = self.DEFAULT_PROJ - _log.warning(f"Project name not found in environment variable '{self.PROJECT_ENV}'," - f"using default") + def __init__(self, project=DEFAULT_PROJ): _log.info(f"Deploy for project={project}") if project not in self.PROJ.keys(): valid_projects = ", ".join((str(x) for x in self.PROJ)) @@ -53,31 +47,24 @@ def __init__(self): raise _log.info(f"Deployment: project={self.project} package={self.package} data_basedir={self.data_basedir}") - -_dpy = Deployment() - - class AppSettings(BaseSettings): #: List of package names in which to look for flowsheets - packages: List[str] = list(_dpy.package) - log_dir: Union[Path, None] = None - custom_flowsheets_dir: Union[Path, None] = None - data_basedir: Path = _dpy.data_basedir + packages: List[str] + log_dir: Path + custom_flowsheets_dir: Path + data_basedir : Path - # @validator("log_dir", always=True) @field_validator("log_dir") def validate_log_dir(cls, v): - if v is None: - v = _dpy.data_basedir / "logs" _log.info(f"Creating log directory '{v}'") v.mkdir(parents=True, exist_ok=True) logging_format = "[%(levelname)s] %(asctime)s %(name)s " \ "(%(filename)s:%(lineno)s): %(message)s" - project_log_file = f"{_dpy.project}-ui_backend_logs.log" + project_log_file = f"ui_backend_logs.log" _log.info(f"Logs will be in rotating files with base name " - f"'{v/project_log_file}'") - logging_file_handler = logging.handlers.RotatingFileHandler( + f"'{v/project_log_file}'") + logging_file_handler = logging_handlers.RotatingFileHandler( v / project_log_file, backupCount=2, maxBytes=5000000, @@ -90,14 +77,16 @@ def validate_log_dir(cls, v): # @validator("custom_flowsheets_dir", always=True) @field_validator("custom_flowsheets_dir") def validate_custom_flowsheets_dir(cls, v): - if v is None: - v = _dpy.data_basedir / "custom_flowsheets" v.mkdir(parents=True, exist_ok=True) return v - class Config: - env_prefix = f"{_dpy.project.upper()}_" + # class Config: + # env_prefix = f"{_dpy.project.upper()}_" + +# def get_deployment() -> Deployment: +# return _dpy -def get_deployment() -> Deployment: - return _dpy \ No newline at end of file +# def set_deployment(project_name) -> Deployment: +# _dpy = Deployment(project_name) +# return _dpy \ No newline at end of file diff --git a/backend/app/main-hooks/hook-watertap.py b/backend/app/main-hooks/hook-watertap.py index 49ab3d48..3c4c36dd 100644 --- a/backend/app/main-hooks/hook-watertap.py +++ b/backend/app/main-hooks/hook-watertap.py @@ -17,6 +17,7 @@ # add all modules to watertap modules hidden imports +# for package in ["watertap", "pyomo", "scipy", "prommis"]: for package in ["watertap", "pyomo", "scipy"]: pkg = importlib.import_module(package) try: diff --git a/backend/app/routers/flowsheets.py b/backend/app/routers/flowsheets.py index bac9e043..d246e8eb 100644 --- a/backend/app/routers/flowsheets.py +++ b/backend/app/routers/flowsheets.py @@ -21,7 +21,6 @@ from app.internal.flowsheet_manager import FlowsheetManager, FlowsheetInfo from app.internal.parameter_sweep import run_parameter_sweep from app.internal.log_parser import parse_logs -from app.internal.settings import get_deployment from watertap.ui.fsapi import FlowsheetInterface, FlowsheetExport import idaes.logger as idaeslog @@ -524,15 +523,15 @@ async def get_logs() -> List: return parse_logs(logs_path, flowsheet_manager.startup_time) -@router.get("/project") -async def get_project_name() -> str: - """Get Project name. +# @router.get("/project") +# async def get_project_name() -> str: +# """Get Project name. - Returns: - Name of the project - """ - dpy = get_deployment() - return dpy.project +# Returns: +# Name of the project +# """ +# dpy = get_deployment() +# return dpy.project @router.post("/download_logs", response_class=FileResponse) @@ -544,3 +543,13 @@ async def download_logs() -> Path: """ logs_path = flowsheet_manager.get_logs_path() return logs_path + +@router.get("/set_project/{project_name}") +async def set_project(project_name: str) -> str: + """Set Project in settings. + + Returns: + Name of the project + """ + flowsheet_manager.set_project(project_name) + return project_name \ No newline at end of file diff --git a/backend/tests/app/internal/test_settings.py b/backend/tests/app/internal/test_settings.py index c2d8e6ad..aa0915e4 100644 --- a/backend/tests/app/internal/test_settings.py +++ b/backend/tests/app/internal/test_settings.py @@ -14,27 +14,28 @@ def test_deployment_valid_projects(): # use approved project names for p in Deployment.PROJ: - os.environ[Deployment.PROJECT_ENV] = p - d = Deployment() + d = Deployment(p) assert d.project == p def test_deployment_invalid_projects(): # try bad project names for name in "bad", "", "\U0001f600": - os.environ[Deployment.PROJECT_ENV] = name with pytest.raises(ValueError): - _ = Deployment() + _ = Deployment(name) def test_deployment_env_default(): - # unset the env entirely - del os.environ[Deployment.PROJECT_ENV] dpy = Deployment() assert dpy.project == Deployment.DEFAULT_PROJ def test_appsettings(): - settings = AppSettings() + settings = AppSettings( + packages = ["watertap"], + log_dir = "./nawi/logs", + custom_flowsheets_dir = "./nawi/custom_flowsheets", + data_basedir = "./nawi/", + ) assert settings.packages assert settings.log_dir assert settings.custom_flowsheets_dir diff --git a/electron/package-lock.json b/electron/package-lock.json index 9d3f6466..d8b12789 100644 --- a/electron/package-lock.json +++ b/electron/package-lock.json @@ -1,12 +1,12 @@ { "name": "watertap-ui", - "version": "24.10.11", + "version": "24.11.20", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "watertap-ui", - "version": "24.10.11", + "version": "24.11.20", "dependencies": { "@electron/remote": "^2.0.8", "@emotion/react": "^11.11.4", diff --git a/electron/package.json b/electron/package.json index 2284420e..eef31d3f 100644 --- a/electron/package.json +++ b/electron/package.json @@ -1,7 +1,7 @@ { "name": "watertap-ui", "author": "Michael Pesce ", - "version": "24.10.11", + "version": "24.11.20", "private": true, "main": "build/main.js", "dependencies": { @@ -71,7 +71,7 @@ "nsis": { "oneClick": false, "allowToChangeInstallationDirectory": true, - "artifactName": "WaterTAP-UI_24.10.11_win64.exe" + "artifactName": "WaterTAP-UI_24.11.20_win64.exe" }, "deb": { "depends": [ @@ -107,7 +107,7 @@ "win": { "target": "nsis", "icon": "build/nawi-logo.ico", - "artifactName": "WaterTAP-UI_24.10.11_win64.exe" + "artifactName": "WaterTAP-UI_24.11.20_win64.exe" }, "linux": { "target": "Deb", diff --git a/electron/ui/cypress/e2e/FlowsheetTesting.cy.js b/electron/ui/cypress/e2e/FlowsheetTesting.cy.js index d26df8b9..8e2be4e3 100644 --- a/electron/ui/cypress/e2e/FlowsheetTesting.cy.js +++ b/electron/ui/cypress/e2e/FlowsheetTesting.cy.js @@ -55,7 +55,8 @@ describe('WaterTAP UI Testing', () => { it('tests new flowsheet', () => { let modelFile = "https://drive.google.com/uc?export=download&id=1XdjuWNpYT9teZxaF8TuwDz0XS2XyXKeT" - let exportFile = "https://drive.google.com/uc?export=download&id=1-jWQmI4wO2OlyUi32fqobFEmPn3zm9Q9" + // let exportFile = "https://drive.google.com/uc?export=download&id=1-jWQmI4wO2OlyUi32fqobFEmPn3zm9Q9" + let exportFile = "https://drive.google.com/uc?export=download&id=1_KtDRLSQeyKoQ3rH-4kNuxpvuQVuhQCu" cy.load_flowsheets_list() cy.screenshot('loaded flowsheet list page') @@ -146,6 +147,12 @@ describe('WaterTAP UI Testing', () => { cy.load_flowsheet(flowsheet.name) cy.screenshot('loaded '+flowsheet.name) + // if model has build options, it must be manually built + if (flowsheet.buildRequired) { + cy.build_flowsheet() + cy.screenshot("built "+flowsheet.name) + } + // set solve type to sweep cy.get('#solve-sweep-select').click() cy.wait(100) @@ -226,9 +233,9 @@ describe('WaterTAP UI Testing', () => { cy.screenshot("value: re-solved-after-input-change-no-flag "+flowsheet_name) }) - it('input change flag for RO with energy recovery value change- fixed/free change', () => { + it('input change flag for RO with energy recovery value change- fixed_free change', () => { cy.load_flowsheets_list() - cy.screenshot('fixed/free: loaded flowsheet list page') + cy.screenshot('fixed_free: loaded flowsheet list page') const flowsheet_name = 'RO with energy recovery flowsheet' @@ -236,18 +243,18 @@ describe('WaterTAP UI Testing', () => { // load flowsheet cy.load_flowsheet(flowsheet.name) - cy.screenshot('fixed/free: loaded '+flowsheet.name) + cy.screenshot('fixed_free: loaded '+flowsheet.name) // solve flowsheet cy.solve_flowsheet() - cy.screenshot("fixed/free: solved "+flowsheet.name) + cy.screenshot("fixed_free: solved "+flowsheet.name) cy.findByRole('tab', {name: /output/i}).click(); // check no flag cy.get('#inputChangeFlag').should('not.exist'); - cy.screenshot('fixed/free: no-input-change-no-flag-'+flowsheet.name) + cy.screenshot('fixed_free: no-input-change-no-flag-'+flowsheet.name) cy.findByRole('tab', {name: /input/i}).click(); @@ -262,17 +269,17 @@ describe('WaterTAP UI Testing', () => { cy.findByRole('option', { name: /fixed/i }).click() cy.wait(100) - cy.screenshot('fixed/free: change-option-free '+flowsheet.name) + cy.screenshot('fixed_free: change-option-free '+flowsheet.name) // go to outputs cy.findByRole('tab', {name: /output/i}).click() - cy.screenshot('fixed/free: LOOK' + flowsheet.name); + cy.screenshot('fixed_free: LOOK' + flowsheet.name); cy.wait(500) // // check for flag cy.get('#inputChangeFlag').should('exist'); - cy.screenshot('fixed/free: output-flag-after-input-change-flag ' + flowsheet.name); + cy.screenshot('fixed_free: output-flag-after-input-change-flag ' + flowsheet.name); }) diff --git a/electron/ui/cypress/support/commands.js b/electron/ui/cypress/support/commands.js index 56b35bd6..b886b01e 100644 --- a/electron/ui/cypress/support/commands.js +++ b/electron/ui/cypress/support/commands.js @@ -10,7 +10,12 @@ require('cypress-downloadfile/lib/downloadFileCommand'); * From page: any */ Cypress.Commands.add('load_flowsheets_list', () => { + cy.intercept({ + method: 'GET', + url: 'http://localhost:8001/flowsheets/**', + }).as('loadFlowsheetsList'); cy.visit('/') + cy.wait('@loadFlowsheetsList', {timeout: 30000}); }) /** diff --git a/electron/ui/src/App.js b/electron/ui/src/App.js index fb4d376b..83bb98aa 100644 --- a/electron/ui/src/App.js +++ b/electron/ui/src/App.js @@ -4,24 +4,28 @@ import '@fontsource/roboto/300.css'; import '@fontsource/roboto/400.css'; import '@fontsource/roboto/500.css'; import '@fontsource/roboto/700.css'; -import {useNavigate} from "react-router-dom"; import SplashPage from './views/SplashPage/SplashPage'; -import {getFlowsheetsList} from "./services/flowsheetsList.service"; -import {getProjectName} from './services/projectName.service'; +import {setProject} from "./services/flowsheet.service"; import MainContent from "./components/MainContent/MainContent"; -import WaitForProject from "./components/WaitForProject/WaitForProject"; import {themes} from './theme'; import { ThemeProvider, createTheme } from '@mui/material/styles'; function App() { - let navigate = useNavigate(); - const [hasFlowsheetsList, setHasFlowsheetsList] = useState(false); - const [hasTheme, setHasTheme] = useState(true); + const [connectedToBackend, setConnectedToBackend] = useState(false); const [numberOfSubprocesses, setNumberOfSubprocesses] = useState({}) - const [theme, setTheme] = useState(themes[process.env.REACT_APP_THEME] || themes["watertap"]); const [checkAgain, setCheckAgain] = useState(1) - const WAIT_TIME = 2 + + /* + if in dev mode, first check for theme in local storage because we allow for toggling between themes in dev mode + if not found or not in dev mode, check for environment variable. + if not found, use watertap as default + */ + let theme + if (process.env.NODE_ENV === 'development') theme = themes[localStorage.getItem("theme")] || themes[process.env.REACT_APP_THEME] || themes["watertap"] + else theme = themes[process.env.REACT_APP_THEME] || themes["watertap"] + + const WAIT_TIME = 1 // use Material UI theme for styles to be consistent throughout app const mui_theme = createTheme({ @@ -31,36 +35,38 @@ function App() { }, }, }); - useEffect(() => { - if (hasTheme && checkAgain !== 0) + if (checkAgain !== 0) { - // Get list of flowsheets - getFlowsheetsList() - .then((data) => { - // console.log("got flowsheets list") - setHasFlowsheetsList(true); - setCheckAgain(0) - }).catch((e) => { - // console.log(`unable to get flowsheets, trying again in ${WAIT_TIME} seconds`) - // if its taking a long time log the error - if (checkAgain > 10) console.log(`get flowsheets failed: ${e}`) - setTimeout(() => { - setCheckAgain(checkAgain+1) - }, WAIT_TIME * 1000) - }); + setProject(theme.project.toLowerCase()) + .then((data) => { + localStorage.setItem("theme", theme.project.toLowerCase()) + setConnectedToBackend(true); + setCheckAgain(0) + }).catch((e) => { + // console.log(`unable to get flowsheets, trying again in ${WAIT_TIME} seconds`) + // if its taking a long time log the error + if (checkAgain > 10) console.log(`get flowsheets failed: ${e}`) + setTimeout(() => { + setCheckAgain(checkAgain+1) + }, WAIT_TIME * 1000) + }); } - }, [theme, checkAgain]); + }, [checkAgain]); + + const changeTheme = (new_theme) => { + localStorage.setItem("theme", new_theme) + window.location.reload() + } const subProcState = {value: numberOfSubprocesses, setValue: setNumberOfSubprocesses} return (
- - - + +
) diff --git a/electron/ui/src/components/Boilerplate/Header/Header.js b/electron/ui/src/components/Boilerplate/Header/Header.js index 6571ce05..8ff00294 100644 --- a/electron/ui/src/components/Boilerplate/Header/Header.js +++ b/electron/ui/src/components/Boilerplate/Header/Header.js @@ -4,9 +4,9 @@ import LoggingPanel from '../../LoggingPanel/LoggingPanel'; import {useNavigate} from "react-router-dom"; import {Menu, MenuItem, IconButton} from '@mui/material'; import ListIcon from '@mui/icons-material/List'; +import {themes} from '../../../theme'; -export default function Header({theme, hasTheme}) { - console.debug("header hasTheme=", hasTheme, ", theme=", theme); +export default function Header({theme, changeTheme}) { let navigate = useNavigate(); const [showLogs, setShowLogs] = React.useState(false) const [actionsList, setActionsList] = React.useState(false) @@ -26,18 +26,6 @@ export default function Header({theme, hasTheme}) { setActionsList(!actionsList) setAnchorEl(event.currentTarget); } - if (!hasTheme) { - // Can't return null, or React complains about handleXYZ hooks not being - // called in the same order. So, return 'hidden' header. - return ( - - ); - } return ( diff --git a/electron/ui/src/components/MainContent/MainContent.js b/electron/ui/src/components/MainContent/MainContent.js index 78fab3fd..9b0b9d79 100644 --- a/electron/ui/src/components/MainContent/MainContent.js +++ b/electron/ui/src/components/MainContent/MainContent.js @@ -14,13 +14,12 @@ import React from "react"; export default function MainContent(props) { console.debug("MainContent: props=", props); - if (props.hasTheme && props.hasFlowsheets) { + if (props.connectedToBackend) { const theme = props.theme; - const hasTheme = props.hasTheme; const spState = props.subProcState; return ( -
+
{ method: 'POST', mode: 'cors' }); +} + +export const setProject = (project) => { + return fetch('http://localhost:8001/flowsheets/set_project/'+project, { + method: 'GET', + mode: 'cors' + }); } \ No newline at end of file diff --git a/electron/ui/src/theme.js b/electron/ui/src/theme.js index 60d150e4..7f79be03 100644 --- a/electron/ui/src/theme.js +++ b/electron/ui/src/theme.js @@ -23,7 +23,7 @@ export const themes = { '(WaterTAP) is an open-source Python-based software package that ' + 'supports the technoeconomic assessment of full water treatment trains.', projectRelease: { - 'version': '24.10.11', 'depVersions': { + 'version': '24.11.20', 'depVersions': { 'WaterTAP': '1.1.0' } }, diff --git a/electron/ui/src/views/SplashPage/SplashPage.js b/electron/ui/src/views/SplashPage/SplashPage.js index 2111edee..fde8ed64 100644 --- a/electron/ui/src/views/SplashPage/SplashPage.js +++ b/electron/ui/src/views/SplashPage/SplashPage.js @@ -4,13 +4,12 @@ import Grid from '@mui/material/Grid'; import Box from '@mui/material/Box'; import {displayVersion} from '../../theme'; -export default function SplashPage({theme, hasTheme, hasFlowsheets}) { - console.debug("splash page theme =", theme, "hasTheme=", hasTheme, "hasFlowsheets=", hasFlowsheets); +export default function SplashPage({theme, connectedToBackend}) { // Stop and return nothing if SplashPage should not be displayed: // - without the theme, we can't display anything yet // - if we have the flowsheets, then no longer show the splash page - if (!hasTheme || hasFlowsheets || theme == null) { + if (connectedToBackend || theme == null) { return null; } diff --git a/move_entrypoints.py b/move_entrypoints.py index fa8eb389..ffb56c8f 100644 --- a/move_entrypoints.py +++ b/move_entrypoints.py @@ -1,43 +1,108 @@ import sys import os import glob +import argparse -conda_prefix = os.environ['CONDA_PREFIX'] +from pathlib import Path -print(f'conda_prefix is {conda_prefix}') +def update_entry_points(project): -try: - if sys.platform == "darwin": - print('darwin') - entrypoints_src_path = f'{conda_prefix}/lib/python*/site-packages/watertap-*info/entry_points.txt' - entrypoints_dst_path = f'{conda_prefix}/lib/python*/site-packages/setuptools-*info/entry_points.txt' - elif sys.platform == "linux": - print('linux') - entrypoints_src_path = f'{conda_prefix}/lib/python*/site-packages/watertap-*info/entry_points.txt' - entrypoints_dst_path = f'{conda_prefix}/lib/python*/site-packages/setuptools-*info/entry_points.txt' + ## temporarily use workarounds while storing flowsheet entrypoints in watertap-ui + if project == "prommis": + conda_package_name = "watertap_ui" + entry_points_project_name = "prommis" + elif project == "idaes": + conda_package_name = "watertap_ui" + entry_points_project_name = "idaes" else: - print('windows') - entrypoints_src_path = f'{conda_prefix}/lib/site-packages/watertap-*info/entry_points.txt' - entrypoints_dst_path = f'{conda_prefix}/lib/site-packages/setuptools-*info/entry_points.txt' -except Exception as e: - print(f'unable to get entry points src/dst: {e}') - -print(f'globbing from {entrypoints_src_path} to {entrypoints_dst_path}') - -entrypoints_src = glob.glob(entrypoints_src_path)[0] -entrypoints_dst = glob.glob(entrypoints_dst_path)[0] - -print(f'moving entry points from {entrypoints_src} to {entrypoints_dst}') - -# get entry points from src -with open(entrypoints_src, 'r') as f: - dst = open(entrypoints_dst, 'r') - if not 'watertap.flowsheets' in (dst.read()): - dst.close() - entry_points = f.read() - print(f'found entry points:\n{entry_points}') - dst = open(entrypoints_dst, 'a') - dst.write(f'\n{entry_points}') - dst.close() + conda_package_name = project + entry_points_project_name = project + + conda_prefix = os.environ["CONDA_PREFIX"] + + try: + if sys.platform == "darwin": + print("darwin") + entrypoints_src_path = ( + f"{conda_prefix}/lib/python*/site-packages/{conda_package_name}-*info/entry_points.txt" + ) + entrypoints_dst_path = f"{conda_prefix}/lib/python*/site-packages/setuptools-*info/entry_points.txt" + elif sys.platform == "linux": + print("linux") + entrypoints_src_path = ( + f"{conda_prefix}/lib/python*/site-packages/{conda_package_name}-*info/entry_points.txt" + ) + entrypoints_dst_path = f"{conda_prefix}/lib/python*/site-packages/setuptools-*info/entry_points.txt" + else: + # print("windows") + entrypoints_src_path = ( + f"{conda_prefix}/lib/site-packages/{conda_package_name}-*info/entry_points.txt" + ) + entrypoints_dst_path = ( + f"{conda_prefix}/lib/site-packages/setuptools-*info/entry_points.txt" + ) + except Exception as e: + print(f"unable to get entry points src/dst: {e}") + + print(f"globbing from {entrypoints_src_path} to {entrypoints_dst_path}") + + entrypoints_src = glob.glob(entrypoints_src_path)[0] + entrypoints_dst = glob.glob(entrypoints_dst_path)[0] + + entry_points = [] + start_getting_entries = False + with open(entrypoints_src, "r") as f: + for line in f: + if f"[{entry_points_project_name}.flowsheets]" in line: + start_getting_entries = True + elif start_getting_entries == True and ("]" in line or line == None or line == "\n"): + print(f"reached end of entry points, breaking") + break + elif start_getting_entries: + entry = line.replace("\n", "") + if line is not None: + entry_points.append(entry) + else: + print(f"line is none, breaking") + + ## if entry points for this project exist, remove current set of entry points + entrypoints_dst_str = "" + found_entrypoints = False + with open(entrypoints_dst, "r") as f: + for line in f: + if f"[{entry_points_project_name}.flowsheets]" in line: + found_entrypoints = True + elif found_entrypoints == True and (line == None or line == "\n"): + found_entrypoints = False + elif found_entrypoints: + entry = line.replace("\n", "") + else: + entrypoints_dst_str+=line + + ## remove any trailing new lines + while entrypoints_dst_str[-1] == "\n": + entrypoints_dst_str = entrypoints_dst_str[0:-1] + + ## add in entrypoints from the list + entrypoints_dst_str+=f"\n\n[{entry_points_project_name}.flowsheets]" + for each in entry_points: + entrypoints_dst_str+=f"\n{each}" + + ## write this string to the dst path + with open(entrypoints_dst, "w") as f: + f.write(entrypoints_dst_str) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("-p", "--project", help="Project to search for entry points. If not provided, default is WaterTAP.") + args = parser.parse_args() + project = args.project + if project is None: + project = "watertap" + elif project.lower() == "idaes": + project = "idaes" else: - print(f'file already has watertap entry points, no need to add them') \ No newline at end of file + project = project.lower() + update_entry_points(project) + \ No newline at end of file diff --git a/setup.py b/setup.py index 111c3825..822ac91d 100644 --- a/setup.py +++ b/setup.py @@ -19,5 +19,8 @@ entry_points={ "watertap.flowsheets": [ ], + "prommis.flowsheets": [ + "uky = prommis.uky.uky_flowsheet_ui", + ], } )