Merge branch 'frontend'
Add cron capability
This commit is contained in:
commit
badc29ee97
27
frontend/package-lock.json
generated
27
frontend/package-lock.json
generated
@ -19,6 +19,7 @@
|
|||||||
"@angular/platform-browser-dynamic": "~13.2.0",
|
"@angular/platform-browser-dynamic": "~13.2.0",
|
||||||
"@angular/router": "~13.2.0",
|
"@angular/router": "~13.2.0",
|
||||||
"bootstrap": "^5.1.3",
|
"bootstrap": "^5.1.3",
|
||||||
|
"ngx-cron-editor": "^0.7.3",
|
||||||
"rxjs": "~7.5.0",
|
"rxjs": "~7.5.0",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"zone.js": "~0.11.4"
|
"zone.js": "~0.11.4"
|
||||||
@ -7890,6 +7891,24 @@
|
|||||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/ngx-cron-editor": {
|
||||||
|
"version": "0.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ngx-cron-editor/-/ngx-cron-editor-0.7.3.tgz",
|
||||||
|
"integrity": "sha512-ICrikARGU5HJ9hZ8H4aGkKZP/T3U9Ym/2rIpS2wjimB3ASypp/8pAm6cEqaaJ5IHbSjgZBHEMeoomVkTa15l2g==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/animations": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0",
|
||||||
|
"@angular/common": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0",
|
||||||
|
"@angular/core": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0",
|
||||||
|
"@angular/forms": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0",
|
||||||
|
"@angular/material": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0",
|
||||||
|
"@angular/platform-browser": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0",
|
||||||
|
"@angular/platform-browser-dynamic": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0",
|
||||||
|
"@angular/router": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/nice-napi": {
|
"node_modules/nice-napi": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
|
||||||
@ -17247,6 +17266,14 @@
|
|||||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ngx-cron-editor": {
|
||||||
|
"version": "0.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ngx-cron-editor/-/ngx-cron-editor-0.7.3.tgz",
|
||||||
|
"integrity": "sha512-ICrikARGU5HJ9hZ8H4aGkKZP/T3U9Ym/2rIpS2wjimB3ASypp/8pAm6cEqaaJ5IHbSjgZBHEMeoomVkTa15l2g==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nice-napi": {
|
"nice-napi": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
"@angular/platform-browser-dynamic": "~13.2.0",
|
"@angular/platform-browser-dynamic": "~13.2.0",
|
||||||
"@angular/router": "~13.2.0",
|
"@angular/router": "~13.2.0",
|
||||||
"bootstrap": "^5.1.3",
|
"bootstrap": "^5.1.3",
|
||||||
|
"ngx-cron-editor": "^0.7.3",
|
||||||
"rxjs": "~7.5.0",
|
"rxjs": "~7.5.0",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"zone.js": "~0.11.4"
|
"zone.js": "~0.11.4"
|
||||||
|
@ -66,4 +66,23 @@ export class ProfileService {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} cronString
|
||||||
|
* @returns Observable
|
||||||
|
*/
|
||||||
|
public addCronString(cron: string): Observable<any> {
|
||||||
|
return this.http.put(
|
||||||
|
'https://gruppe1.testsites.info/api/user' + '/setCron',
|
||||||
|
{
|
||||||
|
cron,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: new HttpHeaders({
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: 'Bearer ' + this.tokenStorage.getToken(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
/>
|
/>
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
<span
|
||||||
|
>*To add a keyword, after writing, either press enter or click outside
|
||||||
|
of keyword input field.</span
|
||||||
|
>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</mat-grid-tile>
|
</mat-grid-tile>
|
||||||
@ -52,6 +56,10 @@
|
|||||||
/>
|
/>
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
<span
|
||||||
|
>*To add a share, after writing, either press enter or click outside
|
||||||
|
of keyword input field.</span
|
||||||
|
>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</mat-grid-tile>
|
</mat-grid-tile>
|
||||||
|
@ -3,24 +3,23 @@
|
|||||||
<span class="example-spacer"></span>
|
<span class="example-spacer"></span>
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
class="example-icon favorite-icon"
|
|
||||||
aria-label="Example icon-button with heart icon"
|
aria-label="Example icon-button with heart icon"
|
||||||
[matMenuTriggerFor]="menu"
|
routerLink="/profile"
|
||||||
>
|
>
|
||||||
<mat-icon>settings</mat-icon>
|
|
||||||
</button>
|
|
||||||
<mat-menu #menu="matMenu">
|
|
||||||
<button mat-menu-item routerLink="/profile">
|
|
||||||
<mat-icon>account_circle</mat-icon>
|
<mat-icon>account_circle</mat-icon>
|
||||||
<span>Profile</span>
|
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item routerLink="/settings">
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
class="example-icon favorite-icon"
|
||||||
|
routerLink="/settings"
|
||||||
|
>
|
||||||
<mat-icon>ballot</mat-icon>
|
<mat-icon>ballot</mat-icon>
|
||||||
<span>Bot Settings</span>
|
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item (click)="logout()">
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
aria-label="Example icon-button with heart icon"
|
||||||
|
(click)="logout()"
|
||||||
|
>
|
||||||
<mat-icon>logout</mat-icon>
|
<mat-icon>logout</mat-icon>
|
||||||
<span>Logout</span>
|
|
||||||
</button>
|
</button>
|
||||||
</mat-menu>
|
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<div class="containeer">
|
<div class="containeer">
|
||||||
<h1 mat-dialog-title>Aktion bestätigen</h1>
|
<h1 mat-dialog-title>Confirm Action</h1>
|
||||||
<div mat-dialog-content class="content">
|
<div mat-dialog-content class="content">
|
||||||
<span>Sind sie sicher, dass sie diese Handlung abschließen wollen?</span>
|
<span>Are you sure, that you want to continue?</span>
|
||||||
</div>
|
</div>
|
||||||
<div mat-dialog-actions class="form-group footer-buttons">
|
<div mat-dialog-actions class="form-group footer-buttons">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
@ -21,7 +21,7 @@
|
|||||||
(click)="confirm()"
|
(click)="confirm()"
|
||||||
[mat-dialog-close]="true"
|
[mat-dialog-close]="true"
|
||||||
>
|
>
|
||||||
Ok
|
Yes
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
<div class="containeer">
|
||||||
|
<h1 mat-dialog-title>How to add your Telegram account</h1>
|
||||||
|
<div mat-dialog-content class="content">
|
||||||
|
<span
|
||||||
|
>To get your UserId, you have to write "/id" or "/auth" to the bot on
|
||||||
|
Telegram. (<a href="https://t.me/projektaktienbot)"
|
||||||
|
>https://t.me/projektaktienbot)</a
|
||||||
|
>)</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div mat-dialog-actions class="form-group footer-buttons">
|
||||||
|
<div class="inner">
|
||||||
|
<button
|
||||||
|
id="okButton"
|
||||||
|
class="btn btn-secondary btn-block"
|
||||||
|
(click)="close()"
|
||||||
|
[mat-dialog-close]="true"
|
||||||
|
>
|
||||||
|
Ok
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,18 @@
|
|||||||
|
.footer-buttons {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
flex-grow: 1;
|
||||||
|
width: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
height: 80%;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HelpDialogComponent } from './help-dialog.component';
|
||||||
|
|
||||||
|
describe('HelpDialogComponent', () => {
|
||||||
|
let component: HelpDialogComponent;
|
||||||
|
let fixture: ComponentFixture<HelpDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ HelpDialogComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(HelpDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,14 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-help-dialog',
|
||||||
|
templateUrl: './help-dialog.component.html',
|
||||||
|
styleUrls: ['./help-dialog.component.scss'],
|
||||||
|
})
|
||||||
|
export class HelpDialogComponent implements OnInit {
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
ngOnInit(): void {}
|
||||||
|
|
||||||
|
close() {}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
<mat-grid-list cols="2">
|
<mat-grid-list cols="2" rowHeight="45%">
|
||||||
<mat-grid-tile>
|
<mat-grid-tile colspan="1" rowspan="2">
|
||||||
<mat-card class="card">
|
<mat-card class="card placeholder">
|
||||||
<mat-card-title class="card-title">Profile Information</mat-card-title>
|
<mat-card-title class="card-title">Profile Information</mat-card-title>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<form
|
<form
|
||||||
@ -95,9 +95,11 @@
|
|||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</mat-grid-tile>
|
</mat-grid-tile>
|
||||||
<mat-grid-tile>
|
<mat-grid-tile colspan="1" rowspan="1">
|
||||||
<mat-card class="card">
|
<mat-card class="card placeholderRHS">
|
||||||
<mat-card-title class="card-title">Add Telegram Id</mat-card-title>
|
<mat-card-title class="card-title">
|
||||||
|
<span>Connect Telegram Account</span>
|
||||||
|
</mat-card-title>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<form
|
<form
|
||||||
name="form"
|
name="form"
|
||||||
@ -129,6 +131,34 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<button class="btn btn-secondary btn-block" (click)="openHelp()">
|
||||||
|
Help
|
||||||
|
</button>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</mat-grid-tile>
|
||||||
|
<mat-grid-tile colspan="1" rowspan="1">
|
||||||
|
<mat-card class="card placeholderRHS">
|
||||||
|
<mat-card-title class="card-title">
|
||||||
|
<span>Add automatic updates</span>
|
||||||
|
</mat-card-title>
|
||||||
|
<mat-card-content class="cron-content">
|
||||||
|
<form
|
||||||
|
name="form"
|
||||||
|
(ngSubmit)="f.form.valid && setCronString()"
|
||||||
|
#f="ngForm"
|
||||||
|
novalidate
|
||||||
|
class="backgorund form"
|
||||||
|
>
|
||||||
|
<cron-editor
|
||||||
|
class="cron-editor"
|
||||||
|
[formControl]="cronForm"
|
||||||
|
[options]="cronOptions"
|
||||||
|
></cron-editor>
|
||||||
|
<div class="form-group footer-buttons">
|
||||||
|
<button class="btn btn-primary btn-block">Add</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</mat-grid-tile>
|
</mat-grid-tile>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
.card {
|
.card {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
height: 80%;
|
height: 90%;
|
||||||
margin: 5%;
|
margin: 5%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,3 +20,16 @@ mat-grid {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.placeholder {
|
||||||
|
height: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholderRHS {
|
||||||
|
height: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cron-content {
|
||||||
|
height: 70%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { FormControl, PatternValidator, Validators } from '@angular/forms';
|
import { FormControl, PatternValidator, Validators } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { CronOptions } from 'ngx-cron-editor';
|
||||||
import { ProfileService } from 'src/app/Services/profile.service';
|
import { ProfileService } from 'src/app/Services/profile.service';
|
||||||
import { ConfirmationDialogComponent } from './confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from './confirmation-dialog/confirmation-dialog.component';
|
||||||
|
import { HelpDialogComponent } from './help-dialog/help-dialog.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-profile',
|
selector: 'app-profile',
|
||||||
@ -30,6 +32,26 @@ export class ProfileComponent implements OnInit {
|
|||||||
public dialog: MatDialog
|
public dialog: MatDialog
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
cronForm = new FormControl('0 0 1/1 * *');
|
||||||
|
public cronOptions: CronOptions = {
|
||||||
|
defaultTime: '00:00:00',
|
||||||
|
|
||||||
|
hideMinutesTab: true,
|
||||||
|
hideHourlyTab: true,
|
||||||
|
hideDailyTab: false,
|
||||||
|
hideWeeklyTab: true,
|
||||||
|
hideMonthlyTab: true,
|
||||||
|
hideYearlyTab: true,
|
||||||
|
hideAdvancedTab: true,
|
||||||
|
hideSpecificWeekDayTab: true,
|
||||||
|
hideSpecificMonthWeekTab: true,
|
||||||
|
|
||||||
|
use24HourTime: true,
|
||||||
|
hideSeconds: true,
|
||||||
|
|
||||||
|
cronFlavor: 'quartz', //standard or quartz
|
||||||
|
};
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.profileService.getUserData().subscribe((result) => {
|
this.profileService.getUserData().subscribe((result) => {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
@ -75,4 +97,19 @@ export class ProfileComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setCronString() {
|
||||||
|
this.profileService
|
||||||
|
.addCronString(this.cronForm.value)
|
||||||
|
.subscribe((result) => {
|
||||||
|
console.log(result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openHelp() {
|
||||||
|
const dialogRef = this.dialog.open(HelpDialogComponent, {
|
||||||
|
width: '50vw',
|
||||||
|
height: '20vh',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ import { MatDialogModule } from '@angular/material/dialog';
|
|||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
|
|
||||||
|
import { CronEditorModule } from 'ngx-cron-editor';
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { LoginComponent } from './Views/login/login.component';
|
import { LoginComponent } from './Views/login/login.component';
|
||||||
@ -25,6 +27,7 @@ import { ProfileComponent } from './Views/profile/profile.component';
|
|||||||
import { BotSettingsComponent } from './Views/bot-settings/bot-settings.component';
|
import { BotSettingsComponent } from './Views/bot-settings/bot-settings.component';
|
||||||
import { UserDialogComponent } from './Views/dashboard/user-dialog/user-dialog.component';
|
import { UserDialogComponent } from './Views/dashboard/user-dialog/user-dialog.component';
|
||||||
import { ConfirmationDialogComponent } from './Views/profile/confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from './Views/profile/confirmation-dialog/confirmation-dialog.component';
|
||||||
|
import { HelpDialogComponent } from './Views/profile/help-dialog/help-dialog.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -37,6 +40,7 @@ import { ConfirmationDialogComponent } from './Views/profile/confirmation-dialog
|
|||||||
BotSettingsComponent,
|
BotSettingsComponent,
|
||||||
UserDialogComponent,
|
UserDialogComponent,
|
||||||
ConfirmationDialogComponent,
|
ConfirmationDialogComponent,
|
||||||
|
HelpDialogComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
@ -55,6 +59,7 @@ import { ConfirmationDialogComponent } from './Views/profile/confirmation-dialog
|
|||||||
MatInputModule,
|
MatInputModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatChipsModule,
|
MatChipsModule,
|
||||||
|
CronEditorModule,
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent],
|
bootstrap: [AppComponent],
|
||||||
|
Loading…
Reference in New Issue
Block a user