Skip to content
Snippets Groups Projects
Commit 70b2e14b authored by bedran.sezer's avatar bedran.sezer Committed by michael.minelli
Browse files

update fuzzy matching

parent 47750aa8
Branches
Tags
No related merge requests found
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>
\ No newline at end of file
#/-------------------.env.vault---------------------/ #/-------------------.env.vault---------------------/
#/ cloud-agnostic vaulting standard / #/ cloud-agnostic vaulting standard /
#/ [how it works](https://dotenvx.com/env-vault) / #/ [how it works](https://dotenv.org/env-vault) /
#/--------------------------------------------------/ #/--------------------------------------------------/
# development # development
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" /> <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
<mapping directory="$PROJECT_DIR$/DojoExercise_Technique_de compilation - TP" vcs="Git" />
<mapping directory="$PROJECT_DIR$/src/shared" vcs="Git" /> <mapping directory="$PROJECT_DIR$/src/shared" vcs="Git" />
<mapping directory="$PROJECT_DIR$/src/sharedByClients" vcs="Git" /> <mapping directory="$PROJECT_DIR$/src/sharedByClients" vcs="Git" />
</component> </component>
......
...@@ -3,6 +3,7 @@ import ExerciseCreateCommand from './subcommands/ExerciseCreateCommand.js'; ...@@ -3,6 +3,7 @@ import ExerciseCreateCommand from './subcommands/ExerciseCreateCommand.js';
import ExerciseRunCommand from './subcommands/ExerciseRunCommand.js'; import ExerciseRunCommand from './subcommands/ExerciseRunCommand.js';
import ExerciseCorrectionCommand from './subcommands/ExerciseCorrectionCommand.js'; import ExerciseCorrectionCommand from './subcommands/ExerciseCorrectionCommand.js';
import ExerciseDeleteCommand from './subcommands/ExerciseDeleteCommand'; import ExerciseDeleteCommand from './subcommands/ExerciseDeleteCommand';
import ExerciseListCommand from "./subcommands/ExerciseListCommand";
class ExerciseCommand extends CommanderCommand { class ExerciseCommand extends CommanderCommand {
...@@ -18,6 +19,7 @@ class ExerciseCommand extends CommanderCommand { ...@@ -18,6 +19,7 @@ class ExerciseCommand extends CommanderCommand {
ExerciseRunCommand.registerOnCommand(this.command); ExerciseRunCommand.registerOnCommand(this.command);
ExerciseDeleteCommand.registerOnCommand(this.command); ExerciseDeleteCommand.registerOnCommand(this.command);
ExerciseCorrectionCommand.registerOnCommand(this.command); ExerciseCorrectionCommand.registerOnCommand(this.command);
ExerciseListCommand.registerOnCommand(this.command);
} }
protected async commandAction(): Promise<void> { protected async commandAction(): Promise<void> {
......
// ExerciseListCommand.ts
import CommanderCommand from '../../CommanderCommand';
import chalk from 'chalk';
import ora from 'ora';
import DojoBackendManager from '../../../managers/DojoBackendManager';
import AccessesHelper from '../../../helpers/AccessesHelper';
import Exercise from '../../../sharedByClients/models/Exercise';
import inquirer from 'inquirer';
import Table from 'cli-table3';
import Fuse from 'fuse.js';
import User from '../../../sharedByClients/models/User';
class ExerciseListCommand extends CommanderCommand {
protected commandName: string = 'list';
protected defineCommand(): void {
this.command
.description('list your exercises')
.action(this.commandAction.bind(this));
}
protected async commandAction(): Promise<void> {
console.log(chalk.cyan('Please wait while we retrieve your exercises...'));
// Check access
if (!await AccessesHelper.checkStudent()) {
return;
}
// Fetch user's exercises
const userExercises: Exercise[] | undefined = await DojoBackendManager.getUserExercises();
if (!userExercises || userExercises.length === 0) {
ora().info('You have no exercises yet.');
return;
}
// Display the list of exercises
this.displayExerciseList(userExercises);
// Ask the user for further actions
await this.askUserForActions(userExercises);
}
private async askUserForActions(exercises: Exercise[]): Promise<void> {
const { action } = await inquirer.prompt([
{
type: 'list',
name: 'action',
message: 'Que souhaitez-vous faire ?',
choices: [
{ name: 'Voir les détails d\'exercice', value: 'details'},
{ name: 'Filter les exercises', value: 'filter' },
{ name: 'Exit', value: 'exit' },
],
},
]);
if (action === 'details') {
await this.selectExerciseForDetails(exercises);
} else if (action === 'filter') {
await this.filterExercises(exercises);
} else {
ora().info('No further actions selected.');
}
}
private async selectExerciseForDetails(exercises: Exercise[]): Promise<void> {
const { selectedExercise } = await inquirer.prompt([{
type: 'list',
name: 'selectedExercise',
message: 'Selectionner un exercice :',
choices: [
...exercises.map(exercise => ({
name: exercise.name,
value: exercise.id,
})),
{ name: 'Exit', value: 'exit' },
],
}]);
if (selectedExercise === 'exit') {
ora().info('Pas de détails requis: détails dispo avec la commande `dojo exercise info <id>`.');
return;
}
const selected = exercises.find(ex => ex.id === selectedExercise);
if (selected) {
await this.displayExerciseDetails(selected);
} else {
ora().info('Invalid selection. No exercise details to show.');
}
}
private async filterExercises(exercises: Exercise[]): Promise<void> {
const { filterType } = await inquirer.prompt([
{
type: 'list',
name: 'filterType',
message: 'Comment souhaitez-vous filtrer les exercices ?',
choices: [
{ name: 'Par saisie texte', value: 'fuzzy' },
{ name: 'Par professeurs', value: 'professor' },
{ name: 'Exit', value: 'exit' },
],
},
]);
if (filterType === 'fuzzy') {
await this.fuzzySearchExercises(exercises);
} else if (filterType === 'professor') {
await this.filterByProfessor(exercises);
} else {
ora().info('No filtering selected.');
}
}
private async fuzzySearchExercises(exercises: Exercise[]): Promise<void> {
const { searchQuery } = await inquirer.prompt([
{
type: 'input',
name: 'searchQuery',
message: 'Entrez le nom de l\'exercice (laisser vide pour la liste complète) :',
},
]);
if (!searchQuery) {
this.displayExerciseList(exercises);
return;
}
const fuse = new Fuse(exercises, {
keys: ['name'],
threshold: 0.5,
distance: 150,
});
const searchResults = fuse.search(searchQuery).map(result => result.item);
if (searchResults.length === 0) {
ora().info('Aucun exercice trouvé correspondant à votre recherche.');
return;
}
if (searchResults.length === 1) {
// Display details and members for the single matching exercise
const singleExercise = searchResults[0];
this.displayExerciseDetails(singleExercise);
} else {
// Display only exercise names and info about viewing details
ora().info(' Plusieurs exercices trouvés correspondant à votre recherche :');
const exerciseNames = searchResults.map(exercise => exercise.name);
console.log(' ', exerciseNames.join('\n '));
ora().info('Les détails sont disponibles avec la commande : `dojo exercise info <id>`.');
}
}
private async filterByProfessor(exercises: Exercise[]): Promise<void> {
const professors: User[] | undefined = await DojoBackendManager.getProfessors();
if (!professors || professors.length === 0) {
ora().info('No professors found.');
return;
}
const professorChoices = professors.map(professor => ({
name: `${professor.gitlabUsername}`,
value: professor // Use the professor object as the value
}));
const { selectedProfessor } = await inquirer.prompt([
{
type: 'list',
name: 'selectedProfessor',
message: 'Selectionnez un professeur:',
choices: professorChoices
}
]);
console.log(`Selected professor: ${selectedProfessor.gitlabUsername}`);
ora().info('Filter by professor is not yet implemented.');
}
private displayExerciseList(exercises: Exercise[]): void {
const headers = ['Exercise Name', 'GitLab Link'];
// Calculate the maximum width for each column
const maxWidths = headers.map(header => header.length);
exercises.forEach(exercise => {
maxWidths[0] = Math.max(maxWidths[0], exercise.name.length);
maxWidths[1] = Math.max(maxWidths[1], exercise.gitlabLink.length);
});
const table = new Table({
head: headers,
});
exercises.forEach((exercise) => {
table.push([
exercise.name,
exercise.gitlabLink,
]);
});
ora().info('Your exercises:');
console.log(table.toString());
}
private async displayExerciseDetails(exercise: Exercise): Promise<void> {
ora().info(`Detail of Exercise with ID: ${exercise.id}`);
console.log(chalk.magenta(' - Exercise Name:'), exercise.name);
console.log(chalk.magenta(' - Assignment Name:'), exercise.assignmentName);
console.log(chalk.magenta(' - GitLab ID:'), exercise.gitlabId);
console.log(chalk.magenta(' - GitLab Link:'), chalk.blue.underline(exercise.gitlabLink));
console.log(chalk.magenta(' - GitLab Last Info Date:'), exercise.gitlabLastInfoDate);
// Fetch exercise members
const exerciseMembers = await DojoBackendManager.getExerciseMembers(exercise.id);
if (exerciseMembers && exerciseMembers.length > 0) {
ora().info('Exercise Members:');
exerciseMembers.forEach(member => {
console.log(chalk.magenta(` - ${member.id} ${member.name}`));
});
} else {
ora().info('No members found for this exercise.');
}
}
}
export default new ExerciseListCommand();
\ No newline at end of file
...@@ -554,6 +554,17 @@ class DojoBackendManager { ...@@ -554,6 +554,17 @@ class DojoBackendManager {
public async getTeachers(): Promise<Array<User> | undefined> { public async getTeachers(): Promise<Array<User> | undefined> {
return this.getUsers('teacher'); return this.getUsers('teacher');
} }
public async getExerciseDetail(exerciseId: string): Promise<Exercise | undefined> {
try {
const response = await axios.get<Exercise>(DojoBackendHelper.getApiUrl(ApiRoute.EXERCISE_DETAIL).replace('{{exerciseId}}', String(exerciseId)));
return response.data;
} catch ( error ) {
console.error('Error fetching exercise details:', error);
return undefined;
}
}
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment