diff --git a/frontend_v2/src/app/components/challenge/challenge.module.ts b/frontend_v2/src/app/components/challenge/challenge.module.ts index 0294ab3a50..2ef886e3c6 100644 --- a/frontend_v2/src/app/components/challenge/challenge.module.ts +++ b/frontend_v2/src/app/components/challenge/challenge.module.ts @@ -11,6 +11,7 @@ import { MatRadioModule, MatDialogModule, MatSliderModule, + MatTabsModule, } from '@angular/material'; // import components @@ -66,6 +67,7 @@ import { ChallengeanalyticsComponent } from './challengeanalytics/challengeanaly MatRadioModule, MatDialogModule, MatSliderModule, + MatTabsModule, ], exports: [ ChallengeComponent, diff --git a/frontend_v2/src/app/components/challenge/challengeleaderboard/challengeleaderboard.component.html b/frontend_v2/src/app/components/challenge/challengeleaderboard/challengeleaderboard.component.html index d8ab8bc653..30cd029661 100644 --- a/frontend_v2/src/app/components/challenge/challengeleaderboard/challengeleaderboard.component.html +++ b/frontend_v2/src/app/components/challenge/challengeleaderboard/challengeleaderboard.component.html @@ -20,7 +20,7 @@
Leaderboard
Challenge Settings
-
- -
-
- Edit challenge details -
-
-
-
-
- - + + + + +
+
+
+
+ + +
+
+ + Upload New Image +
+
+
+ + {{ challenge['title'] }} + + + + + + + +
+
+
+ + Challenge Overview + + + + +
+
+
+
+ + Terms and Conditions + + + + +
+
+ + + Starts on: + {{ challenge['start_date'] | date: 'medium' }} {{ challenge['start_zone'] }} + + + + + + +
+ + + Ends on: + {{ challenge['end_date'] | date: 'medium' }} {{ challenge['end_zone'] }} + + + + + + +
+ + + {{ publishChallenge.state }} + + + +
+ Close Participation + +
+
+
+ + +
+
+ Banned emails Ids: +
+
+ + + + {{ email }} + cancel + + + + +
{{ message }}
+
+ Update +
+
+
+
+
+ + + +
+
+ Edit Phase
-
- - Upload New Image +
+
+
+ +
+ +
+ + Phase Details + + + +      + + Is Public + + + +      + + Submission Visibility + + + + +
+ +
-
- - {{ challenge['title'] }} - - - - - - - -
-
-
- - Challenge Overview - - - - + +
+
+ Edit Leaderboard
-
-
-
- - Terms and Conditions - - - - +
+
+
+ + +
+
+
+ + Leaderboard Visibility + + + +      +
+
+
- - - Starts on: - {{ challenge['start_date'] | date: 'medium' }} {{ challenge['start_zone'] }} - - - - - - -
- - - Ends on: - {{ challenge['end_date'] | date: 'medium' }} {{ challenge['end_zone'] }} - - - - - - -
- - - {{ publishChallenge.state }} - - - -
- Close Participation - -
-
-
- - -
-
- Edit phase details -
-
-
-
-
- -
-
- - Phase Details - - - -      - - Is Public - - - -      - - Submission Visibility - - - - -
-
-
-
+ - -
-
- Edit leaderboard details -
-
-
-
-
- - + + + +
+
+
+
Evaluation script
+
+
+
+
+ + + Evaluation Criteria + + + +    + + + Evaluation Script + + + + +
+
-
-
- - Leaderboard Visibility - - - -      + +
+
+
+
Submission worker actions
+
+
+
+
+ + + +
+
+
+
+
Submission worker logs
+
+
+
+
{{ log }}
+
-
-
-
-
- - -
-
- Evaluation and Annotations -
-
-
-
- - - Evaluation Criteria - - - -    - - - Evaluation Script - - - - -
-
-
+ + -
-
- Banned emails Ids: -
-
- - - - {{ email }} - cancel - - - - -
{{ message }}
-
- Update -
-
-
-
-
-
-
Submission worker actions
-
-
-
-
- - - -
-
-
-
-
Submission worker logs
-
-
-
-
{{ log }}
-
-
+
diff --git a/frontend_v2/src/app/components/challenge/challengesettings/challengesettings.component.scss b/frontend_v2/src/app/components/challenge/challengesettings/challengesettings.component.scss index 543e84f175..1984bb61be 100644 --- a/frontend_v2/src/app/components/challenge/challengesettings/challengesettings.component.scss +++ b/frontend_v2/src/app/components/challenge/challengesettings/challengesettings.component.scss @@ -3,14 +3,31 @@ .challenge-card { .bottom-card-container { + padding: 0px 30px; .settings-section { - padding: 20px 30px; + padding: 50px; border: 1px solid; border-radius: 5px; min-height: 50px; color: rgb(101, 97, 97); } } + .row { + margin: 20px 0px 3% 0px; + } +} + +.row .col { + padding: 0px; +} + +input { + border-bottom: none; +} + +:host ::ng-deep .mat-tab-label .mat-tab-label-content{ + font-weight: $fw-light !important; + font-size: $fs-16 !important; } .phase-card { @@ -21,21 +38,29 @@ margin-left: 25px; } -@include screen-medium { +.worker-title { + margin-bottom: 2%; +} + +.upload-container { + text-align:center; +} + +@media (max-width: 992px) { .settings-section { - padding: 10px 20px !important; + padding: 50px !important; } } -@include screen-small-medium { - .settings-section { - padding: 10px 10px !important; +@media (min-width: 992px) { + .col-md-12 { + width: auto; } } -@include screen-small { +@media (max-width: 600px) { .settings-section { - padding: 10px 5px !important; + padding: 25px !important; } } @@ -48,7 +73,6 @@ } .challenge-detail { - margin-left: 25%; padding: 8px; } diff --git a/frontend_v2/src/app/components/challenge/challengesettings/challengesettings.component.ts b/frontend_v2/src/app/components/challenge/challengesettings/challengesettings.component.ts index 5f60443037..e4de5f05b1 100644 --- a/frontend_v2/src/app/components/challenge/challengesettings/challengesettings.component.ts +++ b/frontend_v2/src/app/components/challenge/challengesettings/challengesettings.component.ts @@ -30,6 +30,16 @@ export class ChallengesettingsComponent implements OnInit, OnDestroy { */ challenge: any; + /** + * Is challenge host + */ + isChallengeHost = false; + + /** + * To call the API inside modal for editing the challenge details + */ + apiCall: any; + /** * Challenge phase list */ @@ -50,21 +60,40 @@ export class ChallengesettingsComponent implements OnInit, OnDestroy { */ filteredPhaseSplits = []; + /** + * Currently selected phase + */ + selectedPhase: any = null; /** * Phase selection type (radio button or select box) */ phaseSelectionType = 'selectBox'; + /** + * Select box list type + */ + phaseSelectionListType = 'phase'; + /** - * Select box list type + * If the submission is public */ - phaseSelectionListType = 'phase'; + isSubmissionPublic : boolean = false; + + /** + * If the phase is public + */ + isPhasePublic : boolean = false; /** - * Currently selected phase + * If leaderboard is public */ - selectedPhase: any = null; + isLeaderboardPublic : boolean = false; + + /** + * Currently selected phase split + */ + selectedPhaseSplit: any = null; /** * Phase selection type (radio button or select box) @@ -77,9 +106,11 @@ export class ChallengesettingsComponent implements OnInit, OnDestroy { phaseLeaderboardSelectionListType = 'settingsPhaseSplit'; /** - * Currently selected phase split + * If leaderboard of phase split is public + * 1 -> private + * 3 -> public */ - selectedPhaseSplit: any = null; + isPhaseSplitLeaderboardPublic: number = 1; /** * store worker logs @@ -91,16 +122,6 @@ export class ChallengesettingsComponent implements OnInit, OnDestroy { */ pollingInterval: any; - /** - * Is challenge host - */ - isChallengeHost = false; - - /** - * To call the API inside modal for editing the challenge details - */ - apiCall: any; - /** * Participants banned emails ids */ @@ -120,28 +141,6 @@ export class ChallengesettingsComponent implements OnInit, OnDestroy { * Email error message */ message: string; - - /** - * If the submission is public - */ - isSubmissionPublic : boolean = false; - - /** - * If the phase is public - */ - isPhasePublic : boolean = false; - - /** - * If leaderboard is public - */ - isLeaderboardPublic : boolean = false; - - /** - * If leaderboard of phase split is public - * 1 -> private - * 3 -> public - */ - isPhaseSplitLeaderboardPublic: number = 1; /** * phase visibility state and it's icon @@ -207,6 +206,20 @@ export class ChallengesettingsComponent implements OnInit, OnDestroy { this.challenge = challenge; }); + this.challengeService.isChallengeHost.subscribe((status) => { + this.isChallengeHost = status; + }); + + this.challengeService.currentChallengePublishState.subscribe((publishChallenge) => { + this.publishChallenge.state = publishChallenge.state; + this.publishChallenge.icon = publishChallenge.icon; + }); + + if (!this.challenge["remote_evaluation"]) { + this.fetchWorkerLogs(); + this.startLoadingLogs(); + } + this.challengeService.currentPhases.subscribe((phases) => { this.phases = phases; for (let i = 0; i < this.phases.length; i++) { @@ -220,15 +233,6 @@ export class ChallengesettingsComponent implements OnInit, OnDestroy { this.filteredPhases = this.phases; }); - this.challengeService.isChallengeHost.subscribe((status) => { - this.isChallengeHost = status; - }); - - this.challengeService.currentChallengePublishState.subscribe((publishChallenge) => { - this.publishChallenge.state = publishChallenge.state; - this.publishChallenge.icon = publishChallenge.icon; - }); - this.challengeService.currentPhaseSplit.subscribe((phaseSplits) => { this.phaseSplits = phaseSplits; for (let i = 0; i < this.phaseSplits.length; i++) { @@ -241,298 +245,401 @@ export class ChallengesettingsComponent implements OnInit, OnDestroy { } this.filteredPhaseSplits = this.phaseSplits; }); - - if (!this.challenge["remote_evaluation"]) { - this.fetchWorkerLogs(); - this.startLoadingLogs(); - } } - updateView() { - this.bannedEmailIds = this.challenge.banned_email_ids || []; - this.formerBannedEmailIds = this.bannedEmailIds.concat(); // Creating deep copy - } + // Edit Challenge Details -> /** - * Add banned email chip - * @param event current event + * Edit challenge title function */ - add(event: MatChipInputEvent): void { + editChallengeTitle() { const SELF = this; - const input = event.input; - const value = event.value; - SELF.isValidationError = false; - SELF.message = ''; - // Add our fruit - if ((value || '').trim()) { - if (!SELF.validateEmail(value.trim())) { - SELF.isValidationError = true; - SELF.message = 'Please enter a valid email!'; - } else { - SELF.bannedEmailIds.push(value.trim()); - } - } + SELF.apiCall = (params) => { + const BODY = JSON.stringify(params); + SELF.apiService + .patchUrl(SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), BODY) + .subscribe( + (data) => { + SELF.challenge.title = data.title; + SELF.globalService.showToast('success', 'The challenge title is successfully updated!', 5); + }, + (err) => { + SELF.globalService.handleApiError(err, true); + SELF.globalService.showToast('error', err); + }, + () => {} + ); + }; - // Reset the input value - if (input && !SELF.isValidationError) { - input.value = ''; - } + const PARAMS = { + title: 'Edit Challenge Title', + content: '', + confirm: 'Submit', + deny: 'Cancel', + form: [ + { + name: 'editChallengeTitle', + isRequired: true, + label: 'title', + placeholder: 'Challenge Title', + type: 'text', + value: this.challenge.title, + }, + ], + confirmCallback: SELF.apiCall, + }; + SELF.globalService.showModal(PARAMS); } /** - * This is called when a phase split is selected (from child components) + * Delete challenge */ - phaseSplitSelected () { + deleteChallenge() { const SELF = this; - return (phaseSplit) => { - SELF.selectedPhaseSplit = phaseSplit; - SELF.isPhaseSplitLeaderboardPublic = SELF.selectedPhaseSplit['visibility']; - if(SELF.isPhaseSplitLeaderboardPublic == 3) { - SELF.leaderboardVisibility.state = 'Public'; - SELF.leaderboardVisibility.icon = 'fa fa-toggle-on green-text'; - } - else { - SELF.leaderboardVisibility.state = 'Private'; - SELF.leaderboardVisibility.icon = 'fa fa fa-toggle-off grey-text text-darken-1'; - } - } + const redirectTo = '/dashboard'; + + SELF.apiCall = () => { + const BODY = JSON.stringify({}); + SELF.apiService.postUrl(SELF.endpointsService.deleteChallengeURL(SELF.challenge.id), BODY).subscribe( + (data) => { + SELF.router.navigate([redirectTo]); + SELF.globalService.showToast('success', 'The Challenge is successfully deleted!', 5); + }, + (err) => { + SELF.globalService.handleApiError(err, true); + SELF.globalService.showToast('error', err); + }, + () => {} + ); + }; + + const PARAMS = { + title: 'Delete Challenge', + content: '', + confirm: 'I understand consequences, delete the challenge', + deny: 'Cancel', + form: [ + { + name: 'challegenDeleteInput', + isRequired: true, + label: '', + placeholder: 'Please type in the name of the challenge to confirm', + type: 'text', + value: '', + }, + ], + confirmCallback: SELF.apiCall, + }; + SELF.globalService.showModal(PARAMS); } /** - * Leadeboard Visibility toggle function + * Edit challenge image function */ - toggleLeaderboardVisibility() { + editChallengeImage() { const SELF = this; - let toggleLeaderboardVisibilityState, visibility; - if (SELF.leaderboardVisibility.state === 'Public') { - toggleLeaderboardVisibilityState = 'private'; - visibility = 1; - SELF.leaderboardVisibility.state = 'Private'; - SELF.leaderboardVisibility.icon = 'fa fa fa-toggle-off grey-text text-darken-1'; - } else { - toggleLeaderboardVisibilityState = 'public'; - visibility = 3; - SELF.leaderboardVisibility.state = 'Public'; - SELF.leaderboardVisibility.icon = 'fa fa-toggle-on green-text'; - } - const BODY: FormData = new FormData(); - BODY.append("visibility", visibility); + SELF.apiCall = (params) => { + const FORM_DATA: FormData = new FormData(); + FORM_DATA.append('image', params['image']); SELF.apiService - .patchFileUrl( - SELF.endpointsService.particularChallengePhaseSplitUrl(SELF.selectedPhaseSplit['id']), - BODY - ) + .patchFileUrl( + SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), + FORM_DATA + ) .subscribe( (data) => { - SELF.selectedPhaseSplit['visibility'] = data.visibility; - SELF.challengeService.changePhaseSplitSelected(true); - if (visibility == 3) { - SELF.selectedPhaseSplit['showPrivate'] = false; - SELF.leaderboardVisibility.state = 'Public'; - SELF.leaderboardVisibility.icon = 'fa fa-toggle-on green-text'; - } else { - SELF.selectedPhaseSplit['showPrivate'] = true; - SELF.leaderboardVisibility.state = 'Private'; - SELF.leaderboardVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; - } - SELF.globalService.showToast( - 'success', - 'The phase split was successfully made ' + toggleLeaderboardVisibilityState, - 5 - ); + SELF.challenge.image = data.image; + SELF.globalService.showToast('success', 'The Challenge image successfully updated!', 5); }, (err) => { SELF.globalService.handleApiError(err, true); SELF.globalService.showToast('error', err); - if (visibility == 3) { - SELF.leaderboardVisibility.state = 'Private'; - SELF.leaderboardVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; - } else { - SELF.leaderboardVisibility.state = 'Public'; - SELF.leaderboardVisibility.icon = 'fa fa-toggle-on green-text'; - } }, - () => this.logger.info('LEADERBOARD-VISIBILITY-UPDATE-FINISHED') + () => {} ); - } + }; - /** - * Called when a phase is selected (from child component) - */ - phaseSelected() { - const SELF = this; - return (phase) => { - SELF.selectedPhase = phase; - SELF.isPhasePublic = SELF.selectedPhase['is_public']; - SELF.isSubmissionPublic = SELF.selectedPhase['is_submission_public']; - SELF.isLeaderboardPublic = SELF.selectedPhase['leaderboard_public']; - if (SELF.isPhasePublic) { - SELF.phaseVisibility.state = 'Public'; - SELF.phaseVisibility.icon = 'fa fa-toggle-on green-text'; - } - else { - SELF.phaseVisibility.state = 'Private'; - SELF.phaseVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; - } - if (SELF.isSubmissionPublic) { - SELF.submissionVisibility.state = 'Public'; - SELF.submissionVisibility.icon = 'fa fa-toggle-on green-text'; - } - else { - SELF.submissionVisibility.state = 'Private'; - SELF.submissionVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; - } + /** + * Parameters of the modal + */ + const PARAMS = { + title: 'Edit Challenge Image', + content: '', + confirm: 'Submit', + deny: 'Cancel', + form: [ + { + name: 'Challenge Image', + isRequired: true, + label: 'image', + placeholder: '', + type: 'file', + value: '', + }, + ], + confirmCallback: SELF.apiCall, }; - } + SELF.globalService.showModal(PARAMS); + } - editPhaseDetails() { + /** + * Edit challenge overview function + */ + + editChallengeOverview() { const SELF = this; + SELF.apiCall = (params) => { - const FORM_DATA: FormData = new FormData(); - for (const key in params) { - if (params[key]) { - FORM_DATA.append(key, params[key]); - } - } + const BODY = JSON.stringify(params); SELF.apiService - .patchFileUrl( - SELF.endpointsService.updateChallengePhaseDetailsURL(SELF.challenge.id, SELF.selectedPhase['id']), - FORM_DATA - ) + .patchUrl(SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), BODY) .subscribe( (data) => { - for (var attrname in data) { - SELF.selectedPhase[attrname] = data[attrname]; - } - SELF.globalService.showToast('success', 'The challenge phase details are successfully updated!'); + SELF.challenge.description = data.description; + SELF.globalService.showToast('success', 'The description is successfully updated!', 5); }, (err) => { + SELF.globalService.handleApiError(err, true); SELF.globalService.showToast('error', err); }, - () => {this.logger.info('PHASE-UPDATE-FINISHED')} + () => this.logger.info('EDIT-CHALLENGE-DESCRIPTION-FINISHED') ); }; const PARAMS = { - title: 'Edit Challenge Phase Details', - name: SELF.selectedPhase['name'], + title: 'Edit Challenge Description', label: 'description', - description: SELF.selectedPhase['description'], - startDate: SELF.selectedPhase['start_date'], - endDate: SELF.selectedPhase['end_date'], - maxSubmissionsPerDay: SELF.selectedPhase['max_submissions_per_day'], - maxSubmissionsPerMonth: SELF.selectedPhase['max_submissions_per_month'], - maxSubmissions: SELF.selectedPhase['max_submissions'], - maxConcurrentSubmissionsAllowed: SELF.selectedPhase['max_concurrent_submissions_allowed'], - allowedSubmissionFileTypes: SELF.selectedPhase['allowed_submission_file_types'], + isEditorRequired: true, + editorContent: this.challenge.description, confirm: 'Submit', deny: 'Cancel', confirmCallback: SELF.apiCall, }; - SELF.globalService.showEditPhaseModal(PARAMS); -} + SELF.globalService.showModal(PARAMS); + } /** - * Phase Visibility toggle function + * Edit terms and conditions of the challenge */ - togglePhaseVisibility() { + editTermsAndConditions() { const SELF = this; - let togglePhaseVisibilityState, isPublic; - if (SELF.phaseVisibility.state === 'Public') { - togglePhaseVisibilityState = 'private'; - isPublic = false; - SELF.phaseVisibility.state = 'Private'; - SELF.phaseVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; - } else { - togglePhaseVisibilityState = 'public'; - isPublic = true; - SELF.phaseVisibility.state = 'Public'; - SELF.phaseVisibility.icon = 'fa fa-toggle-on green-text'; - } - const BODY: FormData = new FormData(); - BODY.append("is_public", isPublic); + SELF.apiCall = (params) => { + const BODY = JSON.stringify(params); SELF.apiService - .patchFileUrl( - SELF.endpointsService.updateChallengePhaseDetailsURL(SELF.selectedPhase['challenge'], SELF.selectedPhase['id']), - BODY - ) + .patchUrl(SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), BODY) .subscribe( (data) => { - SELF.selectedPhase['is_public'] = data.is_public; - SELF.selectedPhase['showPrivate'] = !data.is_public; - SELF.challengeService.changePhaseSelected(true); - SELF.globalService.showToast( - 'success', - 'The phase was successfully made ' + togglePhaseVisibilityState, - 5 - ); + SELF.challenge.terms_and_conditions = data.terms_and_conditions; + this.updateView(); + SELF.globalService.showToast('success', 'The terms and conditions are successfully updated!', 5); }, (err) => { SELF.globalService.handleApiError(err, true); SELF.globalService.showToast('error', err); - if (isPublic) { - SELF.phaseVisibility.state = 'Private'; - SELF.phaseVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; - } else { - SELF.phaseVisibility.state = 'Public'; - SELF.phaseVisibility.icon = 'fa fa-toggle-on green-text'; - } }, - () => this.logger.info('PHASE-VISIBILITY-UPDATE-FINISHED') + () => this.logger.info('EDIT-TERMS-AND-CONDITIONS-FINISHED') ); - } + }; + /** + * Parameters of the modal + */ + const PARAMS = { + title: 'Edit Terms And Conditions', + label: 'terms_and_conditions', + isEditorRequired: true, + editorContent: this.challenge.terms_and_conditions, + confirm: 'Submit', + deny: 'Cancel', + confirmCallback: SELF.apiCall, + }; + SELF.globalService.showModal(PARAMS); + } + /** - * Submission Visibility toggle function + * Edit challenge start and end date function */ - toggleSubmissionVisibility() { + challengeDateDialog() { const SELF = this; - if(SELF.isLeaderboardPublic == true) { - let toggleSubmissionVisibilityState, isSubmissionPublic; - if (SELF.submissionVisibility.state === 'Public') { - toggleSubmissionVisibilityState = 'private'; - isSubmissionPublic = false; - SELF.submissionVisibility.state = 'Private'; - SELF.submissionVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; - } else { - toggleSubmissionVisibilityState = 'public'; - isSubmissionPublic = true; - SELF.submissionVisibility.state = 'Public'; - SELF.submissionVisibility.icon = 'fa fa-toggle-on green-text'; - } - const BODY: FormData = new FormData(); - BODY.append("is_submission_public", isSubmissionPublic); + SELF.apiCall = (params) => { + if (new Date(params.start_date).valueOf() < new Date(params.end_date).valueOf()) { + const BODY = JSON.stringify({ + start_date: new Date(params.start_date).toISOString(), + end_date: new Date(params.end_date).toISOString(), + }); SELF.apiService - .patchFileUrl( - SELF.endpointsService.updateChallengePhaseDetailsURL(SELF.selectedPhase['challenge'], SELF.selectedPhase['id']), - BODY - ) + .patchUrl(SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), BODY) .subscribe( (data) => { - SELF.selectedPhase['is_submission_public'] = data.is_submission_public; - SELF.globalService.showToast( - 'success', - 'The submissions were successfully made ' + toggleSubmissionVisibilityState, - 5 - ); + SELF.challenge.start_date = data.start_date; + SELF.challenge.end_date = data.end_date; + SELF.globalService.showToast('success', 'The Challenge start and end date successfully updated!', 5); }, (err) => { SELF.globalService.handleApiError(err, true); SELF.globalService.showToast('error', err); - if (isSubmissionPublic) { - SELF.submissionVisibility.state = 'Private'; - SELF.submissionVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; + }, + () => {} + ); + } else { + SELF.globalService.showToast('error', 'The challenge start date cannot be same or greater than end date.', 5); + } + }; + const PARAMS = { + title: 'Edit Challenge Start and End Date', + content: '', + confirm: 'Confirm', + deny: 'Cancel', + form: [ + { + isRequired: false, + label: 'start_date', + placeholder: 'Start Date and Time', + type: 'text', + value: moment(this.challenge.start_date).format('MM-DD-YYYY hh:mm a'), + }, + { + isRequired: false, + label: 'end_date', + placeholder: 'End Date and Time', + type: 'text', + value: moment(this.challenge.end_date).format('MM-DD-YYYY hh:mm a'), + }, + ], + isButtonDisabled: true, + confirmCallback: SELF.apiCall, + }; + SELF.globalService.showModal(PARAMS); + } + + /** + * Publish challenge click function + */ + togglePublishChallengeState() { + const SELF = this; + let toggleChallengePublishState, isPublished; + if (this.publishChallenge.state === 'Published') { + toggleChallengePublishState = 'private'; + isPublished = false; + } else { + toggleChallengePublishState = 'public'; + isPublished = true; + } + SELF.apiCall = () => { + const BODY = JSON.stringify({ + published: isPublished, + }); + SELF.apiService + .patchUrl(SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), BODY) + .subscribe( + (data) => { + if (isPublished) { + this.publishChallenge.state = 'Published'; + this.publishChallenge.icon = 'fa fa-eye green-text'; + } else { + this.publishChallenge.state = 'Not Published'; + this.publishChallenge.icon = 'fa fa-eye-slash red-text'; + } + SELF.globalService.showToast( + 'success', + 'The challenge was successfully made ' + toggleChallengePublishState, + 5 + ); + }, + (err) => { + SELF.globalService.handleApiError(err, true); + SELF.globalService.showToast('error', err); + }, + () => this.logger.info('PUBLISH-CHALLENGE-UPDATE-FINISHED') + ); + }; + + const PARAMS = { + title: 'Make this challenge ' + toggleChallengePublishState + '?', + content: '', + confirm: "Yes, I'm sure", + deny: 'No', + confirmCallback: SELF.apiCall, + }; + SELF.globalService.showConfirm(PARAMS); + } + + /** + * Close participation function + */ + stopParticipation(event) { + event.preventDefault(); + const participationState = this.challenge['is_registration_open'] ? 'Close' : 'Open'; + const closeParticipationMsg = 'Participation is closed successfully'; + const openParticipationMsg = 'Participation is opened successfully'; + + this.apiCall = () => { + if (this.isChallengeHost && this.challenge['id'] !== null) { + const BODY = JSON.stringify({ + is_registration_open: !this.challenge['is_registration_open'], + }); + this.apiService + .patchUrl(this.endpointsService.editChallengeDetailsURL(this.challenge.creator.id, this.challenge.id), BODY) + .subscribe( + () => { + this.challenge['is_registration_open'] = !this.challenge['is_registration_open']; + if (this.challenge['is_registration_open']) { + this.globalService.showToast('success', openParticipationMsg, 5); } else { - SELF.submissionVisibility.state = 'Public'; - SELF.submissionVisibility.icon = 'fa fa-toggle-on green-text'; + this.globalService.showToast('success', closeParticipationMsg, 5); } }, - () => this.logger.info('SUBMISSION-VISIBILITY-UPDATE-FINISHED') + (err) => { + this.globalService.handleApiError(err, true); + this.globalService.showToast('error', err); + }, + () => {} ); + } + }; + + const PARAMS = { + title: participationState + ' participation in the challenge?', + content: '', + confirm: "Yes, I'm sure", + deny: 'No', + confirmCallback: this.apiCall, + }; + this.globalService.showConfirm(PARAMS); + } + + // Banned Email Ids -> + + updateView() { + this.bannedEmailIds = this.challenge.banned_email_ids || []; + this.formerBannedEmailIds = this.bannedEmailIds.concat(); // Creating deep copy + } + + /** + * Add banned email chip + * @param event current event + */ + add(event: MatChipInputEvent): void { + const SELF = this; + const input = event.input; + const value = event.value; + SELF.isValidationError = false; + SELF.message = ''; + + // Add our fruit + if ((value || '').trim()) { + if (!SELF.validateEmail(value.trim())) { + SELF.isValidationError = true; + SELF.message = 'Please enter a valid email!'; + } else { + SELF.bannedEmailIds.push(value.trim()); + } } - else { - SELF.globalService.showToast('error', "Leaderboard is private, please make the leaderbaord public"); + + // Reset the input value + if (input && !SELF.isValidationError) { + input.value = ''; } } @@ -592,230 +699,309 @@ export class ChallengesettingsComponent implements OnInit, OnDestroy { ); } + // Edit Phase Details -> + /** - * Close participation function + * Called when a phase is selected (from child component) */ - stopParticipation(event) { - event.preventDefault(); - const participationState = this.challenge['is_registration_open'] ? 'Close' : 'Open'; - const closeParticipationMsg = 'Participation is closed successfully'; - const openParticipationMsg = 'Participation is opened successfully'; - - this.apiCall = () => { - if (this.isChallengeHost && this.challenge['id'] !== null) { - const BODY = JSON.stringify({ - is_registration_open: !this.challenge['is_registration_open'], - }); - this.apiService - .patchUrl(this.endpointsService.editChallengeDetailsURL(this.challenge.creator.id, this.challenge.id), BODY) - .subscribe( - () => { - this.challenge['is_registration_open'] = !this.challenge['is_registration_open']; - if (this.challenge['is_registration_open']) { - this.globalService.showToast('success', openParticipationMsg, 5); - } else { - this.globalService.showToast('success', closeParticipationMsg, 5); - } - }, - (err) => { - this.globalService.handleApiError(err, true); - this.globalService.showToast('error', err); - }, - () => {} - ); + phaseSelected() { + const SELF = this; + return (phase) => { + SELF.selectedPhase = phase; + SELF.isPhasePublic = SELF.selectedPhase['is_public']; + SELF.isSubmissionPublic = SELF.selectedPhase['is_submission_public']; + SELF.isLeaderboardPublic = SELF.selectedPhase['leaderboard_public']; + if (SELF.isPhasePublic) { + SELF.phaseVisibility.state = 'Public'; + SELF.phaseVisibility.icon = 'fa fa-toggle-on green-text'; + } + else { + SELF.phaseVisibility.state = 'Private'; + SELF.phaseVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; + } + if (SELF.isSubmissionPublic) { + SELF.submissionVisibility.state = 'Public'; + SELF.submissionVisibility.icon = 'fa fa-toggle-on green-text'; + } + else { + SELF.submissionVisibility.state = 'Private'; + SELF.submissionVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; } }; - - const PARAMS = { - title: participationState + ' participation in the challenge?', - content: '', - confirm: "Yes, I'm sure", - deny: 'No', - confirmCallback: this.apiCall, - }; - this.globalService.showConfirm(PARAMS); - } + } /** - * Edit challenge title function + * Edit Phase Details function */ - editChallengeTitle() { + editPhaseDetails() { const SELF = this; - SELF.apiCall = (params) => { - const BODY = JSON.stringify(params); + const FORM_DATA: FormData = new FormData(); + for (const key in params) { + if (params[key]) { + FORM_DATA.append(key, params[key]); + } + } SELF.apiService - .patchUrl(SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), BODY) + .patchFileUrl( + SELF.endpointsService.updateChallengePhaseDetailsURL(SELF.challenge.id, SELF.selectedPhase['id']), + FORM_DATA + ) .subscribe( (data) => { - SELF.challenge.title = data.title; - SELF.globalService.showToast('success', 'The challenge title is successfully updated!', 5); + for (var attrname in data) { + SELF.selectedPhase[attrname] = data[attrname]; + } + SELF.globalService.showToast('success', 'The challenge phase details are successfully updated!'); }, (err) => { - SELF.globalService.handleApiError(err, true); SELF.globalService.showToast('error', err); }, - () => {} + () => {this.logger.info('PHASE-UPDATE-FINISHED')} ); }; const PARAMS = { - title: 'Edit Challenge Title', - content: '', + title: 'Edit Challenge Phase Details', + name: SELF.selectedPhase['name'], + label: 'description', + description: SELF.selectedPhase['description'], + startDate: SELF.selectedPhase['start_date'], + endDate: SELF.selectedPhase['end_date'], + maxSubmissionsPerDay: SELF.selectedPhase['max_submissions_per_day'], + maxSubmissionsPerMonth: SELF.selectedPhase['max_submissions_per_month'], + maxSubmissions: SELF.selectedPhase['max_submissions'], + maxConcurrentSubmissionsAllowed: SELF.selectedPhase['max_concurrent_submissions_allowed'], + allowedSubmissionFileTypes: SELF.selectedPhase['allowed_submission_file_types'], confirm: 'Submit', deny: 'Cancel', - form: [ - { - name: 'editChallengeTitle', - isRequired: true, - label: 'title', - placeholder: 'Challenge Title', - type: 'text', - value: this.challenge.title, - }, - ], confirmCallback: SELF.apiCall, }; - SELF.globalService.showModal(PARAMS); - } + SELF.globalService.showEditPhaseModal(PARAMS); +} /** - * Edit terms and conditions of the challenge + * Phase Visibility toggle function */ - editTermsAndConditions() { + togglePhaseVisibility() { const SELF = this; - SELF.apiCall = (params) => { - const BODY = JSON.stringify(params); + let togglePhaseVisibilityState, isPublic; + if (SELF.phaseVisibility.state === 'Public') { + togglePhaseVisibilityState = 'private'; + isPublic = false; + SELF.phaseVisibility.state = 'Private'; + SELF.phaseVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; + } else { + togglePhaseVisibilityState = 'public'; + isPublic = true; + SELF.phaseVisibility.state = 'Public'; + SELF.phaseVisibility.icon = 'fa fa-toggle-on green-text'; + } + const BODY: FormData = new FormData(); + BODY.append("is_public", isPublic); SELF.apiService - .patchUrl(SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), BODY) + .patchFileUrl( + SELF.endpointsService.updateChallengePhaseDetailsURL(SELF.selectedPhase['challenge'], SELF.selectedPhase['id']), + BODY + ) .subscribe( (data) => { - SELF.challenge.terms_and_conditions = data.terms_and_conditions; - this.updateView(); - SELF.globalService.showToast('success', 'The terms and conditions are successfully updated!', 5); + SELF.selectedPhase['is_public'] = data.is_public; + SELF.selectedPhase['showPrivate'] = !data.is_public; + SELF.challengeService.changePhaseSelected(true); + if(!SELF.selectedPhase['is_public']) { + for(let i = 0; i < SELF.phaseSplits.length; i++) { + if(SELF.phaseSplits[i]['challenge_phase_name'] === SELF.selectedPhase['name'] && SELF.phaseSplits[i]['visibility'] == 3) { + let visibility: any = 1; + const BODY: FormData = new FormData(); + BODY.append("visibility", visibility); + SELF.apiService + .patchFileUrl( + SELF.endpointsService.particularChallengePhaseSplitUrl(SELF.phaseSplits[i]['id']), + BODY + ) + .subscribe( + (data) => { + SELF.phaseSplits[i]['visibility'] = data.visibility; + SELF.challengeService.changePhaseSplitSelected(true); + SELF.phaseSplits[i]['showPrivate'] = true; + if(SELF.selectedPhaseSplit === SELF.phaseSplits[i]) { + SELF.leaderboardVisibility.state = 'Private'; + SELF.leaderboardVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; + } + }, + (err) => { + SELF.globalService.handleApiError(err, true); + SELF.globalService.showToast('error', err); + }, + () => this.logger.info('Change leaderboard visibility after phase is updated') + ); + } + } + } + + SELF.globalService.showToast( + 'success', + 'The phase was successfully made ' + togglePhaseVisibilityState, + 5 + ); }, (err) => { SELF.globalService.handleApiError(err, true); SELF.globalService.showToast('error', err); + if (isPublic) { + SELF.phaseVisibility.state = 'Private'; + SELF.phaseVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; + } else { + SELF.phaseVisibility.state = 'Public'; + SELF.phaseVisibility.icon = 'fa fa-toggle-on green-text'; + } }, - () => this.logger.info('EDIT-TERMS-AND-CONDITIONS-FINISHED') + () => this.logger.info('PHASE-VISIBILITY-UPDATE-FINISHED') ); - }; - - /** - * Parameters of the modal - */ - const PARAMS = { - title: 'Edit Terms And Conditions', - label: 'terms_and_conditions', - isEditorRequired: true, - editorContent: this.challenge.terms_and_conditions, - confirm: 'Submit', - deny: 'Cancel', - confirmCallback: SELF.apiCall, - }; - SELF.globalService.showModal(PARAMS); - } - - - /** - * Delete challenge - */ - deleteChallenge() { - const SELF = this; - const redirectTo = '/dashboard'; - - SELF.apiCall = () => { - const BODY = JSON.stringify({}); - SELF.apiService.postUrl(SELF.endpointsService.deleteChallengeURL(SELF.challenge.id), BODY).subscribe( - (data) => { - SELF.router.navigate([redirectTo]); - SELF.globalService.showToast('success', 'The Challenge is successfully deleted!', 5); - }, - (err) => { - SELF.globalService.handleApiError(err, true); - SELF.globalService.showToast('error', err); - }, - () => {} - ); - }; - - const PARAMS = { - title: 'Delete Challenge', - content: '', - confirm: 'I understand consequences, delete the challenge', - deny: 'Cancel', - form: [ - { - name: 'challegenDeleteInput', - isRequired: true, - label: '', - placeholder: 'Please type in the name of the challenge to confirm', - type: 'text', - value: '', - }, - ], - confirmCallback: SELF.apiCall, - }; - SELF.globalService.showModal(PARAMS); } /** - * Edit challenge start and end date function + * Submission Visibility toggle function */ - challengeDateDialog() { - const SELF = this; - SELF.apiCall = (params) => { - if (new Date(params.start_date).valueOf() < new Date(params.end_date).valueOf()) { - const BODY = JSON.stringify({ - start_date: new Date(params.start_date).toISOString(), - end_date: new Date(params.end_date).toISOString(), - }); + toggleSubmissionVisibility() { + const SELF = this; + if(SELF.isLeaderboardPublic == true) { + let toggleSubmissionVisibilityState, isSubmissionPublic; + if (SELF.submissionVisibility.state === 'Public') { + toggleSubmissionVisibilityState = 'private'; + isSubmissionPublic = false; + SELF.submissionVisibility.state = 'Private'; + SELF.submissionVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; + } else { + toggleSubmissionVisibilityState = 'public'; + isSubmissionPublic = true; + SELF.submissionVisibility.state = 'Public'; + SELF.submissionVisibility.icon = 'fa fa-toggle-on green-text'; + } + const BODY: FormData = new FormData(); + BODY.append("is_submission_public", isSubmissionPublic); SELF.apiService - .patchUrl(SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), BODY) + .patchFileUrl( + SELF.endpointsService.updateChallengePhaseDetailsURL(SELF.selectedPhase['challenge'], SELF.selectedPhase['id']), + BODY + ) .subscribe( (data) => { - SELF.challenge.start_date = data.start_date; - SELF.challenge.end_date = data.end_date; - SELF.globalService.showToast('success', 'The Challenge start and end date successfully updated!', 5); + SELF.selectedPhase['is_submission_public'] = data.is_submission_public; + SELF.globalService.showToast( + 'success', + 'The submissions were successfully made ' + toggleSubmissionVisibilityState, + 5 + ); }, (err) => { SELF.globalService.handleApiError(err, true); SELF.globalService.showToast('error', err); + if (isSubmissionPublic) { + SELF.submissionVisibility.state = 'Private'; + SELF.submissionVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; + } else { + SELF.submissionVisibility.state = 'Public'; + SELF.submissionVisibility.icon = 'fa fa-toggle-on green-text'; + } }, - () => {} + () => this.logger.info('SUBMISSION-VISIBILITY-UPDATE-FINISHED') ); + } + else { + SELF.globalService.showToast('error', "Leaderboard is private, please make the leaderbaord public"); + } + } + + // Edit Leaderboard Details -> + + /** + * This is called when a phase split is selected (from child components) + */ + phaseSplitSelected () { + const SELF = this; + return (phaseSplit) => { + SELF.selectedPhaseSplit = phaseSplit; + SELF.isPhaseSplitLeaderboardPublic = SELF.selectedPhaseSplit['visibility']; + if(SELF.isPhaseSplitLeaderboardPublic == 3) { + SELF.leaderboardVisibility.state = 'Public'; + SELF.leaderboardVisibility.icon = 'fa fa-toggle-on green-text'; + } + else { + SELF.leaderboardVisibility.state = 'Private'; + SELF.leaderboardVisibility.icon = 'fa fa fa-toggle-off grey-text text-darken-1'; + } + } + } + + /** + * Leadeboard Visibility toggle function + */ + toggleLeaderboardVisibility() { + const SELF = this; + let toggleLeaderboardVisibilityState, visibility, phaseIsPublic; + for(let i = 0; i < SELF.filteredPhases.length; i++) { + if(SELF.filteredPhases[i]['name'] === SELF.selectedPhaseSplit['challenge_phase_name']) { + phaseIsPublic = SELF.filteredPhases[i]['is_public']; + } + } + if(phaseIsPublic) { + if (SELF.leaderboardVisibility.state === 'Public') { + toggleLeaderboardVisibilityState = 'private'; + visibility = 1; + SELF.leaderboardVisibility.state = 'Private'; + SELF.leaderboardVisibility.icon = 'fa fa fa-toggle-off grey-text text-darken-1'; } else { - SELF.globalService.showToast('error', 'The challenge start date cannot be same or greater than end date.', 5); + toggleLeaderboardVisibilityState = 'public'; + visibility = 3; + SELF.leaderboardVisibility.state = 'Public'; + SELF.leaderboardVisibility.icon = 'fa fa-toggle-on green-text'; } - }; - const PARAMS = { - title: 'Edit Challenge Start and End Date', - content: '', - confirm: 'Confirm', - deny: 'Cancel', - form: [ - { - isRequired: false, - label: 'start_date', - placeholder: 'Start Date and Time', - type: 'text', - value: moment(this.challenge.start_date).format('MM-DD-YYYY hh:mm a'), + const BODY: FormData = new FormData(); + BODY.append("visibility", visibility); + SELF.apiService + .patchFileUrl(SELF.endpointsService.particularChallengePhaseSplitUrl(SELF.selectedPhaseSplit['id']),BODY) + .subscribe( + (data) => { + SELF.selectedPhaseSplit['visibility'] = data.visibility; + SELF.challengeService.changePhaseSplitSelected(true); + if (visibility == 3) { + SELF.selectedPhaseSplit['showPrivate'] = false; + SELF.leaderboardVisibility.state = 'Public'; + SELF.leaderboardVisibility.icon = 'fa fa-toggle-on green-text'; + } else { + SELF.selectedPhaseSplit['showPrivate'] = true; + SELF.leaderboardVisibility.state = 'Private'; + SELF.leaderboardVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; + } + SELF.globalService.showToast( + 'success', + 'The phase split was successfully made ' + toggleLeaderboardVisibilityState, + 5 + ); }, - { - isRequired: false, - label: 'end_date', - placeholder: 'End Date and Time', - type: 'text', - value: moment(this.challenge.end_date).format('MM-DD-YYYY hh:mm a'), + (err) => { + SELF.globalService.handleApiError(err, true); + SELF.globalService.showToast('error', err); + if (visibility == 3) { + SELF.leaderboardVisibility.state = 'Private'; + SELF.leaderboardVisibility.icon = 'fa fa-toggle-off grey-text text-darken-1'; + } else { + SELF.leaderboardVisibility.state = 'Public'; + SELF.leaderboardVisibility.icon = 'fa fa-toggle-on green-text'; + } }, - ], - isButtonDisabled: true, - confirmCallback: SELF.apiCall, - }; - SELF.globalService.showModal(PARAMS); + () => this.logger.info('LEADERBOARD-VISIBILITY-UPDATE-FINISHED') + ); + } + else { + SELF.globalService.showToast('error', 'The phase is private, please make the phase public'); + } } + // Edit Evaluation Script and Criteria -> + /** * Edit evaluation criteria of the challenge */ @@ -900,90 +1086,7 @@ export class ChallengesettingsComponent implements OnInit, OnDestroy { SELF.globalService.showModal(PARAMS); } - /** - * Edit challenge image function - */ - editChallengeImage() { - const SELF = this; - SELF.apiCall = (params) => { - const FORM_DATA: FormData = new FormData(); - FORM_DATA.append('image', params['image']); - SELF.apiService - .patchFileUrl( - SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), - FORM_DATA - ) - .subscribe( - (data) => { - SELF.challenge.image = data.image; - SELF.globalService.showToast('success', 'The Challenge image successfully updated!', 5); - }, - (err) => { - SELF.globalService.handleApiError(err, true); - SELF.globalService.showToast('error', err); - }, - () => {} - ); - }; - - /** - * Parameters of the modal - */ - const PARAMS = { - title: 'Edit Challenge Image', - content: '', - confirm: 'Submit', - deny: 'Cancel', - form: [ - { - name: 'Challenge Image', - isRequired: true, - label: 'image', - placeholder: '', - type: 'file', - value: '', - }, - ], - confirmCallback: SELF.apiCall, - }; - SELF.globalService.showModal(PARAMS); - } - - /** - * Edit challenge overview function - */ - - editChallengeOverview() { - const SELF = this; - - SELF.apiCall = (params) => { - const BODY = JSON.stringify(params); - SELF.apiService - .patchUrl(SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), BODY) - .subscribe( - (data) => { - SELF.challenge.description = data.description; - SELF.globalService.showToast('success', 'The description is successfully updated!', 5); - }, - (err) => { - SELF.globalService.handleApiError(err, true); - SELF.globalService.showToast('error', err); - }, - () => this.logger.info('EDIT-CHALLENGE-DESCRIPTION-FINISHED') - ); - }; - - const PARAMS = { - title: 'Edit Challenge Description', - label: 'description', - isEditorRequired: true, - editorContent: this.challenge.description, - confirm: 'Submit', - deny: 'Cancel', - confirmCallback: SELF.apiCall, - }; - SELF.globalService.showModal(PARAMS); - } + // Worker logs -> /** * API call to manage the worker from UI. @@ -1035,61 +1138,12 @@ export class ChallengesettingsComponent implements OnInit, OnDestroy { SELF.fetchWorkerLogs(); }, 5000); } - - ngOnDestroy() { - clearInterval(this.pollingInterval); - } - + /** - * Publish challenge click function + * Component on destroyed. */ - togglePublishChallengeState() { - const SELF = this; - let toggleChallengePublishState, isPublished; - if (this.publishChallenge.state === 'Published') { - toggleChallengePublishState = 'private'; - isPublished = false; - } else { - toggleChallengePublishState = 'public'; - isPublished = true; - } - SELF.apiCall = () => { - const BODY = JSON.stringify({ - published: isPublished, - }); - SELF.apiService - .patchUrl(SELF.endpointsService.editChallengeDetailsURL(SELF.challenge.creator.id, SELF.challenge.id), BODY) - .subscribe( - (data) => { - if (isPublished) { - this.publishChallenge.state = 'Published'; - this.publishChallenge.icon = 'fa fa-eye green-text'; - } else { - this.publishChallenge.state = 'Not Published'; - this.publishChallenge.icon = 'fa fa-eye-slash red-text'; - } - SELF.globalService.showToast( - 'success', - 'The challenge was successfully made ' + toggleChallengePublishState, - 5 - ); - }, - (err) => { - SELF.globalService.handleApiError(err, true); - SELF.globalService.showToast('error', err); - }, - () => this.logger.info('PUBLISH-CHALLENGE-UPDATE-FINISHED') - ); - }; - - const PARAMS = { - title: 'Make this challenge ' + toggleChallengePublishState + '?', - content: '', - confirm: "Yes, I'm sure", - deny: 'No', - confirmCallback: SELF.apiCall, - }; - SELF.globalService.showConfirm(PARAMS); + ngOnDestroy() { + clearInterval(this.pollingInterval); } } diff --git a/frontend_v2/src/app/components/challenge/challengesubmit/challengesubmit.component.ts b/frontend_v2/src/app/components/challenge/challengesubmit/challengesubmit.component.ts index f18cfb5697..f3cc067088 100644 --- a/frontend_v2/src/app/components/challenge/challengesubmit/challengesubmit.component.ts +++ b/frontend_v2/src/app/components/challenge/challengesubmit/challengesubmit.component.ts @@ -38,6 +38,11 @@ export class ChallengesubmitComponent implements OnInit { */ isSubmissionUsingCli: any; + /** + * If phase has been selected + */ + isPhaseSelected:boolean = false; + /** * Is user logged in */ @@ -476,16 +481,19 @@ export class ChallengesubmitComponent implements OnInit { const SELF = this; return (phase) => { SELF.selectedPhase = phase; + SELF.isPhaseSelected = true; SELF.isLeaderboardPublic = phase['leaderboard_public']; if (SELF.challenge['id'] && phase['id']) { SELF.getMetaDataDetails(SELF.challenge['id'], phase['id']); SELF.fetchRemainingSubmissions(SELF.challenge['id'], phase['id']); SELF.clearMetaAttributeValues(); SELF.submissionError = ''; - SELF.components['_results'].forEach((element) => { - element.value = ''; - element.message = ''; - }); + if(SELF.components) { + SELF.components['_results'].forEach((element) => { + element.value = ''; + element.message = ''; + }); + } } }; } diff --git a/frontend_v2/src/app/components/utility/selectphase/selectphase.component.html b/frontend_v2/src/app/components/utility/selectphase/selectphase.component.html index cdeb130a9f..74845ecbd2 100644 --- a/frontend_v2/src/app/components/utility/selectphase/selectphase.component.html +++ b/frontend_v2/src/app/components/utility/selectphase/selectphase.component.html @@ -3,6 +3,7 @@ Select phase - + - {{ phaseName }} + {{ phaseName }} - + Private @@ -64,13 +65,13 @@ Select Phase Split - + Phase: {{ phaseName }}, Split:  {{ settingsSplitName }}   - + Private @@ -78,7 +79,7 @@ - + Phase:{{ key.challenge_phase_name }}, Split: {{ key.dataset_split_name }}   @@ -102,13 +103,13 @@ Phase: {{ phaseName }}, Split:  {{ splitName }}   - + Private - + Phase:{{ key.challenge_phase_name }}, Split: {{ key.dataset_split_name }}   diff --git a/frontend_v2/src/app/components/utility/selectphase/selectphase.component.scss b/frontend_v2/src/app/components/utility/selectphase/selectphase.component.scss index 142e73be80..7728cd91b2 100644 --- a/frontend_v2/src/app/components/utility/selectphase/selectphase.component.scss +++ b/frontend_v2/src/app/components/utility/selectphase/selectphase.component.scss @@ -28,6 +28,17 @@ padding-right: 0px; } +@media (max-width: 400px) { + .mat-form-field { + margin-right: 40px; + display: block; + } + .col-xs-12 { + padding-bottom: 5px; + width: 80%; + } +} + ::ng-deep .mat-select-placeholder { padding-bottom: 10px; } diff --git a/frontend_v2/src/app/components/utility/selectphase/selectphase.component.ts b/frontend_v2/src/app/components/utility/selectphase/selectphase.component.ts index 199d60bc11..0936782f59 100644 --- a/frontend_v2/src/app/components/utility/selectphase/selectphase.component.ts +++ b/frontend_v2/src/app/components/utility/selectphase/selectphase.component.ts @@ -16,6 +16,16 @@ export class SelectphaseComponent implements OnInit, OnChanges { */ @Input() phases: any; + /** + * Phase Splits list for settings tab + */ + @Input() settingsPhaseSplits: any; + + /** + * Phase Splits list + */ + @Input() phaseSplits: any; + /** * Selected phase callback */ @@ -86,6 +96,11 @@ export class SelectphaseComponent implements OnInit, OnChanges { */ challenge: any; + /** + * Select default radio option if same as phase id + */ + radioSelected: number; + /** * Constructor. * @param globalService GlobalService Injection. @@ -100,6 +115,20 @@ export class SelectphaseComponent implements OnInit, OnChanges { this.challengeService.currentChallenge.subscribe((challenge) => { this.challenge = challenge; }); + + if(Array.isArray(this.phases) && this.phases.length) { + this.selectedPhase = this.phases[0]; + this.radioSelected = this.phases[0].id; + this.selectPhase(this.phases[0]); + } + else if(Array.isArray(this.settingsPhaseSplits) && this.settingsPhaseSplits.length) { + this.selectedPhaseSplit = this.settingsPhaseSplits[0]; + this.selectSettingsPhaseSplit(this.settingsPhaseSplits[0], "selectBox", "settingsPhaseSplit"); + } + else if(Array.isArray(this.phaseSplits) && this.phaseSplits.length) { + this.selectedPhaseSplit = this.phaseSplits[0]; + this.selectPhaseSplit(this.phaseSplits[0], "selectBox", "phaseSplit"); + } } /**