fix: News now display author
This commit is contained in:
@@ -1,43 +1,43 @@
|
|||||||
<button mat-raised-button (click)="newPost()" color="accent">Nowy post</button>
|
<button mat-raised-button (click)="newPost()" color="accent" class="newPost">Nowy post</button>
|
||||||
@if (loading) {
|
<div class="mainc">
|
||||||
<mat-spinner></mat-spinner>
|
@if (ac.state() != 2) {
|
||||||
}
|
<app-load-shade [state]="ac.state()" [error]="ac.error()" (refresh)="ac.refresh()"/>
|
||||||
@for (item of news; track item) {
|
}
|
||||||
<mat-card>
|
@for (item of ac.news | async; track item) {
|
||||||
<mat-card-header>
|
<mat-card>
|
||||||
<mat-card-title>{{item.title}}</mat-card-title>
|
<mat-card-header>
|
||||||
@if (item.pinned) {
|
<mat-card-title>{{item.title}}</mat-card-title>
|
||||||
<mat-icon>push_pin</mat-icon>
|
@if (item.pinned) {
|
||||||
}
|
<mat-icon>push_pin</mat-icon>
|
||||||
<!-- <mat-card-subtitle>{{item._id}}</mat-card-subtitle> -->
|
|
||||||
</mat-card-header>
|
|
||||||
<mat-card-content [innerHTML]="item.formatted"></mat-card-content>
|
|
||||||
<mat-card-actions>
|
|
||||||
<button mat-mini-fab (click)="editPost(item)"><mat-icon>edit</mat-icon></button>
|
|
||||||
<button mat-mini-fab (click)="pinToggle(item)"><mat-icon>push_pin</mat-icon></button>
|
|
||||||
@switch (item.visible) {
|
|
||||||
@case (true) {
|
|
||||||
<button mat-mini-fab (click)="visibleToggle(item)">
|
|
||||||
<mat-icon>visibility</mat-icon>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
@default {
|
|
||||||
<button mat-mini-fab (click)="visibleToggle(item)" color="warn">
|
|
||||||
<mat-icon>visibility_off</mat-icon>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
<button mat-mini-fab (click)="delete(item._id)"><mat-icon>delete_forever</mat-icon></button>
|
</mat-card-header>
|
||||||
</mat-card-actions>
|
<mat-card-content [innerHTML]="item.formatted"></mat-card-content>
|
||||||
<mat-card-footer>
|
<mat-card-actions>
|
||||||
<p>{{item.date | date:'d-LL-yyyy HH:mm'}}</p>
|
<button mat-mini-fab (click)="editPost(item)"><mat-icon>edit</mat-icon></button>
|
||||||
</mat-card-footer>
|
<button mat-mini-fab (click)="pinToggle(item)"><mat-icon>push_pin</mat-icon></button>
|
||||||
</mat-card>
|
@switch (item.visible) {
|
||||||
}
|
@case (true) {
|
||||||
@if (news.length == 0) {
|
<button mat-mini-fab (click)="visibleToggle(item)">
|
||||||
<mat-card>
|
<mat-icon>visibility</mat-icon>
|
||||||
<p>
|
</button>
|
||||||
Brak wiadomości.
|
}
|
||||||
</p>
|
@default {
|
||||||
</mat-card>
|
<button mat-mini-fab (click)="visibleToggle(item)" color="warn">
|
||||||
}
|
<mat-icon>visibility_off</mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<button mat-mini-fab (click)="delete(item._id)"><mat-icon>delete_forever</mat-icon></button>
|
||||||
|
</mat-card-actions>
|
||||||
|
<mat-card-footer>
|
||||||
|
<p>{{fullName(item)}} {{item.date | date:'d-LL-yyyy HH:mm'}}</p>
|
||||||
|
</mat-card-footer>
|
||||||
|
</mat-card>
|
||||||
|
} @empty {
|
||||||
|
<mat-card>
|
||||||
|
<p>
|
||||||
|
Brak wiadomości.
|
||||||
|
</p>
|
||||||
|
</mat-card>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
mat-card {
|
mat-card {
|
||||||
margin: 15px;
|
margin: 15px;
|
||||||
padding: 1ch;
|
padding: 1ch;
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mat-card-title {
|
mat-card-title {
|
||||||
@@ -31,8 +30,19 @@ button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
padding: 8pt;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainc {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newPost {
|
||||||
|
margin: 1ch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ import { MatDialog } from '@angular/material/dialog'
|
|||||||
import { NewPostComponent } from './new-post/edit-post.component'
|
import { NewPostComponent } from './new-post/edit-post.component'
|
||||||
import { catchError, throwError } from 'rxjs'
|
import { catchError, throwError } from 'rxjs'
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar'
|
import { MatSnackBar } from '@angular/material/snack-bar'
|
||||||
import { News } from 'src/app/types/news'
|
import { News } from 'src/app/types/news.model'
|
||||||
import { marked } from 'marked'
|
|
||||||
import { NewsEditService } from './news-edit.service'
|
import { NewsEditService } from './news-edit.service'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -14,29 +13,15 @@ import { NewsEditService } from './news-edit.service'
|
|||||||
standalone: false,
|
standalone: false,
|
||||||
})
|
})
|
||||||
export class NewsEditComponent implements OnInit {
|
export class NewsEditComponent implements OnInit {
|
||||||
news: Array<News & { formatted: string }> = new Array<
|
|
||||||
News & { formatted: string }
|
|
||||||
>()
|
|
||||||
loading = true
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private ac: NewsEditService,
|
protected ac: NewsEditService,
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
private sb: MatSnackBar
|
private sb: MatSnackBar
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.loading = true
|
this.ac.refresh()
|
||||||
this.ac.getNews().subscribe(data => {
|
|
||||||
this.loading = false
|
|
||||||
this.news = data.map(v => {
|
|
||||||
var nd: News & { formatted: string } = {
|
|
||||||
...v,
|
|
||||||
formatted: marked.parse(v.content, { breaks: true }).toString(),
|
|
||||||
}
|
|
||||||
return nd
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newPost() {
|
newPost() {
|
||||||
@@ -131,4 +116,12 @@ export class NewsEditComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fullName(n: News): string {
|
||||||
|
const { author: { fname, surname, uname } } = n;
|
||||||
|
if (fname || surname) {
|
||||||
|
return [fname, surname].filter(Boolean).join(' ');
|
||||||
|
}
|
||||||
|
return uname;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, signal } from '@angular/core';
|
||||||
import { News } from 'src/app/types/news';
|
import { marked } from 'marked';
|
||||||
|
import { BehaviorSubject, catchError, map, of } from 'rxjs';
|
||||||
|
import { News } from 'src/app/types/news.model';
|
||||||
|
import { STATE } from 'src/app/types/state';
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@@ -8,12 +11,41 @@ import { environment } from 'src/environments/environment';
|
|||||||
})
|
})
|
||||||
export class NewsEditService {
|
export class NewsEditService {
|
||||||
|
|
||||||
|
private _news = new BehaviorSubject<(News & {formatted: string})[]>([])
|
||||||
|
public readonly news = this._news.asObservable()
|
||||||
|
private _state = signal(STATE.NOT_LOADED);
|
||||||
|
public readonly state = this._state.asReadonly();
|
||||||
|
private _error = signal<string | undefined>(undefined);
|
||||||
|
public readonly error = this._error.asReadonly();
|
||||||
|
|
||||||
constructor(private http: HttpClient) { }
|
constructor(private http: HttpClient) { }
|
||||||
|
|
||||||
getNews() {
|
public refresh() {
|
||||||
return this.http.get<News[]>(environment.apiEndpoint + `/admin/news`, {
|
this.getNews()
|
||||||
withCredentials: true,
|
}
|
||||||
})
|
|
||||||
|
private getNews() {
|
||||||
|
this._state.set(STATE.PENDING)
|
||||||
|
this.http.get
|
||||||
|
<News[]>
|
||||||
|
(environment.apiEndpoint + `/admin/news`, { withCredentials: true, })
|
||||||
|
.pipe(
|
||||||
|
catchError((err: Error) => {
|
||||||
|
this._state.set(STATE.ERROR)
|
||||||
|
this._error.set(err.message)
|
||||||
|
return of()
|
||||||
|
}),
|
||||||
|
map(i => {
|
||||||
|
return i.map(v => ({
|
||||||
|
...v,
|
||||||
|
formatted: marked.parse(v.content, { breaks: true }).toString()
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
).subscribe(v => {
|
||||||
|
this._error.set(undefined)
|
||||||
|
this._news.next(v ?? [])
|
||||||
|
this._state.set(STATE.LOADED)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
postNews(title: string, content: string) {
|
postNews(title: string, content: string) {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<mat-card-content [innerHTML]="item.content">
|
<mat-card-content [innerHTML]="item.content">
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
<mat-card-footer>
|
<mat-card-footer>
|
||||||
<p>{{item.date | date:'d-LL-yyyy HH:mm'}}</p>
|
<p>{{fullName(item)}} {{item.date | date:'d-LL-yyyy HH:mm'}}</p>
|
||||||
</mat-card-footer>
|
</mat-card-footer>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit } from '@angular/core'
|
||||||
import { UpdatesService } from '../../services/updates.service'
|
import { UpdatesService } from '../../services/updates.service'
|
||||||
import { LocalStorageService } from 'src/app/services/local-storage.service'
|
import { LocalStorageService } from 'src/app/services/local-storage.service'
|
||||||
import { News } from 'src/app/types/news'
|
import { News } from 'src/app/types/news.model'
|
||||||
import { marked } from 'marked'
|
import { marked } from 'marked'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -16,7 +16,7 @@ export class NewsComponent implements OnInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private newsapi: UpdatesService,
|
private newsapi: UpdatesService,
|
||||||
private ls: LocalStorageService
|
private ls: LocalStorageService
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.ls.newsflag = false
|
this.ls.newsflag = false
|
||||||
@@ -31,4 +31,12 @@ export class NewsComponent implements OnInit {
|
|||||||
this.ls.news = this.news
|
this.ls.news = this.news
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fullName(n: News): string {
|
||||||
|
const { author: { fname, surname, uname } } = n;
|
||||||
|
if (fname || surname) {
|
||||||
|
return [fname, surname].filter(Boolean).join(' ');
|
||||||
|
}
|
||||||
|
return uname;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,4 +8,5 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { News } from '../types/news'
|
import { News } from '../types/news.model'
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'
|
|||||||
import { HttpClient } from '@angular/common/http'
|
import { HttpClient } from '@angular/common/http'
|
||||||
import { Menu } from '../types/menu'
|
import { Menu } from '../types/menu'
|
||||||
import { environment } from 'src/environments/environment'
|
import { environment } from 'src/environments/environment'
|
||||||
import { News } from '../types/news'
|
import { News } from '../types/news.model'
|
||||||
import { UKey } from '../types/key'
|
import { UKey } from '../types/key'
|
||||||
import { CleanNote } from '../types/clean-note'
|
import { CleanNote } from '../types/clean-note'
|
||||||
import { Status } from '../types/status'
|
import { Status } from '../types/status'
|
||||||
|
|||||||
@@ -4,5 +4,10 @@ export interface News {
|
|||||||
content: string
|
content: string
|
||||||
date: string
|
date: string
|
||||||
visible?: boolean
|
visible?: boolean
|
||||||
pinned?: boolean
|
pinned?: boolean,
|
||||||
|
author: {
|
||||||
|
fname?: string,
|
||||||
|
surname?: string,
|
||||||
|
uname: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user