Skip to content

Commit

Permalink
Merge branch 'develop' into chore/client-warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
tobias-lippert authored Oct 24, 2023
2 parents d24a6e8 + 71ab36f commit 4064bc6
Show file tree
Hide file tree
Showing 29 changed files with 387 additions and 83 deletions.
46 changes: 44 additions & 2 deletions docs/user/communication.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ Users of a course can communicate in private via the Messages page. (see image b
Conversation sidebar on the left, where users can search for other participants of the current course and start a conversation
with them.

If the recipient is browsing another conversation when they receive a new message, an envelope icon appears in their
Conversation sidebar, next to the affiliated user who has sent the message. This way, users become aware of the new message
If the recipient is browsing another conversation when they receive a new message, an icon with an unread-messages counter is displayed in their
conversation sidebar, next to the affiliated conversation that the new message was sent to. This way, users become aware of the new message
within that discussion.

The authorities of tutors and instructors are more restricted in the Messages Page compared to the Course Communication
Expand All @@ -78,6 +78,17 @@ located on the right-hand side of the Messages Page when displayed.

|messages|

If the message content contains links, a preview of the link will be shown under the message. This way, users will have a good understanding
of what that link is about. If they prefer not to have a preview, they can hover over the preview and click the appearing `X` button.
The preview will be removed.

|link-preview|

If the message contains more than one link, the preview will not have a preview image of the link to have more compact previews
for multiple links.

|link-preview-multiple|

Features for Users
------------------

Expand Down Expand Up @@ -182,6 +193,27 @@ Reference Lecture Attachments
Users can refer to lectures of the current course, via the dropdown menu ``Lecture`` available on the posting markdown
editor (see image above). Here, lecture attachments can be found in a nested structure.

Reference Lecture Attachment Units
""""""""""""""""""""""""""""""""""

Users can refer to lecture attachment units of the current course, via the dropdown menu ``Lecture`` available on the posting markdown
editor, see image below. Here, lecture attachment units can be found when users hover over the specific lecture.

Reference Lecture Unit Slides
"""""""""""""""""""""""""""""

Users can refer to lecture unit slides of the current course, via the dropdown menu ``Lecture``. Here, slides can be found when users
hover over a specific unit, see image below.

|slide-reference-menu|

After the user references a single slide they can see it as an image included in the message. Additionally, they can preview the slide
in order to easily read the content by clicking the image.

|slide-reference|

|referenced-slide-preview|

Prevent Post Duplication
^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -267,3 +299,13 @@ Additionally, announcements visually differ from normal posts and are always dis
:width: 600
.. |messages| image:: communication/messages.png
:width: 1000
.. |slide-reference| image:: communication/slide-reference.png
:width: 600
.. |slide-reference-menu| image:: communication/slide-reference-menu.png
:width: 1000
.. |referenced-slide-preview| image:: communication/referenced-slide-preview.png
:width: 600
.. |link-preview| image:: communication/link-preview.png
:width: 600
.. |link-preview-multiple| image:: communication/link-preview-multiple.png
:width: 600
Binary file added docs/user/communication/link-preview-multiple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/communication/link-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/user/communication/messages.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/communication/slide-reference-menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/communication/slide-reference.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.tum.in.www1.artemis.service.metis;

import java.time.ZonedDateTime;
import java.util.Objects;
import java.util.Set;

Expand Down Expand Up @@ -144,6 +145,8 @@ public AnswerPost updateAnswerMessage(Long courseId, Long answerMessageId, Answe
existingAnswerMessage.setContent(answerMessage.getContent());
}

existingAnswerMessage.setUpdatedDate(ZonedDateTime.now());

updatedAnswerMessage = answerPostRepository.save(existingAnswerMessage);
updatedAnswerMessage.getPost().setConversation(conversation);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div class="doughnut mx-3">
<a *ngIf="titleLink" [routerLink]="['/course-management', course.id, titleLink]">
<h4 class="text-center">{{ 'artemisApp.course.detail.' + doughnutChartTitle + 'Title' | artemisTranslate }}</h4>
<h5 class="text-center">{{ 'artemisApp.course.detail.' + doughnutChartTitle + 'Title' | artemisTranslate }}</h5>
</a>
<h4 *ngIf="!titleLink" class="text-center">{{ 'artemisApp.course.detail.' + doughnutChartTitle + 'Title' | artemisTranslate }}</h4>
<h5 *ngIf="!titleLink" class="text-center">{{ 'artemisApp.course.detail.' + doughnutChartTitle + 'Title' | artemisTranslate }}</h5>
<div class="doughnut-chart-container" [ngClass]="titleLink ? 'clickable' : ''" (click)="openCorrespondingPage()">
<div class="doughnut-chart-text">
<h2 *ngIf="receivedStats" class="text-center">{{ currentPercentage }}%</h2>
Expand All @@ -11,6 +11,6 @@ <h1 *ngIf="!receivedStats" class="text-center" style="z-index: 1">
<fa-icon [icon]="faSpinner" [spin]="true">&nbsp;</fa-icon>
</h1>
</div>
<ngx-charts-pie-chart [view]="[250, 250]" [results]="ngxData" [scheme]="ngxColor" [doughnut]="true" [tooltipText]="bindFormatting"> </ngx-charts-pie-chart>
<ngx-charts-pie-chart [view]="[200, 200]" [results]="ngxData" [scheme]="ngxColor" [doughnut]="true" [tooltipText]="bindFormatting"> </ngx-charts-pie-chart>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h5>{{ 'artemisApp.courseStatistics.activeStudents' | artemisTranslate }}</h5>
></fa-icon>
<div #containerRef class="chart col-md-10 mt-1 justify-content-center align-items-start h-99" [ngClass]="showsCurrentWeek && startDateDisplayed ? 'col-12' : 'col-10'">
<ngx-charts-line-chart
[view]="[containerRef.offsetWidth, 500]"
[view]="[containerRef.offsetWidth, 400]"
[scheme]="chartColor"
[legend]="legend"
[showXAxisLabel]="showXAxisLabel"
Expand Down
110 changes: 72 additions & 38 deletions src/main/webapp/app/course/manage/detail/course-detail.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ <h2><span jhiTranslate="artemisApp.course.detail.title">Course Details:</span></
<dd id="course-short-name">
<span>{{ course.shortName }}</span>
</dd>
<ng-container *ngIf="!!course.organizations?.length">
<dt><span jhiTranslate="artemisApp.course.organizations">Course Organizations</span></dt>
<dd id="course-organisations">
<span *ngFor="let organization of course.organizations" class="badge bg-primary font-weight-normal m-1 ps-3">{{ organization.name }}</span>
</dd>
</ng-container>
<!--
For users which are at least instructor we show the group name including a link to the course user group management,
where new users can be added to the group, since they have the permission to add/remove users to/from the group
Expand Down Expand Up @@ -110,23 +116,29 @@ <h2><span jhiTranslate="artemisApp.course.detail.title">Course Details:</span></
</dd>
</div>
</ng-template>
<dt><span jhiTranslate="artemisApp.course.maxPoints.title">Max. Number of Points</span></dt>
<dd>
<span>{{ course.maxPoints || '-' }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.accuracyOfScores">Number of decimal places used for calculating the scores</span></dt>
<dd>
<span>{{ course.accuracyOfScores || '-' }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.startDate">Start Date</span></dt>
<dd id="course-start-date">
<span>{{ course.startDate | artemisDate }}</span>
<span>{{ (course.startDate | artemisDate) || '-' }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.endDate">End Date</span></dt>
<dd id="course-end-date">
<span>{{ course.endDate | artemisDate }}</span>
<span>{{ (course.endDate | artemisDate) || '-' }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.semester">Semester</span></dt>
<dd id="course-semester">
<span *ngIf="course.semester && course.semester !== ''">{{ course.semester }}</span>
<span *ngIf="!course.semester || course.semester === ''">{{ 'global.generic.unset' | artemisTranslate }}</span>
<span>{{ course.semester || '-' }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.defaultProgrammingLanguage">Default Programming Language</span></dt>
<dd id="course-programming-language">
<span *ngIf="course.defaultProgrammingLanguage">{{ course.defaultProgrammingLanguage }}</span>
<span *ngIf="!course.defaultProgrammingLanguage">{{ 'global.generic.unset' | artemisTranslate }}</span>
<span>{{ course.defaultProgrammingLanguage || '-' }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.testCourse.title">Test Course</span></dt>
<dd id="course-test-course">
Expand All @@ -145,28 +157,28 @@ <h2><span jhiTranslate="artemisApp.course.detail.title">Course Details:</span></
<a [routerLink]="['/course-management', course?.id, 'lti-configuration']">LTI Configuration</a>
</dd>
</ng-container>
<dt><span jhiTranslate="artemisApp.course.registrationEnabled.title">Student Course Registration Enabled</span></dt>
<dd id="course-enrollment-enabled">
<span *ngIf="course.enrollmentEnabled">{{ 'global.generic.yes' | artemisTranslate }}</span>
<span *ngIf="!course.enrollmentEnabled">{{ 'global.generic.no' | artemisTranslate }}</span>
</dd>
<dt *ngIf="course.enrollmentEnabled"><span jhiTranslate="artemisApp.course.enrollmentStartDate">Enrollment Start</span></dt>
<dd *ngIf="course.enrollmentEnabled" id="course-enrollment-start-date">
<span>{{ course.enrollmentStartDate | artemisDate }}</span>
</dd>
<dt *ngIf="course.enrollmentEnabled"><span jhiTranslate="artemisApp.course.enrollmentEndDate">Enrollment End</span></dt>
<dd *ngIf="course.enrollmentEnabled" id="course-enrollment-end-date">
<span>{{ course.enrollmentEndDate | artemisDate }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.unenrollmentEnabled.title">Student Course Unenrollment Enabled</span></dt>
<dd *ngIf="course.enrollmentEnabled" id="course-unenrollment-enabled">
<span *ngIf="course.unenrollmentEnabled">{{ 'global.generic.yes' | artemisTranslate }}</span>
<span *ngIf="!course.unenrollmentEnabled">{{ 'global.generic.no' | artemisTranslate }}</span>
</dd>
<dt *ngIf="course.unenrollmentEnabled"><span jhiTranslate="artemisApp.course.unenrollmentEndDate">Latest date to unenroll</span></dt>
<dd *ngIf="course.unenrollmentEnabled" id="course-unenrollment-end-date">
<span>{{ course.unenrollmentEndDate | artemisDate }}</span>
</dd>
<ng-container *ngIf="course.enrollmentEnabled">
<dt><span jhiTranslate="artemisApp.course.enrollmentStartDate">Enrollment Start</span></dt>
<dd id="course-enrollment-start-date">
<span>{{ (course.enrollmentStartDate | artemisDate) || '-' }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.enrollmentEndDate">Enrollment End</span></dt>
<dd id="course-enrollment-end-date">
<span>{{ (course.enrollmentEndDate | artemisDate) || '-' }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.registrationConfirmationMessage">Registration Confirmation Message</span></dt>
<dd
id="course-enrollment-confirmation"
class="markdown-preview editor-outline-background"
[innerHTML]="course.enrollmentConfirmationMessage | htmlForMarkdown"
></dd>
</ng-container>
<ng-container *ngIf="course.unenrollmentEnabled">
<dt><span jhiTranslate="artemisApp.course.unenrollmentEndDate">Latest date to unenroll</span></dt>
<dd id="course-unenrollment-end-date">
<span>{{ (course.unenrollmentEndDate | artemisDate) || '-' }}</span>
</dd>
</ng-container>
<ng-container [jhiFeatureToggleLink]="FeatureToggle.TutorialGroups">
<dt>
<span>{{ 'artemisApp.forms.configurationForm.timeZoneInput.label' | artemisTranslate }} </span>
Expand All @@ -180,30 +192,52 @@ <h2><span jhiTranslate="artemisApp.course.detail.title">Course Details:</span></
</div>
</dd>
</ng-container>
<ng-container *ngIf="course.maxComplaints !== 0">
<ng-container *ngIf="course.complaintsEnabled">
<dt><span jhiTranslate="artemisApp.course.maxComplaints.title">Maximum amount of complaints per student</span></dt>
<dd id="course-max-complaints">
<span>{{ course.maxComplaints }}</span>
<span>{{ course.maxComplaints || '-' }}</span>
</dd>
</ng-container>
<ng-container *ngIf="course.maxTeamComplaints !== 0">
<dt><span jhiTranslate="artemisApp.course.maxTeamComplaints.title">Maximum amount of complaints per team</span></dt>
<dd id="course-max-team-complaints">
<span>{{ course.maxTeamComplaints }}</span>
<span>{{ course.maxTeamComplaints || '-' }}</span>
</dd>
</ng-container>
<ng-container *ngIf="course.maxComplaintTimeDays !== 0">
<dt><span jhiTranslate="artemisApp.course.maxComplaintTimeDays.title">Due date for complaints in days after result date</span></dt>
<dd id="course-max-time-days">
<span>{{ course.maxComplaintTimeDays }}</span>
<span>{{ course.maxComplaintTimeDays || '-' }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.maxComplaintTextLimit.title">Maximum number of characters per complaint</span></dt>
<dd id="course-max-complaint-text-limit">
<span>{{ course.maxComplaintTextLimit || '-' }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.maxComplaintResponseTextLimit.title">Maximum number of characters per complaint response</span></dt>
<dd id="course-max-complaint-response-text-limit">
<span>{{ course.maxComplaintResponseTextLimit || '-' }}</span>
</dd>
</ng-container>
<ng-container *ngIf="course.maxRequestMoreFeedbackTimeDays !== 0">
<ng-container *ngIf="course.requestMoreFeedbackEnabled">
<dt><span jhiTranslate="artemisApp.course.maxRequestMoreFeedbackTimeDays.title">Due date for more feedback requests in days after result date</span></dt>
<dd id="course-max-request-more-feedback-days">
<span>{{ course.maxRequestMoreFeedbackTimeDays }}</span>
<span>{{ course.maxRequestMoreFeedbackTimeDays || '-' }}</span>
</dd>
</ng-container>
<dt><span jhiTranslate="artemisApp.course.courseCommunicationSetting.communicationEnabled.label">Communication Enabled</span></dt>
<dd id="course-communication-enabled">
<span *ngIf="this.communicationEnabled">{{ 'global.generic.yes' | artemisTranslate }}</span>
<span *ngIf="!this.communicationEnabled">{{ 'global.generic.no' | artemisTranslate }}</span>
</dd>
<dt><span jhiTranslate="artemisApp.course.courseCommunicationSetting.messagingEnabled.label">Messaging Enabled</span></dt>
<dd id="course-messaging-enabled">
<span *ngIf="this.messagingEnabled">{{ 'global.generic.yes' | artemisTranslate }}</span>
<span *ngIf="!this.messagingEnabled">{{ 'global.generic.no' | artemisTranslate }}</span>
</dd>
<ng-container *ngIf="this.messagingEnabled">
<dt><span jhiTranslate="artemisApp.course.courseCommunicationSetting.messagingEnabled.codeOfConduct">Messaging Code of Conduct</span></dt>
<dd
id="course-code-of-conduct"
class="markdown-preview editor-outline-background"
[innerHTML]="course.courseInformationSharingMessagingCodeOfConduct | htmlForMarkdown"
></dd>
</ng-container>
</dl>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { AlertService } from 'app/core/util/alert.service';
import { EventManager } from 'app/core/util/event-manager.service';
import { faChartBar, faClipboard, faEye, faFlag, faListAlt, faTable, faTimes, faWrench } from '@fortawesome/free-solid-svg-icons';
import { FeatureToggle } from 'app/shared/feature-toggle/feature-toggle.service';
import { OrganizationManagementService } from 'app/admin/organization-management/organization-management.service';

export enum DoughnutChartType {
ASSESSMENT = 'ASSESSMENT',
Expand All @@ -36,6 +37,9 @@ export class CourseDetailComponent implements OnInit, OnDestroy {
activeStudents?: number[];
course: Course;

messagingEnabled: boolean;
communicationEnabled: boolean;

ltiEnabled = false;

private eventSubscriber: Subscription;
Expand All @@ -54,6 +58,7 @@ export class CourseDetailComponent implements OnInit, OnDestroy {
constructor(
private eventManager: EventManager,
private courseManagementService: CourseManagementService,
private organizationService: OrganizationManagementService,
private route: ActivatedRoute,
private alertService: AlertService,
private profileService: ProfileService,
Expand All @@ -69,6 +74,8 @@ export class CourseDetailComponent implements OnInit, OnDestroy {
this.route.data.subscribe(({ course }) => {
if (course) {
this.course = course;
this.messagingEnabled = !!this.course.courseInformationSharingConfiguration?.includes('MESSAGING');
this.communicationEnabled = !!this.course.courseInformationSharingConfiguration?.includes('COMMUNICATION');
}
});
// There is no course 0 -> will fetch no course if route does not provide different courseId
Expand All @@ -78,6 +85,7 @@ export class CourseDetailComponent implements OnInit, OnDestroy {
});
this.fetchCourseStatistics(courseId);
this.registerChangeInCourses(courseId);
this.fetchOrganizations(courseId);
}

/**
Expand Down Expand Up @@ -114,4 +122,10 @@ export class CourseDetailComponent implements OnInit, OnDestroy {
error: (error: HttpErrorResponse) => onError(this.alertService, error),
});
}

private fetchOrganizations(courseId: number) {
this.organizationService.getOrganizationsByCourse(courseId).subscribe((organizations) => {
this.course.organizations = organizations;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ export class NavbarComponent implements OnInit, OnDestroy {
participate: 'artemisApp.submission.detail.title',
live: 'artemisApp.submission.detail.title',
courses: 'artemisApp.course.home.title',
enroll: 'artemisApp.studentDashboard.enroll.title',
};

/**
Expand Down
Loading

0 comments on commit 4064bc6

Please sign in to comment.