Skip to content

Commit

Permalink
add kommentar functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
dysTOS committed Apr 2, 2024
1 parent b982d6b commit 0f7ace3
Show file tree
Hide file tree
Showing 12 changed files with 293 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ import { CircleParallelMinorPipePipe } from './tools/pipes/circle-parallel-minor
import { MitgliedInstrumenteListComponent } from './components/mitglieder/mitglied-instrumente-list/mitglied-instrumente-list.component';
import { MkjRatingComponent } from './utilities/form-input-components/mkj-rating/mkj-rating.component';
import { MkjUserNotificationsComponent } from './utilities/mkj-user-notifications/mkj-user-notifications.component';
import { MkjCommentsComponent } from './utilities/mkj-comments/mkj-comments.component';

// FullCalendarModule.registerPlugins([
// dayGridPlugin,
Expand Down Expand Up @@ -416,6 +417,7 @@ registerLocaleData(localeDe);
MitgliedInstrumenteListComponent,
MkjRatingComponent,
MkjUserNotificationsComponent,
MkjCommentsComponent,
],
providers: [
mkjAppInitializer(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
(click)="navigateToEditView(noten)"
></button>
</div>

<div class="card">
<mkj-comments [modelType]="'noten'" [modelId]="noten.id"></mkj-comments>
</div>
</ng-template>

<ng-template #bewertungTemplate let-noten>
Expand Down
15 changes: 15 additions & 0 deletions src/app/models/Kommentar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ModelType } from './_ModelType';

export interface Kommentar {
id?: string;
text?: string;
commentable_type?: ModelType;
commentable_id?: string;
mitglied_id?: number;
mitglied_name?: string;
number_child_comments?: number;
parent_comment_id?: string;
created_at?: string;
updated_at?: string;
subComments?: Kommentar[];
}
5 changes: 5 additions & 0 deletions src/app/models/_ModelType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum ModelType {
Kommentar = 'kommentar',
Mitglied = 'mitglied',
Noten = 'noten',
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Observable } from 'rxjs';
import { GetListOutput } from 'src/app/interfaces/api-middleware';
import { KeyOf } from 'src/app/types/KeyOf';
import { GenericFieldValue } from 'src/app/utilities/_list-datasources/generic-field-values-datasource.class';

export interface GenericFieldValueService {
Expand Down
15 changes: 15 additions & 0 deletions src/app/services/api/kommentar-api.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Kommentar } from 'src/app/models/Kommentar';
import { AbstractCrudApiService } from './_abstract-crud-api-service.class';

@Injectable({
providedIn: 'root',
})
export class KommentarApiService extends AbstractCrudApiService<Kommentar> {
protected controllerApiUrlKey = 'kommentare';

constructor(httpClient: HttpClient) {
super(httpClient);
}
}
3 changes: 2 additions & 1 deletion src/app/services/api/noten-api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { environment } from 'src/environments/environment';
import { Noten } from '../../models/Noten';
import { AbstractCrudApiService } from './_abstract-crud-api-service.class';
import { KeyOf } from 'src/app/types/KeyOf';
import { GenericFieldValueService } from './_generic-field-value-serivce.interface';

@Injectable({
providedIn: 'root',
})
export class NotenApiService extends AbstractCrudApiService<Noten> {
export class NotenApiService extends AbstractCrudApiService<Noten> implements GenericFieldValueService {
protected controllerApiUrlKey: string = 'noten';
private apiURL = environment.apiUrl;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface DisplayModelConfiguration<T> {
fields: DisplayModelField<T>[];
rateable?: boolean;
commentable?: boolean;
}

export interface DisplayModelField<T> {
Expand Down
81 changes: 81 additions & 0 deletions src/app/utilities/mkj-comments/mkj-comments.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
@for (c of comments; track c) {
<ng-template [ngTemplateOutlet]="commentTemplate" [ngTemplateOutletContext]="{ $implicit: c }"></ng-template>
}
@if (subCommentId == null) {
<div class="mt-4">
<ng-template [ngTemplateOutlet]="inputTemplate"></ng-template>
</div>
}

<ng-template #commentTemplate let-comment>
<div class="comment">
<div class="comment__header">
<div>
<i class="pi pi-user header-icon mr-2"></i
><span class="header-text">
{{ comment.mitglied_name }}
</span>
</div>
<span class="date">
{{ comment.updated_at | date: 'E d. MMM yyyy | HH:mm' }}
</span>
</div>
<div class="comment__text">{{ comment.text }}</div>
<div class="comment__footer">
<div>
@if (comment.number_child_comments > 0) {
<button
pButton
class="p-button-small p-button-text p-button-secondary"
label="Antworten: {{ comment.number_child_comments }}"
[icon]="comment.loading ? 'pi pi-spin pi-spinner' : 'pi pi-arrow-down'"
[disabled]="comment.loading"
(click)="getComments(comment)"
></button>
}
</div>
<button
pButton
class="p-button-small p-button-text p-button-secondary"
[label]="subCommentId === comment.id ? 'Abbrechen' : 'Kommentieren'"
[icon]="subCommentId === comment.id ? 'pi pi-times' : null"
(click)="this.initCommentInput(comment)"
></button>
</div>
@if (subCommentId === comment.id) {
<div class="comment__input_wrapper">
<ng-template
[ngTemplateOutlet]="inputTemplate"
[ngTemplateOutletContext]="{ $implicit: comment }"
></ng-template>
</div>
}
@if (comment.subComments?.length > 0) {
<div class="comment__subcomments">
@for (c of comment.subComments; track c) {
<ng-template [ngTemplateOutlet]="commentTemplate" [ngTemplateOutletContext]="{ $implicit: c }"></ng-template>
}
</div>
}
</div>
</ng-template>

<ng-template #inputTemplate let-comment>
<div class="comment__input">
<mkj-text-input
label="Kommentar"
placeholder="Kommentieren..."
class="w-full"
[disabled]="saving"
[(value)]="commentText"
(onEnter)="createComment(comment)"
></mkj-text-input>
<button
pButton
class="p-button-small p-button-text p-button-secondary"
[icon]="saving ? 'pi pi-spin pi-spinner' : 'pi pi-send'"
[disabled]="saving"
(click)="createComment(comment)"
></button>
</div>
</ng-template>
53 changes: 53 additions & 0 deletions src/app/utilities/mkj-comments/mkj-comments.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.comment {
display: flex;
flex-direction: column;

border: 1px solid var(--surface-200);
border-radius: 5px;

&__header {
display: flex;
gap: 0.5rem;
align-items: end;
justify-content: space-between;
padding: 10px;
font-weight: 600;
background: var(--surface-200);

.date {
font-weight: normal;
opacity: 0.7;
}
}

&__text {
padding: 10px;
}

&__footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
width: 100%;
}

&__subcomments {
display: flex;
flex-direction: column;
gap: 1rem;
margin-left: 3rem;
padding: 10px;
}

&__input_wrapper {
padding: 10px;
background: var(--surface-200);
}

&__input {
display: flex;
align-items: center;
justify-content: end;
}
}
114 changes: 114 additions & 0 deletions src/app/utilities/mkj-comments/mkj-comments.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { GetListInput } from 'src/app/interfaces/api-middleware';
import { Kommentar } from 'src/app/models/Kommentar';
import { ModelType } from 'src/app/models/_ModelType';
import { KommentarApiService } from 'src/app/services/api/kommentar-api.service';

@Component({
selector: 'mkj-comments',
templateUrl: './mkj-comments.component.html',
styleUrl: './mkj-comments.component.scss',
})
export class MkjCommentsComponent implements OnInit {
@Input({ required: true }) modelType: ModelType;
@Input({ required: true }) modelId: string;

@ViewChild('inputTemplate') inputTemplate: any;

public comments: Kommentar[] = [];
public commentText: string;
public subCommentId: string;

public saving = false;

constructor(private apiService: KommentarApiService) {}

public ngOnInit(): void {
this.getComments();
}

public getComments(parent?: Kommentar): void {
if (parent) {
(parent as any).loading = true;
}

const input: GetListInput<Kommentar> = {
filterAnd: [
{
field: 'commentable_type',
value: this.modelType,
},
{
field: 'commentable_id',
value: this.modelId,
},
{
field: 'parent_comment_id',
value: parent?.id || null,
operator: '=',
},
],
sort: {
field: 'updated_at',
order: 'asc',
},
};

this.apiService.getList(input).subscribe((response) => {
if (parent) {
parent.subComments = response.values;
(parent as any).loading = false;
} else {
this.comments = response.values;
}
});
}

public createComment(parent?: Kommentar): void {
this.saving = true;

this.apiService
.create({
text: this.commentText,
commentable_type: this.modelType,
commentable_id: this.modelId,
parent_comment_id: parent?.id,
})
.subscribe((response) => {
this.insertComment(response);
this.saving = false;
});
}

public initCommentInput(comment: Kommentar, text?: string): void {
this.subCommentId = this.subCommentId === comment.id ? null : comment.id;
this.commentText = text || '';
}

private insertComment(comment: Kommentar): void {
this.commentText = '';
this.subCommentId = null;
if (comment.parent_comment_id) {
const parent = this.findParentComment(comment, this.comments);
if (parent) {
parent.subComments = [...(parent.subComments ?? []), comment];
parent.number_child_comments++;
}
} else {
this.comments.push(comment);
}
}

private findParentComment(c: Kommentar, arr: Kommentar[]): Kommentar {
for (const item of arr) {
if (item.id === c.parent_comment_id) {
return item;
} else if (item.subComments) {
const result = this.findParentComment(c, item.subComments);
if (result) return result;
}
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<i
pBadge
class="pi pi-bell text-2xl cursor-pointer"
style="color: var(--primary-color-text)"
severity="warning"
[value]="this.menuItems.length"
[class.p-disabled]="this.menuItems.length === 0"
Expand Down

0 comments on commit 0f7ace3

Please sign in to comment.