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

Follow up fix for #610 and #637 #664

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion frontend/src/api/network/builds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { k8sListResource } from '@openshift/dynamic-plugin-sdk-utils';
import { BuildConfigModel, BuildModel } from '../models';
import { BuildConfigKind, BuildKind } from '../../k8sTypes';

export const getBuildConfigs = (namespace: string): Promise<BuildConfigKind[]> => {
export const getNotebookBuildConfigs = (namespace: string): Promise<BuildConfigKind[]> => {
return k8sListResource<BuildConfigKind>({
model: BuildConfigModel,
queryOptions: {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/api/network/imageStreams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { k8sListResourceItems } from '@openshift/dynamic-plugin-sdk-utils';
import { ImageStreamModel } from '../models';
import { ImageStreamKind } from '../../k8sTypes';

export const getImageStreams = (namespace: string): Promise<ImageStreamKind[]> => {
export const getNotebookImageStreams = (namespace: string): Promise<ImageStreamKind[]> => {
return k8sListResourceItems<ImageStreamKind>({
model: ImageStreamModel,
queryOptions: {
Expand Down
3 changes: 0 additions & 3 deletions frontend/src/k8sTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,6 @@ export type ImageStreamKind = K8sResourceCommon & {
};
};

/**
* type of `imageStream.spec.tags[i]`
*/
export type ImageStreamSpecTagType = {
name: string;
annotations?: ImageStreamSpecTagAnnotations;
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/pages/projects/ProjectDetailsContext.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { ProjectKind } from '../../k8sTypes';
import { useParams } from 'react-router';
import { Outlet, useParams } from 'react-router-dom';
import {
Bullseye,
Button,
Expand All @@ -23,7 +23,7 @@ export const ProjectDetailsContext = React.createContext<ProjectDetailsContextTy
currentProject: null as unknown as ProjectKind,
});

const ProjectDetailsContextProvider: React.FC = ({ children }) => {
const ProjectDetailsContextProvider: React.FC = () => {
const navigate = useNavigate();
const { namespace } = useParams<{ namespace: string }>();
const [project, loaded, error] = useProject(namespace);
Expand Down Expand Up @@ -55,7 +55,7 @@ const ProjectDetailsContextProvider: React.FC = ({ children }) => {

return (
<ProjectDetailsContext.Provider value={{ currentProject: project }}>
{children}
<Outlet />
</ProjectDetailsContext.Provider>
);
};
Expand Down
20 changes: 4 additions & 16 deletions frontend/src/pages/projects/ProjectViewRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,10 @@ const ProjectViewRoutes: React.FC = () => {
return (
<Routes>
<Route path="/" element={<ProjectView />} />
<Route
path="/:namespace/*"
element={
<ProjectDetailsContextProvider>
<ProjectDetails />
</ProjectDetailsContextProvider>
}
/>
<Route
path="/:namespace/spawner"
element={
<ProjectDetailsContextProvider>
<SpawnerPage />
</ProjectDetailsContextProvider>
}
/>
<Route path="/:namespace/*" element={<ProjectDetailsContextProvider />}>
<Route index element={<ProjectDetails />} />
<Route path="spawner" element={<SpawnerPage />} />
</Route>
<Route path="*" element={<Navigate to="." />} />
</Routes>
);
Expand Down
77 changes: 77 additions & 0 deletions frontend/src/pages/projects/components/ExistingPVCField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import * as React from 'react';
import { Alert, FormGroup, Select, SelectOption, Skeleton } from '@patternfly/react-core';
import { getPvcDisplayName } from '../utils';
import { PersistentVolumeClaimKind } from '../../../k8sTypes';

type ExistingPVCFieldProps = {
fieldId: string;
storages: PersistentVolumeClaimKind[];
loaded: boolean;
loadError?: Error;
selectedStorage?: string;
setStorage: (storage?: string) => void;
selectDirection?: 'up' | 'down';
menuAppendTo?: HTMLElement | 'parent';
};

const ExistingPVCField: React.FC<ExistingPVCFieldProps> = ({
fieldId,
storages,
loaded,
loadError,
selectedStorage,
setStorage,
selectDirection = 'down',
menuAppendTo = 'parent',
}) => {
const [isOpen, setOpen] = React.useState<boolean>(false);

if (!loaded) {
return <Skeleton />;
}

if (loadError) {
return (
<Alert title="Error loading pvcs" variant="danger">
{loadError.message}
</Alert>
);
}

const options = storages.map((pvc) => (
<SelectOption key={pvc.metadata.name} value={pvc.metadata.name}>
{getPvcDisplayName(pvc)}
</SelectOption>
));

const empty = options.length === 0;

return (
<FormGroup label="PV" fieldId={fieldId}>
<Select
variant="typeahead"
selections={selectedStorage}
isOpen={isOpen}
onClear={() => {
setStorage(undefined);
setOpen(false);
}}
isDisabled={empty}
onSelect={(e, selection) => {
if (typeof selection === 'string') {
setStorage(selection);
setOpen(false);
}
}}
onToggle={setOpen}
placeholderText={empty ? 'No storage available' : 'Select the PV to add to your project'}
direction={selectDirection}
menuAppendTo={menuAppendTo}
>
{options}
</Select>
</FormGroup>
);
};

export default ExistingPVCField;
70 changes: 70 additions & 0 deletions frontend/src/pages/projects/components/ExistingProjectField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import * as React from 'react';
import { Alert, FormGroup, Select, SelectOption, Skeleton } from '@patternfly/react-core';
import { getProjectDisplayName } from '../utils';
import useUserProjects from '../screens/projects/useUserProjects';

type ExistingProjectFieldProps = {
fieldId: string;
selectedProject?: string;
onSelect: (selection?: string) => void;
selectDirection?: 'up' | 'down';
menuAppendTo?: HTMLElement | 'parent';
};

const ExistingProjectField: React.FC<ExistingProjectFieldProps> = ({
fieldId,
selectedProject,
onSelect,
selectDirection = 'down',
menuAppendTo = 'parent',
}) => {
const [isOpen, setOpen] = React.useState<boolean>(false);

const [projects, loaded, loadError] = useUserProjects();

if (!loaded) {
return <Skeleton />;
}

if (loadError) {
return (
<Alert title="Error loading projects" variant="danger">
{loadError.message}
</Alert>
);
}

const options = projects.map((project) => (
<SelectOption key={project.metadata.name} value={project.metadata.name}>
{getProjectDisplayName(project)}
</SelectOption>
));

return (
<FormGroup label="Project" fieldId={fieldId}>
<Select
variant="typeahead"
selections={selectedProject}
isOpen={isOpen}
onClear={() => {
onSelect(undefined);
setOpen(false);
}}
onSelect={(e, selection) => {
if (typeof selection === 'string') {
onSelect(selection);
setOpen(false);
}
}}
onToggle={setOpen}
placeholderText="Select the project connected to the PV"
direction={selectDirection}
menuAppendTo={menuAppendTo}
>
{options}
</Select>
</FormGroup>
);
};

export default ExistingProjectField;
58 changes: 0 additions & 58 deletions frontend/src/pages/projects/components/ExistingStoragePVField.tsx

This file was deleted.

This file was deleted.

43 changes: 43 additions & 0 deletions frontend/src/pages/projects/components/NameDescriptionField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as React from 'react';
import { FormGroup, TextArea, TextInput } from '@patternfly/react-core';
import { NameDescType } from '../types';

type NameDescriptionFieldProps = {
nameFieldId: string;
descriptionFieldId: string;
data: NameDescType;
setData: (data: NameDescType) => void;
};

const NameDescriptionField: React.FC<NameDescriptionFieldProps> = ({
nameFieldId,
descriptionFieldId,
data,
setData,
}) => {
return (
<>
<FormGroup label="Name" fieldId={nameFieldId}>
<TextInput
id={nameFieldId}
name={nameFieldId}
aria-labelledby={nameFieldId}
value={data.name}
onChange={(name) => setData({ ...data, name })}
/>
</FormGroup>
<FormGroup label="Description" fieldId={descriptionFieldId}>
<TextArea
resizeOrientation="vertical"
id={descriptionFieldId}
name={descriptionFieldId}
aria-labelledby={descriptionFieldId}
value={data.description}
onChange={(description) => setData({ ...data, description })}
/>
</FormGroup>
</>
);
};

export default NameDescriptionField;
Loading