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: Add recents section to sidebar #10033

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
(onBrowsePressed)="openChannelOverviewDialog()"
(onDirectChatPressed)="openCreateOneToOneChatDialog()"
(onGroupChatPressed)="openCreateGroupChatDialog()"
[showAddOption]="CHANNEL_TYPE_SHOW_ADD_OPTION"
[channelTypeIcon]="CHANNEL_TYPE_ICON"
[sidebarItemAlwaysShow]="DEFAULT_SHOW_ALWAYS"
[collapseState]="DEFAULT_COLLAPSE_STATE"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { PageType, SortDirection } from 'app/shared/metis/metis.util';
import {
faBan,
faBookmark,
faClock,
faComment,
faComments,
faFile,
Expand All @@ -27,7 +28,7 @@ import {
} from '@fortawesome/free-solid-svg-icons';
import { ButtonType } from 'app/shared/components/button.component';
import { CourseWideSearchComponent, CourseWideSearchConfig } from 'app/overview/course-conversations/course-wide-search/course-wide-search.component';
import { AccordionGroups, ChannelAccordionShowAdd, ChannelTypeIcons, CollapseState, SidebarCardElement, SidebarData, SidebarItemShowAlways } from 'app/types/sidebar';
import { AccordionGroups, ChannelTypeIcons, CollapseState, SidebarCardElement, SidebarData, SidebarItemShowAlways } from 'app/types/sidebar';
import { CourseOverviewService } from 'app/overview/course-overview.service';
import { GroupChatCreateDialogComponent } from 'app/overview/course-conversations/dialogs/group-chat-create-dialog/group-chat-create-dialog.component';
import { defaultFirstLayerDialogOptions, defaultSecondLayerDialogOptions } from 'app/overview/course-conversations/other/conversation.util';
Expand All @@ -44,6 +45,7 @@ import { canCreateChannel } from 'app/shared/metis/conversations/conversation-pe

const DEFAULT_CHANNEL_GROUPS: AccordionGroups = {
favoriteChannels: { entityData: [] },
recents: { entityData: [] },
generalChannels: { entityData: [] },
exerciseChannels: { entityData: [] },
lectureChannels: { entityData: [] },
Expand All @@ -52,18 +54,6 @@ const DEFAULT_CHANNEL_GROUPS: AccordionGroups = {
savedPosts: { entityData: [] },
};

const CHANNEL_TYPE_SHOW_ADD_OPTION: ChannelAccordionShowAdd = {
generalChannels: true,
exerciseChannels: true,
examChannels: true,
groupChats: true,
directMessages: true,
favoriteChannels: false,
lectureChannels: true,
hiddenChannels: false,
savedPosts: false,
};

const CHANNEL_TYPE_ICON: ChannelTypeIcons = {
generalChannels: faMessage,
exerciseChannels: faList,
Expand All @@ -74,6 +64,7 @@ const CHANNEL_TYPE_ICON: ChannelTypeIcons = {
lectureChannels: faFile,
hiddenChannels: faBan,
savedPosts: faBookmark,
recents: faClock,
};

const DEFAULT_COLLAPSE_STATE: CollapseState = {
Expand All @@ -86,6 +77,7 @@ const DEFAULT_COLLAPSE_STATE: CollapseState = {
lectureChannels: true,
hiddenChannels: true,
savedPosts: true,
recents: true,
};

const DEFAULT_SHOW_ALWAYS: SidebarItemShowAlways = {
Expand All @@ -98,6 +90,7 @@ const DEFAULT_SHOW_ALWAYS: SidebarItemShowAlways = {
lectureChannels: false,
hiddenChannels: false,
savedPosts: true,
recents: true,
};

@Component({
Expand Down Expand Up @@ -135,7 +128,6 @@ export class CourseConversationsComponent implements OnInit, OnDestroy {
openThreadOnFocus = false;
selectedSavedPostStatus: null | SavedPostStatus = null;

readonly CHANNEL_TYPE_SHOW_ADD_OPTION = CHANNEL_TYPE_SHOW_ADD_OPTION;
readonly CHANNEL_TYPE_ICON = CHANNEL_TYPE_ICON;
readonly DEFAULT_COLLAPSE_STATE = DEFAULT_COLLAPSE_STATE;
protected readonly DEFAULT_SHOW_ALWAYS = DEFAULT_SHOW_ALWAYS;
Expand Down Expand Up @@ -409,8 +401,10 @@ export class CourseConversationsComponent implements OnInit, OnDestroy {
prepareSidebarData() {
this.metisConversationService.forceRefresh().subscribe({
complete: () => {
this.sidebarConversations = this.courseOverviewService.mapConversationsToSidebarCardElements(this.conversationsOfUser);
this.accordionConversationGroups = this.courseOverviewService.groupConversationsByChannelType(this.conversationsOfUser, this.messagingEnabled);
this.sidebarConversations = this.courseOverviewService.mapConversationsToSidebarCardElements(this.course!, this.conversationsOfUser);
this.accordionConversationGroups = this.courseOverviewService.groupConversationsByChannelType(this.course!, this.conversationsOfUser, this.messagingEnabled);
const currentConversations = this.sidebarConversations?.filter((item) => item.isCurrent) || [];
this.accordionConversationGroups.recents.entityData = currentConversations;
this.updateSidebarData();
},
});
Expand Down
76 changes: 59 additions & 17 deletions src/main/webapp/app/overview/course-overview.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { isGroupChatDTO } from 'app/entities/metis/conversation/group-chat.model
import { ConversationService } from 'app/shared/metis/conversations/conversation.service';
import { StudentExam } from 'app/entities/student-exam.model';
import { SavedPostStatusMap } from 'app/entities/metis/posting.model';
import { Course } from 'app/entities/course.model';

const DEFAULT_UNIT_GROUPS: AccordionGroups = {
future: { entityData: [] },
Expand Down Expand Up @@ -58,6 +59,7 @@ const GROUP_DECISION_MATRIX: Record<StartDateGroup, Record<EndDateGroup, TimeGro

const DEFAULT_CHANNEL_GROUPS: AccordionGroups = {
favoriteChannels: { entityData: [] },
recents: { entityData: [] },
generalChannels: { entityData: [] },
exerciseChannels: { entityData: [] },
lectureChannels: { entityData: [] },
Expand Down Expand Up @@ -169,20 +171,28 @@ export class CourseOverviewService {
return 'future';
}

getConversationGroup(conversation: ConversationDTO): ChannelGroupCategory {
if (conversation.isFavorite) {
return 'favoriteChannels';
}
getConversationGroup(conversation: ConversationDTO): ChannelGroupCategory[] {
const groups: ChannelGroupCategory[] = [];

if (conversation.isHidden) {
return 'hiddenChannels';
groups.push('hiddenChannels');
return groups;
}
if (isGroupChatDTO(conversation)) {
return 'groupChats';

if (conversation.isFavorite) {
groups.push('favoriteChannels');
}
if (isOneToOneChatDTO(conversation)) {
return 'directMessages';

if (isGroupChatDTO(conversation)) {
groups.push('groupChats');
} else if (isOneToOneChatDTO(conversation)) {
groups.push('directMessages');
} else {
const subTypeGroup = this.getCorrespondingChannelSubType(getAsChannelDTO(conversation)?.subType);
groups.push(subTypeGroup);
}
return this.getCorrespondingChannelSubType(getAsChannelDTO(conversation)?.subType);

return groups;
}

getCorrespondingChannelSubType(channelSubType: ChannelSubType | undefined): ChannelGroupCategory {
Expand Down Expand Up @@ -219,7 +229,7 @@ export class CourseOverviewService {
return groupedLectureGroups;
}

groupConversationsByChannelType(conversations: ConversationDTO[], messagingEnabled: boolean): AccordionGroups {
groupConversationsByChannelType(course: Course, conversations: ConversationDTO[], messagingEnabled: boolean): AccordionGroups {
const channelGroups = messagingEnabled ? { ...DEFAULT_CHANNEL_GROUPS, groupChats: { entityData: [] }, directMessages: { entityData: [] } } : DEFAULT_CHANNEL_GROUPS;
const groupedConversationGroups = cloneDeep(channelGroups) as AccordionGroups;

Expand Down Expand Up @@ -251,11 +261,21 @@ export class CourseOverviewService {
};

for (const conversation of conversations) {
const conversationGroup = this.getConversationGroup(conversation);
const conversationCardItem = this.mapConversationToSidebarCardElement(conversation);
groupedConversationGroups[conversationGroup].entityData.push(conversationCardItem);
const conversationGroups = this.getConversationGroup(conversation);
const conversationCardItem = this.mapConversationToSidebarCardElement(course, conversation);

for (const group of conversationGroups) {
groupedConversationGroups[group].entityData.push(conversationCardItem);
}
}

for (const group in groupedConversationGroups) {
groupedConversationGroups[group].entityData.sort((a, b) => {
const aIsFavorite = a.conversation?.isFavorite ? 1 : 0;
const bIsFavorite = b.conversation?.isFavorite ? 1 : 0;
return bIsFavorite - aIsFavorite;
});
}
return groupedConversationGroups;
}

Expand All @@ -273,8 +293,8 @@ export class CourseOverviewService {
return exams.map((exam, index) => this.mapExamToSidebarCardElement(exam, studentExams?.[index]));
}

mapConversationsToSidebarCardElements(conversations: ConversationDTO[]) {
return conversations.map((conversation) => this.mapConversationToSidebarCardElement(conversation));
mapConversationsToSidebarCardElements(course: Course, conversations: ConversationDTO[]) {
return conversations.map((conversation) => this.mapConversationToSidebarCardElement(course, conversation));
}

mapLectureToSidebarCardElement(lecture: Lecture): SidebarCardElement {
Expand Down Expand Up @@ -349,14 +369,36 @@ export class CourseOverviewService {
}
}

mapConversationToSidebarCardElement(conversation: ConversationDTO): SidebarCardElement {
mapConversationToSidebarCardElement(course: Course, conversation: ConversationDTO): SidebarCardElement {
let isCurrent = false;
const channelDTO = getAsChannelDTO(conversation);
const subTypeRefId = channelDTO?.subTypeReferenceId;
const now = dayjs();
const oneAndHalfWeekBefore = now.subtract(1.5, 'week');
const oneAndHalfWeekLater = now.add(1.5, 'week');
let relevantDate = null;
if (subTypeRefId && course.exercises && channelDTO?.subType === 'exercise') {
const exercise = course.exercises.find((exercise) => exercise.id === subTypeRefId);
const relevantDates = [exercise?.releaseDate, exercise?.dueDate].filter(Boolean);
isCurrent = relevantDates.some((date) => dayjs(date).isBetween(oneAndHalfWeekBefore, oneAndHalfWeekLater, 'day', '[]'));
} else if (subTypeRefId && course.lectures && channelDTO?.subType === 'lecture') {
const lecture = course.lectures.find((lecture) => lecture.id === subTypeRefId);
relevantDate = lecture?.startDate || null;
isCurrent = relevantDate ? dayjs(relevantDate).isBetween(oneAndHalfWeekBefore, oneAndHalfWeekLater, 'day', '[]') : false;
} else if (subTypeRefId && course.exams && channelDTO?.subType === 'exam') {
const exam = course.exams.find((exam) => exam.id === subTypeRefId);
relevantDate = exam?.startDate || null;
isCurrent = relevantDate ? dayjs(relevantDate).isBetween(oneAndHalfWeekBefore, oneAndHalfWeekLater, 'day', '[]') : false;
}

const conversationCardItem: SidebarCardElement = {
title: this.conversationService.getConversationName(conversation) ?? '',
id: conversation.id ?? '',
type: conversation.type,
icon: this.getChannelIcon(conversation),
conversation: conversation,
size: 'S',
isCurrent: isCurrent,
};
return conversationCardItem;
}
Expand Down
3 changes: 1 addition & 2 deletions src/main/webapp/app/shared/sidebar/sidebar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { faCheckDouble, faFilter, faFilterCircleXmark, faHashtag, faPeopleGroup,
import { ActivatedRoute, Params } from '@angular/router';
import { Subscription, distinctUntilChanged } from 'rxjs';
import { ProfileService } from '../layouts/profiles/profile.service';
import { ChannelAccordionShowAdd, ChannelTypeIcons, CollapseState, SidebarCardSize, SidebarData, SidebarItemShowAlways, SidebarTypes } from 'app/types/sidebar';
import { ChannelTypeIcons, CollapseState, SidebarCardSize, SidebarData, SidebarItemShowAlways, SidebarTypes } from 'app/types/sidebar';
asliayk marked this conversation as resolved.
Show resolved Hide resolved
import { SidebarEventService } from './sidebar-event.service';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { cloneDeep } from 'lodash-es';
Expand Down Expand Up @@ -33,7 +33,6 @@ export class SidebarComponent implements OnDestroy, OnChanges, OnInit {
@Input() sidebarData: SidebarData;
@Input() courseId?: number;
@Input() itemSelected?: boolean;
@Input() showAddOption?: ChannelAccordionShowAdd;
@Input() channelTypeIcon?: ChannelTypeIcons;
@Input() collapseState: CollapseState;
sidebarItemAlwaysShow = input.required<SidebarItemShowAlways>();
Expand Down
4 changes: 3 additions & 1 deletion src/main/webapp/app/types/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type AccordionGroups = Record<
>;
export type ChannelGroupCategory =
| 'favoriteChannels'
| 'recents'
| 'generalChannels'
| 'exerciseChannels'
| 'lectureChannels'
Expand All @@ -27,7 +28,6 @@ export type ChannelGroupCategory =
export type CollapseState = {
[key: string]: boolean;
} & (Record<TimeGroupCategory, boolean> | Record<ChannelGroupCategory, boolean> | Record<ExamGroupCategory, boolean> | Record<TutorialGroupCategory, boolean>);
export type ChannelAccordionShowAdd = Record<ChannelGroupCategory, boolean>;
export type ChannelTypeIcons = Record<ChannelGroupCategory, IconProp>;
export type SidebarItemShowAlways = {
[key: string]: boolean;
Expand Down Expand Up @@ -135,4 +135,6 @@ export interface SidebarCardElement {
* Set for Conversation. Will be removed after refactoring
*/
conversation?: ConversationDTO;

isCurrent?: boolean;
}
3 changes: 2 additions & 1 deletion src/main/webapp/i18n/de/student-dashboard.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@
"groupChats": "Gruppenchats",
"directMessages": "Direktnachrichten",
"filterConversationPlaceholder": "Konversationen filtern",
"setChannelAsRead": "Alle Kanäle als gelesen markieren"
"setChannelAsRead": "Alle Kanäle als gelesen markieren",
"recents": "Kürzliches"
},
"menu": {
"exercises": "Aufgaben",
Expand Down
3 changes: 2 additions & 1 deletion src/main/webapp/i18n/en/student-dashboard.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@
"groupChats": "Group Chats",
"directMessages": "Direct Messages",
"filterConversationPlaceholder": "Filter conversations",
"setChannelAsRead": "Mark all channels as read"
"setChannelAsRead": "Mark all channels as read",
"recents": "Recents"
},
"menu": {
"exercises": "Exercises",
Expand Down
Loading
Loading