Skip to content

Commit

Permalink
feat: use data service sessions api
Browse files Browse the repository at this point in the history
  • Loading branch information
andre-code committed Sep 9, 2024
1 parent a03efa6 commit fbc0695
Show file tree
Hide file tree
Showing 28 changed files with 915 additions and 366 deletions.
41 changes: 34 additions & 7 deletions client/src/components/Logs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ import { displaySlice } from "../features/display";
import { NotebooksHelper } from "../notebooks";
import { LOG_ERROR_KEY } from "../notebooks/Notebooks.state";
import { NotebookAnnotations } from "../notebooks/components/session.types";
import useGetSessionLogs from "../utils/customHooks/UseGetSessionLogs";
import useGetSessionLogs, {
useGetSessionLogsV2,
} from "../utils/customHooks/UseGetSessionLogs";
import useAppDispatch from "../utils/customHooks/useAppDispatch.hook";
import useAppSelector from "../utils/customHooks/useAppSelector.hook";
import {
Expand Down Expand Up @@ -317,7 +319,7 @@ function SessionLogs(props: LogBodyProps) {
* @param {object} annotations - list of cleaned annotations
*/
interface EnvironmentLogsProps {
annotations: Record<string, unknown>;
annotations?: Record<string, unknown>;
name: string;
}
const EnvironmentLogs = ({ name, annotations }: EnvironmentLogsProps) => {
Expand Down Expand Up @@ -346,6 +348,31 @@ const EnvironmentLogs = ({ name, annotations }: EnvironmentLogsProps) => {
);
};

export const EnvironmentLogsV2 = ({ name }: EnvironmentLogsProps) => {
const displayModal = useAppSelector(
({ display }) => display.modals.sessionLogs
);
const { logs, fetchLogs } = useGetSessionLogsV2(
displayModal.targetServer,
displayModal.show
);
const dispatch = useAppDispatch();
const toggleLogs = function (target: string) {
dispatch(
displaySlice.actions.toggleSessionLogsModal({ targetServer: target })
);
};

return (
<EnvironmentLogsPresent
fetchLogs={fetchLogs}
toggleLogs={toggleLogs}
logs={logs}
name={name}
/>
);
};

/**
* Simple environment logs container
*
Expand All @@ -356,7 +383,7 @@ const EnvironmentLogs = ({ name, annotations }: EnvironmentLogsProps) => {
* @param {object} annotations - list of annotations
*/
interface EnvironmentLogsPresentProps {
annotations: Record<string, unknown>;
annotations?: Record<string, unknown>;
fetchLogs: IFetchableLogs["fetchLogs"];
logs?: ILogs;
name: string;
Expand All @@ -371,11 +398,11 @@ const EnvironmentLogsPresent = ({
}: EnvironmentLogsPresentProps) => {
if (!logs?.show || logs?.show !== name || !logs) return null;

const cleanAnnotations = NotebooksHelper.cleanAnnotations(
annotations
) as NotebookAnnotations;
const cleanAnnotations =
annotations &&
(NotebooksHelper.cleanAnnotations(annotations) as NotebookAnnotations);

const modalTitle = !cleanAnnotations.renkuVersion && (
const modalTitle = cleanAnnotations && !cleanAnnotations.renkuVersion && (
<div className="fs-5 fw-normal">
<small>
{cleanAnnotations["namespace"]}/{cleanAnnotations["projectName"]} [
Expand Down
47 changes: 12 additions & 35 deletions client/src/features/dashboardV2/DashboardV2Sessions.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import { skipToken } from "@reduxjs/toolkit/query";
import cx from "classnames";
import { useMemo } from "react";
import { Link, generatePath } from "react-router-dom-v5-compat";
import { Col, ListGroup, Row } from "reactstrap";

import { Loader } from "../../components/Loader";
import { EnvironmentLogs } from "../../components/Logs";
import { RtkErrorAlert } from "../../components/errors/RtkErrorAlert";
import { NotebooksHelper } from "../../notebooks";
import { NotebookAnnotations } from "../../notebooks/components/session.types";
import { ABSOLUTE_ROUTES } from "../../routing/routes.constants";
import useAppSelector from "../../utils/customHooks/useAppSelector.hook";
import { useGetProjectsByProjectIdQuery } from "../projectsV2/api/projectV2.enhanced-api";
import { useGetSessionsQuery } from "../session/sessions.api";
import { Session } from "../session/sessions.types";
import { filterSessionsWithCleanedAnnotations } from "../session/sessions.utils";
import { useGetSessionsQuery as useGetSessionsQueryV2 } from "../../features/sessionsV2/sessionsV2.api.ts";
import ActiveSessionButton from "../sessionsV2/components/SessionButton/ActiveSessionButton";
import {
SessionStatusV2Description,
Expand All @@ -23,20 +18,10 @@ import {

// Required for logs formatting
import "../../notebooks/Notebooks.css";
import { SessionV2 } from "../sessionsV2/sessionsV2.types.ts";

export default function DashboardV2Sessions() {
const { data: sessions, error, isLoading } = useGetSessionsQuery();

const v2Sessions = useMemo(
() =>
sessions != null
? filterSessionsWithCleanedAnnotations<NotebookAnnotations>(
sessions,
({ annotations }) => annotations["renkuVersion"] === "2.0"
)
: {},
[sessions]
);
const { data: sessions, error, isLoading } = useGetSessionsQueryV2();

const noSessions = isLoading ? (
<div className={cx("d-flex", "flex-column", "mx-auto")}>
Expand All @@ -48,37 +33,32 @@ export default function DashboardV2Sessions() {
<p>Cannot show sessions.</p>
<RtkErrorAlert error={error} />
</div>
) : !sessions ||
(Object.keys(sessions).length == 0 &&
Object.keys(v2Sessions).length == 0) ? (
) : !sessions || sessions.length == 0 ? (
<div>No running sessions.</div>
) : null;

if (noSessions) return <div>{noSessions}</div>;

return (
<ListGroup flush data-cy="dashboard-session-list">
{Object.entries(v2Sessions).map(([key, session]) => (
<DashboardSession key={key} session={session} />
))}
{sessions &&
sessions?.map((session) => (
<DashboardSession key={session.name} session={session} />
))}
</ListGroup>
);
}

interface DashboardSessionProps {
session: Session;
session: SessionV2;
}
function DashboardSession({ session }: DashboardSessionProps) {
const displayModal = useAppSelector(
({ display }) => display.modals.sessionLogs
);
const { image } = session;
const annotations = NotebooksHelper.cleanAnnotations(
session.annotations
) as NotebookAnnotations;
const projectId = annotations.projectId;
const { image, project_id: projectId } = session;
const { data: project } = useGetProjectsByProjectIdQuery(
projectId ? { projectId: projectId } : skipToken
projectId ? { projectId } : skipToken
);

const projectUrl = project
Expand Down Expand Up @@ -147,10 +127,7 @@ function DashboardSession({ session }: DashboardSessionProps) {
</Row>
</Col>
</Row>
<EnvironmentLogs
name={displayModal.targetServer}
annotations={annotations}
/>
<EnvironmentLogs name={displayModal.targetServer} />
</Link>
);
}
11 changes: 6 additions & 5 deletions client/src/features/session/components/SessionHibernated.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ import AppContext from "../../../utils/context/appContext";
import useLegacySelector from "../../../utils/customHooks/useLegacySelector.hook";
import { Url } from "../../../utils/helpers/url";
import { usePatchSessionMutation } from "../sessions.api";
import { Session } from "../sessions.types";

interface SessionHibernatedProps {
session: Session;
sessionName: string;
}

export default function SessionHibernated({ session }: SessionHibernatedProps) {
export default function SessionHibernated({
sessionName,
}: SessionHibernatedProps) {
const location = useLocation<{ filePath?: string } | undefined>();
const locationFilePath = location.state?.filePath;

Expand All @@ -57,9 +58,9 @@ export default function SessionHibernated({ session }: SessionHibernatedProps) {
const [isResuming, setIsResuming] = useState(false);

const onResumeSession = useCallback(() => {
patchSession({ sessionName: session.name, state: "running" });
patchSession({ sessionName: sessionName, state: "running" });
setIsResuming(true);
}, [patchSession, session.name]);
}, [patchSession, sessionName]);

const { notifications } = useContext(AppContext);

Expand Down
2 changes: 1 addition & 1 deletion client/src/features/session/components/ShowSession.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ function ShowSessionFullscreen({ sessionName }: ShowSessionFullscreenProps) {
!isLoading && thisSession == null ? (
<SessionUnavailable />
) : thisSession?.status.state === "hibernated" ? (
<SessionHibernated session={thisSession} />
<SessionHibernated sessionName={thisSession.name} />
) : thisSession != null ? (
<>
{!isTheSessionReady && (
Expand Down
36 changes: 36 additions & 0 deletions client/src/features/session/components/StartSessionProgressBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import ProgressStepsIndicator, {
} from "../../../components/progress/ProgressSteps";
import cx from "classnames";
import { Button } from "reactstrap";
import ProgressIndicator from "../../../components/progress/Progress";
import { SessionV2 } from "../../sessionsV2/sessionsV2.types";

interface StartSessionProgressBarProps {
includeStepInTitle?: boolean;
Expand Down Expand Up @@ -59,6 +61,40 @@ export default function StartSessionProgressBar({
);
}

interface StartSessionProgressBarV2Props {
includeStepInTitle?: boolean;
session?: SessionV2;
toggleLogs: () => void;
}
export function StartSessionProgressBarV2({
includeStepInTitle,
session,
toggleLogs,
}: StartSessionProgressBarV2Props) {
const statusData = session?.status;
const title = "Starting Session";
const logButton = (
<Button className="mt-3" color="outline-primary" onClick={toggleLogs}>
Open Logs
</Button>
);

const readyNumContainers = statusData?.ready_containers || 0;
const totalNumContainers = statusData?.total_containers || 1;
return (
<div className={cx("progress-box-small", "progress-box-small--steps")}>
<ProgressIndicator
description="Starting the containers for your session"
type={ProgressType.Indeterminate}
style={ProgressStyle.Light}
title={includeStepInTitle ? `Step 2 of 2: ${title}` : title}
feedback={`${readyNumContainers} of ${totalNumContainers} containers ready`}
/>
<div className={cx("progress-box", "pt-0")}>{logButton}</div>
</div>
);
}

function getStatusData(
status: Pick<SessionStatus, "details" | "state"> | undefined
): StepsProgressBar[] {
Expand Down
41 changes: 41 additions & 0 deletions client/src/features/session/useWaitForSessionStatus.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import { useEffect, useMemo, useState } from "react";
import { useGetSessionsQuery } from "./sessions.api";
import { useGetSessionsQuery as useGetSessionsQueryV2 } from "../sessionsV2/sessionsV2.api";
import { SessionStatusState } from "./sessions.types";

const DEFAULT_POLLING_INTERVAL_MS = 5_000;
Expand Down Expand Up @@ -68,3 +69,43 @@ export default function useWaitForSessionStatus({

return { isWaiting, session };
}

export function useWaitForSessionStatusV2({
desiredStatus,
pollingInterval = DEFAULT_POLLING_INTERVAL_MS,
sessionName,
skip,
}: UseWaitForSessionStatusArgs) {
const [isWaiting, setIsWaiting] = useState(false);

const result = useGetSessionsQueryV2(undefined, {
pollingInterval,
skip: skip || !isWaiting,
});
const session = useMemo(() => {
if (result.data == null) {
return undefined;
}
return Object.values(result.data).find(({ name }) => name === sessionName);
}, [result.data, sessionName]);

useEffect(() => {
if (skip) {
setIsWaiting(false);
}
}, [skip]);

useEffect(() => {
if (skip) {
return;
}
const desiredStatuses =
typeof desiredStatus === "string" ? [desiredStatus] : desiredStatus;
const isWaiting =
(session != null && !desiredStatuses.includes(session.status.state)) ||
(session == null && !desiredStatuses.includes("stopping"));
setIsWaiting(isWaiting);
}, [desiredStatus, session, skip]);

return { isWaiting, session };
}
2 changes: 1 addition & 1 deletion client/src/features/sessionsV2/LazyShowSessionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Suspense, lazy } from "react";

import PageLoader from "../../components/PageLoader";

const ShowSessionPage = lazy(() => import("./ShowSessionPage"));
const ShowSessionPage = lazy(() => import("./SessionShowPage/ShowSessionPage"));

export default function LazyShowSessionPage() {
return (
Expand Down
Loading

0 comments on commit fbc0695

Please sign in to comment.