Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
beefcaf
refactor: replace MUI Typography with HTML headings and improve job d…
peppermint-juli Oct 9, 2025
d30e5d1
Update components/ui/web/components/content/jobs/detail/jobFullDetail…
peppermint-juli Oct 14, 2025
c70d7fa
Merge commit '5e0579ef35bbeb73a11c4506546bc7bc2644b33b'
peppermint-juli Oct 22, 2025
50ff8e3
feat: Reuse newSession component to create new Jobs
peppermint-juli Oct 22, 2025
3e23cea
Reuse NewSession form to create
peppermint-juli Oct 28, 2025
44ebc94
feat: update getDomains query to accept jobs parameter
peppermint-juli Oct 28, 2025
15d191c
* Added Command step and steppers component to NewJob component
peppermint-juli Oct 29, 2025
dbd479c
feat: add working directory selection and default job parameters to N…
peppermint-juli Oct 30, 2025
b2c518c
Connected NewJob endpoint to component. Code Cleanup and created a ne…
peppermint-juli Nov 3, 2025
3788839
feat: add optional name field to CreateJobParams and Job types
peppermint-juli Nov 3, 2025
8d34972
refactor: replace MUI Typography with HTML headings and improve job d…
peppermint-juli Oct 9, 2025
7ceebef
Update components/ui/web/components/content/jobs/detail/jobFullDetail…
peppermint-juli Oct 14, 2025
e91fdff
Merge branch 'main' into new-job-screen
peppermint-juli Nov 3, 2025
196998b
Apply suggestions from code review
peppermint-juli Nov 3, 2025
7e57d3d
Update components/ui/web/components/content/jobs/new/commandForm.tsx
peppermint-juli Nov 3, 2025
85ada47
fix: update comparison operator for domain choice and add key prop to…
peppermint-juli Nov 3, 2025
f61b519
* Make helpdesk email link an env variable
peppermint-juli Nov 10, 2025
e9c078a
feat: add helpdesk email as an environment variable in web deployment
peppermint-juli Nov 10, 2025
9cfaecf
Merge branch 'main' into new-job-screen
peppermint-juli Nov 13, 2025
849e509
feat: refactor session management to use NewComputeSession component …
peppermint-juli Dec 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions components/ui/graphql/src/data/domains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export class DomainsAPI extends RESTDataSource {
}

// QUERIES //
async getDomains(): Promise<Domain[]> {
const res = await this.get(`${this.baseURL!}computedomains/`) || [];
async getDomains(jobs = false): Promise<Domain[]> {
const res = await this.get(`${this.baseURL!}computedomains${!jobs ? '' : '?batch=true'}`) || [];
let domains = res.map((r: any) => this.domainReducer(r));
domains = sortBy(domains, 'name');

Expand Down
3 changes: 2 additions & 1 deletion components/ui/graphql/src/generated/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ input CreateJobParams {
command: String!
dockerComputeEndpoint: String!
dockerImageName: String!
name: String
resultsFolderURI: String!
scriptURI: String!
submitterDID: String!
Expand Down Expand Up @@ -217,7 +218,7 @@ type Query {
getDataset(params: DatasetDetailInput!): Dataset
getDatasets(volumeType: VolumeType!): [Dataset!]!
getDomainByID(id: ID!): Domain
getDomains: [Domain!]!
getDomains(jobs: Boolean): [Domain!]!
getJobDetails(jobId: ID!): JobDetails!
getJobs(filters: [JobFilters!], top: Int): [Job!]!
getJsonTree(volumeName: String!): JSONTree!
Expand Down
8 changes: 7 additions & 1 deletion components/ui/graphql/src/generated/typings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export type CreateJobParams = {
command: Scalars['String'];
dockerComputeEndpoint: Scalars['String'];
dockerImageName: Scalars['String'];
name?: InputMaybe<Scalars['String']>;
resultsFolderURI: Scalars['String'];
scriptURI: Scalars['String'];
submitterDID: Scalars['String'];
Expand Down Expand Up @@ -304,6 +305,11 @@ export type QueryGetDomainByIdArgs = {
};


export type QueryGetDomainsArgs = {
jobs?: InputMaybe<Scalars['Boolean']>;
};


export type QueryGetJobDetailsArgs = {
jobId: Scalars['ID'];
};
Expand Down Expand Up @@ -725,7 +731,7 @@ export type QueryResolvers<ContextType = Context, ParentType extends ResolversPa
getDataset?: Resolver<Maybe<ResolversTypes['Dataset']>, ParentType, ContextType, RequireFields<QueryGetDatasetArgs, 'params'>>;
getDatasets?: Resolver<Array<ResolversTypes['Dataset']>, ParentType, ContextType, RequireFields<QueryGetDatasetsArgs, 'volumeType'>>;
getDomainByID?: Resolver<Maybe<ResolversTypes['Domain']>, ParentType, ContextType, RequireFields<QueryGetDomainByIdArgs, 'id'>>;
getDomains?: Resolver<Array<ResolversTypes['Domain']>, ParentType, ContextType>;
getDomains?: Resolver<Array<ResolversTypes['Domain']>, ParentType, ContextType, Partial<QueryGetDomainsArgs>>;
getJobDetails?: Resolver<ResolversTypes['JobDetails'], ParentType, ContextType, RequireFields<QueryGetJobDetailsArgs, 'jobId'>>;
getJobs?: Resolver<Array<ResolversTypes['Job']>, ParentType, ContextType, Partial<QueryGetJobsArgs>>;
getJsonTree?: Resolver<ResolversTypes['JSONTree'], ParentType, ContextType, RequireFields<QueryGetJsonTreeArgs, 'volumeName'>>;
Expand Down
4 changes: 2 additions & 2 deletions components/ui/graphql/src/resolvers/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { QueryResolvers } from '../generated/typings';

export const queryResolvers: QueryResolvers = {
// eslint-disable-next-line no-empty-pattern
getDomains: async (_, { }, { dataSources }) => {
return dataSources.domainsAPI.getDomains();
getDomains: async (_, { jobs }, { dataSources }) => {
return dataSources.domainsAPI.getDomains(jobs ?? undefined);
},
getDomainByID: async (_, { id }, { dataSources }) => {
return dataSources.domainsAPI.getDomainByID(id);
Expand Down
2 changes: 1 addition & 1 deletion components/ui/graphql/src/types/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const typeDefs = gql`
}

type Query {
getDomains: [Domain!]!
getDomains(jobs: Boolean): [Domain!]!
getDomainByID(id: ID!): Domain
}
`;
1 change: 1 addition & 0 deletions components/ui/graphql/src/types/jobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const typeDefs = gql`
dockerImageName: String!
submitterDID: String!
scriptURI: String!
name: String
}

type Query {
Expand Down
9 changes: 6 additions & 3 deletions components/ui/web/.env.development
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
NEXT_PUBLIC_FILE_SERVICE_URL=https://apps.sciserver.org/fileservice/api/
NEXT_PUBLIC_LOGIN_PORTAL_URL=https://apps.sciserver.org/login-portal/
NEXT_PUBLIC_GRAPHQL_URL=http://localhost:4000/graphql
# NEXT_PUBLIC_GRAPHQL_URL=https://apps.sciserver.org/graphql
# NEXT_PUBLIC_GRAPHQL_URL=http://localhost:4000/graphql
NEXT_PUBLIC_GRAPHQL_URL=https://apps.sciserver.org/graphql
Comment on lines +3 to +4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove the commented line and then from here on not modify these lines for typical PRs. local workflows should have a way to replace this without committing the changes (either by another file or by restoring after testing)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't usually modify it, but since I was going to make a change to this file, I decided to commit this one too. For local deployments, it's best to have this point to the apps.sciserver.org version of the GraphQL instead of the local version.

NEXT_PUBLIC_NOTEBOOKS_URL=https://apps.sciserver.org/compute/
NEXT_PUBLIC_FILES_URL=https://apps.sciserver.org/dashboard/files/uservolumes
NEXT_PUBLIC_BASE_PATH='/web'
Expand All @@ -11,4 +11,7 @@ NEXT_PUBLIC_COMPUTE_PING_INTERVAL=60000 #time in milliseconds
NEXT_PUBLIC_LANDING_ROUTE=/datasets #default landing page to redirect from login
NEXT_PUBLIC_QUICK_START_CONFIG='dom=Interactive%20Docker%20Compute%20Domain&img=Sciserver%20Essentials%20(Test)&dvs=97'
NEXT_PUBLIC_NEW_SESSION_DOMAIN_NAME_DEFAULT=Interactive Docker Compute Domain
NEXT_PUBLIC_NEW_SESSION_IMAGE_NAME_DEFAULT=Sciserver Essentials (Test)
NEXT_PUBLIC_NEW_SESSION_IMAGE_NAME_DEFAULT=SciServer Essentials 4.0
NEXT_PUBLIC_NEW_JOB_DOMAIN_NAME_DEFAULT=Small Jobs Domain
NEXT_PUBLIC_NEW_JOB_IMAGE_NAME_DEFAULT=SciServer Essentials 4.0
[email protected]

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
import { FC, useMemo, useState } from 'react';
import { useRouter } from 'next/router';
import styled from 'styled-components';
import {
Button,
CircularProgress,
IconButton,
TextField,
Typography
} from '@mui/material';
import { ArrowBackIos as ArrowBackIcon } from '@mui/icons-material';
import { useQuery, ApolloError } from '@apollo/client';
import { Chip, IconButton } from '@mui/material';
import { Close as CloseIcon } from '@mui/icons-material';
import styled from 'styled-components';

import { DomainAccordionSummary } from 'components/content/compute/newSession/domainAccordion';
import { ImageAccordionSummary } from 'components/content/compute/newSession/imageAccordion';
import { DataVolAccordionSummary } from 'components/content/compute/newSession/dataVolumeAccordion';
import { UserVolAccordionSummary } from 'components/content/compute/newSession/userVolumeAccordion';
import { DataVolume, Domain, Image, UserVolume } from 'src/graphql/typings';
import { GET_DOMAINS } from 'src/graphql/domains';
import { LoadingAnimation } from 'components/common/loadingAnimation';

import { NewComputeSession, NewComputeSessionType } from 'components/content/newComputeSession/newComputeSession';

const Styled = styled.div`
.header {
Expand All @@ -30,44 +21,14 @@ const Styled = styled.div`
color: ${({ theme }) => theme.palette.warning.dark};
}
}

.form {
display: flex;
flex-direction: column;
gap: 2rem;
margin: 2rem 0.5rem;
width: 90%;

.accordion-header {
display: flex;
align-items: center;
gap: 2rem;

.accordion-title {
display: flex;
width: 120px;
align-items: center;

.title {
text-transform: capitalize;
}
}
}

.submit-button {
margin: 2rem 0.1rem;
}
}
`;


export const NewSession: FC = ({ }) => {
export const NewSession: FC = () => {

const router = useRouter();

const [loadingSubmit, setLoadingSubmit] = useState<boolean>(false);


const { loading: loadingData, data } = useQuery(GET_DOMAINS,
{
onError: (error: ApolloError) => {
Expand All @@ -78,6 +39,7 @@ export const NewSession: FC = ({ }) => {
}
);

const [sessionName, setSessionName] = useState<string>('');
const [domainChoice, setDomainChoice] = useState<Domain>();
const [imageChoice, setImageChoice] = useState<Image>();
const [dataVolumesChoice, setDataVolumesChoice] = useState<DataVolume[]>([]);
Expand Down Expand Up @@ -133,27 +95,30 @@ export const NewSession: FC = ({ }) => {
return <Styled>
<div className="header">
<IconButton onClick={() => router.push('/compute')} >
<ArrowBackIcon />
<CloseIcon />
</IconButton>
<Typography variant="h3">New Compute Session</Typography>
<Typography className="alert" variant="h4">(BETA version)</Typography>
<h1>New Compute Session</h1>
<Chip color="warning" label="BETA" />
</div>
<div className="form">
<TextField id="standard-basic" label="Session Name" variant="standard" />
<DomainAccordionSummary domainList={domainList} domainChoice={domainChoice} setDomainChoice={setDomainChoice} />
<ImageAccordionSummary imageList={imageList} imageChoice={imageChoice} setImageChoice={setImageChoice} />
<DataVolAccordionSummary dataVolumeList={dataVolumeList} dataVolumesChoice={dataVolumesChoice} setDataVolumesChoice={setDataVolumesChoice} />
<UserVolAccordionSummary userVolumeList={userVolumeList} userVolumesChoice={userVolumesChoice} setUserVolumesChoice={setUserVolumesChoice} />
<Button className="submit-button" type="submit" onClick={submit} variant="contained">
{loadingSubmit ?
<CircularProgress color="secondary" />
:
'CREATE'
}
</Button>
</div>
{loadingData &&
<LoadingAnimation backDropIsOpen={loadingData} />
}
</Styled >;
<NewComputeSession
sessionType={NewComputeSessionType.INTERACTIVE}
resourceName={sessionName}
setResourceName={setSessionName}
domainList={domainList}
domainChoice={domainChoice}
setDomainChoice={setDomainChoice}
imageList={imageList}
imageChoice={imageChoice}
setImageChoice={setImageChoice}
dataVolumeList={dataVolumeList}
dataVolumesChoice={dataVolumesChoice}
setDataVolumesChoice={setDataVolumesChoice}
userVolumeList={userVolumeList}
userVolumesChoice={userVolumesChoice}
setUserVolumesChoice={setUserVolumesChoice}
submit={submit}
loadingSubmit={loadingSubmit}
loadingData={loadingData}
/>
</Styled>;
};
27 changes: 22 additions & 5 deletions components/ui/web/components/content/jobs/list/jobDatagrid.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { FC, useState } from 'react';
import { useRouter } from 'next/router';
import styled from 'styled-components';
import {
KeyboardArrowUp as KeyboardArrowUpIcon,
KeyboardArrowDown as KeyboardArrowDownIcon
} from '@mui/icons-material';

import {
Button,
Chip,
IconButton,
Paper,
Expand All @@ -21,11 +23,17 @@ import { Job } from 'src/graphql/typings';
import { JobShortDetail } from 'components/content/jobs/detail/jobShortDetail';

const Styled = styled.div`
margin-top: 2rem;
margin-top: 2rem;

.grid {
.new-job {
display: block;
margin: 1rem 3rem 1rem auto; /* pushes the button to the right */
}

.grid {
width: inherit;
.column-header {

.column-header {
font-style: normal;
font-size: 14px;
letter-spacing: 0.25px;
Expand All @@ -47,6 +55,8 @@ type Props = {
}

export const JobsDataGrid: FC<Props> = ({ jobsList }) => {

const router = useRouter();
// State to track which job rows are expanded by their ID
const [openRows, setOpenRows] = useState<Set<string>>(new Set());

Expand Down Expand Up @@ -82,8 +92,15 @@ export const JobsDataGrid: FC<Props> = ({ jobsList }) => {
};

return <Styled>
<Paper sx={{ width: '90%' }}>

<Button
variant="contained"
color="primary"
className="new-job"
onClick={() => router.push('/jobs/new')}
>
New Job
</Button>
<Paper sx={{ width: '95%' }}>
<TableContainer sx={{ maxHeight: 440, minWidth: '100%' }}>
<Table stickyHeader className="grid" aria-label=" Jobs Data Table">
<TableHead>
Expand Down
Loading