Skip to content

Commit

Permalink
Update modals and generate meaningful k8s name for images
Browse files Browse the repository at this point in the history
  • Loading branch information
DaoDaoNoCode committed Jul 25, 2023
1 parent 2c849f3 commit e233810
Show file tree
Hide file tree
Showing 20 changed files with 735 additions and 531 deletions.
19 changes: 16 additions & 3 deletions backend/src/routes/api/images/imageUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ import {
import { FastifyRequest } from 'fastify';
import createError from 'http-errors';

const translateDisplayNameForK8s = (name: string): string =>
name
.trim()
.toLowerCase()
.replace(/\s/g, '-')
.replace(/[^A-Za-z0-9-]/g, '');

export const getImageList = async (
fastify: KubeFastifyInstance,
labels: { [key: string]: string },
Expand Down Expand Up @@ -189,8 +196,14 @@ const packagesToString = (packages: BYONImagePackage[]): string => {
const mapImageStreamToBYONImage = (is: ImageStream): BYONImage => ({
id: is.metadata.uid,
name: is.metadata.name,
display_name: is.metadata.annotations['opendatahub.io/notebook-image-name'] || is.metadata.name,
description: is.metadata.annotations['opendatahub.io/notebook-image-desc'] || '',
display_name:
is.metadata.annotations['opendatahub.io/notebook-image-name'] ||
is.metadata.annotations['openshift.io/display-name'] ||
is.metadata.name,
description:
is.metadata.annotations['opendatahub.io/notebook-image-desc'] ||
is.metadata.annotations['openshift.io/description'] ||
'',
visible: is.metadata.labels['opendatahub.io/notebook-image'] === 'true',
error: getBYONImageErrorMessage(is),
packages: JSON.parse(
Expand Down Expand Up @@ -240,7 +253,7 @@ export const postImage = async (
'opendatahub.io/notebook-image-url': fullUrl,
'opendatahub.io/notebook-image-creator': body.provider,
},
name: `byon-${Date.now()}`,
name: `custom-${translateDisplayNameForK8s(body.display_name)}`,
namespace: namespace,
labels: labels,
},
Expand Down
1 change: 1 addition & 0 deletions backend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ export type ODHSegmentKey = {

export type BYONImage = {
id: string;
// FIXME: This shouldn't be a user defined value consumed from the request payload but should be a controlled value from an authentication middleware.
provider: string;
imported_time: string;
error: string;
Expand Down
39 changes: 39 additions & 0 deletions frontend/src/pages/BYONImages/BYONImageDependenciesList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as React from 'react';
import {
DescriptionListDescription,
DescriptionListGroup,
DescriptionListTerm,
Text,
TextContent,
} from '@patternfly/react-core';

type BYONImageDependenciesListProps = {
dependencies: string[];
term: string;
};

const BYONImageDependenciesList: React.FC<BYONImageDependenciesListProps> = ({
term,
dependencies,
}) => {
if (dependencies.length === 0) {
return null;
}

return (
<DescriptionListGroup>
<DescriptionListTerm>{term}</DescriptionListTerm>
<DescriptionListDescription>
<TextContent>
{dependencies.map((dep, i) => (
<Text style={{ marginBottom: 0 }} key={i} component="small">
{dep}
</Text>
))}
</TextContent>
</DescriptionListDescription>
</DescriptionListGroup>
);
};

export default BYONImageDependenciesList;
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import * as React from 'react';
import {
Button,
EmptyState,
EmptyStateBody,
EmptyStateIcon,
EmptyStatePrimary,
EmptyStateVariant,
TabContent,
Title,
} from '@patternfly/react-core';
import { PlusCircleIcon } from '@patternfly/react-icons';
import { BYONImagePackage } from '~/types';
import { DisplayedContentTab } from './ManageBYONImageModal';
import DisplayedContentTable from './DisplayedContentTable';

type DisplayedContentTabContentProps = {
activeKey: string | number;
tabKey: DisplayedContentTab;
resources: BYONImagePackage[];
setResources: React.Dispatch<React.SetStateAction<BYONImagePackage[]>>;
tempResources: BYONImagePackage[];
setTempResources: React.Dispatch<React.SetStateAction<BYONImagePackage[]>>;
editIndex?: number;
setEditIndex: (index?: number) => void;
};

const DisplayedContentTabContent: React.FC<DisplayedContentTabContentProps> = ({
activeKey,
tabKey,
resources,
setResources,
tempResources,
setTempResources,
editIndex,
setEditIndex,
}) => {
const resourceType = tabKey === DisplayedContentTab.SOFTWARE ? 'software' : 'packages';

const addEmptyRow = React.useCallback(() => {
setTempResources((prev) => [
...prev,
{
name: '',
version: '',
visible: true,
},
]);
setEditIndex(tempResources.length);
}, [tempResources.length, setTempResources, setEditIndex]);

return (
<TabContent
id={`tabContent-${tabKey}`}
eventKey={tabKey}
activeKey={activeKey}
hidden={tabKey !== activeKey}
>
{tempResources.length === 0 ? (
<EmptyState variant={EmptyStateVariant.small}>
<EmptyStateIcon icon={PlusCircleIcon} />
<Title headingLevel="h2" size="lg">
No {resourceType} displayed
</Title>
<EmptyStateBody>
Displayed contents help inform other users of what your notebook image contains. To add
displayed content, add the names of software or packages included in your image that you
want users to know about.
</EmptyStateBody>
<EmptyStatePrimary>
<Button
data-id={`add-${resourceType}-button`}
variant="secondary"
onClick={addEmptyRow}
>
Add {resourceType}
</Button>
</EmptyStatePrimary>
</EmptyState>
) : (
<DisplayedContentTable
tabKey={tabKey}
onReset={() => {
setTempResources([...resources]);
setEditIndex(undefined);
}}
onConfirm={(rowIndex, name, version) => {
const copiedArray = [...tempResources];
copiedArray[rowIndex].name = name;
copiedArray[rowIndex].version = version;
setTempResources(copiedArray);
setResources(copiedArray);
setEditIndex(undefined);
}}
resources={tempResources}
onAdd={addEmptyRow}
editIndex={editIndex}
onEdit={setEditIndex}
onDelete={(index) => {
const copiedArray = [...resources];
copiedArray.splice(index, 1);
setTempResources(copiedArray);
setResources(copiedArray);
}}
/>
)}
</TabContent>
);
};

export default DisplayedContentTabContent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import * as React from 'react';
import { Button, Panel, PanelFooter, PanelHeader, PanelMainBody } from '@patternfly/react-core';
import { PlusCircleIcon } from '@patternfly/react-icons';
import Table from '~/components/table/Table';
import { BYONImagePackage } from '~/types';
import { DisplayedContentTab } from './ManageBYONImageModal';
import { getColumns } from './tableData';
import DisplayedContentTableRow from './DisplayedContentTableRow';

type DisplayedContentTableProps = {
tabKey: DisplayedContentTab;
onReset: () => void;
onConfirm: (rowIndex: number, name: string, version: string) => void;
resources: BYONImagePackage[];
onAdd: () => void;
editIndex?: number;
onEdit: (index: number) => void;
onDelete: (index: number) => void;
};

const DisplayedContentTable: React.FC<DisplayedContentTableProps> = ({
tabKey,
onReset,
onConfirm,
resources,
onAdd,
editIndex,
onEdit,
onDelete,
}) => {
const content = tabKey === DisplayedContentTab.SOFTWARE ? 'software' : 'packages';
const columns = getColumns(tabKey);

return (
<Panel>
<PanelHeader>
Add the {content} labels that will be displayed with this notebook image. Modifying the{' '}
{content} here does not effect the contents of the notebook image.
</PanelHeader>
<PanelMainBody>
<Table
variant="compact"
data={resources}
columns={columns}
disableRowRenderSupport
rowRenderer={(resource, rowIndex) => (
<DisplayedContentTableRow
key={rowIndex}
obj={resource}
tabKey={tabKey}
isActive={editIndex === rowIndex}
isEditing={editIndex !== undefined}
onConfirm={(name, version) => onConfirm(rowIndex, name, version)}
onReset={onReset}
onEdit={() => onEdit(rowIndex)}
onDelete={() => onDelete(rowIndex)}
onMoveToNextRow={() => {
if (rowIndex === resources.length - 1) {
onAdd();
} else {
onEdit(rowIndex + 1);
}
}}
/>
)}
/>
</PanelMainBody>
<PanelFooter>
<Button
data-id="add-resource-button"
variant="link"
icon={<PlusCircleIcon />}
onClick={onAdd}
isDisabled={editIndex !== undefined}
isInline
>
Add {content}
</Button>
</PanelFooter>
</Panel>
);
};

export default DisplayedContentTable;
Loading

0 comments on commit e233810

Please sign in to comment.