Refactor tutorial management and add AI image model functionality
- Updated application.properties for local database configuration. - Introduced DateTimeHelper for timestamp parsing. - Added MyAIImageModel and MyImageOptions for AI image processing. - Enhanced Tutorial model to include created and modified timestamps. - Implemented tutorial editing component with improved UI and functionality. - Updated user API service to handle tutorial retrieval and updates. - Refactored tutorials list component to support selection and batch deletion.
This commit is contained in:
@@ -1,6 +1,47 @@
|
||||
export class Tutorial {
|
||||
isSelected?: boolean;
|
||||
id?: any;
|
||||
title?: string;
|
||||
description?: string;
|
||||
published?: boolean;
|
||||
created?: Date;
|
||||
modified?: Date;
|
||||
isEdit?: boolean;
|
||||
}
|
||||
|
||||
export const TutorialColumns = [
|
||||
{
|
||||
key: 'isSelected',
|
||||
type: 'isSelected',
|
||||
label: '',
|
||||
},
|
||||
{
|
||||
key: 'title',
|
||||
type: 'text',
|
||||
label: 'Title',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
key: 'published',
|
||||
type: 'boolean',
|
||||
label: 'Is Published',
|
||||
},
|
||||
{
|
||||
key: 'created',
|
||||
type: 'datetime',
|
||||
label: 'Created Date',
|
||||
required: true,
|
||||
|
||||
},
|
||||
{
|
||||
key: 'modified',
|
||||
type: 'datetime',
|
||||
label: 'Modified Date',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: 'isEdit',
|
||||
type: 'isEdit',
|
||||
label: '',
|
||||
}
|
||||
];
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<mat-card appearance="outlined">
|
||||
<mat-card-header>
|
||||
<mat-card-title>Edit tutorial</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content >
|
||||
<mat-form-field class="example-full-width">
|
||||
<mat-label>Title</mat-label>
|
||||
<input matInput required
|
||||
[(ngModel)]="tutorial.title">
|
||||
</mat-form-field>
|
||||
<mat-tab-group>
|
||||
<mat-tab label="Markdown text">
|
||||
<textarea class="variable-textarea" [(ngModel)]="tutorial.description"></textarea>
|
||||
<markdown class="variable-binding" [data]="tutorial.description"></markdown>
|
||||
</mat-tab>
|
||||
<mat-tab label="Result">
|
||||
<markdown class="preview" [data]="tutorial.description"></markdown>
|
||||
</mat-tab>
|
||||
<mat-tab label="Example">
|
||||
<textarea class="variable-textarea" [(ngModel)]="markdown"></textarea>
|
||||
<markdown class="variable-binding" [data]="markdown"></markdown>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
|
||||
<button matButton (click)="updateTutorial()">Save</button>
|
||||
@if (hasError){
|
||||
<mat-error>
|
||||
{{errorMessage}}
|
||||
</mat-error>
|
||||
}
|
||||
@if(submitted) {
|
||||
<h4>Tutorial was submitted successfully!</h4>
|
||||
<button matButton routerLink="../tutorial-add">Add new tutorial</button>
|
||||
<button matButton routerLink="../tutorials-list">Back to list</button>
|
||||
}
|
||||
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
.submit-form {
|
||||
max-width: 400px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
mat-card{
|
||||
margin: 20px;
|
||||
}
|
||||
mat-card-title{
|
||||
color: cyan;
|
||||
}
|
||||
|
||||
.example-form {
|
||||
min-width: 150px;
|
||||
max-width: 500px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.example-full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.variable-binding,
|
||||
.variable-textarea {
|
||||
width: 49%;
|
||||
}
|
||||
|
||||
.variable-textarea {
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.07);
|
||||
min-height: 420px;
|
||||
padding: 8px;
|
||||
transition: all 300ms ease-out;
|
||||
}
|
||||
|
||||
.variable-textarea:hover {
|
||||
box-shadow: 0 6px 12px 3px rgba(0,0,0,.09),
|
||||
0 2px 3px 1px rgba(0,0,0,.06);
|
||||
}
|
||||
|
||||
.variable-binding {
|
||||
display: block;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.preview {
|
||||
/* display: block;
|
||||
float: right;*/
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TutorialEditComponent } from './tutorial-edit.component';
|
||||
|
||||
describe('TutorialEditComponent', () => {
|
||||
let component: TutorialEditComponent;
|
||||
let fixture: ComponentFixture<TutorialEditComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [TutorialEditComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(TutorialEditComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,91 @@
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
|
||||
import {MarkdownComponent} from 'ngx-markdown';
|
||||
import {MatButton} from '@angular/material/button';
|
||||
import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from '@angular/material/card';
|
||||
import {MatError, MatFormField, MatInput, MatLabel} from '@angular/material/input';
|
||||
import {MatTab, MatTabGroup} from '@angular/material/tabs';
|
||||
import {NgIf} from '@angular/common';
|
||||
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
import {Tutorial} from '../../models/tutorial.model';
|
||||
import {UserApiService} from '../user-api.service';
|
||||
import {ActivatedRoute, Router, RouterLink} from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tutorial-edit.component',
|
||||
imports: [
|
||||
MarkdownComponent,
|
||||
MatButton,
|
||||
MatCard,
|
||||
MatCardActions,
|
||||
MatCardContent,
|
||||
MatCardHeader,
|
||||
MatFormField,
|
||||
MatInput,
|
||||
MatLabel,
|
||||
MatTab,
|
||||
MatTabGroup,
|
||||
ReactiveFormsModule,
|
||||
FormsModule,
|
||||
MatFormField,
|
||||
RouterLink,
|
||||
MatError
|
||||
],
|
||||
templateUrl: './tutorial-edit.component.html',
|
||||
styleUrl: './tutorial-edit.component.scss',
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class TutorialEditComponent {
|
||||
tutorial: Tutorial = new Tutorial();
|
||||
submitted = false;
|
||||
hasError = false;
|
||||
errorMessage = '';
|
||||
markdown = `## Markdown __rulez__!
|
||||
---
|
||||
|
||||
### Syntax highlight
|
||||
\`\`\`typescript
|
||||
const language = 'typescript';
|
||||
\`\`\`
|
||||
|
||||
### Lists
|
||||
1. Ordered list
|
||||
2. Another bullet point
|
||||
- Unordered list
|
||||
- Another unordered bullet
|
||||
|
||||
### Blockquote
|
||||
> Blockquote to the max`;
|
||||
private id: string | null | undefined;
|
||||
|
||||
constructor(private userApiService: UserApiService, private route: ActivatedRoute) {
|
||||
|
||||
this.route.queryParams
|
||||
.subscribe(params => {
|
||||
console.log(params);
|
||||
this.id = params['id'];
|
||||
console.log(this.id);
|
||||
});
|
||||
|
||||
this.userApiService.getTutorial(this.id).subscribe(
|
||||
data=>{
|
||||
this.tutorial = data;
|
||||
}
|
||||
);
|
||||
}
|
||||
updateTutorial(): void {
|
||||
this.userApiService.update(this.id, this.tutorial)
|
||||
.subscribe(
|
||||
response => {
|
||||
console.log(response);
|
||||
this.submitted = true;
|
||||
this.hasError = false;
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
|
||||
this.errorMessage = error.error.message;
|
||||
|
||||
this.hasError = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
+143
-24
@@ -1,29 +1,148 @@
|
||||
<p>tutorials-list.component works!</p>
|
||||
<article class="table-header">
|
||||
<button
|
||||
class="button-remove-rows"
|
||||
mat-button
|
||||
(click)="removeSelectedRows()"
|
||||
>
|
||||
Remove Rows
|
||||
</button>
|
||||
<!--<button class="button-add-row" mat-button (click)="addRow()">
|
||||
Add Row
|
||||
</button>-->
|
||||
<button mat-raised-button routerLink="../tutorial-add">Add tutorial</button>
|
||||
|
||||
<button mat-raised-button routerLink="../tutorial-add">Add tutorial</button>
|
||||
</article>
|
||||
<table mat-table [dataSource]="dataSource">
|
||||
@for (column of columnsSchema; track column){
|
||||
<ng-container [matColumnDef]="column.key">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
@switch (column.key) {
|
||||
@case ('isSelected') {
|
||||
<mat-checkbox
|
||||
(change)="selectAll($event)"
|
||||
[checked]="isAllSelected()"
|
||||
[indeterminate]="!isAllSelected() && isAnySelected()"
|
||||
></mat-checkbox>
|
||||
}
|
||||
@default {
|
||||
{{ column.label }}
|
||||
}
|
||||
}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<!-- @if (element.isEdit) {-->
|
||||
@switch (column.type) {
|
||||
@case ('isSelected') {
|
||||
<mat-checkbox
|
||||
(change)="element.isSelected = $event.checked"
|
||||
[checked]="element.isSelected"
|
||||
></mat-checkbox>
|
||||
}
|
||||
@case('isEdit') {
|
||||
<div class="btn-edit" >
|
||||
<button mat-button routerLink='../tutorial-edit' [queryParams]="{id:element.id}" (click)="element.isEdit = !element.isEdit">
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
class="button-remove"
|
||||
(click)="removeRow(element.id)"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
@case ('boolean') {
|
||||
<mat-slide-toggle
|
||||
class="example-margin"
|
||||
[checked]="element[column.key]"
|
||||
[disabled]="true">
|
||||
|
||||
<mat-list role="list">
|
||||
@for (tutorial of tutorials; track tutorial) {
|
||||
<!--
|
||||
<mat-list-item role="listitem">
|
||||
{{tutorial.title}}
|
||||
</mat-slide-toggle>
|
||||
}
|
||||
@case ('datetime') {
|
||||
{{ element[column.key] | date: 'medium' }}
|
||||
}
|
||||
@default {
|
||||
{{ element[column.key] }}
|
||||
}
|
||||
}
|
||||
<!-- }-->
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<span class="spacer"></span>
|
||||
<button mat-button>
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button mat-button>
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</mat-list-item>-->
|
||||
<mat-option >
|
||||
<div style="display:flex; justify-content: space-between">
|
||||
<span>{{tutorial.title}}</span>
|
||||
<span></span>
|
||||
<span (click)="deleteOption($event, tutorial)">X</span>
|
||||
</div>
|
||||
</mat-option>
|
||||
}
|
||||
<!--<ng-container [matColumnDef]="col.key" *ngFor="let col of columnsSchema">-->
|
||||
<!--<th mat-header-cell *matHeaderCellDef [ngSwitch]="col.key">
|
||||
<span *ngSwitchCase="'isSelected'">
|
||||
<mat-checkbox
|
||||
(change)="selectAll($event)"
|
||||
[checked]="isAllSelected()"
|
||||
[indeterminate]="!isAllSelected() && isAnySelected()"
|
||||
></mat-checkbox>
|
||||
</span>
|
||||
<span *ngSwitchDefault>{{ col.label }}</span>
|
||||
</th>-->
|
||||
<!-- <mat-form-field-->
|
||||
<!--<td mat-cell *matCellDef="let element">
|
||||
<div [ngSwitch]="col.type" *ngIf="!element.isEdit">
|
||||
<ng-container *ngSwitchCase="'isSelected'">
|
||||
<mat-checkbox
|
||||
(change)="element.isSelected = $event.checked"
|
||||
[checked]="element.isSelected"
|
||||
></mat-checkbox>
|
||||
</ng-container>
|
||||
<div class="btn-edit" *ngSwitchCase="'isEdit'">
|
||||
<button mat-button (click)="element.isEdit = !element.isEdit">
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
class="button-remove"
|
||||
(click)="removeRow(element.id)"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
<span *ngSwitchCase="'date'">
|
||||
{{ element[col.key] | date: 'mediumDate' }}
|
||||
</span>
|
||||
<span *ngSwitchDefault>
|
||||
{{ element[col.key] }}
|
||||
</span>
|
||||
</div>
|
||||
<div [ngSwitch]="col.type" *ngIf="element.isEdit">
|
||||
<div *ngSwitchCase="'isSelected'"></div>
|
||||
<div class="btn-edit" *ngSwitchCase="'isEdit'">
|
||||
<button
|
||||
mat-button
|
||||
(click)="editRow(element)"
|
||||
[disabled]="disableSubmit(element.id)"
|
||||
>
|
||||
Done
|
||||
</button>
|
||||
</div>
|
||||
class="form-input"
|
||||
*ngSwitchCase="'date'"
|
||||
appearance="fill"
|
||||
>
|
||||
<mat-label>Choose a date</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="picker"
|
||||
[(ngModel)]="element[col.key]"
|
||||
/>
|
||||
<mat-datepicker-toggle
|
||||
matSuffix
|
||||
[for]="picker"
|
||||
></mat-datepicker-toggle>
|
||||
<mat-datepicker #picker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>-->
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
|
||||
|
||||
</mat-list>
|
||||
|
||||
+11
@@ -1,3 +1,14 @@
|
||||
.table-header {
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
text-align: right;
|
||||
margin-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.spacer{
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
+130
-26
@@ -1,6 +1,6 @@
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA, OnInit} from '@angular/core';
|
||||
import {MatList, MatListItem} from '@angular/material/list';
|
||||
import {Tutorial} from '../../models/tutorial.model';
|
||||
import {Tutorial, TutorialColumns} from '../../models/tutorial.model';
|
||||
import {TutorialService} from '../../services/tutorial.service';
|
||||
import {UserApiService} from '../user-api.service';
|
||||
import {MatButton} from '@angular/material/button';
|
||||
@@ -11,29 +11,80 @@ import {EventBusService} from '../../_shared/event-bus.service';
|
||||
import {EventData} from '../../_shared/event.class';
|
||||
import {Router, RouterLink} from '@angular/router';
|
||||
import {AuthService} from '../../services/auth.service';
|
||||
import {FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
import {
|
||||
MatCell,
|
||||
MatCellDef,
|
||||
MatColumnDef, MatHeaderCell, MatHeaderCellDef,
|
||||
MatHeaderRow,
|
||||
MatHeaderRowDef,
|
||||
MatRow,
|
||||
MatRowDef,
|
||||
MatTable,
|
||||
MatTableDataSource
|
||||
} from '@angular/material/table';
|
||||
import {MatFormField, MatInput} from '@angular/material/input';
|
||||
import {DatePipe, NgForOf, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';
|
||||
import {MatCheckbox} from '@angular/material/checkbox';
|
||||
import {MatDatepicker, MatDatepickerInput, MatDatepickerToggle} from '@angular/material/datepicker';
|
||||
import {MatSlideToggle} from '@angular/material/slide-toggle';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tutorials-list.component',
|
||||
imports: [
|
||||
MatList,
|
||||
MatListItem,
|
||||
MatLine,
|
||||
MatButton,
|
||||
MatIcon,
|
||||
MatOption,
|
||||
RouterLink
|
||||
],
|
||||
schemas:[CUSTOM_ELEMENTS_SCHEMA],
|
||||
templateUrl: './tutorials-list.component.html',
|
||||
styleUrl: './tutorials-list.component.scss'
|
||||
})
|
||||
export class TutorialsListComponent implements OnInit {
|
||||
tutorials?: Tutorial[];
|
||||
|
||||
@Component({
|
||||
selector: 'app-tutorials-list.component',
|
||||
imports: [
|
||||
MatList,
|
||||
MatListItem,
|
||||
MatLine,
|
||||
MatButton,
|
||||
MatIcon,
|
||||
MatOption,
|
||||
RouterLink,
|
||||
ReactiveFormsModule,
|
||||
MatTable,
|
||||
MatHeaderRowDef,
|
||||
MatHeaderRow,
|
||||
MatRowDef,
|
||||
MatRow,
|
||||
FormsModule,
|
||||
MatInput,
|
||||
MatFormField,
|
||||
MatColumnDef,
|
||||
MatHeaderCell,
|
||||
MatHeaderCellDef,
|
||||
NgSwitch,
|
||||
NgSwitchCase,
|
||||
NgSwitchDefault,
|
||||
MatCellDef,
|
||||
MatCheckbox,
|
||||
MatDatepickerInput,
|
||||
MatDatepickerToggle,
|
||||
MatDatepicker,
|
||||
DatePipe,
|
||||
NgIf,
|
||||
NgForOf,
|
||||
MatCell,
|
||||
MatSlideToggle
|
||||
],
|
||||
schemas:[CUSTOM_ELEMENTS_SCHEMA],
|
||||
templateUrl: './tutorials-list.component.html',
|
||||
styleUrl: './tutorials-list.component.scss'
|
||||
})
|
||||
export class TutorialsListComponent implements OnInit {
|
||||
//tutorials?: Tutorial[];
|
||||
|
||||
displayedColumns: string[] = TutorialColumns.map((col) => col.key)
|
||||
columnsSchema: any = TutorialColumns
|
||||
dataSource = new MatTableDataSource<Tutorial>()
|
||||
valid: any = {}
|
||||
|
||||
constructor(private userApiService: UserApiService,
|
||||
private storageService: TokenStorageService,
|
||||
private eventBusService: EventBusService,
|
||||
private router: Router, private authService: AuthService) {
|
||||
private router: Router,
|
||||
private authService: AuthService
|
||||
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
@@ -41,14 +92,13 @@ export class TutorialsListComponent implements OnInit {
|
||||
this.eventBusService.on('logout', () => {
|
||||
this.logout();
|
||||
})
|
||||
this.retrieveTutorials();
|
||||
this.getTutorials();
|
||||
}
|
||||
|
||||
retrieveTutorials(): void {
|
||||
getTutorials(): void {
|
||||
this.userApiService.getUserAllTutorials()
|
||||
.subscribe(
|
||||
data => {
|
||||
this.tutorials = data;
|
||||
.subscribe(( data:Tutorial[] ) => {
|
||||
this.dataSource.data = data;
|
||||
console.log(data);
|
||||
},
|
||||
error => {
|
||||
@@ -65,9 +115,63 @@ export class TutorialsListComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
deleteOption($event: MouseEvent, option: any) {
|
||||
selectAll(event: any) {
|
||||
this.dataSource.data = this.dataSource.data.map((item) => ({
|
||||
...item,
|
||||
isSelected: event.checked
|
||||
}));
|
||||
}
|
||||
|
||||
isAllSelected() {
|
||||
return this.dataSource.data.every((item) => item.isSelected)
|
||||
}
|
||||
|
||||
isAnySelected() {
|
||||
return this.dataSource.data.some((item) => item.isSelected)
|
||||
}
|
||||
|
||||
removeSelectedRows() {
|
||||
const selectedTutorials = this.dataSource.data.filter((u: Tutorial) => u.isSelected)
|
||||
/*this.dialog
|
||||
.open(ConfirmDialogComponent)
|
||||
.afterClosed()
|
||||
.subscribe((confirm) => {*/
|
||||
// if (confirm) {
|
||||
this.userApiService.deleteTutorials(selectedTutorials).subscribe(() => {
|
||||
this.dataSource.data = this.dataSource.data.filter(
|
||||
(u: Tutorial) => !u.isSelected
|
||||
)
|
||||
})
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
removeRow(id: number) {
|
||||
this.userApiService.deleteTutorial(id).subscribe(() => {
|
||||
this.dataSource.data = this.dataSource.data.filter(
|
||||
(u: Tutorial) => u.id !== id,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
editRow(row: Tutorial) {
|
||||
/*if (row.id === 0) {
|
||||
this.userService.addUser(row).subscribe((newUser: User) => {
|
||||
row.id = newUser.id
|
||||
row.isEdit = false
|
||||
})
|
||||
} else {
|
||||
this.userService.updateUser(row).subscribe(() => (row.isEdit = false))
|
||||
}*/
|
||||
}
|
||||
|
||||
disableSubmit(id: number) {
|
||||
if (this.valid[id]) {
|
||||
return Object.values(this.valid[id]).some((item) => item === false)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
logout(): void {
|
||||
this.authService.logout().subscribe({
|
||||
next: res => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {Observable} from 'rxjs';
|
||||
import {forkJoin, Observable} from 'rxjs';
|
||||
import {Tutorial} from '../models/tutorial.model';
|
||||
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
||||
|
||||
@@ -21,7 +21,28 @@ export class UserApiService {
|
||||
return this.http.get<Tutorial[]>(`${this.baseUrl}/tutorials`, this.httpOptions);
|
||||
}
|
||||
|
||||
getTutorial(id: string | null | undefined): Observable<Tutorial> {
|
||||
return this.http.get<Tutorial>(`${this.baseUrl}/tutorial-get/${id}`);
|
||||
}
|
||||
|
||||
create(data: any): Observable<any> {
|
||||
return this.http.post(`${this.baseUrl}/tutorial-add`, data);
|
||||
}
|
||||
|
||||
update(id: any,data: any): Observable<any> {
|
||||
return this.http.put(`${this.baseUrl}/tutorial-update/${id}`, data);
|
||||
}
|
||||
|
||||
deleteTutorials(tutorials: Tutorial[]): Observable<Tutorial[]> {
|
||||
return forkJoin(
|
||||
tutorials.map((tutorial) =>
|
||||
this.http.delete<Tutorial>(`${this.baseUrl}/tutorials/${tutorial.id}`)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
deleteTutorial(id: number): Observable<Tutorial> {
|
||||
return this.http.delete<Tutorial>(`${this.baseUrl}/tutorials/${id}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,4 +47,6 @@ mat-sidenav-content{
|
||||
}
|
||||
.pc-container{
|
||||
top: 0px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@ const USER_ROUTES: Routes = [
|
||||
path: 'tutorial-add',
|
||||
loadComponent: () => import('../user-module/tutorial-add.component/tutorial-add.component').then((c) => c.TutorialAddComponent)
|
||||
},
|
||||
{
|
||||
path: 'tutorial-edit',
|
||||
loadComponent: () => import('../user-module/tutorial-edit.component/tutorial-edit.component').then((c) => c.TutorialEditComponent)
|
||||
},
|
||||
{
|
||||
path: 'ai-models',
|
||||
loadComponent: () => import('../user-module/ai-models.component/ai-models.component').then((c) => c.AiModelsComponent)
|
||||
|
||||
Reference in New Issue
Block a user