Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

336 fix spark badge display #337

Merged
merged 7 commits into from
Dec 10, 2024
14 changes: 13 additions & 1 deletion examples/[email protected]/demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
{
"cell_type": "code",
"isExecuted": true,
"isExecuted": false,
"lastExecutionResult": "success",
"lastExecutionTime": "2024-12-10 10:26:03",
"metadata": {},
Expand Down Expand Up @@ -43,6 +43,18 @@
"spark = create_spark(\"work/[email protected]/demo.ipynb\")\n",
"spark"
]
},
{
"cell_type": "code",
"execution_count": null,
"isExecuted": true,
"lastExecutionResult": "success",
"lastExecutionTime": "2024-12-10 12:27:14",
"metadata": {},
"outputs": [],
"source": [
"spark.stop()"
]
}
],
"metadata": {
Expand Down
52 changes: 37 additions & 15 deletions webapp/src/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import LoginForm from './components/auth/LoginForm';
import Sidebar from './components/sidebar/Sidebar';
import Notebook from './components/notebook/Notebook';
Expand All @@ -8,6 +8,7 @@ import { createTheme, ThemeProvider } from '@mui/material/styles';
import config from './config';
import NotebookModel from './models/NotebookModel';
import DirectoryModel from './models/DirectoryModel';
import SparkModel from './models/SparkModel';

const theme = createTheme({
components: {
Expand Down Expand Up @@ -59,6 +60,12 @@ const App = () => {
const [workspaceFiles, setWorkspaceFiles] = useState([]);
const [refreshKey, setRefreshKey] = useState(0);

const notebookRef = useRef(null);

useEffect(() => {
console.log('notebookRef current:', notebookRef.current);
}, [notebookRef.current]);

// Auth
useEffect(() => {
const storedUsername = localStorage.getItem('username');
Expand Down Expand Up @@ -128,22 +135,36 @@ const App = () => {
}
};

const handleExistingNotebookClick = (path) => {
const handleExistingNotebookClick = async (path) => {
if (handleUnsavedChanges()) {
NotebookModel.fetchNotebook(`${path}`).then((data) => {
if (data.message == 'Token has expired') {
console.error('Token has expired, please log in again');
logout();
} else {
console.log('Fetched notebook:', data);
setNotebook(data);
setShowHistoryServer(false);
setShowScheduler(false);
setShowNotebook(true);
try {
const [notebookData, sparkApp] = await Promise.all([
NotebookModel.fetchNotebook(`${path}`),
SparkModel.getSparkAppByNotebookPath(path)
]);

if (notebookData.message === 'Token has expired') {
console.error('Token has expired, please log in again');
logout();
return;
}

console.log('Fetched notebook:', notebookData);
setNotebook(notebookData);

console.log('Associated Spark app:', sparkApp);

// Update Spark badge if there's an active Spark app
if (sparkApp && sparkApp.spark_app_id) {
notebookRef.current?.setSparkAppId(sparkApp.spark_app_id);
}

setShowHistoryServer(false);
setShowScheduler(false);
setShowNotebook(true);
} catch (error) {
console.error('Failed to fetch notebook or Spark app:', error);
}
}).catch((error) => {
console.error('Failed to fetch notebook:', error);
});
}
}

Expand Down Expand Up @@ -211,6 +232,7 @@ const App = () => {
username={username}
useremail={useremail}/>
<Notebook
ref={notebookRef}
showNotebook={showNotebook}
notebook={notebook}
notebookState={notebookState}
Expand Down
39 changes: 32 additions & 7 deletions webapp/src/components/notebook/Notebook.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import NotebookHeader from './header/NotebookHeader';
import Code from './content/Code';
import Config from './content/Config';
Expand All @@ -13,15 +13,15 @@ import config from '../../config';
import { Box } from '@mui/material';


function Notebook({
const Notebook = forwardRef(({
showNotebook,
notebook,
notebookState,
setNotebookState,
isNotebookModified,
setIsNotebookModified,
handleDeleteNotebook }) {

handleDeleteNotebook
}, ref) => {
const jupyterBaseUrl= `${config.jupyterBaseUrl}`
const baseUrl = `${jupyterBaseUrl}/api/contents/`

Expand Down Expand Up @@ -61,7 +61,7 @@ function Notebook({
isExecuted: cell.cell_type === 'code' ? false : cell.cell_type === 'markdown' ? true : cell.isExecuted,
lastExecutionResult: cell.lastExecutionResult === null? null : cell.lastExecutionResult,
lastExecutionTime: cell.lastExecutionTime === null? null : cell.lastExecutionTime
}));
}));
setNotebookState({
...notebook,
content: {
Expand All @@ -70,12 +70,24 @@ function Notebook({
}
});
setCurrentName(notebook.name);

// Reset sparkAppId when switching notebooks, but immediately fetch the associated Spark app
setSparkAppId(null);
SparkModel.getSparkAppByNotebookPath(notebook.path)
.then(sparkApp => {
if (sparkApp && sparkApp.spark_app_id) {
setSparkAppId(sparkApp.spark_app_id);
}
})
.catch(error => {
console.error('Failed to fetch Spark app:', error);
});
}

SessionModel.getSession(notebook.path)
.then((kernelId) => {
setKernelId(kernelId);
});
setSparkAppId(null);
}, [notebook]);

const clearOutputs = () => {
Expand Down Expand Up @@ -318,6 +330,19 @@ function Notebook({
}
};

// Add useEffect to log sparkAppId changes
useEffect(() => {
console.log('sparkAppId changed:', sparkAppId);
}, [sparkAppId]);

// Expose setSparkAppId to parent through ref
useImperativeHandle(ref, () => ({
setSparkAppId: (id) => {
console.log('setSparkAppId called with:', id);
setSparkAppId(id);
}
}));

return (
<div>
{showNotebook && (
Expand Down Expand Up @@ -382,6 +407,6 @@ function Notebook({
)}
</div>
);
}
});

export default Notebook;
22 changes: 22 additions & 0 deletions webapp/src/models/SparkModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,28 @@ spark`;
throw error;
}
}

static async getSparkAppByNotebookPath(notebookPath) {
const token = sessionStorage.getItem('token');
try {
const response = await fetch(`${config.serverBaseUrl}/notebook/spark_app/${notebookPath}`, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});

if (!response.ok) {
return null;
}

const sparkApps = await response.json();
return sparkApps.length > 0 ? sparkApps[0] : null;
} catch (error) {
console.error('Failed to fetch Spark app:', error);
return null;
}
}
}

export default SparkModel;
Expand Down
Loading