Commit d7ec02d3 authored by Paul Legoût's avatar Paul Legoût
Browse files

Resolve "Articles-page"

parent 726e133e
No related merge requests found
Showing with 492 additions and 18391 deletions
+492 -18391
This diff is collapsed.
......@@ -22,13 +22,16 @@ import { MatNativeDateModule } from '@angular/material/core';
import {MatIconModule} from '@angular/material/icon';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { GraphicsPageModule } from './pages/graphics-page/graphics-page.module'
import { MatTableModule } from '@angular/material/table';
import { MatDialogModule } from '@angular/material/dialog';
import { HttpClientModule } from '@angular/common/http';
//////////////////// Components declared \\\\\\\\\\\\\\\\\\\\
import { HomeComponent } from './pages/home/home.component';
import { SettingsComponent } from './pages/settings/settings.component';
import { ArticlesComponent } from './pages/articles/articles.component';
import { ArticlesComponent} from './pages/articles/articles.component';
import { DataEntryComponent } from './pages/data-entry/data-entry.component';
import { ToolbarComponent } from './toolbar/toolbar.component';
import { OverlayContainer } from '@angular/cdk/overlay';
......@@ -43,7 +46,7 @@ import { OverlayContainer } from '@angular/cdk/overlay';
DataEntryComponent,
HomeComponent,
SettingsComponent,
ArticlesComponent
ArticlesComponent,
],
imports: [
BrowserModule,
......@@ -67,6 +70,9 @@ import { OverlayContainer } from '@angular/cdk/overlay';
MatNativeDateModule,
GraphicsPageModule,
MatIconModule,
MatTableModule,
MatDialogModule,
HttpClientModule,
],
providers: [
{ provide: OverlayContainer },
......
mat-form-field {
width: 70%;
font-size: 26px;
font-size: 22px;
margin-left: 10%;
}
form {
margin-bottom: 60px;
margin-bottom: -100px;
}
.filter-tables {
position: absolute;
float:right;
margin-left: 1%;
width: 5%;
font-size: 16px;
margin-top: 19px;
}
.table-articles, .table-implications {
width: 100%;
}
.div-table {
position: relative;
max-height: 600px;
overflow: auto;
width: 180%;
margin-left: -40%;
}
h1 {
text-align: center;
margin-left: -10%;
color: rgb(0,94,184);
font-size: 28px;
margin-bottom: 25px;
margin-top: 160px;
}
th {
font-size: 18px;
}
.cell-title {
cursor: pointer;
}
.cell-title:hover {
font-size: 19px;
}
.button-return {
background-color: rgb(0,94,184);
border: 2px solid rgb(0,94,184);
color: white;
font-size: 22px;
width: 150px;
height: 50px;
margin-left: -7%;
}
.button-return:hover {
background-color: white;
color: rgb(0,94,184);
transform: scale(1.2);
}
<body>
<!-- Search bar -->
<form >
<mat-form-field>
<mat-label>Rechercher un article</mat-label>
<input matInput type="text" name="input-article" id="input-article">
<form class="form">
<mat-form-field >
<mat-label >Rechercher</mat-label>
<input matInput (keyup)="applyFilter($event)" name="input-article" id="input-article" #input>
</mat-form-field>
<!-- Select table to display (default: both) -->
<mat-form-field title="Selectionner la table à afficher" class="filter-tables">
<mat-label>Tables</mat-label>
<mat-select [(value)]="displayTable">
<mat-option value="">Toutes</mat-option>
<mat-option value="articles">Communiqués</mat-option>
<mat-option value="implications">Retombées</mat-option>
</mat-select>
</mat-form-field>
</form>
<h1>Articles page</h1>
</body>
<button mat-button *ngIf="!allTables" class="button-return" (click)="backAllArticles()"><strong>Retour</strong></button>
<!-- Display articles -->
<h1 *ngIf="displayTable == 'articles' || displayTable == ''" ><i><strong>{{ titleArticles }}</strong></i></h1>
<div class="div-table" *ngIf="displayTable == 'articles' || displayTable == ''">
<table mat-table [dataSource]="dataSourceArticles" class="table-articles">
<!-- Date -->
<ng-container matColumnDef="date" >
<th mat-header-cell *matHeaderCellDef>Date de parution</th>
<td mat-cell *matCellDef="let article" style="width:250px;">{{ article.date }}</td>
</ng-container>
<!-- Title -->
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef>Titre</th>
<td mat-cell *matCellDef="let article" class="cell-title" title="Cliquez pour voir les retombées associées" (click)="clickedOnArticle(article)"><strong>{{ article.title }}</strong></td>
</ng-container>
<!-- Type -->
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef>Type</th>
<td mat-cell *matCellDef="let article">{{ article.type }}</td>
</ng-container>
<!-- Department -->
<ng-container matColumnDef="department">
<th mat-header-cell *matHeaderCellDef>Département</th>
<td mat-cell *matCellDef="let article">{{ article.department }}</td>
</ng-container>
<!-- Theme -->
<ng-container matColumnDef="theme">
<th mat-header-cell *matHeaderCellDef>Thème</th>
<td mat-cell *matCellDef="let article">{{ article.theme }}</td>
</ng-container>
<!-- Link -->
<ng-container matColumnDef="link">
<th mat-header-cell *matHeaderCellDef>Lien</th>
<td mat-cell *matCellDef="let article"><a href="{{ article.link }}">{{ article.link }}</a></td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColArticles"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColArticles;"></tr>
<!-- Row shown when there is no matching data. -->
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="6">Pas de résultat pour "{{input.value}}"</td>
</tr>
</table>
</div>
<!-- To do:
display list of articles in alphabetic order from server + manage search bar and classed in two sections ("retombées de presse" and "communiqués de presse")
-->
<!-- Display implications-->
<h1 *ngIf="displayTable == 'implications' || displayTable == ''"><i><strong>{{ titleImplications }}</strong></i></h1>
<div class="div-table" style="margin-bottom: 80px;" *ngIf="displayTable == 'implications' || displayTable == ''">
<table mat-table [dataSource]="dataSourceImplications" class="table-implications">
<!-- Date -->
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef>Date de parution</th>
<td mat-cell *matCellDef="let article" style="width:250px;">{{ article.date }}</td>
</ng-container>
<!-- Title -->
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef>Titre</th>
<td mat-cell *matCellDef="let article">{{ article.title }}</td>
</ng-container>
<!-- Type -->
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef>Type</th>
<td mat-cell *matCellDef="let article">{{ article.type }}</td>
</ng-container>
<!-- Department -->
<ng-container matColumnDef="department">
<th mat-header-cell *matHeaderCellDef>Département</th>
<td mat-cell *matCellDef="let article">{{ article.department }}</td>
</ng-container>
<!-- Paper -->
<ng-container matColumnDef="paper">
<th mat-header-cell *matHeaderCellDef>Journal</th>
<td mat-cell *matCellDef="let article">{{ article.paper }}</td>
</ng-container>
<!-- Theme -->
<ng-container matColumnDef="theme">
<th mat-header-cell *matHeaderCellDef>Thème</th>
<td mat-cell *matCellDef="let article">{{ article.theme }}</td>
</ng-container>
<!-- Tonality -->
<ng-container matColumnDef="tonality">
<th mat-header-cell *matHeaderCellDef>Tonalité</th>
<td mat-cell *matCellDef="let article" [style.background]="article.color">{{ article.tonality }}</td>
</ng-container>
<!-- Link -->
<ng-container matColumnDef="link">
<th mat-header-cell *matHeaderCellDef>Lien</th>
<td mat-cell *matCellDef="let article" style="padding-left: 5px;"><a href="{{ article.link }}">{{ article.link }}</a> </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColImplications"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColImplications;"></tr>
<!-- Row shown when there is no matching data. -->
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="8">Pas de résultat pour "{{input.value}}"</td>
</tr>
</table>
</div>
</body>
import { Component } from '@angular/core';
import { Component, Inject } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { HttpClient } from "@angular/common/http";
// import { Observable } from 'rxjs';
/**
*To create an Article instance
*/
export interface Article {
date: String;
title: String;
type: String;
department: String;
theme: String;
link?: String;
associated: Implication[];
}
/**
* To create an Implication instance
*/
export interface Implication {
_id: String;
date: String;
title: String;
type: String;
department: String;
paper: String;
theme: String;
tonality: String;
color?: String;
link?: String;
}
@Component({
......@@ -12,6 +45,197 @@ import { Component } from '@angular/core';
*/
export class ArticlesComponent {
//////////////////// Data \\\\\\\\\\\\\\\\\\\\
public listArticles : Article[] = [];
dataSourceArticles = new MatTableDataSource(this.listArticles);
public displayedColArticles: string[] = ["date", "title", "type", "department", "theme", "link"];
titleArticles = "Communiqués de presse";
obsArticles: any;
public listImplications: Implication[] = [];
public displayedColImplications: string[] = ["date", "title", "type", "department", "paper", "theme", "tonality", "link"];
dataSourceImplications = new MatTableDataSource(this.listImplications);
titleImplications = "Retombées de presse";
obsImplications: any;
//////////////////// Tables filter \\\\\\\\\\\\\\\\\\\\
displayTable: String = '';
allTables = true;
readonly ROOT_URL = '';
constructor(private http: HttpClient) {}
ngOnInit() {
//Get articles and implications from db and fill in the lists
this.getArticles();
this.getImplications();
}
/**
* Get articles from db
*/
private async getArticles() {
//////////////////// Get request, get all the articles and their informations. \\\\\\\\\\\\\\\\\\\\
for (let i = 0; i < 100; i++) {
const article = {
date: "dateA"+i,
title: "titleA"+i,
type: "typeA"+i,
department: "departmentA"+i,
theme: "themeA"+i,
link: "linkA"+i,
associated: [this.listImplications[0]] //example (linked by id)
//articles are associated with implications with foreign keys
}
//Get observable
// this.obsArticles = this.http.get(this.ROOT_URL + "/press_release");
// for (let article of this.obsArticles) {
// const art = {
// date: article.date,
// title: article.title,
// type: article.type,
// department: article.department,
// theme: article.theme,
// link: article.link ?? '',
// associated: [this.listImplications[0]] //example (linked by id)
// //articles are associated with implications with foreign keys
// }
// this.listArticles.push(art);
// }
this.listArticles.push(article);
}
/* TODO:
sort by date the list
*/
}
/**
* Get implications (retombées) from db
*/
private async getImplications() {
//Get request, get all the articles and their informations.
for (let i = 0; i < 100; i++) {
if (i%4 != 0) {
const implication = {
_id: i.toString(),
date: "dateI"+i,
title: "titleI"+i,
type: "typeI"+i,
department: "departmentI"+i,
paper: "paperI"+i,
theme: "themeI"+i,
tonality: "positive",
color: "color",
link: "linkA"+i
}
const color = implication.tonality.toLowerCase() == "positive" ? "rgb(147,201,14)" : "#EF426F"
implication.color = color;
this.listImplications.push(implication);
} else {
const implication = {
_id: i.toString(),
date: "dateI"+i,
title: "titleI"+i,
type: "typeI"+i,
department: "departmentI"+i,
paper: "paperI"+i,
theme: "themeI"+i,
tonality: "negative",
color: "color",
link: "linkA"+i
}
const color = implication.tonality.toLowerCase() == "positive" ? "rgb(147,201,14)" : "#EF426F"
implication.color = color;
this.listImplications.push(implication);
}
// this.obsImplications = this.http.get(this.ROOT_URL + "/articles");
// for (let article of this.obsImplications) {
// const art = {
// _id: article._id,
// date: article.date,
// title: article.title,
// type: article.type,
// department: article.department,
// paper: article.paper,
// theme: article.theme,
// tonality: article.tonality,
// color: article.color.toLowerCase() == "positive"? "rgb(147,201,14)" : "#EF426F",
// link: article.link ?? ''
// }
// this.listImplications.push(art);
// }
}
/* TODO:
sort by date the list
*/
}
/**
* Filter research
*/
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
if (filterValue) {
this.dataSourceArticles.filter = filterValue.trim().toLowerCase();
this.dataSourceImplications.filter = filterValue.trim().toLowerCase();
}
}
/**
* When an article is clicked on, shows solely the article with its associated implications
*/
clickedOnArticle(article: Article) {
//////////////////// Hide search form \\\\\\\\\\\\\\\\\\\\
const form = <HTMLElement>document.querySelector(".form");
if (form) {
form.style.visibility = "hidden";
}
this.allTables = false; //display return button
this.titleArticles = "Communiqué de presse";
this.titleImplications = "Retombées liées à " + article.title;
//////////////////// Display new informations \\\\\\\\\\\\\\\\\\\\
this.dataSourceArticles = new MatTableDataSource([article]);
this.dataSourceImplications = new MatTableDataSource(article.associated);
}
/**
* Display all articles back
*/
backAllArticles() {
const form = <HTMLElement>document.querySelector(".form");
if (form) {
form.style.visibility = "visible";
}
this.allTables = true; //hide return button
this.titleArticles = "Communiqués de presse";
this.titleImplications = "Retombées de presse";
//////////////////// Display all informations \\\\\\\\\\\\\\\\\\\\
this.dataSourceArticles = new MatTableDataSource(this.listArticles);
this.dataSourceImplications = new MatTableDataSource(this.listImplications);
}
}
......@@ -63,7 +63,7 @@ h1 {
}
.form-cp {
width: 100px;
width: 200px;
float: right;
margin-right: 380px;
visibility: hidden;
......
......@@ -22,10 +22,11 @@
<!-- This is displayed if select-graph.value === graphics[0] or graphics[1] -->
<div>
<mat-form-field class="form-cp">
<mat-label>Code CP</mat-label>
<input matInput [formControl]="cpFormControl" [errorStateMatcher]="matcher" type="number" name="cp" id="cp" min="0" [value]="codeCP" required>
<!-- Display an error if input isn't filled -->
<mat-error *ngIf="cpFormControl.hasError('required') ">Code CP est <strong>obligatoire</strong></mat-error>
<mat-label>Titre du communiqué</mat-label>
<mat-select [(value)]="matSelectedName" (selectionChange)="manageSelection()" [formControl]="formControlName" required>
<mat-option *ngFor="let name of articleNames" [value]="name">{{ name }}</mat-option>
</mat-select>
<mat-error *ngIf="formControlName.hasError('required')">Vous devez selectionner un article</mat-error>
</mat-form-field>
</div>
......@@ -40,7 +41,7 @@
<!-- Display graphic if inputs are accurates and button generate is clicked on -->
<app-graphics *ngIf="validate" [graphicType]="matSelectedGraphic" [graphic]="matSelectedValue" [codeCP]="codeCP" [arrayGraphics]="graphics" [arrayGraphicTypes]="graphicTypes" (errorOcc)="error()"></app-graphics>
<app-graphics *ngIf="validate" [graphicType]="matSelectedGraphic" [graphic]="matSelectedValue" [codeCP]="matSelectedName" [arrayGraphics]="graphics" [arrayGraphicTypes]="graphicTypes" (errorOcc)="error()"></app-graphics>
<!-- Displayed if an error has occurred while trying to generate the graphic -->
<p *ngIf="errorOcc" class="error-occurred">Une erreur est survenue. Réessayez plus tard</p>
......
......@@ -36,7 +36,7 @@ export class GraphicsPageComponent {
//Graphic options
graphics : string[] = [
"Tonalité des retombées par code CP", "Departements des retombées par code CP", "Type de retombées", "Type de retombées avec tonalité", "Journaux des retombées", "Départements de retombées", "Tonalité", "Retombées par thème"
"Tonalité des retombées par communiqué", "Departements des retombées par communiqué", "Type de retombées", "Type de retombées avec tonalité", "Journaux des retombées", "Départements de retombées", "Tonalité", "Retombées par thème"
];
//Graphic types
......@@ -44,12 +44,14 @@ export class GraphicsPageComponent {
"Diagramme en bâtons", "Courbe", "Diagramme circulaire"
]
codeCP: string = '';
//Code CP required if selection is graphics[0] or graphics[1]
cpFormControl = new FormControl('', [
Validators.required,
]);
matcher = new MyErrorStateMatcher();
//Will get article names from server
articleNames: string[] = [
"Article 1", "Article 2", "Article 3", "Article 4", "Article 5"
];
public matSelectedName: string = '';
formControlName = new FormControl('', Validators.required);
......@@ -102,6 +104,7 @@ export class GraphicsPageComponent {
public reset() {
this.matSelectedGraphic = '';
this.matSelectedValue = '';
this.matSelectedName = '';
this.validate = false;
if (this.errorOcc)
this.errorOcc = false;
......@@ -128,18 +131,13 @@ export class GraphicsPageComponent {
//If Code CP is required, check if it's valiee
if (this.matSelectedValue === this.graphics[0] || this.matSelectedValue === this.graphics[1]){
//Get codeCP input value
let inputCP = <HTMLInputElement>document.getElementById("cp");
if (inputCP && inputCP.value !== ''){
this.codeCP = inputCP.value;
this.validate = true;
}
if (this.matSelectedName !== '') this.validate = true;
}
else {
this.validate = true;
}
console.log(this.matSelectedName);
}
......
......@@ -8,6 +8,7 @@ import { MatSelectModule } from '@angular/material/select';
import { RouterModule } from '@angular/router';
import { MatButtonModule } from '@angular/material/button';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
......@@ -26,6 +27,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
MatButtonModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
],
exports: [
GraphicsPageComponent
......
......@@ -10,6 +10,6 @@
"src/polyfills.ts"
],
"include": [
"src/**/*.d.ts"
"src/**/*.d.ts",
]
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment