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

[Feature] Data Science Grouping #689

Merged
merged 44 commits into from
Oct 31, 2022
Merged
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
0b85446
Add empty DSG page & nav (#471)
andrewballantyne Sep 1, 2022
cd84b11
Kubernetes Pass Through API & SDK Initialization (#279)
andrewballantyne Sep 2, 2022
c5c2575
Misc cleanup of DSG (#481)
andrewballantyne Sep 9, 2022
99bc6f7
Add project view details page (#578)
DaoDaoNoCode Sep 20, 2022
5257223
Update DSG with latest main
andrewballantyne Sep 21, 2022
48cafdb
Update DSG with latest main
andrewballantyne Sep 23, 2022
e060071
Create projects (#597)
andrewballantyne Sep 26, 2022
7a72e13
List Projects & Delete Project (#605)
andrewballantyne Sep 28, 2022
9480697
Create add storage modal (#582)
DaoDaoNoCode Oct 3, 2022
d5b19fc
Add part of spawner page (#610)
DaoDaoNoCode Oct 4, 2022
8c61265
Add storage section for spawner page (#637)
DaoDaoNoCode Oct 11, 2022
3a3df3b
Workspace Table (#660)
andrewballantyne Oct 12, 2022
7531b28
Follow up fix for #610 and #637 (#664)
DaoDaoNoCode Oct 13, 2022
898875d
Code cleanup (#665)
andrewballantyne Oct 13, 2022
307d064
Add storage list layout (#666)
DaoDaoNoCode Oct 17, 2022
0b53a26
Data Connections List (#671)
andrewballantyne Oct 18, 2022
264a9c2
Stop Notebook Confirmation Modal (#672)
andrewballantyne Oct 18, 2022
4c48d0d
Delete Notebook Modal (#673)
andrewballantyne Oct 18, 2022
08ced68
Spawner Environment Section (#670)
dlabaj Oct 19, 2022
0f34124
Delete Storage Modal (#677)
andrewballantyne Oct 19, 2022
f99bf75
Prometheus connection for inUse storage value (#676)
andrewballantyne Oct 19, 2022
7d24914
Added spawner page. (#679)
dlabaj Oct 20, 2022
998dbba
Cleanup Random DSG stuff (#678)
andrewballantyne Oct 20, 2022
1418b14
Added breadcrumb for project details and spawner page. (#682)
dlabaj Oct 20, 2022
811dbfe
Adjust Storage based on UX input (#684)
andrewballantyne Oct 21, 2022
d915ab4
Add status tooltip and start notebook modal (#683)
DaoDaoNoCode Oct 23, 2022
203f84f
Environment Spawner Section & Data Connections (#688)
andrewballantyne Oct 24, 2022
905be2f
Merge branch 'main' into f/dsg
andrewballantyne Oct 24, 2022
93c197e
Cleanup lint issues
andrewballantyne Oct 24, 2022
0201a38
Create dedicated OAuthclient (#658)
Oct 24, 2022
4cad65c
DSG Fixes (#696)
andrewballantyne Oct 26, 2022
519b016
Merge branch 'main' into f/dsg
DaoDaoNoCode Oct 26, 2022
1822613
Follow-up fix for DSG work (#695)
DaoDaoNoCode Oct 26, 2022
1433957
Refresh notebook status and fetch all status periodically (#697)
DaoDaoNoCode Oct 26, 2022
56bcb61
Improve storage section features and bug fix (#698)
DaoDaoNoCode Oct 27, 2022
9b047ce
Add ability to delete attached PVC (#699)
DaoDaoNoCode Oct 27, 2022
b9effa6
Merge branch 'main' into f/dsg
andrewballantyne Oct 27, 2022
f851e79
Improve Project Creation & Data Connection Modal (#700)
andrewballantyne Oct 27, 2022
406bbd3
Fixes for DSG (#701)
DaoDaoNoCode Oct 28, 2022
4cddc7b
Translate display names into k8s names (#702)
andrewballantyne Oct 28, 2022
c16e5ea
Fix lint issue
andrewballantyne Oct 28, 2022
79f2355
Fixes and features for DSG (#704)
DaoDaoNoCode Oct 31, 2022
9aac7ff
UX Feedback -- DSG Changes (#705)
andrewballantyne Oct 31, 2022
7772917
Fix lint issues
andrewballantyne Oct 31, 2022
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
Prev Previous commit
Next Next commit
Add status tooltip and start notebook modal (#683)
* Add status tooltip and start notebook modal

* get projectName from notebook namespace
  • Loading branch information
DaoDaoNoCode authored Oct 23, 2022

Verified

This commit was signed with the committer’s verified signature.
mostafa Mostafa Moradian
commit d915ab47a02b6839ba0564932fab5bcab77a261f
1 change: 1 addition & 0 deletions frontend/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Normal SDK/pass-through network API calls
export * from './network/builds';
export * from './network/configMaps';
export * from './network/events';
export * from './network/imageStreams';
export * from './network/notebooks';
export * from './network/pods';
6 changes: 6 additions & 0 deletions frontend/src/api/models/k8s.ts
Original file line number Diff line number Diff line change
@@ -6,6 +6,12 @@ export const ConfigMapModel: K8sModelCommon = {
plural: 'configmaps',
};

export const EventModel: K8sModelCommon = {
apiVersion: 'v1',
kind: 'Event',
plural: 'events',
};

export const PodModel: K8sModelCommon = {
apiVersion: 'v1',
kind: 'Pod',
21 changes: 21 additions & 0 deletions frontend/src/api/network/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { k8sListResource } from '@openshift/dynamic-plugin-sdk-utils';
import { EventKind } from '../../k8sTypes';
import { EventModel } from '../models';

export const getNotebookEvents = async (
namespace: string,
podUid: string,
): Promise<EventKind[]> => {
return k8sListResource<EventKind>({
model: EventModel,
queryOptions: {
ns: namespace,
queryParams: {
fieldSelector: `involvedObject.kind=Pod,involvedObject.uid=${podUid}`,
},
},
}).then(
// Filter the events by pods that have the same name as the notebook
(r) => r.items,
);
};
14 changes: 14 additions & 0 deletions frontend/src/k8sTypes.ts
Original file line number Diff line number Diff line change
@@ -106,6 +106,20 @@ export type ConfigMapKind = K8sResourceCommon & {
data?: Record<string, string>;
};

export type EventKind = K8sResourceCommon & {
metadata: {
uid?: string;
};
involvedObject: {
name: string;
};
lastTimestamp?: string;
eventTime: string;
type: 'Normal' | 'Warning';
reason: string;
message: string;
};

export type ImageStreamKind = K8sResourceCommon & {
metadata: {
annotations?: ImageStreamAnnotations;
12 changes: 9 additions & 3 deletions frontend/src/pages/projects/notebook/NotebookRouteLink.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Button } from '@patternfly/react-core';
import { Button, ButtonVariant } from '@patternfly/react-core';
import { ExclamationCircleIcon, ExternalLinkAltIcon } from '@patternfly/react-icons';
import { NotebookKind } from '../../../k8sTypes';
import useRouteForNotebook from './useRouteForNotebook';
@@ -10,9 +10,15 @@ type NotebookRouteLinkProps = {
label?: React.ReactNode;
notebook: NotebookKind;
isRunning: boolean;
variant?: ButtonVariant;
};

const NotebookRouteLink: React.FC<NotebookRouteLinkProps> = ({ label, notebook, isRunning }) => {
const NotebookRouteLink: React.FC<NotebookRouteLinkProps> = ({
label,
notebook,
isRunning,
variant,
}) => {
const [routeLink, loaded, error] = useRouteForNotebook(notebook);
const isStopped = hasStopAnnotation(notebook);
const canLink = !!routeLink && !error && !isStopped && isRunning;
@@ -25,7 +31,7 @@ const NotebookRouteLink: React.FC<NotebookRouteLinkProps> = ({ label, notebook,
isLoading={!loaded}
href={error || !routeLink ? undefined : routeLink}
target="_blank"
variant="link"
variant={variant || 'link'}
icon={
error ? (
<ExclamationCircleIcon title="Error getting link for notebook" />
71 changes: 71 additions & 0 deletions frontend/src/pages/projects/notebook/NotebookStatusPopover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import * as React from 'react';
import { Button, Popover } from '@patternfly/react-core';
import StartNotebookModal from './StartNotebookModal';
import { NotebookState } from './types';
import { getEventFullMessage, useNotebookStatus } from './utils';
import { useDeepCompareMemoize } from '../../../utilities/useDeepCompareMemoize';

type NotebookStatusPopoverProps = {
isVisible: boolean;
onClose: () => void;
notebookState: NotebookState;
stopNotebook: () => void;
};

const NotebookStatusPopover: React.FC<NotebookStatusPopoverProps> = ({
children,
onClose,
isVisible,
notebookState,
stopNotebook,
}) => {
const { notebook, runningPodUid, isStarting } = notebookState;
const [isStartModalOpen, setStartModalOpen] = React.useState(false);
const [unstableNotebookStatus, events] = useNotebookStatus(notebook, runningPodUid, isStarting);
const notebookStatus = useDeepCompareMemoize(unstableNotebookStatus);

return (
<>
<Popover
shouldClose={onClose}
isVisible={isVisible}
headerContent="Notebook status"
bodyContent={
<>
{events[events.length - 1]
? getEventFullMessage(events[events.length - 1])
: 'Waiting for notebook to start...'}
</>
}
footerContent={
<Button
variant="link"
isInline
onClick={() => {
setStartModalOpen(true);
onClose();
}}
>
Event log
</Button>
}
>
<>{children}</>
</Popover>
<StartNotebookModal
isOpen={isStartModalOpen}
notebookState={notebookState}
notebookStatus={notebookStatus}
events={events}
onClose={(stopped) => {
if (stopped) {
stopNotebook();
}
setStartModalOpen(false);
}}
/>
</>
);
};

export default NotebookStatusPopover;
27 changes: 18 additions & 9 deletions frontend/src/pages/projects/notebook/NotebookStatusToggle.tsx
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import { NotebookState } from './types';
import useRefreshNotebookUntilStart from './useRefreshNotebookUntilStart';
import StopNotebookConfirmModal from './StopNotebookConfirmModal';
import useStopNotebookModalAvailability from './useStopNotebookModalAvailability';
import NotebookStatusPopover from './NotebookStatusPopover';

type NotebookStatusToggleProps = {
notebookState: NotebookState;
@@ -14,37 +15,43 @@ const NotebookStatusToggle: React.FC<NotebookStatusToggleProps> = ({ notebookSta
const { notebook, isStarting, isRunning, refresh } = notebookState;
const [isOpenConfirm, setOpenConfirm] = React.useState(false);
const [inProgress, setInProgress] = React.useState(false);
const [isPopoverVisible, setPopoverVisible] = React.useState(false);
const listenToNotebookStart = useRefreshNotebookUntilStart(notebookState);
const [dontShowModalValue] = useStopNotebookModalAvailability();
const notebookName = notebook.metadata.name;
const notebookNamespace = notebook.metadata.namespace;
const startingNotRunning = isStarting && !isRunning;
const isRunningOrStarting = isStarting || isRunning;

/** If in progress, it is faking the opposite */
const isChecked = inProgress ? !isRunningOrStarting : isRunningOrStarting;

let label = '';
if (startingNotRunning) {
if (isStarting) {
label = 'Starting...';
} else if (inProgress) {
label = isChecked ? 'Starting...' : 'Stopping...';
} else {
label = isRunning ? 'Started' : 'Stopped';
label = isRunning ? 'Running' : 'Stopped';
}

const handleStop = () => {
const handleStop = React.useCallback(() => {
setInProgress(true);
stopNotebook(notebookName, notebookNamespace).then(() => {
refresh().then(() => setInProgress(false));
listenToNotebookStart(false);
});
};
}, [notebookName, notebookNamespace, refresh, listenToNotebookStart]);

return (
<>
<NotebookStatusPopover
isVisible={isPopoverVisible}
notebookState={notebookState}
stopNotebook={handleStop}
onClose={() => setPopoverVisible(false)}
>
<Switch
label={label}
isDisabled={inProgress || startingNotRunning}
isDisabled={inProgress}
id={notebookName}
isChecked={isChecked}
onClick={() => {
@@ -54,11 +61,13 @@ const NotebookStatusToggle: React.FC<NotebookStatusToggleProps> = ({ notebookSta
} else {
setOpenConfirm(true);
}
} else if (isStarting) {
setPopoverVisible((visible) => !visible);
} else {
setInProgress(true);
startNotebook(notebookName, notebookNamespace).then(() => {
refresh().then(() => setInProgress(false));
listenToNotebookStart();
listenToNotebookStart(true);
});
}
}}
@@ -73,7 +82,7 @@ const NotebookStatusToggle: React.FC<NotebookStatusToggleProps> = ({ notebookSta
setOpenConfirm(false);
}}
/>
</>
</NotebookStatusPopover>
);
};

Loading
Oops, something went wrong.