Implement Feed creation

This commit is contained in:
Tobias Eidelpes
2021-05-02 17:49:42 +02:00
parent b96a8d35c5
commit e648a03166
13 changed files with 186 additions and 113 deletions
+24 -24
View File
@@ -57,6 +57,7 @@
"karma-coverage-istanbul-reporter": "~2.1.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.5.4",
"ngx-material-file-input": "^2.1.1",
"protractor": "~5.4.4",
"ts-node": "~8.5.4",
"tslint": "~5.20.1",
@@ -431,9 +432,6 @@
"version": "9.2.4",
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-9.2.4.tgz",
"integrity": "sha512-iw2+qHMXHYVC6K/fttHeNHIieSKiTEodVutZoOEcBu9rmRTGbLB26V/CRsfIRmA1RBk+uFYWc6UQZnMC3RdnJQ==",
"dependencies": {
"parse5": "^5.0.0"
},
"optionalDependencies": {
"parse5": "^5.0.0"
}
@@ -969,7 +967,6 @@
"dependencies": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
"fsevents": "~2.1.2",
"glob-parent": "~5.1.0",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
@@ -2149,7 +2146,6 @@
"dependencies": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
"fsevents": "~2.1.2",
"glob-parent": "~5.1.0",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
@@ -3702,8 +3698,7 @@
"dependencies": {
"esprima": "~1.0.4",
"estraverse": "~1.5.0",
"esutils": "~1.0.0",
"source-map": "~0.1.30"
"esutils": "~1.0.0"
},
"optionalDependencies": {
"source-map": "~0.1.30"
@@ -6542,8 +6537,7 @@
"esprima": "^4.0.1",
"estraverse": "^4.2.0",
"esutils": "^2.0.2",
"optionator": "^0.8.1",
"source-map": "~0.6.1"
"optionator": "^0.8.1"
},
"optionalDependencies": {
"source-map": "~0.6.1"
@@ -7559,7 +7553,6 @@
"minimist": "^1.2.5",
"neo-async": "^2.6.0",
"source-map": "^0.6.1",
"uglify-js": "^3.1.4",
"wordwrap": "^1.0.0"
},
"optionalDependencies": {
@@ -9279,7 +9272,6 @@
"dependencies": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
"fsevents": "~2.1.2",
"glob-parent": "~5.1.0",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
@@ -9419,12 +9411,8 @@
"clone": "^2.1.2",
"errno": "^0.1.1",
"graceful-fs": "^4.1.2",
"image-size": "~0.5.0",
"make-dir": "^2.1.0",
"mime": "^1.4.1",
"promise": "^7.1.1",
"request": "^2.83.0",
"source-map": "~0.6.0",
"tslib": "^1.10.0"
},
"optionalDependencies": {
@@ -9644,7 +9632,6 @@
"anymatch": "^2.0.0",
"async-each": "^1.0.1",
"braces": "^2.3.2",
"fsevents": "^1.2.7",
"glob-parent": "^3.1.0",
"inherits": "^2.0.3",
"is-binary-path": "^1.0.0",
@@ -10727,6 +10714,19 @@
"vlq": "^1.0.0"
}
},
"node_modules/ngx-material-file-input": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ngx-material-file-input/-/ngx-material-file-input-2.1.1.tgz",
"integrity": "sha512-FbaIjiJnL6BZtZYWLvMSn9aSaM62AZaJegloTUphmLz5jopXPzE5W+3aC+dsf9h1IIqHSCLcyv0w+qH0ypBhMA==",
"dev": true,
"peerDependencies": {
"@angular/cdk": "^8.1.1 || ^9.0.0",
"@angular/common": "^8.1.3 || ^9.0.0",
"@angular/core": "^8.1.3 || ^9.0.0",
"@angular/material": "^8.1.1 || ^9.0.0",
"tslib": "^1.10.0"
}
},
"node_modules/nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@@ -13626,9 +13626,6 @@
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.1.0.tgz",
"integrity": "sha512-gfE1455AEazVVTJoeQtcOq/U6GSxwoj4XPSWVsuWmgIxj7sBQNLDOSA82PbdMe+cP8ql8fR1jogPFe8Wg8g4SQ==",
"dev": true,
"dependencies": {
"fsevents": "~2.1.2"
},
"optionalDependencies": {
"fsevents": "~2.1.2"
}
@@ -13775,7 +13772,6 @@
"dependencies": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
"fsevents": "~2.1.2",
"glob-parent": "~5.1.0",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
@@ -16518,10 +16514,8 @@
"integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==",
"dev": true,
"dependencies": {
"chokidar": "^3.4.1",
"graceful-fs": "^4.1.2",
"neo-async": "^2.5.0",
"watchpack-chokidar2": "^2.0.0"
"neo-async": "^2.5.0"
},
"optionalDependencies": {
"chokidar": "^3.4.1",
@@ -17227,7 +17221,6 @@
"anymatch": "^2.0.0",
"async-each": "^1.0.1",
"braces": "^2.3.2",
"fsevents": "^1.2.7",
"glob-parent": "^3.1.0",
"inherits": "^2.0.3",
"is-binary-path": "^1.0.0",
@@ -29344,6 +29337,13 @@
"vlq": "^1.0.0"
}
},
"ngx-material-file-input": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ngx-material-file-input/-/ngx-material-file-input-2.1.1.tgz",
"integrity": "sha512-FbaIjiJnL6BZtZYWLvMSn9aSaM62AZaJegloTUphmLz5jopXPzE5W+3aC+dsf9h1IIqHSCLcyv0w+qH0ypBhMA==",
"dev": true,
"requires": {}
},
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+1
View File
@@ -60,6 +60,7 @@
"karma-coverage-istanbul-reporter": "~2.1.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.5.4",
"ngx-material-file-input": "^2.1.1",
"protractor": "~5.4.4",
"ts-node": "~8.5.4",
"tslint": "~5.20.1",
+21 -19
View File
@@ -27,29 +27,31 @@ import { NavigationComponent } from './component/navigation/navigation.component
import {MatSnackBarModule} from '@angular/material/snack-bar';
import {MatCheckboxModule} from '@angular/material/checkbox';
import { EditierenComponent } from './component/einstellungen/editieren/editieren.component';
import {MaterialFileInputModule} from 'ngx-material-file-input';
@NgModule({
declarations: [LandingComponent, LoginComponent, NavigationComponent,
TweetsComponent, EinstellungenComponent, EditierenComponent],
imports: [
ReactiveFormsModule,
BrowserModule,
BrowserAnimationsModule,
AppRoutingModule,
LoggerModule.forRoot({level: environment.log_level, serverLogLevel: NgxLoggerLevel.ERROR}),
HttpClientModule,
MatFormFieldModule,
FormsModule,
MatButtonModule,
MatInputModule,
MatSlideToggleModule,
MatSliderModule,
MatToolbarModule,
MatIconModule,
MatMenuModule,
MatSnackBarModule,
MatCheckboxModule
],
imports: [
ReactiveFormsModule,
BrowserModule,
BrowserAnimationsModule,
AppRoutingModule,
LoggerModule.forRoot({level: environment.log_level, serverLogLevel: NgxLoggerLevel.ERROR}),
HttpClientModule,
MatFormFieldModule,
FormsModule,
MatButtonModule,
MatInputModule,
MatSlideToggleModule,
MatSliderModule,
MatToolbarModule,
MatIconModule,
MatMenuModule,
MatSnackBarModule,
MatCheckboxModule,
MaterialFileInputModule
],
// enables injecting
providers: [
AuthService,
@@ -2,34 +2,42 @@
<div class="content">
<div class="text-center">
<p class="font-weight-bold">RSS-Feed erstellen</p>
<div class="input-row">
<mat-form-field appearance="standard" class="input">
<mat-label>Vollständige URL des RSS-Feeds:</mat-label>
<input matInput placeholder="https://rss.orf.at/news.xml">
</mat-form-field>
</div>
<div class="input-row text-left">
<mat-form-field appearance="standard" class="input">
<mat-label>Folgende Stichwörter im Feed suchen:</mat-label>
<input matInput placeholder="Spiel, Spaß, Schokolade">
</mat-form-field>
<mat-checkbox>Alle Stichworte müssen enthalten sein</mat-checkbox>
</div>
<div class="input-row text-left">
<span>Optionales Icon:</span>
<br>
<img (click)="iconChooser()" class="feed-icon" src="{{icon}}" alt="Feed-Icon">
<input hidden type="file"
(change)="fileChangeEvent($event)"
id="feed-icon-picker" name="icon"
accept="image/png, image/svg+xml">
</div>
<div class="input-row text-left">
<mat-slide-toggle color="primary">Slide me!</mat-slide-toggle>
</div>
<div class="input-row margin-auto einstellungen_buttons_wrapper">
<button routerLink="/einstellungen" mat-raised-button>Abbrechen</button>
<button mat-raised-button><mat-icon>save</mat-icon> Speichern</button>
</div>
<form [formGroup]="feedForm" enctype="multipart/form-data">
<div class=" input-row">
<mat-form-field appearance="standard" class="input">
<mat-label>Vollständige URL des RSS-Feeds</mat-label>
<input matInput formControlName="url" placeholder="https://rss.orf.at/news.xml">
</mat-form-field>
</div>
<div class="input-row text-left">
<mat-form-field appearance="standard" class="input">
<mat-label>Gesuchte Stichwörter</mat-label>
<input matInput formControlName="keywords" placeholder="Spiel,Spaß,Schokolade">
</mat-form-field>
<mat-checkbox>Alle Stichworte müssen enthalten sein</mat-checkbox>
</div>
<div class="input-row text-left">
<mat-form-field class="col">
<ngx-mat-file-input formControlName="icon" placeholder="Optionales Icon"
></ngx-mat-file-input>
<mat-icon matSuffix>folder</mat-icon>
<mat-error *ngIf="feedForm.get('icon').hasError('maxContentSize')">
Die maximale Dateigröße ist {{feedForm.get('icon')?.getError('maxContentSize').maxSize | byteFormat}}
({{feedForm.get('icon')?.getError('maxContentSize').actualSize
| byteFormat}}).
</mat-error>
</mat-form-field>
</div>
<div class="input-row text-left">
<mat-slide-toggle color="primary" formControlName="active">Slide me!</mat-slide-toggle>
</div>
<div class="input-row margin-auto einstellungen_buttons_wrapper">
<button routerLink="/einstellungen" mat-raised-button>Abbrechen</button>
<button mat-raised-button (click)="saveFeed(feedForm.value)">
<mat-icon>save</mat-icon>
Speichern
</button>
</div>
</form>
</div>
</div>
@@ -1,5 +1,13 @@
import { Component, OnInit } from '@angular/core';
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {FormGroup, FormBuilder, FormControl} from '@angular/forms';
import {FileInput, FileValidator} from 'ngx-material-file-input';
import {HttpClient} from '@angular/common/http';
import {environment} from '../../../../environments/environment';
import {throwError} from 'rxjs';
import {NGXLogger} from 'ngx-logger';
import {MatSnackBar} from '@angular/material/snack-bar';
import {isElementScrolledOutsideView} from '@angular/cdk/overlay/position/scroll-clip';
@Component({
selector: 'app-editieren',
@@ -7,14 +15,23 @@ import {ActivatedRoute} from '@angular/router';
styleUrls: ['./editieren.component.css']
})
export class EditierenComponent implements OnInit {
icon;
id;
constructor(private route: ActivatedRoute) {
this.icon = 'assets/logo.svg';
this.route.paramMap.subscribe( paramMap => {
feedForm: FormGroup;
url: String;
active = true;
icon: File;
keywords: String;
readonly maxSize = 10240;
private currentLocation = environment.location;
constructor(private route: ActivatedRoute,
private formBuilder: FormBuilder,
private http: HttpClient,
private _snackbar: MatSnackBar,
private _logger: NGXLogger) {
this.route.paramMap.subscribe(paramMap => {
this.id = paramMap.get('id');
if (this.id) {
this.loadFeed(this.id);
@@ -23,6 +40,12 @@ export class EditierenComponent implements OnInit {
}
ngOnInit(): void {
this.feedForm = this.formBuilder.group({
url: this.url,
active: this.active,
icon: [undefined, [FileValidator.maxContentSize(this.maxSize)]],
keywords: this.keywords
});
}
loadFeed(id) {
@@ -33,22 +56,24 @@ export class EditierenComponent implements OnInit {
// TODO: bei Input-Words die Leerzeichen vor- und nach dem letzten Zeichen entfernen: " Formel 1 " wird zu "Formel 1"
iconChooser() {
document.getElementById('feed-icon-picker').click();
}
fileChangeEvent(event) {
if (event && event.target) {
const files = event.target.files;
if (files && files[0]) {
const reader = new FileReader();
reader.onload = () => {
if (reader.result) {
this.icon = reader.result;
}
};
reader.readAsDataURL(files[0]);
}
saveFeed(feedData) {
const form: FormData = new FormData();
form.append('url', feedData.url);
form.append('active', feedData.active);
if (feedData.keywords != null) {
form.append('keywords', feedData.keywords);
}
if (feedData.icon != null) {
form.append('icon', feedData.icon._files['0']);
}
this.http.post('http://127.0.0.1:8000/feeds/', form).subscribe(
() => {
this._snackbar.open('Feed erfolgreich gespeichert!', 'Schließen', {duration: 3000});
},
err => {
this._logger.error(err);
return throwError(err);
}
);
}
}