Archived
comments
This commit is contained in:
1 parent
368cf265c5
commit
d035328d84
32 files changed
+426
-43
No files matched your search
@@ -31,6 +31,13 @@ const routes: Routes = [
|
|||||||
(m) => m.SolutionFormModule
|
(m) => m.SolutionFormModule
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'issue/:id/solution',
|
||||||
|
loadChildren: () =>
|
||||||
|
import('./modules/solution/solution.module').then(
|
||||||
|
(m) => m.SolutionModule
|
||||||
|
),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { SidebarModule } from 'primeng/sidebar';
|
|||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { IssueEffect } from './store/effect/issue.effect';
|
import { IssueEffect } from './store/effect/issue.effect';
|
||||||
|
import { SolutionEffect } from './store/effect/solution.effect';
|
||||||
import { issueReducer } from './store/reducer/issue.reducer';
|
import { issueReducer } from './store/reducer/issue.reducer';
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [AppComponent],
|
declarations: [AppComponent],
|
||||||
@@ -20,7 +21,7 @@ import { issueReducer } from './store/reducer/issue.reducer';
|
|||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
FontAwesomeModule,
|
FontAwesomeModule,
|
||||||
StoreModule.forRoot({ issueState: issueReducer }),
|
StoreModule.forRoot({ issueState: issueReducer }),
|
||||||
EffectsModule.forRoot([IssueEffect]),
|
EffectsModule.forRoot([IssueEffect, SolutionEffect]),
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: !isDevMode() }),
|
StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: !isDevMode() }),
|
||||||
SidebarModule,
|
SidebarModule,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { CommentModel } from './comment.model';
|
import { CommentModel } from './comment.model';
|
||||||
|
|
||||||
export interface SolutionModel {
|
export interface SolutionModel {
|
||||||
id?: string;
|
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
comments: CommentModel[];
|
comments: CommentModel[];
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { ModuleWithProviders, NgModule } from '@angular/core';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { CardModule } from 'primeng/card';
|
||||||
|
import { InputTextModule } from 'primeng/inputtext';
|
||||||
|
import { InputTextareaModule } from 'primeng/inputtextarea';
|
||||||
|
import { CommentFormComponent } from './components/comment-form/comment-form.component';
|
||||||
|
import { CommentComponent } from './components/comment/comment.component';
|
||||||
|
import { CommentsComponent } from './components/comments/comments.component';
|
||||||
|
import { CommentService, commentTypeToken } from './services/comment.service';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [CommentsComponent, CommentComponent, CommentFormComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
CardModule,
|
||||||
|
InputTextModule,
|
||||||
|
ButtonModule,
|
||||||
|
InputTextareaModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
],
|
||||||
|
exports: [CommentsComponent],
|
||||||
|
providers: [CommentService],
|
||||||
|
})
|
||||||
|
export class CommentModule {
|
||||||
|
static forRoot(
|
||||||
|
commentType: 'solution' | 'issues'
|
||||||
|
): ModuleWithProviders<CommentModule> {
|
||||||
|
return {
|
||||||
|
ngModule: CommentModule,
|
||||||
|
providers: [{ provide: commentTypeToken, useValue: commentType }],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
<div class="comment-form">
|
||||||
|
<form [formGroup]="formGroup">
|
||||||
|
<p-card>
|
||||||
|
<ng-template pTemplate="header">
|
||||||
|
<div class="comment-header">
|
||||||
|
<span class="p-float-label">
|
||||||
|
<input
|
||||||
|
pInputText
|
||||||
|
id="username"
|
||||||
|
type="text"
|
||||||
|
formControlName="username"
|
||||||
|
/>
|
||||||
|
<label htmlFor="username">Nazwa Użytkownika</label>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
<span class="p-float-label">
|
||||||
|
<textarea
|
||||||
|
id="content"
|
||||||
|
rows="5"
|
||||||
|
cols="40"
|
||||||
|
pInputTextarea
|
||||||
|
[autoResize]="true"
|
||||||
|
formControlName="content"
|
||||||
|
></textarea>
|
||||||
|
<label htmlFor="content">Komentarz</label>
|
||||||
|
</span>
|
||||||
|
<ng-template pTemplate="footer">
|
||||||
|
<div class="footer">
|
||||||
|
<button
|
||||||
|
pButton
|
||||||
|
type="button"
|
||||||
|
label="Dodaj"
|
||||||
|
(click)="submit()"
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</p-card>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-header {
|
||||||
|
margin-right: 20px;
|
||||||
|
padding: 28px 0 0 28px;
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CommentFormComponent } from './comment-form.component';
|
||||||
|
|
||||||
|
describe('CommentFormComponent', () => {
|
||||||
|
let component: CommentFormComponent;
|
||||||
|
let fixture: ComponentFixture<CommentFormComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [CommentFormComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(CommentFormComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
|
import { CommentService } from '../../services/comment.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-comment-form',
|
||||||
|
templateUrl: './comment-form.component.html',
|
||||||
|
styleUrls: ['./comment-form.component.scss'],
|
||||||
|
})
|
||||||
|
export class CommentFormComponent {
|
||||||
|
@Input() issueId!: string;
|
||||||
|
|
||||||
|
constructor(private commentService: CommentService) {}
|
||||||
|
formGroup = new FormGroup({
|
||||||
|
content: new FormControl('', Validators.required),
|
||||||
|
username: new FormControl('', Validators.required),
|
||||||
|
});
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
const form = this.formGroup.getRawValue();
|
||||||
|
this.commentService
|
||||||
|
.addComment(this.issueId, form.username || '', form.content || '')
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<div class="comment">
|
||||||
|
<p-card>
|
||||||
|
<ng-template pTemplate="header">
|
||||||
|
<p class="comment-header">{{ comment.userName }}</p>
|
||||||
|
</ng-template>
|
||||||
|
<p>{{ comment.content }}</p>
|
||||||
|
<ng-template pTemplate="footer">
|
||||||
|
<div class="date">
|
||||||
|
{{ comment.createdAt | date : "dd.MM.yyyy, HH:mm" }}
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</p-card>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
.date {
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-header {
|
||||||
|
margin-right: 20px;
|
||||||
|
padding: 20px 0 0 20px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CommentComponent } from './comment.component';
|
||||||
|
|
||||||
|
describe('CommentComponent', () => {
|
||||||
|
let component: CommentComponent;
|
||||||
|
let fixture: ComponentFixture<CommentComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [CommentComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(CommentComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
import { CommentModel } from 'src/app/models/comment.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-comment',
|
||||||
|
templateUrl: './comment.component.html',
|
||||||
|
styleUrls: ['./comment.component.scss'],
|
||||||
|
})
|
||||||
|
export class CommentComponent {
|
||||||
|
@Input() comment!: CommentModel;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<h2>Komentarze</h2>
|
||||||
|
<div class="comments">
|
||||||
|
<app-comment
|
||||||
|
*ngFor="let comment of comments"
|
||||||
|
[comment]="comment"
|
||||||
|
></app-comment>
|
||||||
|
<app-comment-form [issueId]="issueId"></app-comment-form>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
.comments {
|
||||||
|
margin: 30px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CommentsComponent } from './comments.component';
|
||||||
|
|
||||||
|
describe('CommentsComponent', () => {
|
||||||
|
let component: CommentsComponent;
|
||||||
|
let fixture: ComponentFixture<CommentsComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [CommentsComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(CommentsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
import { CommentModel } from 'src/app/models/comment.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-comments',
|
||||||
|
templateUrl: './comments.component.html',
|
||||||
|
styleUrls: ['./comments.component.scss'],
|
||||||
|
})
|
||||||
|
export class CommentsComponent {
|
||||||
|
@Input() comments!: CommentModel[];
|
||||||
|
@Input() issueId!: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Inject, Injectable, InjectionToken } from '@angular/core';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
import { environments } from 'src/environments/environments';
|
||||||
|
|
||||||
|
export const commentTypeToken = new InjectionToken<'issues' | 'solution'>(
|
||||||
|
'Comment Type'
|
||||||
|
);
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CommentService {
|
||||||
|
constructor(
|
||||||
|
private http: HttpClient,
|
||||||
|
private store: Store,
|
||||||
|
@Inject(commentTypeToken) private commentType: 'issues' | 'solution'
|
||||||
|
) {}
|
||||||
|
|
||||||
|
addComment(issueId: string, username: string, content: string) {
|
||||||
|
return this.http.post(
|
||||||
|
environments.apiUrl +
|
||||||
|
'/issues/' +
|
||||||
|
issueId +
|
||||||
|
(this.commentType === 'issues' ? '' : '/solution') +
|
||||||
|
'/comments',
|
||||||
|
{
|
||||||
|
username,
|
||||||
|
content,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,12 @@ import { NgModule } from '@angular/core';
|
|||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
import { IssueComponent } from './issue.component';
|
import { IssueComponent } from './issue.component';
|
||||||
|
|
||||||
const routes: Routes = [{ path: ':id', component: IssueComponent }];
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: ':id',
|
||||||
|
component: IssueComponent,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forChild(routes)],
|
imports: [RouterModule.forChild(routes)],
|
||||||
|
|||||||
@@ -21,25 +21,13 @@
|
|||||||
<p-button
|
<p-button
|
||||||
*ngIf="(issue$ | async)?.solution"
|
*ngIf="(issue$ | async)?.solution"
|
||||||
label="Rozwiązanie"
|
label="Rozwiązanie"
|
||||||
[routerLink]="['/', 'solution', (issue$ | async)?.solution?.id]"
|
[routerLink]="['/', 'issue', (issue$ | async)?.id, 'solution']"
|
||||||
></p-button>
|
></p-button>
|
||||||
</div>
|
</div>
|
||||||
</p-card>
|
</p-card>
|
||||||
</div>
|
<app-comments
|
||||||
<h2>Komentarze</h2>
|
[comments]="(issue$ | async)?.comments || []"
|
||||||
<div class="comments">
|
[issueId]="(issue$ | async)?.id || ''"
|
||||||
<div class="comment" *ngFor="let comment of (issue$ | async)?.comments">
|
></app-comments>
|
||||||
<p-card>
|
|
||||||
<ng-template pTemplate="header">
|
|
||||||
<p class="comment-header">{{ comment.userName }}</p>
|
|
||||||
</ng-template>
|
|
||||||
<p>{{ comment.content }}</p>
|
|
||||||
<ng-template pTemplate="footer">
|
|
||||||
<div class="date">
|
|
||||||
{{ comment.createdAt | date : "dd.MM.yyyy, HH:mm" }}
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
</p-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -12,13 +12,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.comments {
|
|
||||||
margin: 30px 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main .content {
|
.main .content {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
@@ -30,21 +23,8 @@
|
|||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
.date {
|
|
||||||
display: flex;
|
|
||||||
justify-content: end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.comment-header {
|
|
||||||
margin-right: 20px;
|
|
||||||
padding: 20px 0 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.issue {
|
.issue {
|
||||||
max-width: 900px;
|
max-width: 900px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
::ng-deep .p-card-content {
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,7 @@ import { NgModule } from '@angular/core';
|
|||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from 'primeng/button';
|
||||||
import { CardModule } from 'primeng/card';
|
import { CardModule } from 'primeng/card';
|
||||||
import { TagModule } from 'primeng/tag';
|
import { TagModule } from 'primeng/tag';
|
||||||
|
import { CommentModule } from '../comment/comment.module';
|
||||||
import { IssueRoutingModule } from './issue-routing.module';
|
import { IssueRoutingModule } from './issue-routing.module';
|
||||||
import { IssueComponent } from './issue.component';
|
import { IssueComponent } from './issue.component';
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@ import { IssueComponent } from './issue.component';
|
|||||||
IssueRoutingModule,
|
IssueRoutingModule,
|
||||||
TagModule,
|
TagModule,
|
||||||
ButtonModule,
|
ButtonModule,
|
||||||
|
CommentModule.forRoot('issues'),
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { tap } from 'rxjs';
|
import { tap } from 'rxjs';
|
||||||
import { IssueModel } from 'src/app/models/issue.model';
|
import { IssueModel } from 'src/app/models/issue.model';
|
||||||
|
import { receivedSolutionSuccessAction } from 'src/app/store/actions/solution.actions';
|
||||||
import { environments } from 'src/environments/environments';
|
import { environments } from 'src/environments/environments';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@@ -16,6 +17,20 @@ export class SolutionFormService {
|
|||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
})
|
})
|
||||||
.pipe(tap());
|
.pipe(
|
||||||
|
tap(() =>
|
||||||
|
this.store.dispatch(
|
||||||
|
receivedSolutionSuccessAction({
|
||||||
|
issueId: issue.id,
|
||||||
|
solution: {
|
||||||
|
comments: [],
|
||||||
|
createdAt: new Date(),
|
||||||
|
description,
|
||||||
|
title,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { SolutionComponent } from './solution.component';
|
||||||
|
|
||||||
|
const routes: Routes = [{ path: '', component: SolutionComponent }];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(routes)],
|
||||||
|
exports: [RouterModule],
|
||||||
|
})
|
||||||
|
export class SolutionRoutingModule {}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<div class="solution">
|
||||||
|
<div class="main">
|
||||||
|
<p-card>
|
||||||
|
<ng-template pTemplate="header">
|
||||||
|
<div class="header">
|
||||||
|
<h1>{{ (solution$ | async)?.title }}</h1>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
<div class="content">
|
||||||
|
<p>{{ (solution$ | async)?.description }}</p>
|
||||||
|
</div>
|
||||||
|
</p-card>
|
||||||
|
<app-comments
|
||||||
|
[comments]="(solution$ | async)?.comments || []"
|
||||||
|
[issueId]="issueId"
|
||||||
|
></app-comments>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
.header {
|
||||||
|
margin: 10px 30px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
h1 {
|
||||||
|
flex: 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .content {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comments .content {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solution {
|
||||||
|
max-width: 900px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { SolutionComponent } from './solution.component';
|
||||||
|
|
||||||
|
describe('SolutionComponent', () => {
|
||||||
|
let component: SolutionComponent;
|
||||||
|
let fixture: ComponentFixture<SolutionComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [SolutionComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(SolutionComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
import { EMPTY, Observable } from 'rxjs';
|
||||||
|
import { SolutionModel } from 'src/app/models/solution.model';
|
||||||
|
import { selectSolution } from 'src/app/store/selectors/solution.selectors';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-solution',
|
||||||
|
templateUrl: './solution.component.html',
|
||||||
|
styleUrls: ['./solution.component.scss'],
|
||||||
|
})
|
||||||
|
export class SolutionComponent implements OnInit {
|
||||||
|
solution$: Observable<SolutionModel | undefined> = EMPTY;
|
||||||
|
issueId!: string;
|
||||||
|
constructor(private store: Store, private route: ActivatedRoute) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.route.params.subscribe((params) => {
|
||||||
|
this.issueId = params['id'];
|
||||||
|
this.solution$ = this.store.select(selectSolution(params['id']));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CardModule } from 'primeng/card';
|
||||||
|
import { CommentModule } from '../comment/comment.module';
|
||||||
|
import { SolutionRoutingModule } from './solution-routing.module';
|
||||||
|
import { SolutionComponent } from './solution.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
CommentModule.forRoot('solution'),
|
||||||
|
SolutionRoutingModule,
|
||||||
|
CardModule,
|
||||||
|
],
|
||||||
|
declarations: [SolutionComponent],
|
||||||
|
})
|
||||||
|
export class SolutionModule {}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
<div *ngFor="let solution of solutions$ | async">
|
<div *ngFor="let solution of solutions$ | async">
|
||||||
{{ solution.title }}
|
{{ solution.title }}
|
||||||
</div>
|
</div>
|
||||||
gv gvghv
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { createSelector } from '@ngrx/store';
|
||||||
|
import { selectIssue } from './issue.selectors';
|
||||||
|
|
||||||
|
export const selectSolution = (issueId: string) =>
|
||||||
|
createSelector(selectIssue(issueId), (issue) => issue?.solution);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Dev
|
// Dev
|
||||||
export const environments = {
|
export const environments = {
|
||||||
apiUrl: 'http://localhost',
|
apiUrl: 'http://localhost/api',
|
||||||
};
|
};
|
||||||
@@ -16,3 +16,7 @@ h3,
|
|||||||
p {
|
p {
|
||||||
color: #495057;
|
color: #495057;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-card-content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user