Skip to content

Commit

Permalink
Implement new App Launcher Not Running Page/Functionality (#384)
Browse files Browse the repository at this point in the history
* Updates to generalize base templates. Add not running template. Add new not running page to app.

* Update to redirect and display modal when not started.

* Fix modal title. Fix modal styling.

* Refactor urls into utils.

* Update to display not running dialog when apps ready and card clicked.

* Update to track app to start in session storage.

* Add todo.

* Add and update unit tests.

* Add progress indicator to not running page.

* Remove unneeded server status alert.

* Fix context menu showing server not showing when click away.
  • Loading branch information
jbouder authored Jul 16, 2024
1 parent a6c8951 commit 563b8df
Show file tree
Hide file tree
Showing 26 changed files with 805 additions and 73 deletions.
2 changes: 1 addition & 1 deletion jhub_apps/service/japps_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ async def handle_apps(request: Request):
if not theme:
theme = themes.DEFAULT_THEME
return templates.TemplateResponse(
"japps_home.html",
"japps_custom.html",
{
"request": request,
"version_hash": now.strftime("%Y%m%d%H%M%S"),
Expand Down
10 changes: 8 additions & 2 deletions jhub_apps/service/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
get_conda_envs,
get_jupyterhub_config,
get_spawner_profiles,
get_thumbnail_data_url, get_shared_servers,
get_thumbnail_data_url,
get_shared_servers,
)
from jhub_apps.spawner.types import FRAMEWORKS
from jhub_apps.version import get_version
Expand Down Expand Up @@ -101,7 +102,12 @@ async def get_server(user: User = Depends(get_current_user), server_name=None):
hub_client = HubClient(username=user.name)
hub_user = hub_client.get_user()
user_servers = hub_user["servers"]
if server_name:

# If server_name is 'lab' then it is the default user
if server_name == "lab" or server_name == "vscode":
server_name = ""

if server_name is not None:
# Get a particular server
for s_name, server_details in user_servers.items():
if s_name == server_name:
Expand Down
2 changes: 1 addition & 1 deletion jhub_apps/static/css/index.css

Large diffs are not rendered by default.

62 changes: 31 additions & 31 deletions jhub_apps/static/js/index.js

Large diffs are not rendered by default.

18 changes: 1 addition & 17 deletions jhub_apps/templates/home.html
Original file line number Diff line number Diff line change
@@ -1,17 +1 @@
{% extends "page.html" %} {% block main %}

<div id="root"></div>
<script src="/services/japps/static/js/index.js?v={{version_hash}}"></script>
<link
rel="stylesheet"
href="/services/japps/static/css/index.css?v={{version_hash}}"
/>
<script type="text/javascript">
window.theme = {
logo: "{{ logo }}",
};
// Hide the navbar since using new one
document.querySelector(".navbar")?.style.setProperty("display", "none");
</script>

{% endblock %}
{% extends "japps_page.html" %}
File renamed without changes.
17 changes: 17 additions & 0 deletions jhub_apps/templates/japps_page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{% extends "page.html" %} {% block main %}

<div id="root"></div>
<script src="/services/japps/static/js/index.js?v={{version_hash}}"></script>
<link
rel="stylesheet"
href="/services/japps/static/css/index.css?v={{version_hash}}"
/>
<script type="text/javascript">
window.theme = {
logo: "{{ logo }}",
};
// Hide the navbar since using new one
document.querySelector(".navbar")?.style.setProperty("display", "none");
</script>

{% endblock %}
1 change: 1 addition & 0 deletions jhub_apps/templates/not_running.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% extends "japps_page.html" %}
9 changes: 9 additions & 0 deletions jhub_apps/templates/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,10 @@ a:focus {
border: unset;
}

.card-dialog-body-wrapper {
padding: 0 24px 20px !important;
}

.MuiButton-containedPrimary:not(:disabled) {
color: var(--light-text-color);
background-color: var(--primary-color) !important;
Expand Down Expand Up @@ -520,6 +524,11 @@ a:focus {
background-color: var(--primary-color) !important;
}

.MuiCircularProgress-colorPrimary {
color: var(--primary-color) !important;

}

/* Misc */
.version {
position: fixed;
Expand Down
2 changes: 2 additions & 0 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Navigation, NotificationBar } from './components';
import { CreateApp } from './pages/create-app/create-app';
import { EditApp } from './pages/edit-app/edit-app';
import { Home } from './pages/home/home';
import { NotRunning } from './pages/not-running/not-running';
import { ServerTypes } from './pages/server-types/server-types';
import { StopPending } from './pages/stop-pending/stop-pending';
import {
Expand Down Expand Up @@ -109,6 +110,7 @@ export const App = (): React.ReactElement => {
)}
<Routes>
<Route path="/home" element={<Home />} />
<Route path="/user/:id/*" element={<NotRunning />} />
<Route path="/create-app" element={<CreateApp />} />
<Route path="/edit-app" element={<EditApp />} />
<Route path="/server-types" element={<ServerTypes />} />
Expand Down
27 changes: 23 additions & 4 deletions ui/src/components/app-card/app-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
currentNotification,
currentProfiles as defaultProfiles,
isDeleteOpen,
isStartNotRunningOpen,
isStartOpen,
isStopOpen,
} from '../../store';
Expand Down Expand Up @@ -66,11 +67,10 @@ export const AppCard = ({
const [, setIsStartOpen] = useRecoilState<boolean>(isStartOpen);
const [, setIsStopOpen] = useRecoilState<boolean>(isStopOpen);
const [, setIsDeleteOpen] = useRecoilState<boolean>(isDeleteOpen);
const [, setIsStartNotRunningOpen] = useRecoilState(isStartNotRunningOpen);

useEffect(() => {
if (!serverStatus) {
setNotification('Server status id undefined.');
} else {
if (serverStatus) {
setAppStatus(serverStatus);
}
}, [serverStatus, setNotification]);
Expand Down Expand Up @@ -182,7 +182,26 @@ export const AppCard = ({
id={`card-${id}`}
tabIndex={0}
>
<Link href={url}>
<Link
href={url}
onClick={(e) => {
if (app && serverStatus === 'Ready') {
e.preventDefault();
setCurrentApp({
id,
name: title,
framework: app?.framework || '',
url: app?.url || '',
ready: app?.ready || false,
public: app?.public || false,
shared: false,
last_activity: new Date(app?.last_activity || ''),
status: 'Ready',
});
setIsStartNotRunningOpen(true);
}
}}
>
<Card id={`card-${id}`} tabIndex={0} className="Mui-card">
<div
className={`card-content-header ${isAppCard ? '' : 'card-content-header-service'}`}
Expand Down
6 changes: 4 additions & 2 deletions ui/src/components/context-menu/context-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ export const ContextMenu = ({
event.stopPropagation();
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
const handleClose = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(null);
event.stopPropagation();
};

return (
Expand Down Expand Up @@ -125,9 +126,10 @@ export const ContextMenu = ({
}}
onClick={(e) => {
if (!item.disabled && item.onClick) {
e.stopPropagation();
item.onClick(e);
}
handleClose();
handleClose(e);
}}
disabled={item.disabled}
>
Expand Down
2 changes: 2 additions & 0 deletions ui/src/data/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export const app: AppQueryGetProps = {
last_activity: '',
pending: null,
ready: true,
started: '',
stopped: false,
url: 'http://',
user_options: {
Expand Down Expand Up @@ -92,6 +93,7 @@ export const serverApps = {
{
name: '',
url: '/user/test',
started: '2021-01-01T00:00:00',
ready: true,
user_options: {
profile: 'small1',
Expand Down
4 changes: 1 addition & 3 deletions ui/src/pages/home/apps-section/app-table/app-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ export const AppTable = ({ apps }: AppTableProps): React.ReactElement => {
const [, setIsDeleteOpen] = useRecoilState<boolean>(isDeleteOpen);
const serverStatus = apps.map((app) => app.status);
useEffect(() => {
if (!serverStatus) {
setNotification('Server status id undefined.');
} else {
if (serverStatus) {
setAppStatus(serverStatus.join(', ')); // Convert the array of strings to a single string
}
}, [serverStatus, setNotification]);
Expand Down
4 changes: 1 addition & 3 deletions ui/src/pages/home/apps-section/apps-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,7 @@ export const AppsSection = (): React.ReactElement => {

useEffect(() => {
const serverStatus = apps.map((app) => app.status);
if (serverStatus.length === 0) {
setNotification('Server status id undefined.');
} else {
if (serverStatus) {
setAppStatus(serverStatus.join(', ')); // Convert the array of strings to a single string
}
}, [apps, setNotification, setAppStatus]);
Expand Down
2 changes: 1 addition & 1 deletion ui/src/pages/home/home.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.card-dialog-body-wrapper {
padding: 0px 24px;
padding: 0px 24px 8px 24px;
}

.card-dialog-body {
Expand Down
Loading

0 comments on commit 563b8df

Please sign in to comment.