Skip to content

Commit

Permalink
task/WP-673: Interactive Modal Redesign (#1456)
Browse files Browse the repository at this point in the history
* interactive session modal context

* use shared state

* use shared context for interactive session modal

* update existing modal context upon interactive session ready

* new design

* change launch button wording

* linting

* remove default message for interactive session

* change resubmit to relaunch for interactive apps

* linting

* linting

* formatting
  • Loading branch information
rstijerina authored Oct 4, 2024
1 parent 453bab5 commit e409cbe
Show file tree
Hide file tree
Showing 13 changed files with 225 additions and 138 deletions.
1 change: 1 addition & 0 deletions client/modules/_hooks/src/workspace/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export * from './useGetJobs';
export * from './usePostJobs';
export * from './types';
export * from './useGetAllocations';
export * from './useInteractiveModalContext';
20 changes: 20 additions & 0 deletions client/modules/_hooks/src/workspace/useInteractiveModalContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { createContext, useContext } from 'react';

type TInteractiveModalDetails = {
show: boolean;
interactiveSessionLink?: string;
message?: string;
openedBySubmit?: boolean;
};

export type TInteractiveModalContext = [
TInteractiveModalDetails,
React.Dispatch<React.SetStateAction<TInteractiveModalDetails>>
];

export const InteractiveModalContext =
createContext<TInteractiveModalContext | null>(null);

export const useInteractiveModalContext = () => {
return useContext(InteractiveModalContext);
};
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ export const AppsSubmissionDetails: React.FC<{
htmlType="submit"
disabled={!isValid}
loading={isSubmitting}
style={{ width: 120 }}
style={{ width: 130 }}
>
Submit Job
{definition.notes.isInteractive ? 'Launch Session' : 'Submit Job'}
</PrimaryButton>
}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
TJobBody,
useGetAllocationsSuspense,
TTapisJob,
useInteractiveModalContext,
TInteractiveModalContext,
} from '@client/hooks';
import { AppsSubmissionDetails } from '../AppsSubmissionDetails/AppsSubmissionDetails';
import { AppsWizard } from '../AppsWizard/AppsWizard';
Expand Down Expand Up @@ -73,6 +75,9 @@ export const AppsSubmissionForm: React.FC = () => {
data: TTapisJob;
};

const [, setInteractiveModalDetails] =
useInteractiveModalContext() as TInteractiveModalContext;

const { definition, license, defaultSystemNeedsKeys } = app;

const defaultStorageHost = defaultStorageSystem.host;
Expand Down Expand Up @@ -368,6 +373,9 @@ export const AppsSubmissionForm: React.FC = () => {
setPushKeysSystem(submitResult.execSys);
} else if (isSuccess) {
reset(initialValues);
if (definition.notes.isInteractive) {
setInteractiveModalDetails({ show: true, openedBySubmit: true });
}
}
}, [submitResult]);

Expand Down Expand Up @@ -516,20 +524,22 @@ export const AppsSubmissionForm: React.FC = () => {

return (
<>
{submitResult && !submitResult.execSys && (
<Alert
message={
<>
Job submitted successfully. Monitor its progress in{' '}
<NavLink to={'/history'}>Job Status</NavLink>.
</>
}
type="success"
closable
showIcon
style={{ marginBottom: '1rem' }}
/>
)}
{submitResult &&
!submitResult.execSys &&
!definition.notes.isInteractive && (
<Alert
message={
<>
Job submitted successfully. Monitor its progress in{' '}
<NavLink to={'/history'}>Job Status</NavLink>.
</>
}
type="success"
closable
showIcon
style={{ marginBottom: '1rem' }}
/>
)}
{missingAllocation && (
<Alert
message={
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
.session-modal-header {
background-color: #f4f4f4;
h5 {
font-weight: normal;
}
}

.session-modal-body {
display: flex;
flex-direction: column;
margin-bottom: 25px;
min-height: 225px;
& > * {
margin: 0.4rem;
}
Expand All @@ -17,3 +12,7 @@
color: grey;
font-style: italic;
}

.icon {
margin-left: 10px;
}
Original file line number Diff line number Diff line change
@@ -1,41 +1,82 @@
import { Modal } from 'antd';
import React from 'react';
import { PrimaryButton } from '@client/common-components';
import { Modal } from 'antd';
import { PrimaryButton, Icon } from '@client/common-components';
import {
useInteractiveModalContext,
TInteractiveModalContext,
} from '@client/hooks';
import styles from './InteractiveSessionModal.module.css';

export const InteractiveSessionModal: React.FC<{
isOpen: boolean;
interactiveSessionLink: string;
message?: string;
onCancel: VoidFunction;
}> = ({ isOpen, interactiveSessionLink, message, onCancel }) => {
export const InteractiveSessionModal = () => {
const [interactiveModalDetails, setInteractiveModalDetails] =
useInteractiveModalContext() as TInteractiveModalContext;

const { interactiveSessionLink, message, openedBySubmit, show } =
interactiveModalDetails;

return (
<Modal
title={<h2>Open Session</h2>}
width="500px"
open={isOpen}
footer={
<PrimaryButton href={interactiveSessionLink} target="_blank">
Connect
</PrimaryButton>
title={
<h3>
Interactive Session is {interactiveSessionLink ? 'Ready' : 'Queueing'}
</h3>
}
width="650px"
open={show}
footer={null}
onCancel={() =>
setInteractiveModalDetails({
show: false,
})
}
onCancel={onCancel}
>
<div className={styles['session-modal-body']}>
<span>
Click the button below to connect to the interactive session.
</span>
<div style={{ alignSelf: 'center' }}>
<PrimaryButton
href={interactiveSessionLink}
target="_blank"
loading={!interactiveSessionLink}
style={{ width: 150, margin: '25px 0' }}
size="large"
>
Connect
{interactiveSessionLink && (
<Icon
className={`ds-icon-New-Tab ${styles.icon}`}
label="Connect"
/>
)}
</PrimaryButton>
</div>
{openedBySubmit && !interactiveSessionLink && (
<span>
While you wait, you can either:
<ul>
<li>Keep this modal open and wait to connect.</li>
<li>
Close this window and wait for a notification via{' '}
<strong>Job Status</strong>.
</li>
</ul>
</span>
)}
{message && <b>{message}</b>}
<span>To end the job, quit the application within the session.</span>
<span>
Files may take some time to appear in the output location after the
job has ended.
</span>
<span className={styles.url}>
For security purposes, this is the URL that the connect button will
open:
</span>
<span className={styles.url}>{interactiveSessionLink}</span>
{interactiveSessionLink && (
<>
<span>
To end the job, quit the application within the session.
</span>
<span>
Files may take some time to appear in the output location after
the job has ended.
</span>
<span className={styles.url}>
For security purposes, this is the URL that the connect button
will open:
</span>
<span className={styles.url}>{interactiveSessionLink}</span>
</>
)}
</div>
</Modal>
);
Expand Down
30 changes: 14 additions & 16 deletions client/modules/workspace/src/JobsDetailModal/JobsDetailModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ export const JobsDetailModalBody: React.FC<{
(isInteractiveJob(jobData) ? (
<JobActionButton
uuid={jobData.uuid}
title="Resubmit Job"
title="Relaunch Job"
operation="resubmitJob"
type="primary"
/>
Expand Down Expand Up @@ -296,21 +296,19 @@ export const JobsDetailModal: React.FC<{ uuid: string }> = ({ uuid }) => {
<Modal
className={`${styles.root} job-history-modal`}
title={
<>
<header>
Job Detail: {uuid}
{jobData && (
<dl className={styles['header-details']}>
<dt>Job UUID: </dt>
<dd>{jobData.uuid}</dd>
<dt>Application: </dt>
<dd>{JSON.parse(jobData.notes).label || jobData.appId}</dd>
<dt>System: </dt>
<dd>{jobData.execSystemId}</dd>
</dl>
)}
</header>
</>
<header>
Job Detail: {uuid}
{jobData && (
<dl className={styles['header-details']}>
<dt>Job UUID: </dt>
<dd>{jobData.uuid}</dd>
<dt>Application: </dt>
<dd>{JSON.parse(jobData.notes).label || jobData.appId}</dd>
<dt>System: </dt>
<dd>{jobData.execSystemId}</dd>
</dl>
)}
</header>
}
width="60%"
open={isModalOpen}
Expand Down
32 changes: 15 additions & 17 deletions client/modules/workspace/src/JobsListing/JobsListing.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo, useState, useEffect } from 'react';
import React, { useMemo, useEffect } from 'react';
import useWebSocket from 'react-use-websocket';
import { TableProps, Row, Flex, Button as AntButton } from 'antd';
import type { ButtonSize } from 'antd/es/button';
Expand All @@ -13,6 +13,8 @@ import {
TJobPostOperations,
useReadNotifications,
TGetNotificationsResponse,
useInteractiveModalContext,
TInteractiveModalContext,
} from '@client/hooks';
import {
JobsListingTable,
Expand All @@ -26,7 +28,6 @@ import {
isInteractiveJob,
isTerminalState,
} from '../utils';
import { InteractiveSessionModal } from '../InteractiveSessionModal';
import styles from './JobsListing.module.css';
import { formatDateTimeFromValue } from '../utils/timeFormat';
import { JobsReuseInputsButton } from '../JobsReuseInputsButton/JobsReuseInputsButton';
Expand Down Expand Up @@ -59,16 +60,23 @@ export const JobActionButton: React.FC<{

const InteractiveSessionButtons: React.FC<{
uuid: string;
interactiveSessionLink: string;
interactiveSessionLink?: string;
message?: string;
}> = ({ uuid, interactiveSessionLink, message }) => {
const [interactiveModalState, setInteractiveModalState] = useState(false);
const [, setInteractiveModalDetails] =
useInteractiveModalContext() as TInteractiveModalContext;

return (
<>
<SecondaryButton
size="small"
onClick={() => setInteractiveModalState(true)}
onClick={() =>
setInteractiveModalDetails({
show: true,
interactiveSessionLink,
message,
})
}
>
Open
</SecondaryButton>
Expand All @@ -78,12 +86,6 @@ const InteractiveSessionButtons: React.FC<{
title="End"
size="small"
/>
<InteractiveSessionModal
isOpen={interactiveModalState}
interactiveSessionLink={interactiveSessionLink}
message={message}
onCancel={() => setInteractiveModalState(false)}
/>
</>
);
};
Expand Down Expand Up @@ -175,7 +177,7 @@ export const JobsListing: React.FC<Omit<TableProps, 'columns'>> = ({
<JobActionButton
uuid={job.uuid}
operation="resubmitJob"
title="Resubmit"
title="Relaunch"
size="small"
/>
) : (
Expand Down Expand Up @@ -247,9 +249,5 @@ export const JobsListing: React.FC<Omit<TableProps, 'columns'>> = ({
[interactiveSessionNotifs]
);

return (
<>
<JobsListingTable columns={columns} {...tableProps} />
</>
);
return <JobsListingTable columns={columns} {...tableProps} />;
};
Loading

0 comments on commit e409cbe

Please sign in to comment.