Skip to content

Commit

Permalink
feat: Use filtered resource pools when creating notebook (#9045)
Browse files Browse the repository at this point in the history
  • Loading branch information
gt2345 authored Mar 26, 2024
1 parent 74fe16b commit 1e6f0f7
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 10 deletions.
1 change: 1 addition & 0 deletions webui/react/src/components/JupyterLabModal.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const SIMPLE_CONFIG_TEMPLATE_TEXT = 'Template';
const SHOW_SIMPLE_CONFIG_TEXT = 'Show Simple Config';

vi.mock('services/api', () => ({
getAvailableResourcePools: () => Promise.resolve([]),
getCurrentUser: () => Promise.resolve({ id: 1 }),
getResourcePools: () => Promise.resolve([]),
getTaskTemplates: () => Promise.resolve([]),
Expand Down
34 changes: 24 additions & 10 deletions webui/react/src/components/JupyterLabModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { paths } from 'routes/utils';
import { getTaskTemplates } from 'services/api';
import clusterStore from 'stores/cluster';
import workspaceStore from 'stores/workspaces';
import { RawJson, Template, Workspace } from 'types';
import { RawJson, ResourcePool, Template, Workspace } from 'types';
import handleError from 'utils/error';
import { JupyterLabOptions, launchJupyterLab, previewJupyterLab } from 'utils/jupyter';
import { useObservable } from 'utils/observable';
Expand Down Expand Up @@ -349,12 +349,22 @@ const JupyterLabForm: React.FC<{
}> = ({ form, formId, currentWorkspace, defaults, lockedWorkspace, setWorkspace, workspaces }) => {
const [templates, setTemplates] = useState<Template[]>([]);

const resourcePools = Loadable.getOrElse([], useObservable(clusterStore.resourcePools));
const selectedWorkspaceId = Form.useWatch('workspaceId', form);

const resourcePools = useObservable(clusterStore.resourcePools);
const boundResourcePoolsMap = useObservable(workspaceStore.boundResourcePoolsMap());

const boundResourcePools: ResourcePool[] = useMemo(() => {
if (!Loadable.isLoaded(resourcePools) || !selectedWorkspaceId) return [];
return resourcePools.data.filter(
(rp) => boundResourcePoolsMap.get(selectedWorkspaceId)?.includes(rp.name),
);
}, [resourcePools, boundResourcePoolsMap, selectedWorkspaceId]);

const selectedPoolName = Form.useWatch('pool', form);

const resourceInfo = useMemo(() => {
const selectedPool = resourcePools.find((pool) => pool.name === selectedPoolName);
const selectedPool = boundResourcePools.find((pool) => pool.name === selectedPoolName);
if (!selectedPool) return { hasAux: false, hasCompute: false, maxSlots: 0 };

/**
Expand All @@ -372,7 +382,7 @@ const JupyterLabForm: React.FC<{
hasCompute: hasComputeCapacity,
maxSlots: maxSlots,
};
}, [selectedPoolName, resourcePools]);
}, [selectedPoolName, boundResourcePools]);

useEffect(() => {
if (!resourceInfo.hasCompute && resourceInfo.hasAux) form.setFieldValue('slots', 0);
Expand All @@ -382,6 +392,10 @@ const JupyterLabForm: React.FC<{
}
}, [resourceInfo, form]);

useEffect(() => {
selectedWorkspaceId && workspaceStore.fetchAvailableResourcePools(selectedWorkspaceId);
}, [selectedWorkspaceId]);

const fetchTemplates = useCallback(async () => {
try {
setTemplates(await getTaskTemplates({}));
Expand All @@ -396,11 +410,11 @@ const JupyterLabForm: React.FC<{

useEffect(() => {
const fields = form.getFieldsValue(true);
if (!fields?.pool && resourcePools[0]?.name) {
const firstPoolInList = resourcePools[0]?.name;
if (!fields?.pool && boundResourcePools[0]?.name) {
const firstPoolInList = boundResourcePools[0]?.name;
form.setFieldValue('pool', firstPoolInList);
}
}, [resourcePools, form]);
}, [boundResourcePools, form]);

useEffect(() => {
form.setFieldValue('workspaceId', currentWorkspace?.id);
Expand Down Expand Up @@ -442,9 +456,9 @@ const JupyterLabForm: React.FC<{
<Form.Item initialValue={defaults?.name} label="Name" name="name">
<Input placeholder="Name (optional)" />
</Form.Item>
<Form.Item initialValue={defaults?.pool} label="Resource Pool" name="pool">
<Select allowClear placeholder="Pick the best option">
{resourcePools.map((pool) => (
<Form.Item label="Resource Pool" name="pool">
<Select allowClear disabled={!selectedWorkspaceId} placeholder="Pick the best option">
{boundResourcePools.map((pool) => (
<Option key={pool.name} value={pool.name}>
{pool.name}
</Option>
Expand Down
2 changes: 2 additions & 0 deletions webui/react/src/stores/workspaces.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ class WorkspaceStore extends PollingStore {
public readonly boundResourcePools = (workspaceId: number) =>
this.#boundResourcePools.select((map) => map.get(workspaceId)?.toJS());

public readonly boundResourcePoolsMap = () => this.#boundResourcePools.readOnly();

public async fetchAvailableResourcePools(workspaceId: number) {
const response = await getAvailableResourcePools({ workspaceId });
this.#boundResourcePools.update((map) => map.set(workspaceId, List(response)));
Expand Down

0 comments on commit 1e6f0f7

Please sign in to comment.