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: Refactor consecutive message view #9456

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
1 change: 1 addition & 0 deletions src/main/webapp/app/entities/metis/answer-post.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Posting } from 'app/entities/metis/posting.model';
export class AnswerPost extends Posting {
public resolvesPost?: boolean;
public post?: Post;
public isConsecutive?: boolean = false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

LGTM! Consider adding a comment for clarity.

The addition of the isConsecutive property aligns well with the PR objectives for enhancing message grouping. The implementation follows the coding guidelines, using camelCase for property naming.

Consider adding a brief comment explaining the purpose of the isConsecutive property for better code documentation. For example:

// Indicates whether this post is part of a consecutive message group
public isConsecutive?: boolean = false;


constructor() {
super();
Expand Down
1 change: 1 addition & 0 deletions src/main/webapp/app/entities/metis/post.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class Post extends Posting {
public conversation?: Conversation;
public displayPriority?: DisplayPriority;
public resolved?: boolean;
public isConsecutive?: boolean = false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

LGTM! Consider making the property non-optional for type safety.

The addition of the isConsecutive property aligns well with the PR objectives for enhancing message grouping. The naming and default value are appropriate.

For improved type safety, consider making the property non-optional:

public isConsecutive: boolean = false;

This change would eliminate the need for null checks when using this property elsewhere in the codebase.


constructor() {
super();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,24 @@
>
<!-- list of all top level posts -->
<!-- answers are opened in the thread sidebar -->
@for (post of posts; track postsTrackByFn($index, post)) {
<div>
<jhi-posting-thread
#postingThread
[lastReadDate]="_activeConversation?.lastReadDate"
[hasChannelModerationRights]="!!getAsChannel(_activeConversation)?.hasChannelModerationRights"
[id]="'item-' + post.id"
[post]="post"
[showAnswers]="false"
[readOnlyMode]="!!getAsChannel(_activeConversation)?.isArchived"
[isCommunicationPage]="true"
(openThread)="setPostForThread($event)"
/>
@for (group of groupedPosts; track postsTrackByFn($index, group)) {
<div class="message-group">
@for (post of group.posts; track postsTrackByFn($index, post)) {
<div class="post-item">
<jhi-posting-thread
#postingThread
[lastReadDate]="_activeConversation?.lastReadDate"
[hasChannelModerationRights]="!!getAsChannel(_activeConversation)?.hasChannelModerationRights"
[id]="'item-' + post.id"
[post]="post"
[showAnswers]="false"
[readOnlyMode]="!!getAsChannel(_activeConversation)?.isArchived"
[isCommunicationPage]="true"
(openThread)="setPostForThread($event)"
[isConsecutive]="post.isConsecutive || false"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Consider using the nullish coalescing operator for default values

Instead of using the logical OR || to assign a default value to [isConsecutive], consider using the nullish coalescing operator ?? for clarity and to handle falsy values correctly:

-[isConsecutive]="post.isConsecutive || false"
+[isConsecutive]="post.isConsecutive ?? false"

This ensures that if post.isConsecutive is explicitly false, it remains false, and only null or undefined values are replaced with false.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[isConsecutive]="post.isConsecutive || false"
[isConsecutive]="post.isConsecutive ?? false"

></jhi-posting-thread>
</div>
}
</div>
}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,25 @@
padding-bottom: 100px;
}
}

.message-group {
display: flex;
flex-direction: column;
margin-bottom: 10px;
}

.grouped-posts {
margin-left: 30px;
padding-left: 10px;
}
Comment on lines +70 to +73
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

LGTM: Good indentation for grouped posts

The .grouped-posts class creates an effective indentation for grouped messages, which helps distinguish between the main message and subsequent grouped messages. This aligns well with the PR objective of grouping messages from the same user sent within a one-hour timeframe.

Consider using CSS variables for the margin and padding values to maintain consistency and ease future adjustments. For example:

:root {
  --grouped-posts-left-margin: 30px;
  --grouped-posts-left-padding: 10px;
}

.grouped-posts {
  margin-left: var(--grouped-posts-left-margin);
  padding-left: var(--grouped-posts-left-padding);
}


.grouped-posts,
.grouped-post {
margin-top: 0;
margin-bottom: 0;
padding: 0;
}

jhi-posting-thread {
margin-bottom: 5px;
}
Comment on lines +82 to +84
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

LGTM: Appropriate spacing for posting threads

The addition of a 5px bottom margin to the jhi-posting-thread element provides a subtle separation between posting threads, which enhances the overall visual hierarchy and readability of the conversation.

Consider using a class selector instead of an element selector to be more consistent with BEM naming conventions and to improve the modularity of your styles. For example:

.posting-thread {
  margin-bottom: 5px;
}

Then, apply this class to your jhi-posting-thread element in the HTML template.

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ import { MetisConversationService } from 'app/shared/metis/metis-conversation.se
import { OneToOneChat, isOneToOneChatDTO } from 'app/entities/metis/conversation/one-to-one-chat.model';
import { canCreateNewMessageInConversation } from 'app/shared/metis/conversations/conversation-permissions.utils';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
import dayjs from 'dayjs/esm';
import { User } from 'app/core/user/user.model';

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ standalone: true, name: 'dayjsToDate' })
export class DayjsToDatePipe implements PipeTransform {
transform(value: dayjs.Dayjs | undefined): Date | undefined {
return value ? value.toDate() : undefined;
}
}

interface PostGroup {
author: User | undefined;
posts: Post[];
}

@Component({
selector: 'jhi-conversation-messages',
Expand Down Expand Up @@ -69,6 +85,7 @@ export class ConversationMessagesComponent implements OnInit, AfterViewInit, OnD

newPost?: Post;
posts: Post[] = [];
groupedPosts: PostGroup[] = [];
totalNumberOfPosts = 0;
page = 1;
public isFetchingPosts = true;
Expand Down Expand Up @@ -159,11 +176,70 @@ export class ConversationMessagesComponent implements OnInit, AfterViewInit, OnD
};
}

toDate(dayjsDate: dayjs.Dayjs | undefined): Date | undefined {
return dayjsDate ? dayjsDate.toDate() : undefined;
}
Comment on lines +180 to +182
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Eliminate duplicate code by removing the toDate method

The toDate method duplicates the functionality of the DayjsToDatePipe. To adhere to the DRY (Don't Repeat Yourself) principle and promote code reuse, consider removing the toDate method and using the DayjsToDatePipe wherever date conversion is needed.


private groupPosts(): void {
if (!this.posts || this.posts.length === 0) {
this.groupedPosts = [];
return;
}

const sortedPosts = this.posts.sort((a, b) => {
const aDate = (a as any).creationDateAsDate;
const bDate = (b as any).creationDateAsDate;
Comment on lines +191 to +192
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Replace as any casts with proper typings

Using as any to access creationDateAsDate circumvents TypeScript's type checking. Define an extended Post interface that includes creationDateAsDate to maintain type safety and improve code clarity.

Also applies to: 205-206

return (aDate?.getTime() || 0) - (bDate?.getTime() || 0);
});

const groups: PostGroup[] = [];
let currentGroup: PostGroup = {
author: sortedPosts[0].author,
posts: [{ ...sortedPosts[0], isConsecutive: false }],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid adding isConsecutive property directly to Post objects

Adding isConsecutive directly to Post instances may cause unintended side effects if Post objects are used elsewhere. Consider defining an interface or class that extends Post to include isConsecutive, or use a separate data structure to store this information.

Also applies to: 214-214

};

for (let i = 1; i < sortedPosts.length; i++) {
const currentPost = sortedPosts[i];
const lastPostInGroup = currentGroup.posts[currentGroup.posts.length - 1];

const currentDate = (currentPost as any).creationDateAsDate;
const lastDate = (lastPostInGroup as any).creationDateAsDate;

let timeDiff = Number.MAX_SAFE_INTEGER;
if (currentDate && lastDate) {
timeDiff = Math.abs(currentDate.getTime() - lastDate.getTime()) / 60000;
}

if (currentPost.author?.id === currentGroup.author?.id && timeDiff <= 60) {
currentGroup.posts.push({ ...currentPost, isConsecutive: true }); // consecutive post
} else {
groups.push(currentGroup);
currentGroup = {
author: currentPost.author,
posts: [{ ...currentPost, isConsecutive: false }],
};
}
}

groups.push(currentGroup);
this.groupedPosts = groups;
this.cdr.detectChanges();
}

setPosts(posts: Post[]): void {
if (this.content) {
this.previousScrollDistanceFromTop = this.content.nativeElement.scrollHeight - this.content.nativeElement.scrollTop;
}
this.posts = posts.slice().reverse();

this.posts = posts
.slice()
.reverse()
.map((post) => {
(post as any).creationDateAsDate = post.creationDate ? dayjs(post.creationDate).toDate() : undefined;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid mutating Post objects by adding new properties

Adding creationDateAsDate directly to Post instances via type casting to any can introduce type safety issues and complicate maintenance. Consider creating a new interface or class that extends Post and includes the additional property, or use a mapping structure to avoid mutating the original objects.

return post;
});

this.groupPosts();
}

fetchNextPage() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,51 @@
<div [id]="'item-' + posting.id" class="row" [ngClass]="isCommunicationPage ? 'module-bg mt-2 rounded-2' : 'answer-post m-1'">
<jhi-answer-post-header
[posting]="posting"
[isReadOnlyMode]="isReadOnlyMode"
(openPostingCreateEditModal)="createAnswerPostModal.open()"
[isCommunicationPage]="isCommunicationPage"
[lastReadDate]="lastReadDate"
[hasChannelModerationRights]="hasChannelModerationRights"
/>
@if (!isConsecutive) {
<jhi-answer-post-header
[posting]="posting"
[isReadOnlyMode]="isReadOnlyMode"
[isCommunicationPage]="isCommunicationPage"
[lastReadDate]="lastReadDate"
[hasChannelModerationRights]="hasChannelModerationRights"
/>
}
@if (!createAnswerPostModal.isInputOpen) {
<div class="answer-post-content-margin">
<jhi-posting-content
[content]="posting.content"
[isEdited]="!!posting.updatedDate"
[author]="posting.author"
[posting]="posting"
[isReply]="true"
(userReferenceClicked)="userReferenceClicked.emit($event)"
(channelReferenceClicked)="channelReferenceClicked.emit($event)"
/>
<div class="answer-post-content-margin message-container">
<div class="message-content">
<jhi-posting-content
[content]="posting.content"
[isEdited]="!!posting.updatedDate"
[author]="posting.author"
[posting]="posting"
[isReply]="true"
(userReferenceClicked)="userReferenceClicked.emit($event)"
(channelReferenceClicked)="channelReferenceClicked.emit($event)"
/>
<div class="answer-post-content-margin hover-actions">
<jhi-answer-post-reactions-bar
[isReadOnlyMode]="isReadOnlyMode"
[posting]="posting"
[isLastAnswer]="isLastAnswer"
[isThreadSidebar]="isThreadSidebar"
(openPostingCreateEditModal)="createAnswerPostModal.open()"
(reactionsUpdated)="onReactionsUpdated($event)"
/>
</div>
</div>
Comment on lines 11 to +33
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

LGTM: New structure aligns with PR objectives

The new structure with the hover-actions div and the placement of jhi-answer-post-reactions-bar within it aligns well with the PR objective of displaying all message actions side by side on hover. The use of @if is correct and follows our coding guidelines.

Consider adding an aria-label to the hover-actions div to improve accessibility. For example:

- <div class="answer-post-content-margin hover-actions">
+ <div class="answer-post-content-margin hover-actions" aria-label="Message actions">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@if (!createAnswerPostModal.isInputOpen) {
<div class="answer-post-content-margin">
<jhi-posting-content
[content]="posting.content"
[isEdited]="!!posting.updatedDate"
[author]="posting.author"
[posting]="posting"
[isReply]="true"
(userReferenceClicked)="userReferenceClicked.emit($event)"
(channelReferenceClicked)="channelReferenceClicked.emit($event)"
/>
<div class="answer-post-content-margin message-container">
<div class="message-content">
<jhi-posting-content
[content]="posting.content"
[isEdited]="!!posting.updatedDate"
[author]="posting.author"
[posting]="posting"
[isReply]="true"
(userReferenceClicked)="userReferenceClicked.emit($event)"
(channelReferenceClicked)="channelReferenceClicked.emit($event)"
/>
<div class="answer-post-content-margin hover-actions">
<jhi-answer-post-reactions-bar
[isReadOnlyMode]="isReadOnlyMode"
[posting]="posting"
[isLastAnswer]="isLastAnswer"
[isThreadSidebar]="isThreadSidebar"
(openPostingCreateEditModal)="createAnswerPostModal.open()"
(reactionsUpdated)="onReactionsUpdated($event)"
/>
</div>
</div>
@if (!createAnswerPostModal.isInputOpen) {
<div class="answer-post-content-margin message-container">
<div class="message-content">
<jhi-posting-content
[content]="posting.content"
[isEdited]="!!posting.updatedDate"
[author]="posting.author"
[posting]="posting"
[isReply]="true"
(userReferenceClicked)="userReferenceClicked.emit($event)"
(channelReferenceClicked)="channelReferenceClicked.emit($event)"
/>
<div class="answer-post-content-margin hover-actions" aria-label="Message actions">
<jhi-answer-post-reactions-bar
[isReadOnlyMode]="isReadOnlyMode"
[posting]="posting"
[isLastAnswer]="isLastAnswer"
[isThreadSidebar]="isThreadSidebar"
(openPostingCreateEditModal)="createAnswerPostModal.open()"
(reactionsUpdated)="onReactionsUpdated($event)"
/>
</div>
</div>

</div>
}
<div class="answer-post-content-margin">
<ng-container #createEditAnswerPostContainer />
</div>
<div class="answer-post-content-margin">
<jhi-answer-post-footer
<jhi-answer-post-reactions-bar
[isReadOnlyMode]="isReadOnlyMode"
[posting]="posting"
[isLastAnswer]="isLastAnswer"
[isThreadSidebar]="isThreadSidebar"
(openPostingCreateEditModal)="openPostingCreateEditModal.emit()"
(openPostingCreateEditModal)="createAnswerPostModal.open()"
(reactionsUpdated)="onReactionsUpdated($event)"
[isEmojiCount]="true"
/>
Comment on lines +40 to 48
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

LGTM: Standalone reactions bar for emoji counts

The addition of a standalone jhi-answer-post-reactions-bar with [isEmojiCount]="true" aligns with the PR objective of adding an emoji add button next to existing emoji reactions. This implementation allows for a clear separation between the hover actions and the persistent emoji count display.

For consistency, consider moving the [isEmojiCount]="true" property to be with the other input properties:

<jhi-answer-post-reactions-bar
    [isReadOnlyMode]="isReadOnlyMode"
    [posting]="posting"
    [isLastAnswer]="isLastAnswer"
    [isThreadSidebar]="isThreadSidebar"
+   [isEmojiCount]="true"
    (openPostingCreateEditModal)="createAnswerPostModal.open()"
    (reactionsUpdated)="onReactionsUpdated($event)"
-   [isEmojiCount]="true"
/>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<jhi-answer-post-reactions-bar
[isReadOnlyMode]="isReadOnlyMode"
[posting]="posting"
[isLastAnswer]="isLastAnswer"
[isThreadSidebar]="isThreadSidebar"
(openPostingCreateEditModal)="openPostingCreateEditModal.emit()"
(openPostingCreateEditModal)="createAnswerPostModal.open()"
(reactionsUpdated)="onReactionsUpdated($event)"
[isEmojiCount]="true"
/>
<jhi-answer-post-reactions-bar
[isReadOnlyMode]="isReadOnlyMode"
[posting]="posting"
[isLastAnswer]="isLastAnswer"
[isThreadSidebar]="isThreadSidebar"
[isEmojiCount]="true"
(openPostingCreateEditModal)="createAnswerPostModal.open()"
(reactionsUpdated)="onReactionsUpdated($event)"
/>

</div>
</div>
<jhi-answer-post-create-edit-modal #createAnswerPostModal [posting]="posting" [createEditAnswerPostContainerRef]="containerRef" />
<jhi-answer-post-create-edit-modal #createAnswerPostModal [posting]="posting" (postingUpdated)="onPostingUpdated($event)" [createEditAnswerPostContainerRef]="containerRef" />
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,52 @@
.answer-post-content-margin {
padding-left: 3.2rem;
}

.message-container {
position: relative;
border-radius: 5px;
transition: background-color 0.3s ease;
}
Comment on lines +10 to +14
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

LGTM! Consider adding box-shadow for depth.

The .message-container class is well-structured and aligns with the PR objectives. The relative positioning and border-radius enhance the visual appeal, while the transition prepares for smooth hover effects.

To further improve the visual hierarchy, consider adding a subtle box-shadow:

 .message-container {
     position: relative;
     border-radius: 5px;
     transition: background-color 0.3s ease;
+    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.message-container {
position: relative;
border-radius: 5px;
transition: background-color 0.3s ease;
}
.message-container {
position: relative;
border-radius: 5px;
transition: background-color 0.3s ease;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}


.message-content {
padding-left: 0.3rem;
}

.message-container:hover {
background: var(--metis-selection-option-hover-background);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

LGTM! Consider adding keyboard focus styles for accessibility.

The hover effect for .message-container is well-implemented and aligns with the PR objectives. To improve accessibility, consider adding styles for keyboard focus as suggested in the previous review:

-.message-container:hover {
+.message-container:hover,
+.message-container:focus-within {
     background: var(--metis-selection-option-hover-background);
 }

This ensures that keyboard users can also access the hover state.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.message-container:hover {
background: var(--metis-selection-option-hover-background);
}
.message-container:hover,
.message-container:focus-within {
background: var(--metis-selection-option-hover-background);
}


.hover-actions {
position: absolute;
top: 0;
right: 1%;
display: flex;
gap: 10px;
visibility: hidden;
transition:
opacity 0.2s ease-in-out,
visibility 0.2s ease-in-out;
background: var(--metis-selection-option-background);
padding: 5px;
border-radius: 5px;
}

.message-container:hover .hover-actions {
opacity: 1;
visibility: visible;
}
Comment on lines +40 to +43
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

LGTM! Consider adding keyboard focus styles for accessibility.

The implementation for showing hover actions when the message container is hovered over is well done. To improve accessibility, consider adding styles for keyboard focus:

-.message-container:hover .hover-actions {
+.message-container:hover .hover-actions,
+.message-container:focus-within .hover-actions {
     opacity: 1;
     visibility: visible;
 }

This ensures that keyboard users can also access the hover actions.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.message-container:hover .hover-actions {
opacity: 1;
visibility: visible;
}
.message-container:hover .hover-actions,
.message-container:focus-within .hover-actions {
opacity: 1;
visibility: visible;
}


.clickable {
cursor: pointer;
}

.reactionIcon,
.editIcon,
.deleteIcon {
font-size: 1rem;
color: var(--metis-blue);
}

.hover-actions .clickable:hover {
color: var(--bs-white);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

LGTM! Consider using a CSS variable for icon size.

The icon styles and hover effects are well-implemented, providing consistent sizing and clear visual feedback. The use of CSS variables for colors ensures theme consistency.

For improved maintainability, consider using a CSS variable for the icon size:

+:root {
+    --metis-icon-size: 1rem;
+}

 .reactionIcon,
 .editIcon,
 .deleteIcon {
-    font-size: 1rem;
+    font-size: var(--metis-icon-size);
     color: var(--metis-blue);
 }

This makes it easier to adjust the icon size globally if needed.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.reactionIcon,
.editIcon,
.deleteIcon {
font-size: 1rem;
color: var(--metis-blue);
}
.hover-actions .clickable:hover {
color: var(--bs-white);
}
:root {
--metis-icon-size: 1rem;
}
.reactionIcon,
.editIcon,
.deleteIcon {
font-size: var(--metis-icon-size);
color: var(--metis-blue);
}
.hover-actions .clickable:hover {
color: var(--bs-white);
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewCh
import { AnswerPost } from 'app/entities/metis/answer-post.model';
import { PostingDirective } from 'app/shared/metis/posting.directive';
import dayjs from 'dayjs/esm';
import { Posting } from 'app/entities/metis/posting.model';
import { Reaction } from 'app/entities/metis/reaction.model';

@Component({
selector: 'jhi-answer-post',
Expand All @@ -20,4 +22,13 @@ export class AnswerPostComponent extends PostingDirective<AnswerPost> {
isReadOnlyMode = false;
// ng-container to render answerPostCreateEditModalComponent
@ViewChild('createEditAnswerPostContainer', { read: ViewContainerRef }) containerRef: ViewContainerRef;
@Input() isConsecutive: boolean = false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Remove unnecessary type annotation

The type of isConsecutive is inferred from its initialization. You can omit the explicit type annotation : boolean.

Apply this diff to remove the redundant type annotation:

- @Input() isConsecutive: boolean = false;
+ @Input() isConsecutive = false;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Input() isConsecutive: boolean = false;
@Input() isConsecutive = false;
🧰 Tools
🪛 Biome

[error] 25-25: This type annotation is trivially inferred from its initialization.

Safe fix: Remove the type annotation.

(lint/style/noInferrableTypes)


onPostingUpdated(updatedPosting: Posting) {
this.posting = updatedPosting;
}
Comment on lines +27 to +29
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Add unit tests for onPostingUpdated method

To ensure the correctness and maintainability of the onPostingUpdated method, please add meaningful unit tests.

I can assist in creating unit tests or open a GitHub issue to track this task.


onReactionsUpdated(updatedReactions: Reaction[]) {
this.posting = { ...this.posting, reactions: updatedReactions };
}
Comment on lines +31 to +33
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Add unit tests for onReactionsUpdated method

To ensure the correctness and maintainability of the onReactionsUpdated method, please add meaningful unit tests.

I can assist in creating unit tests or open a GitHub issue to track this task.

}
3 changes: 0 additions & 3 deletions src/main/webapp/app/shared/metis/metis.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { AnswerPostHeaderComponent } from 'app/shared/metis/posting-header/answe
import { PostHeaderComponent } from 'app/shared/metis/posting-header/post-header/post-header.component';
import { AnswerPostCreateEditModalComponent } from 'app/shared/metis/posting-create-edit-modal/answer-post-create-edit-modal/answer-post-create-edit-modal.component';
import { PostCreateEditModalComponent } from 'app/shared/metis/posting-create-edit-modal/post-create-edit-modal/post-create-edit-modal.component';
import { AnswerPostFooterComponent } from 'app/shared/metis/posting-footer/answer-post-footer/answer-post-footer.component';
import { PostFooterComponent } from 'app/shared/metis/posting-footer/post-footer/post-footer.component';
import { PostTagSelectorComponent } from 'app/shared/metis/posting-create-edit-modal/post-create-edit-modal/post-tag-selector/post-tag-selector.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
Expand Down Expand Up @@ -72,7 +71,6 @@ import { MetisConversationService } from 'app/shared/metis/metis-conversation.se
PostTagSelectorComponent,
PostFooterComponent,
AnswerPostCreateEditModalComponent,
AnswerPostFooterComponent,
PostingButtonComponent,
PostingMarkdownEditorComponent,
PostComponent,
Expand All @@ -99,7 +97,6 @@ import { MetisConversationService } from 'app/shared/metis/metis-conversation.se
PostTagSelectorComponent,
AnswerPostCreateEditModalComponent,
PostFooterComponent,
AnswerPostFooterComponent,
PostingButtonComponent,
PostingMarkdownEditorComponent,
PostComponent,
Expand Down
Loading
Loading