Skip to content
Snippets Groups Projects
Commit e8894725 authored by Loic Huder's avatar Loic Huder
Browse files

Add a way to discover all tasks in the current Python env

parent 4133c83b
No related branches found
No related tags found
1 merge request!382Add a way to discover all tasks in the current Python env
Pipeline #137034 passed
......@@ -6,6 +6,9 @@ it('discovers tasks from an existing module', () => {
cy.findByRole('button', { name: 'Discover tasks' }).click();
cy.findByRole('textbox', { name: 'Module name' }).type('ewokscore');
cy.findByRole('checkbox', { name: /^Discover from all modules/ }).should(
'not.be.checked'
);
cy.findByRole('button', { name: 'Discover' }).click();
cy.findByRole('button', { name: 'Cancel' }).click();
......@@ -31,6 +34,9 @@ it('shows a warning when discovering tasks from an non-existing module', () => {
cy.findByRole('button', { name: 'Discover tasks' }).click();
cy.findByRole('textbox', { name: 'Module name' }).type('not_a_module');
cy.findByRole('checkbox', { name: /^Discover from all modules/ }).should(
'not.be.checked'
);
cy.findByRole('button', { name: 'Discover' }).click();
// Need "hidden: true" because MUI puts Snackbars into a hidden div
......@@ -39,3 +45,14 @@ it('shows a warning when discovering tasks from an non-existing module', () => {
"No module named 'not_a_module'"
);
});
it('discovers tasks from the current Python env', () => {
cy.findByRole('button', { name: 'Discover tasks' }).click();
cy.findByRole('checkbox', { name: /^Discover from all modules/ }).check();
cy.findByRole('button', { name: 'Discover' }).click();
cy.findByRole('alert', { hidden: true }).should(
'contain.text',
'7 tasks imported.'
);
});
......@@ -11,6 +11,11 @@ import type {
} from './models';
import { QueryKey } from './models';
const TEST_TASKS = new Set([
'ewokscore.tests.examples.tasks.sumlist.SumList',
'ewokscore.tests.examples.tasks.sumlist.SumTask',
]);
// Get '/tasks/descriptions'
export async function fetchTaskDescriptions() {
return client.get<TaskDescriptionsResponse>(`/tasks/descriptions`);
......@@ -35,10 +40,17 @@ export function putTask(task: Task) {
}
// Discover tasks
export async function discoverTasks(moduleNames: string[]) {
return client.post<ListResponse>(`/tasks/discover`, {
export async function discoverTasks(moduleNames?: string[]): Promise<string[]> {
const { data } = await client.post<ListResponse>(`/tasks/discover`, {
modules: moduleNames,
});
const { identifiers } = data;
if (identifiers.length === 0) {
throw new Error('No tasks found in this module');
}
return identifiers.filter((id) => !TEST_TASKS.has(id));
}
export function useTasks(): Task[] {
......
import { Button } from '@material-ui/core';
import { Add } from '@material-ui/icons';
import { useState } from 'react';
import DiscoverTasksDialog from './DiscoverMenuDialog';
import DiscoverTasksDialog from './DiscoverTasksDialog';
function DiscoverTasksButton() {
const [isOpen, setOpen] = useState(false);
......
import {
Button,
Checkbox,
Dialog,
DialogActions,
DialogContent,
......@@ -13,6 +14,7 @@ import { discoverTasks } from '../../api/tasks';
import commonStrings from '../../commonStrings.json';
import { textForError } from '../../utils';
import { useInvalidateTasks } from '../../api/tasks';
import Spinner from '../../general/Spinner';
interface Props {
open: boolean;
......@@ -23,40 +25,45 @@ export default function DiscoverTasksDialog(props: Props) {
const { open, onClose } = props;
const showSuccessMsg = useSnackbarStore((state) => state.showSuccessMsg);
const showWarningMsg = useSnackbarStore((state) => state.showWarningMsg);
const [textValue, setTextValue] = useState<string>('');
const [textValue, setTextValue] = useState('');
const [discoverAll, setDiscoverAll] = useState(false);
const [isLoading, setLoading] = useState(false);
const invalidateTasks = useInvalidateTasks();
async function discover() {
if (!textValue) {
showWarningMsg('Please provide a module name');
return;
}
async function discover(moduleNames?: string[]) {
try {
const { data } = await discoverTasks([textValue]);
const { identifiers } = data;
if (identifiers.length === 0) {
showWarningMsg('No tasks found in this module');
return;
}
setLoading(true);
const identifiers = await discoverTasks(moduleNames);
showSuccessMsg(`${identifiers.length} tasks imported.`);
invalidateTasks();
} catch (error) {
showWarningMsg(textForError(error, commonStrings.savingError));
} finally {
setLoading(false);
}
}
async function discoverFromModule() {
if (!textValue) {
showWarningMsg('Please provide a module name');
return;
}
discover([textValue]);
}
return (
<Dialog open={open} onClose={onClose}>
<DialogTitle>Discover tasks from a module</DialogTitle>
<DialogTitle>Discover tasks</DialogTitle>
<DialogContent>
<DialogContentText>
Provide the module name from which tasks will be discovered.
Provide the name of the module from which tasks will be discovered
</DialogContentText>
<TextField
disabled={discoverAll}
margin="dense"
label="Module name"
fullWidth
......@@ -65,24 +72,47 @@ export default function DiscoverTasksDialog(props: Props) {
onChange={(event) => setTextValue(event.target.value)}
onKeyPress={(event) => {
if (event.key === 'Enter') {
discover();
discoverFromModule();
}
}}
inputProps={{ 'aria-label': 'Module name' }}
/>
</DialogContent>
<DialogActions>
<Button
<Checkbox
color="primary"
onClick={() => {
discover();
id="discoverAllCheckbox"
checked={discoverAll}
onChange={() => {
setDiscoverAll(!discoverAll);
}}
>
Discover
</Button>
<Button color="primary" onClick={onClose}>
Cancel
</Button>
/>
<label htmlFor="discoverAllCheckbox">
Discover from all modules in the current Python environment
</label>
</DialogContent>
<DialogActions>
{isLoading ? (
<Spinner />
) : (
<>
<Button
color="primary"
onClick={() => {
if (discoverAll) {
discover();
} else {
discoverFromModule();
}
}}
>
Discover
</Button>
<Button color="primary" onClick={onClose}>
Cancel
</Button>
</>
)}
</DialogActions>
</Dialog>
);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment