Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Development: Extract client duplicates into re-usable components #7242

Merged
merged 25 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8085b10
Refactor reuse of working time control and entity name confirmation
aplr Sep 21, 2023
840303b
Replace confirm component in reset-repo-button
aplr Sep 21, 2023
5a56ca3
Fix tests
aplr Sep 22, 2023
30b0e16
Fix tests
aplr Sep 22, 2023
9eb86e8
Add tests for ConfirmEntityNameComponent
aplr Sep 22, 2023
9bb23dd
Fix exam duration change translations
aplr Sep 25, 2023
4195e4a
Merge branch 'develop' into refactor/reuse-client-components
aplr Sep 26, 2023
6932a91
Merge branch 'develop' into refactor/reuse-client-components
aplr Sep 29, 2023
2c20f1b
Merge branch 'develop' into refactor/reuse-client-components
aplr Oct 6, 2023
1c54ae1
Fix data export confirmation dialog tests
aplr Oct 6, 2023
225eb91
Merge branch 'develop' into refactor/reuse-client-components
aplr Oct 10, 2023
81f09ae
Merge commit '4b8bd1511fd1c730fb9a3ae059ac0c2946d6db3e' into refactor…
aplr Oct 15, 2023
e1a9a63
Fix tests
aplr Oct 15, 2023
01d2b7e
Fix tests
aplr Oct 15, 2023
89b75da
Fix tests
aplr Oct 15, 2023
5581fcd
Remove local cypress config from git
aplr Oct 15, 2023
7c3e3d1
Merge commit '60927d04683d23e5e3f76c78efc14defa5d12bed' into refactor…
aplr Oct 15, 2023
0ed34fe
Fix cypress tests
aplr Oct 15, 2023
1549c67
Merge branch 'develop' into refactor/reuse-client-components
aplr Oct 16, 2023
8e37def
Merge branch 'develop' into refactor/reuse-client-components
aplr Oct 20, 2023
4bba37a
Merge branch 'develop' into refactor/reuse-client-components
aplr Nov 6, 2023
41c8f5d
Merge branch 'develop' into refactor/reuse-client-components
aplr Nov 8, 2023
4e736fa
Merge branch 'develop' into refactor/reuse-client-components
aplr Nov 9, 2023
4f64438
Merge branch 'develop' into refactor/reuse-client-components
aplr Nov 27, 2023
23171ba
Merge branch 'develop' into refactor/reuse-client-components
krusche Nov 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@ <h4 class="modal-title">
/>
<label for="request-for-other-user" class="form-check-label">{{ 'artemisApp.dataExport.requestForAnotherUser' | artemisTranslate }}</label>
</div>
<jhi-type-ahead-user-search-field *ngIf="requestForAnotherUser" [(loginOrName)]="expectedLogin"></jhi-type-ahead-user-search-field>
<jhi-type-ahead-user-search-field *ngIf="requestForAnotherUser" [(loginOrName)]="expectedLogin" />
</div>
</div>
<div class="form-group">
<label for="confirm-login" [jhiTranslate]="confirmationTextHint">Please type in your login to confirm</label>
<input id="confirm-login" type="text" class="form-control" name="confirmLogin" [(ngModel)]="enteredLogin" />
</div>
<jhi-confirm-entity-name
[entityName]="expectedLogin"
[confirmationText]="confirmationTextHint"
[disabled]="submitDisabled"
[(ngModel)]="enteredLogin"
name="confirmEntityName"
/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="clear()" [disabled]="submitDisabled">
Expand All @@ -36,8 +39,8 @@ <h4 class="modal-title">
id="request"
type="submit"
class="btn btn-primary"
[style.cursor]="dataExportConfirmationForm.form.invalid || this.enteredLogin !== this.expectedLogin || submitDisabled ? 'not-allowed' : 'pointer'"
[disabled]="dataExportConfirmationForm.form.invalid || this.enteredLogin !== this.expectedLogin || this.enteredLogin?.trim()?.length === 0 || submitDisabled"
[style.cursor]="dataExportConfirmationForm.invalid || submitDisabled ? 'not-allowed' : 'pointer'"
[disabled]="dataExportConfirmationForm.invalid || submitDisabled"
>
<span *ngIf="submitDisabled"><fa-icon [icon]="faSpinner" [spin]="true">&nbsp;</fa-icon>&nbsp;</span>
<fa-icon [icon]="faCheck"></fa-icon>&nbsp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ <h4 class="modal-title">
name="workingTimeSeconds"
durationLabelText="artemisApp.examManagement.editWorkingTime.label"
[(ngModel)]="workingTimeSeconds"
[showRelative]="false"
[disabled]="isLoading"
/>

Expand All @@ -31,8 +30,8 @@ <h4 class="modal-title">
confirmationText="artemisApp.examManagement.editWorkingTime.typeNameToConfirm"
[entityName]="exam.title!"
[disabled]="isLoading"
[(ngModel)]="confirmEntityName"
name="confirmEntityName"
ngModel
/>
</div>
</div>
Expand All @@ -44,8 +43,8 @@ <h4 class="modal-title">
id="confirm"
type="submit"
class="btn btn-warning"
[style.cursor]="editForm.invalid || isLoading || !isWorkingTimeValid() ? 'not-allowed' : 'pointer'"
[disabled]="editForm.invalid || isLoading || !isWorkingTimeValid()"
[style.cursor]="editForm.invalid || isLoading || !isWorkingTimeChangeValid ? 'not-allowed' : 'pointer'"
[disabled]="editForm.invalid || isLoading || !isWorkingTimeChangeValid"
>
<span *ngIf="isLoading"><fa-icon [icon]="faSpinner" [spin]="true">&nbsp;</fa-icon>&nbsp;</span>
<fa-icon *ngIf="!isLoading" [icon]="faCheck"></fa-icon>&nbsp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ export class ExamEditWorkingTimeDialogComponent {
faSpinner = faSpinner;
faCheck = faCheck;

confirmEntityName: string;

workingTimeSeconds = 0;

get absoluteWorkingTimeDuration() {
Expand All @@ -44,7 +42,7 @@ export class ExamEditWorkingTimeDialogComponent {
}

confirmUpdateWorkingTime(): void {
if (!this.isWorkingTimeValid()) return;
if (!this.isWorkingTimeChangeValid) return;
this.isLoading = true;
this.examManagementService.updateWorkingTime(this.exam.course!.id!, this.exam.id!, this.workingTimeSeconds).subscribe({
next: (res: HttpResponse<Exam>) => {
Expand All @@ -59,7 +57,7 @@ export class ExamEditWorkingTimeDialogComponent {
});
}

isWorkingTimeValid(): boolean {
get isWorkingTimeChangeValid(): boolean {
return Math.abs(this.workingTimeSeconds) !== 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,71 +33,18 @@ <h5><span jhiTranslate="artemisApp.studentExamDetail.student">Student</span></h5
</div>

<div class="mb-3" *ngIf="!isTestExam">
<h5><span jhiTranslate="artemisApp.studentExams.workingTime">Working time</span></h5>
<h5 jhiTranslate="artemisApp.studentExams.workingTime">Working time</h5>
<form #form="ngForm" (ngSubmit)="saveWorkingTime()">
<div class="mb-1 working-time-form">
<div class="input-group mb-1 d-flex justify-content-between align-items-center">
<label for="hours" class="me-4" jhiTranslate="artemisApp.studentExams.setWorkingTime">Absolute:</label>
<input
[(ngModel)]="workingTimeFormValues.hours"
(ngModelChange)="updateWorkingTimePercent()"
[disabled]="isFormDisabled()"
id="hours"
name="hours"
type="number"
class="text-center form-control form-number-input"
min="0"
step="1"
required
/>
<label for="hours" class="input-group-text">h</label>
<input
[(ngModel)]="workingTimeFormValues.minutes"
(ngModelChange)="updateWorkingTimePercent()"
[disabled]="isFormDisabled()"
id="minutes"
name="minutes"
type="number"
class="text-center form-control form-number-input"
min="0"
max="59"
step="1"
required
/>
<label for="minutes" class="input-group-text">min</label>
<input
[(ngModel)]="workingTimeFormValues.seconds"
(ngModelChange)="updateWorkingTimePercent()"
[disabled]="isFormDisabled()"
id="seconds"
name="seconds"
type="number"
class="text-center form-control form-number-input"
min="0"
max="59"
step="1"
required
/>
<label for="seconds" class="input-group-text">s</label>
</div>
<div class="input-group d-flex justify-content-between align-items-center">
<label for="percent" class="me-4 flex-fill" jhiTranslate="artemisApp.studentExams.setWorkingTimeRelative">Addition relative to regular working time:</label>
<input
[(ngModel)]="workingTimeFormValues.percent"
(ngModelChange)="updateWorkingTimeDuration()"
[disabled]="isFormDisabled()"
id="percent"
name="percent"
type="number"
class="text-center form-control form-number-input"
min="-100"
step=".01"
required
/>
<label for="percent" class="input-group-text">%</label>
</div>
</div>
<button id="save" type="submit" class="btn btn-primary me-2" [disabled]="!form.valid || isFormDisabled()">
<jhi-working-time-control
name="workingTime"
[relative]="true"
[disabled]="isWorkingTimeFormDisabled"
[(ngModel)]="workingTimeSeconds"
[exam]="studentExam.exam"
durationLabelText="artemisApp.studentExams.setWorkingTime"
relativeLabelText="artemisApp.studentExams.setWorkingTimeRelative"
/>
<button id="save" type="submit" class="btn btn-primary mt-2" [disabled]="!form.valid || isWorkingTimeFormDisabled">
<fa-icon [icon]="faSave"></fa-icon>
<span jhiTranslate="entity.action.save">Save</span>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,19 @@ import { StudentExam } from 'app/entities/student-exam.model';
import { StudentExamService } from 'app/exam/manage/student-exams/student-exam.service';
import { Course } from 'app/entities/course.model';
import { User } from 'app/core/user/user.model';
import { ArtemisDurationFromSecondsPipe } from 'app/shared/pipes/artemis-duration-from-seconds.pipe';
import { AlertService } from 'app/core/util/alert.service';
import { round } from 'app/shared/util/utils';
import dayjs from 'dayjs/esm';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { getLatestSubmissionResult, setLatestSubmissionResult } from 'app/entities/submission.model';
import { GradeType } from 'app/entities/grading-scale.model';
import { faSave } from '@fortawesome/free-solid-svg-icons';
import { getRelativeWorkingTimeExtension, normalWorkingTime } from 'app/exam/participate/exam.utils';
import { Exercise } from 'app/entities/exercise.model';
import { StudentExamWithGradeDTO } from 'app/exam/exam-scores/exam-score-dtos.model';

@Component({
selector: 'jhi-student-exam-detail',
templateUrl: './student-exam-detail.component.html',
styleUrls: ['./student-exam-detail.component.scss'],
providers: [ArtemisDurationFromSecondsPipe],
})
export class StudentExamDetailComponent implements OnInit {
courseId: number;
Expand All @@ -44,20 +40,14 @@ export class StudentExamDetailComponent implements OnInit {
isBonus = false;
passed = false;

workingTimeFormValues = {
hours: 0,
minutes: 0,
seconds: 0,
percent: 0,
};

// Icons
faSave = faSave;

workingTimeSeconds = 0;

constructor(
private route: ActivatedRoute,
private studentExamService: StudentExamService,
private artemisDurationFromSecondsPipe: ArtemisDurationFromSecondsPipe,
private alertService: AlertService,
private modalService: NgbModal,
) {}
Expand Down Expand Up @@ -98,8 +88,7 @@ export class StudentExamDetailComponent implements OnInit {
*/
saveWorkingTime() {
this.isSavingWorkingTime = true;
const seconds = this.getWorkingTimeSeconds();
this.studentExamService.updateWorkingTime(this.courseId, this.studentExam.exam!.id!, this.studentExam.id!, seconds).subscribe({
this.studentExamService.updateWorkingTime(this.courseId, this.studentExam.exam!.id!, this.studentExam.id!, this.workingTimeSeconds).subscribe({
next: (res) => {
if (res.body) {
this.setStudentExam(res.body);
Expand Down Expand Up @@ -185,58 +174,14 @@ export class StudentExamDetailComponent implements OnInit {
}
}

/**
* Updates the form values based on the working time of the student exam.
*/
private initWorkingTimeForm() {
this.setWorkingTimeDuration(this.studentExam.workingTime!);
this.updateWorkingTimePercent();
}

/**
* Updates the working time duration values of the form whenever the percent value has been changed by the user.
*/
updateWorkingTimeDuration() {
const regularWorkingTime = normalWorkingTime(this.studentExam.exam!)!;
const seconds = round(regularWorkingTime * (1.0 + this.workingTimeFormValues.percent / 100), 0);
this.setWorkingTimeDuration(seconds);
}

/**
* Updates the hours, minutes, and seconds values of the form.
* @param seconds the total number of seconds of working time.
*/
private setWorkingTimeDuration(seconds: number) {
const workingTime = this.artemisDurationFromSecondsPipe.secondsToDuration(seconds);
this.workingTimeFormValues.hours = workingTime.days * 24 + workingTime.hours;
this.workingTimeFormValues.minutes = workingTime.minutes;
this.workingTimeFormValues.seconds = workingTime.seconds;
}

/**
* Uses the current durations saved in the form to update the extension percent value.
*/
updateWorkingTimePercent() {
this.workingTimeFormValues.percent = getRelativeWorkingTimeExtension(this.studentExam.exam!, this.getWorkingTimeSeconds());
}

/**
* Calculates how many seconds the currently set working time has in total.
*/
private getWorkingTimeSeconds(): number {
const duration = {
days: 0,
hours: this.workingTimeFormValues.hours,
minutes: this.workingTimeFormValues.minutes,
seconds: this.workingTimeFormValues.seconds,
};
return this.artemisDurationFromSecondsPipe.durationToSeconds(duration);
this.workingTimeSeconds = this.studentExam.workingTime ?? 0;
}

/**
* Checks if the user should be able to edit the inputs.
*/
isFormDisabled(): boolean {
get isWorkingTimeFormDisabled(): boolean {
return this.isSavingWorkingTime || (this.isTestRun && !!this.studentExam.submitted) || !this.studentExam.exam;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
<div class="d-flex flex-column gap-1 working-time-control">
<div class="d-flex flex-column gap-1">
<label for="hours" class="me-4" [jhiTranslate]="durationLabelText" *ngIf="durationLabelText"></label>
<label for="workingTimeHours" class="me-4" [jhiTranslate]="durationLabelText" *ngIf="durationLabelText"></label>
<div class="input-group">
<input
[(ngModel)]="workingTime.hours"
(ngModelChange)="onDurationChanged()"
[disabled]="disabled"
id="hours"
id="workingTimeHours"
name="hours"
type="number"
class="text-center form-control form-number-input"
min="0"
step="1"
required
/>
<label for="hours" class="input-group-text">h</label>
<label for="workingTimeHours" class="input-group-text">h</label>
<input
[(ngModel)]="workingTime.minutes"
(ngModelChange)="onDurationChanged()"
[disabled]="disabled"
id="minutes"
id="workingTimeMinutes"
name="minutes"
type="number"
class="text-center form-control form-number-input"
Expand All @@ -28,12 +28,12 @@
step="1"
required
/>
<label for="minutes" class="input-group-text">min</label>
<label for="workingTimeMinutes" class="input-group-text">min</label>
<input
[(ngModel)]="workingTime.seconds"
(ngModelChange)="onDurationChanged()"
[disabled]="disabled"
id="seconds"
id="workingTimeSeconds"
name="seconds"
type="number"
class="text-center form-control form-number-input"
Expand All @@ -42,25 +42,25 @@
step="1"
required
/>
<label for="seconds" class="input-group-text">s</label>
<label for="workingTimeSeconds" class="input-group-text">s</label>
</div>
</div>
<div class="d-flex flex-column gap-1" *ngIf="exam && showRelative">
<label for="percent" class="me-4 flex-fill" [jhiTranslate]="relativeLabelText" *ngIf="relativeLabelText"></label>
<div class="d-flex flex-column gap-1" *ngIf="exam && relative">
<label for="workingTimePercent" class="me-4 flex-fill" [jhiTranslate]="relativeLabelText" *ngIf="relativeLabelText"></label>
<div class="input-group">
<input
[(ngModel)]="workingTime.percent"
(ngModelChange)="onPercentChanged()"
[disabled]="disabled"
id="percent"
id="workingTimePercent"
name="percent"
type="number"
class="text-center form-control form-number-input"
min="-100"
step=".01"
required
/>
<label for="percent" class="input-group-text">%</label>
<label for="workingTimePercent" class="input-group-text">%</label>
</div>
</div>
</div>
Loading