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

Communication: Configure messaging code of conduct #7118

Merged
merged 17 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
10 changes: 10 additions & 0 deletions src/main/java/de/tum/in/www1/artemis/domain/Course.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ public class Course extends DomainObject {
@JsonView(QuizView.Before.class)
private CourseInformationSharingConfiguration courseInformationSharingConfiguration = CourseInformationSharingConfiguration.COMMUNICATION_AND_MESSAGING; // default value

@Column(name = "info_sharing_messaging_code_of_conduct")
private String courseInformationSharingMessagingCodeOfConduct;

@Column(name = "max_complaints", nullable = false)
@JsonView(QuizView.Before.class)
private Integer maxComplaints = 3; // default value
Expand Down Expand Up @@ -981,4 +984,11 @@ public void setCourseInformationSharingConfiguration(CourseInformationSharingCon
this.courseInformationSharingConfiguration = courseInformationSharingConfiguration;
}

public String getCourseInformationSharingMessagingCodeOfConduct() {
return this.courseInformationSharingMessagingCodeOfConduct;
}

public void setCourseInformationSharingMessagingCodeOfConduct(String courseInformationSharingMessagingCodeOfConduct) {
this.courseInformationSharingMessagingCodeOfConduct = courseInformationSharingMessagingCodeOfConduct;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="zbil" id="20230830183901">
<addColumn tableName="course">
<column name="info_sharing_messaging_code_of_conduct" type="longtext"/>
</addColumn>
</changeSet>
</databaseChangeLog>
1 change: 1 addition & 0 deletions src/main/resources/config/liquibase/master.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
<include file="classpath:config/liquibase/changelog/20230713171500_changelog.xml" relativeToChangelogFile="false"/>
<include file="classpath:config/liquibase/changelog/20230721135400_changelog.xml" relativeToChangelogFile="false"/>
<include file="classpath:config/liquibase/changelog/20230812135300_changelog.xml" relativeToChangelogFile="false"/>
<include file="classpath:config/liquibase/changelog/20230830183901_changelog.xml" relativeToChangelogFile="false"/>
nityanandaz marked this conversation as resolved.
Show resolved Hide resolved
<include file="classpath:config/liquibase/changelog/20230713113211_changelog.xml" relativeToChangelogFile="false"/>
<!-- NOTE: please use the format "YYYYMMDDhhmmss_changelog.xml", i.e. year month day hour minutes seconds and not something else! -->
<!-- we should also stay in a chronological order! -->
Expand Down
20 changes: 20 additions & 0 deletions src/main/webapp/app/course/manage/course-update.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,26 @@ <h5>
ngbTooltip="{{ 'artemisApp.course.courseCommunicationSetting.messagingEnabled.tooltip' | artemisTranslate }}"
></fa-icon>
</div>
<div class="form-group" *ngIf="messagingEnabled">
<label
class="form-control-label"
jhiTranslate="artemisApp.course.courseCommunicationSetting.messagingEnabled.codeOfConduct.label"
for="field_messagingCodeOfConduct"
>Messaging Code of Conduct
</label>
<fa-icon
[icon]="faQuestionCircle"
class="text-secondary"
ngbTooltip="{{ 'artemisApp.course.courseCommunicationSetting.messagingEnabled.codeOfConduct.tooltip' | artemisTranslate }}"
></fa-icon>
nityanandaz marked this conversation as resolved.
Show resolved Hide resolved
<textarea
id="field_messagingCodeOfConduct"
class="form-control"
rows="2"
nityanandaz marked this conversation as resolved.
Show resolved Hide resolved
formControlName="courseInformationSharingMessagingCodeOfConduct"
[(ngModel)]="course.courseInformationSharingMessagingCodeOfConduct"
></textarea>
</div>
</div>
<div class="form-check" *ngIf="!this.course.enrollmentEnabled">
<input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ export class CourseUpdateComponent implements OnInit {
editorGroupName: new FormControl(this.course.editorGroupName),
instructorGroupName: new FormControl(this.course.instructorGroupName),
description: new FormControl(this.course.description),
courseInformationSharingMessagingCodeOfConduct: new FormControl(this.course.courseInformationSharingMessagingCodeOfConduct),
organizations: new FormControl(this.courseOrganizations),
startDate: new FormControl(this.course.startDate),
endDate: new FormControl(this.course.endDate),
Expand Down
1 change: 1 addition & 0 deletions src/main/webapp/app/entities/course.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export class Course implements BaseEntity {
public tutorialGroups?: TutorialGroup[];
public onlineCourseConfiguration?: OnlineCourseConfiguration;
public courseInformationSharingConfiguration?: CourseInformationSharingConfiguration;
public courseInformationSharingMessagingCodeOfConduct?: string;

// helper attributes
public isAtLeastTutor?: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<ng-template #controls>
<button class="btn btn-primary" type="button" (click)="openDialog()">{{ 'artemisApp.conversation.codeOfConduct.topBar.button' | artemisTranslate }}</button>
</ng-template>

<jhi-loading-indicator-container [isLoading]="isLoading">
<div class="row mt-2" *ngIf="isServiceSetUp && course">
<div class="col d-flex flex-grow-1 justify-end px-0 me-1" style="max-width: min-content">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { AfterViewInit, Component, OnDestroy, OnInit, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core';
import { ConversationDto } from 'app/entities/metis/conversation/conversation.model';
import { Post } from 'app/entities/metis/post.model';
import { ActivatedRoute, Router } from '@angular/router';
Expand All @@ -8,6 +8,10 @@ import { getAsChannelDto } from 'app/entities/metis/conversation/channel.model';
import { MetisService } from 'app/shared/metis/metis.service';
import { Course } from 'app/entities/course.model';
import { PageType } from 'app/shared/metis/metis.util';
import { BarControlConfiguration } from 'app/shared/tab-bar/tab-bar';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { ConversationAcceptCodeOfConductDialogComponent } from 'app/overview/course-conversations/dialogs/code-of-conduct/accept/conversation-accept-code-of-conduct-dialog.component';
import { ConversationCodeOfConductDialogComponent } from 'app/overview/course-conversations/dialogs/code-of-conduct/conversation-code-of-conduct-dialog.component';

@Component({
selector: 'jhi-course-conversations',
Expand All @@ -16,20 +20,29 @@ import { PageType } from 'app/shared/metis/metis.util';
encapsulation: ViewEncapsulation.None,
providers: [MetisService],
})
export class CourseConversationsComponent implements OnInit, OnDestroy {
export class CourseConversationsComponent implements OnInit, OnDestroy, AfterViewInit {
private ngUnsubscribe = new Subject<void>();
course?: Course;
isLoading = false;
isServiceSetUp = false;
postInThread?: Post;
activeConversation?: ConversationDto = undefined;
conversationsOfUser: ConversationDto[] = [];

// The extracted controls template from our template to be rendered in the top bar of "CourseOverviewComponent"
@ViewChild('controls', { static: false }) private controls: TemplateRef<any>;
// Provides the control configuration to be read and used by "CourseOverviewComponent"
public readonly controlConfiguration: BarControlConfiguration = {
subject: new Subject<TemplateRef<any>>(),
};

// MetisConversationService is created in course overview, so we can use it here
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
public metisConversationService: MetisConversationService,
public metisService: MetisService,
private modalService: NgbModal,
) {}

getAsChannel = getAsChannelDto;
Expand Down Expand Up @@ -83,11 +96,30 @@ export class CourseConversationsComponent implements OnInit, OnDestroy {
});
}

ngAfterViewInit(): void {
// Send our controls template to parent so it will be rendered in the top bar
if (this.controls) {
this.controlConfiguration.subject!.next(this.controls);
}

this.openAcceptDialog();
}

ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}

openAcceptDialog() {
const modalRef: NgbModalRef = this.modalService.open(ConversationAcceptCodeOfConductDialogComponent, { backdrop: 'static', size: 'xl' });
modalRef.componentInstance.codeOfConduct = this.course?.courseInformationSharingMessagingCodeOfConduct;
}

openDialog() {
const modalRef: NgbModalRef = this.modalService.open(ConversationCodeOfConductDialogComponent, {});
modalRef.componentInstance.codeOfConduct = this.course?.courseInformationSharingMessagingCodeOfConduct;
}

private subscribeToActiveConversation() {
this.metisConversationService.activeConversation$.pipe(takeUntil(this.ngUnsubscribe)).subscribe((conversation: ConversationDto) => {
this.activeConversation = conversation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { ConversationAddUsersDialogComponent } from './dialogs/conversation-add-
import { ConversationAddUsersFormComponent } from './dialogs/conversation-add-users-dialog/add-users-form/conversation-add-users-form.component';
import { CourseUsersSelectorModule } from 'app/shared/course-users-selector/course-users-selector.module';
import { ConversationMembersComponent } from './dialogs/conversation-detail-dialog/tabs/conversation-members/conversation-members.component';
import { ConversationCodeOfConductDialogComponent } from 'app/overview/course-conversations/dialogs/code-of-conduct/conversation-code-of-conduct-dialog.component';
import { ConversationDetailDialogComponent } from './dialogs/conversation-detail-dialog/conversation-detail-dialog.component';
import { ConversationInfoComponent } from './dialogs/conversation-detail-dialog/tabs/conversation-info/conversation-info.component';
import { ConversationMemberRowComponent } from './dialogs/conversation-detail-dialog/tabs/conversation-members/conversation-member-row/conversation-member-row.component';
Expand All @@ -30,6 +31,8 @@ import { ConversationSidebarEntryComponent } from './layout/conversation-selecti
import { OneToOneChatCreateDialogComponent } from './dialogs/one-to-one-chat-create-dialog/one-to-one-chat-create-dialog.component';
import { GroupChatCreateDialogComponent } from './dialogs/group-chat-create-dialog/group-chat-create-dialog.component';
import { GroupChatIconComponent } from './other/group-chat-icon/group-chat-icon.component';
import { ArtemisMarkdownModule } from 'app/shared/markdown.module';
import { ConversationAcceptCodeOfConductDialogComponent } from 'app/overview/course-conversations/dialogs/code-of-conduct/accept/conversation-accept-code-of-conduct-dialog.component';

const routes: Routes = [
{
Expand All @@ -51,6 +54,7 @@ const routes: Routes = [
ArtemisDataTableModule,
InfiniteScrollModule,
CourseUsersSelectorModule,
ArtemisMarkdownModule,
],
declarations: [
CourseConversationsComponent,
Expand All @@ -67,6 +71,8 @@ const routes: Routes = [
ConversationAddUsersDialogComponent,
ConversationAddUsersFormComponent,
ConversationMembersComponent,
ConversationAcceptCodeOfConductDialogComponent,
ConversationCodeOfConductDialogComponent,
ConversationDetailDialogComponent,
ConversationInfoComponent,
ConversationMemberRowComponent,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div class="conversation-accept-code-of-conduct-dialog">
<div class="modal-body" [innerHTML]="codeOfConduct | htmlForMarkdown"></div>
<div class="col-12 text-center">
<button class="btn btn-primary" type="button" (click)="accept()">Accept</button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.conversation-accept-code-of-conduct-dialog {
padding: 0.5rem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Component, Input } from '@angular/core';
import { AbstractDialogComponent } from 'app/overview/course-conversations/dialogs/abstract-dialog.component';

@Component({
selector: 'jhi-conversation-accept-code-of-conduct-dialog',
templateUrl: `conversation-accept-code-of-conduct-dialog.component.html`,
styleUrls: ['./conversation-accept-code-of-conduct-dialog.component.scss'],
})
export class ConversationAcceptCodeOfConductDialogComponent extends AbstractDialogComponent {
@Input() codeOfConduct: string;

accept() {
this.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div class="conversation-code-of-conduct-dialog">
<div class="modal-header">
<h4 class="modal-title">Code of Conduct</h4>
<button type="button" class="btn-close" (click)="clear()"></button>
</div>
<div class="modal-body" [innerHTML]="codeOfConduct | htmlForMarkdown"></div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Component, Input } from '@angular/core';
import { AbstractDialogComponent } from 'app/overview/course-conversations/dialogs/abstract-dialog.component';

@Component({
selector: 'jhi-conversation-code-of-conduct-dialog',
templateUrl: './conversation-code-of-conduct-dialog.component.html',
})
export class ConversationCodeOfConductDialogComponent extends AbstractDialogComponent {
@Input() codeOfConduct: string;

clear() {
this.close();
}
}
7 changes: 7 additions & 0 deletions src/main/webapp/i18n/de/conversation.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
"mainParagraph": "Gib im Chat keine vertraulichen Informationen wie Passwörter, Kreditkartennummern oder persönliche Identifikationsnummern weiter. Diese Informationen sind sensibel und könnten für Identitätsdiebstahl oder Betrug verwendet werden, wenn sie in die falschen Hände geraten.",
"lastParagraph": "Bewahre deine persönlichen Daten sicher auf, indem du sie für dich behältst und sie nicht online weitergibst."
},
"conversation": {
"codeOfConduct": {
"topBar": {
"button": "Verhaltens-Kodex"
nityanandaz marked this conversation as resolved.
Show resolved Hide resolved
}
}
},
"conversationsLayout": {
"tabTitle": "Kursnachrichten",
"breadCrumbLabel": "Nachrichten",
Expand Down
6 changes: 5 additions & 1 deletion src/main/webapp/i18n/de/course.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@
},
"messagingEnabled": {
"label": "Nachrichten aktiviert",
"tooltip": "Ermöglicht den Nachrichtenaustausch zwischen Nutzer:innen in privaten oder öffentlichen Kanälen, Gruppenchats oder Direktnachrichten. Kanäle können nur von Lehrenden und Tutor:innen erstellt werden. Nutzer:innen können selbst öffentlichen Kanälen beitreten und müssen zu privaten Kanälen hinzugefügt werden. Alle Nutzer:innen können einen privaten Gruppenchat starten und andere Nutzer:innen hinzufügen. Ein Gruppenchat ist auf zehn Mitglieder:innen begrenzt. Alle Nutzer:innen können Direktnachrichten an andere Nutzer:innen senden. Die Chats finden im Nachrichtenbereich des Kurses statt."
"tooltip": "Ermöglicht den Nachrichtenaustausch zwischen Nutzer:innen in privaten oder öffentlichen Kanälen, Gruppenchats oder Direktnachrichten. Kanäle können nur von Lehrenden und Tutor:innen erstellt werden. Nutzer:innen können selbst öffentlichen Kanälen beitreten und müssen zu privaten Kanälen hinzugefügt werden. Alle Nutzer:innen können einen privaten Gruppenchat starten und andere Nutzer:innen hinzufügen. Ein Gruppenchat ist auf zehn Mitglieder:innen begrenzt. Alle Nutzer:innen können Direktnachrichten an andere Nutzer:innen senden. Die Chats finden im Nachrichtenbereich des Kurses statt.",
"codeOfConduct": {
"label": "Nachrichten-Verhaltenskodex",
"tooltip": "Der Nachrichten-Verhaltenskodex gibt Nutzer:innen an, wie sie miteinander kollaborieren sollen und welche Konsequenzen bei Fehlverhalten drohen können, sowie einen Kontakt zur Berichterstattung."
nityanandaz marked this conversation as resolved.
Show resolved Hide resolved
}
}
},
"registrationEnabled": {
Expand Down
7 changes: 7 additions & 0 deletions src/main/webapp/i18n/en/conversation.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
"mainParagraph": "Do not share confidential information like passwords, credit card numbers, or personal identification numbers in the chat. This information is sensitive and could potentially be used for identity theft or fraud if it falls into the wrong hands.",
"lastParagraph": "Keep your personal information safe by keeping it to yourself and not sharing it online."
},
"conversation": {
"codeOfConduct": {
"topBar": {
"button": "Code of Conduct"
}
}
},
"conversationsLayout": {
"tabTitle": "Course Messages",
"breadCrumbLabel": "Messages",
Expand Down
6 changes: 5 additions & 1 deletion src/main/webapp/i18n/en/course.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@
},
"messagingEnabled": {
"label": "Messaging Enabled",
"tooltip": "Enables messaging between course users in private or public channels, group chats or direct messages. Channels can only be created by instructors and tutors. Users can self-join public channels and must be invited to private channels. Every user can start a private group chat and add other users. A group chat is limited to 10 members. Every user can start a private one-to-one chat with another user. The chats happens in the messaging space of the course."
"tooltip": "Enables messaging between course users in private or public channels, group chats or direct messages. Channels can only be created by instructors and tutors. Users can self-join public channels and must be invited to private channels. Every user can start a private group chat and add other users. A group chat is limited to 10 members. Every user can start a private one-to-one chat with another user. The chats happens in the messaging space of the course.",
"codeOfConduct": {
"label": "Messages Code of Conduct",
"tooltip": "The Messages Code of Conduct describes to users how best to collaborate and which consequences might be raised if there is misconduct, as well as, contact information for reporting."
}
}
},
"registrationEnabled": {
Expand Down