diff --git a/NodeApp/src/commander/assignment/subcommands/correction/AssignmentCorrectionCommand.ts b/NodeApp/src/commander/assignment/subcommands/correction/AssignmentCorrectionCommand.ts index 1ff39af42304fd623e842705375f9b445f1c2461..3eb929a078f49994e94e544dd6f381741da578f5 100644 --- a/NodeApp/src/commander/assignment/subcommands/correction/AssignmentCorrectionCommand.ts +++ b/NodeApp/src/commander/assignment/subcommands/correction/AssignmentCorrectionCommand.ts @@ -1,6 +1,7 @@ import CommanderCommand from '../../../CommanderCommand.js'; import AssignmentCorrectionLinkCommand from './subcommands/AssignmentCorrectionLinkCommand.js'; import AssignmentCorrectionUpdateCommand from './subcommands/AssignmentCorrectionUpdateCommand.js'; +import AssignmentCorrectionUnlinkCommand from './subcommands/AssignmentCorrectionUnlinkCommand.js'; class AssignmentCorrectionCommand extends CommanderCommand { @@ -14,6 +15,7 @@ class AssignmentCorrectionCommand extends CommanderCommand { protected defineSubCommands() { AssignmentCorrectionLinkCommand.registerOnCommand(this.command); AssignmentCorrectionUpdateCommand.registerOnCommand(this.command); + AssignmentCorrectionUnlinkCommand.registerOnCommand(this.command); } protected async commandAction(): Promise<void> { diff --git a/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkUpdateCommand.ts b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkUpdateCommand.ts index 230e0202ee9f69357574658b9a3b4a21a00297ca..cc790d2cd72ef1e395e7a24eae7e297ae4cf8056 100644 --- a/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkUpdateCommand.ts +++ b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionLinkUpdateCommand.ts @@ -14,12 +14,22 @@ abstract class AssignmentCorrectionLinkUpdateCommand extends CommanderCommand { .description(this.isUpdate ? 'update a correction of an assignment' : 'link an exercise repo as a correction for an assignment') .argument('<string>', 'id or url of the exercise that is the correction') .requiredOption('-a, --assignment <string>', 'id or url of the assignment of the correction') + .option('-c, --commit <string>', 'specific commit to link as correction (default: last commit)') + .option('-d, --description <string>', 'description of the correction (limited to 80 characters, default: empty)') .action(this.commandAction.bind(this)); } - protected async commandAction(exerciseIdOrUrl: string, options: { assignment: string }): Promise<void> { + protected async commandAction(exerciseIdOrUrl: string, options: { assignment: string, commit?: string, description?: string }): Promise<void> { let assignment!: Assignment | undefined; + // Check requirements + { + if ( options.description && options.description.length > 80 ) { + ora('Description is limited to 80 characters').start().fail(); + return; + } + } + // Check access { console.log(TextStyle.BLOCK('Please wait while we check access...')); @@ -53,7 +63,7 @@ abstract class AssignmentCorrectionLinkUpdateCommand extends CommanderCommand { { console.log(TextStyle.BLOCK('Please wait while we link the exercise...')); - await DojoBackendManager.linkUpdateCorrection(exerciseIdOrUrl, assignment, this.isUpdate); + await DojoBackendManager.linkUpdateCorrection(exerciseIdOrUrl, assignment, options.commit, options.description, this.isUpdate); } } } diff --git a/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionUnlinkCommand.ts b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionUnlinkCommand.ts new file mode 100644 index 0000000000000000000000000000000000000000..ceb10cd00f7c4e8cd042ee34df27cd24f5df48a9 --- /dev/null +++ b/NodeApp/src/commander/assignment/subcommands/correction/subcommands/AssignmentCorrectionUnlinkCommand.ts @@ -0,0 +1,54 @@ +import Assignment from '../../../../../sharedByClients/models/Assignment.js'; +import ora from 'ora'; +import TextStyle from '../../../../../types/TextStyle.js'; +import DojoBackendManager from '../../../../../managers/DojoBackendManager.js'; +import SessionManager from '../../../../../managers/SessionManager.js'; +import CommanderCommand from '../../../../CommanderCommand.js'; + + +class AssignmentCorrectionLinkCommand extends CommanderCommand { + protected commandName: string = 'unlink'; + + protected defineCommand() { + this.command + .description('remove a correction of an assignment') + .argument('<string>', 'id or url of the exercise that is the correction') + .requiredOption('-a, --assignment <string>', 'id or url of the assignment of the correction') + .action(this.commandAction.bind(this)); + } + + protected async commandAction(exerciseIdOrUrl: string, options: { assignment: string }): Promise<void> { + let assignment!: Assignment | undefined; + + // Check access + { + console.log(TextStyle.BLOCK('Please wait while we check access...')); + + const assignmentGetSpinner: ora.Ora = ora('Checking if assignment exists').start(); + assignment = await DojoBackendManager.getAssignment(options.assignment); + if ( !assignment ) { + assignmentGetSpinner.fail(`The assignment doesn't exists`); + return; + } + assignmentGetSpinner.succeed(`The assignment exists`); + + + const assignmentAccessSpinner: ora.Ora = ora('Checking assignment access').start(); + if ( assignment.staff.find(staff => staff.id === SessionManager.profile?.id) === undefined ) { + assignmentAccessSpinner.fail(`You are not in the staff of the assignment`); + return; + } + assignmentAccessSpinner.succeed(`You are in the staff of the assignment`); + } + + // Link the exercise + { + console.log(TextStyle.BLOCK('Please wait while we unlink the exercise...')); + + await DojoBackendManager.unlinkCorrection(exerciseIdOrUrl, assignment); + } + } +} + + +export default new AssignmentCorrectionLinkCommand(); \ No newline at end of file diff --git a/NodeApp/src/commander/exercise/subcommands/ExerciseCorrectionCommand.ts b/NodeApp/src/commander/exercise/subcommands/ExerciseCorrectionCommand.ts index 6dfddd1a4eed2f39a8ae2def689536d4b9275bdf..5e6310b214c162fa585584c4c3e46a61aab96595 100644 --- a/NodeApp/src/commander/exercise/subcommands/ExerciseCorrectionCommand.ts +++ b/NodeApp/src/commander/exercise/subcommands/ExerciseCorrectionCommand.ts @@ -39,8 +39,10 @@ class ExerciseCorrectionCommand extends CommanderCommand { private getCorrections(assignment: Assignment): Array<CorrectionResume> { return assignment.corrections.map(correction => { + const authors = correction.name.replace(correction.assignmentName, '').split('-')[2].trim(); + return { - name : correction.name.replace(correction.assignmentName, '').split('-')[2].trim(), + name : (correction.correctionDescription && correction.correctionDescription != '' ? `${ correction.correctionDescription } (${ authors })` : authors), value: correction.correctionCommit?.web_url?.replace('/commit/', '/tree/') ?? '' }; }); diff --git a/NodeApp/src/managers/DojoBackendManager.ts b/NodeApp/src/managers/DojoBackendManager.ts index 5a2f45bad5baba805663e6f7978c70d5711de1e3..8c8a5a9685c1ab1fb2cabbfc4740f2914b54beae 100644 --- a/NodeApp/src/managers/DojoBackendManager.ts +++ b/NodeApp/src/managers/DojoBackendManager.ts @@ -193,7 +193,7 @@ class DojoBackendManager { } } - public async linkUpdateCorrection(exerciseIdOrUrl: string, assignment: Assignment, isUpdate: boolean, verbose: boolean = true): Promise<boolean> { + public async linkUpdateCorrection(exerciseIdOrUrl: string, assignment: Assignment, commit: string | undefined, description: string | undefined, isUpdate: boolean, verbose: boolean = true): Promise<boolean> { const spinner: ora.Ora = ora(`${ isUpdate ? 'Updating' : 'Linking' } correction`); if ( verbose ) { @@ -202,13 +202,15 @@ class DojoBackendManager { try { const axiosFunction = isUpdate ? axios.patch.bind(axios) : axios.post.bind(axios); - const route = isUpdate ? ApiRoute.ASSIGNMENT_CORRECTION_UPDATE : ApiRoute.ASSIGNMENT_CORRECTION_LINK; + const route = isUpdate ? ApiRoute.ASSIGNMENT_CORRECTION_UPDATE_DELETE : ApiRoute.ASSIGNMENT_CORRECTION_LINK; await axiosFunction(DojoBackendHelper.getApiUrl(route, { assignmentNameOrUrl: assignment.name, exerciseIdOrUrl : exerciseIdOrUrl }), { - exerciseIdOrUrl: exerciseIdOrUrl + exerciseIdOrUrl: exerciseIdOrUrl, + commit : commit, + description : description }); if ( verbose ) { @@ -222,6 +224,31 @@ class DojoBackendManager { return false; } } + + public async unlinkCorrection(exerciseIdOrUrl: string, assignment: Assignment, verbose: boolean = true): Promise<boolean> { + const spinner: ora.Ora = ora(`Unlinking correction`); + + if ( verbose ) { + spinner.start(); + } + + try { + await axios.delete(DojoBackendHelper.getApiUrl(ApiRoute.ASSIGNMENT_CORRECTION_UPDATE_DELETE, { + assignmentNameOrUrl: assignment.name, + exerciseIdOrUrl : exerciseIdOrUrl + })); + + if ( verbose ) { + spinner.succeed(`Correction unlinked`); + } + + return true; + } catch ( error ) { + this.handleApiError(error, spinner, verbose, `Correction unlink error: ${ error }`); + + return false; + } + } } diff --git a/NodeApp/src/sharedByClients b/NodeApp/src/sharedByClients index 4011aa146ae4b808da599b8eb0cca2d36e82a52c..5bbb2606d4aecdd9d54d91ffdd53c87a2c983916 160000 --- a/NodeApp/src/sharedByClients +++ b/NodeApp/src/sharedByClients @@ -1 +1 @@ -Subproject commit 4011aa146ae4b808da599b8eb0cca2d36e82a52c +Subproject commit 5bbb2606d4aecdd9d54d91ffdd53c87a2c983916