Add new components, styles, and services for user management and navigation
This commit is contained in:
@@ -44,7 +44,8 @@
|
||||
<input matInput required
|
||||
[(ngModel)]="tutorial.title">
|
||||
</mat-form-field>
|
||||
<kendo-editor [(ngModel)]="tutorial.description" ></kendo-editor>
|
||||
<!-- <kendo-editor [(ngModel)]="tutorial.description" ></kendo-editor>-->
|
||||
<textarea matInput required [(ngModel)]="tutorial.description"></textarea>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button matButton (click)="saveTutorial()" *ngIf="!submitted">Save</button>
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA, OnInit} from '@angular/core';
|
||||
import {Tutorial} from '../../models/tutorial.model';
|
||||
import {TutorialService} from '../../services/tutorial.service';
|
||||
import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from '@angular/material/card';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {MatButton} from '@angular/material/button';
|
||||
import {MatFormField, MatInput, MatLabel} from '@angular/material/input';
|
||||
import {NgIf} from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-add-tutorial',
|
||||
templateUrl: './add-tutorial.component.html',
|
||||
styleUrls: ['./add-tutorial.component.scss'],
|
||||
standalone: false
|
||||
imports: [
|
||||
MatCardActions,
|
||||
FormsModule,
|
||||
MatCard,
|
||||
MatCardHeader,
|
||||
MatCardContent,
|
||||
MatFormField,
|
||||
MatLabel,
|
||||
|
||||
MatButton,
|
||||
MatInput,
|
||||
NgIf,
|
||||
MatLabel,
|
||||
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class AddTutorialComponent implements OnInit {
|
||||
|
||||
|
||||
@@ -1,25 +1,45 @@
|
||||
import {Component, computed, model, OnInit} from '@angular/core';
|
||||
import {Component, computed, CUSTOM_ELEMENTS_SCHEMA, model, OnInit} from '@angular/core';
|
||||
|
||||
import {User} from "../../models/user.model";
|
||||
import {MatChipInputEvent} from "@angular/material/chips";
|
||||
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
|
||||
import {MatChipGrid, MatChipInput, MatChipInputEvent, MatChipRow} from "@angular/material/chips";
|
||||
import {
|
||||
MatAutocomplete,
|
||||
MatAutocompleteSelectedEvent,
|
||||
MatAutocompleteTrigger,
|
||||
MatOption
|
||||
} from "@angular/material/autocomplete";
|
||||
import {COMMA, ENTER} from "@angular/cdk/keycodes";
|
||||
import {AsyncPipe} from "@angular/common";
|
||||
import {FormControl} from "@angular/forms";
|
||||
import {AsyncPipe, NgForOf} from "@angular/common";
|
||||
import {FormControl, ReactiveFormsModule} from "@angular/forms";
|
||||
import {Observable, startWith} from "rxjs";
|
||||
import {map} from "rxjs/operators";
|
||||
import {UserService} from '../../services/user.service';
|
||||
import {RolesService} from '../../services/roles.service';
|
||||
import {Role} from '../../models/role';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {MatFormField} from '@angular/material/form-field';
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-board-admin',
|
||||
templateUrl: './board-admin.component.html',
|
||||
styleUrls: ['./board-admin.component.scss'],
|
||||
standalone: false,
|
||||
selector: 'app-board-admin',
|
||||
templateUrl: './board-admin.component.html',
|
||||
styleUrls: ['./board-admin.component.scss'],
|
||||
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
imports: [
|
||||
MatAutocomplete,
|
||||
ReactiveFormsModule,
|
||||
MatOption,
|
||||
NgForOf,
|
||||
MatFormField,
|
||||
MatChipGrid,
|
||||
|
||||
MatChipRow,
|
||||
MatIcon,
|
||||
MatChipInput,
|
||||
MatAutocompleteTrigger
|
||||
]
|
||||
})
|
||||
export class BoardAdminComponent implements OnInit {
|
||||
private gridApi: any;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<div class="card" [ngClass]="cardClass()">
|
||||
@if (showHeader()) {
|
||||
<div class="card-header d-flex align-items-center justify-content-between" [ngClass]="headerClass()">
|
||||
<div>
|
||||
<h5>{{ cardTitle() }}</h5>
|
||||
<ng-container *ngTemplateOutlet="headerTitleTemplate"></ng-container>
|
||||
</div>
|
||||
<ng-container *ngTemplateOutlet="headerOptionsTemplate"></ng-container>
|
||||
</div>
|
||||
}
|
||||
@if (showContent()) {
|
||||
<div class="card-body" [ngClass]="blockClass()" [style.padding.px]="padding()">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -0,0 +1,58 @@
|
||||
// Angular import
|
||||
import { Component, ContentChild, ElementRef, TemplateRef, input } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-card',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
templateUrl: './card.component.html',
|
||||
styleUrls: ['./card.component.scss']
|
||||
})
|
||||
export class CardComponent {
|
||||
// public props
|
||||
/**
|
||||
* Title of card. It will be visible at left side of card header
|
||||
*/
|
||||
cardTitle = input<string>();
|
||||
|
||||
/**
|
||||
* Class to be applied at card level
|
||||
*/
|
||||
cardClass = input<string>();
|
||||
|
||||
/**
|
||||
* To hide content from card
|
||||
*/
|
||||
showContent = input(true);
|
||||
|
||||
/**
|
||||
* Class to be applied at card content.
|
||||
*/
|
||||
blockClass = input<string>();
|
||||
|
||||
/**
|
||||
* Class to be applied on card header
|
||||
*/
|
||||
headerClass = input<string>();
|
||||
|
||||
/**
|
||||
* To hide header from card
|
||||
*/
|
||||
showHeader = input(true);
|
||||
|
||||
/**
|
||||
* padding around card content. default in px
|
||||
*/
|
||||
padding = input(20); // set default to 24 px
|
||||
|
||||
/**
|
||||
* Template reference of header actions on custom header
|
||||
*/
|
||||
@ContentChild('headerOptionsTemplate') headerOptionsTemplate!: TemplateRef<ElementRef>;
|
||||
|
||||
/**
|
||||
* Template reference of header actions besides title at left
|
||||
*/
|
||||
@ContentChild('headerTitleTemplate') headerTitleTemplate!: TemplateRef<ElementRef>;
|
||||
}
|
||||
@@ -14,7 +14,8 @@ import {MatFormField, MatLabel, MatSuffix} from "@angular/material/form-field";
|
||||
import {MatInput} from "@angular/material/input";
|
||||
import {FormsModule} from "@angular/forms";
|
||||
import {MatIcon} from "@angular/material/icon";
|
||||
import {DialogData} from "../../app.component";
|
||||
import {DialogData} from '../../main-module/main.component/main.component';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
<p>home.component works!</p>
|
||||
+1
-3
@@ -8,12 +8,10 @@ describe('HomeComponent', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ HomeComponent ]
|
||||
imports: [HomeComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(HomeComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home.component',
|
||||
imports: [],
|
||||
templateUrl: './home.component.html',
|
||||
styleUrl: './home.component.scss'
|
||||
})
|
||||
export class HomeComponent {
|
||||
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
<p-splitter [style]="{ height: '300px' }" styleClass="mb-8" layout="vertical">
|
||||
<ng-template #panel>
|
||||
<div class="flex items-center justify-center h-full">Panel 1</div>
|
||||
</ng-template>
|
||||
<ng-template #panel>
|
||||
<div class="flex items-center justify-center h-full">Panel 2</div>
|
||||
<p-scrollPanel [style]="{ width: '100%', height: '150px' }">
|
||||
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet...
|
||||
</p>
|
||||
<p>
|
||||
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium...
|
||||
</p>
|
||||
<p class="m-0">
|
||||
At vero eos et accusamus et iusto odio dignissimos...
|
||||
dfsd
|
||||
f
|
||||
sdf
|
||||
|
||||
dsf
|
||||
sd
|
||||
f
|
||||
sd
|
||||
fs
|
||||
fs
|
||||
fsfs
|
||||
fs
|
||||
fs
|
||||
fs
|
||||
fs
|
||||
fs
|
||||
</p>
|
||||
<app-article-comments />
|
||||
</p-scrollPanel>
|
||||
|
||||
|
||||
</ng-template>
|
||||
</p-splitter>
|
||||
|
||||
<p-scrollPanel [style]="{ width: '100%', height: '150px' }">
|
||||
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet...
|
||||
</p>
|
||||
<p>
|
||||
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium...
|
||||
</p>
|
||||
<p class="m-0">
|
||||
At vero eos et accusamus et iusto odio dignissimos...
|
||||
dfsd
|
||||
f
|
||||
sdf
|
||||
|
||||
dsf
|
||||
sd
|
||||
f
|
||||
sd
|
||||
fs
|
||||
fs
|
||||
fsfs
|
||||
fs
|
||||
fs
|
||||
fs
|
||||
fs
|
||||
fs
|
||||
</p>
|
||||
<app-article-comments />
|
||||
</p-scrollPanel>
|
||||
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
@defer (on viewport(container); prefetch on idle) {
|
||||
<app-article-comments></app-article-comments>
|
||||
} @loading {
|
||||
<mat-progress-spinner></mat-progress-spinner>
|
||||
|
||||
loading
|
||||
} @placeholder {
|
||||
<div class="skeleton-loader"></div>
|
||||
|
||||
<app-article-comments></app-article-comments>
|
||||
placeholder
|
||||
} @error {
|
||||
Error
|
||||
}
|
||||
|
||||
|
||||
<div #container>
|
||||
<h1>How I feel about Angular</h1>
|
||||
<article>
|
||||
<p>
|
||||
Angular is my favorite framework, and
|
||||
this is why. Angular has the coolest
|
||||
deferrable view feature that makes defer
|
||||
loading content the easiest and most
|
||||
ergonomic it could possibly be.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
@defer {
|
||||
<app-article-comments />
|
||||
} @placeholder (minimum 1s) {
|
||||
<p>Placeholder for comments</p>
|
||||
} @loading (minimum 1s; after 500ms) {
|
||||
<p>Loading comments...</p>
|
||||
} @error {
|
||||
<p>Failed to load comments</p>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
<ng-container [ngComponentOutlet]="profileComponent()" />
|
||||
-->
|
||||
|
||||
<mat-card #showComments appearance="outlined" >
|
||||
<mat-card-header>
|
||||
<mat-card-title>Tutorials</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
|
||||
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
@defer (on hover; on interaction(showComments)) {
|
||||
<app-article-comments />
|
||||
} @placeholder ( ;minimum 1s) {
|
||||
<p>Placeholder for comments</p>
|
||||
} @loading (minimum 1s; after 500ms) {
|
||||
<p>Loading comments...</p>
|
||||
} @error {
|
||||
<p>Failed to load comments</p>
|
||||
}
|
||||
|
||||
@for (tutorial of tutorials; track $index){
|
||||
<mat-card appearance="outlined" class="tutorial-card">
|
||||
<mat-card-content [innerHTML]="tutorial.description">
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
mat-card{
|
||||
margin: 20px;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
mat-card-title{
|
||||
color: cyan;
|
||||
}
|
||||
.tutorial-card{
|
||||
color: white;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import {Component, computed, OnInit} from '@angular/core';
|
||||
import {TutorialService} from '../../services/tutorial.service';
|
||||
|
||||
import {Tutorial} from '../../models/tutorial.model';
|
||||
import {ArticleComments} from '../article-comments/article-comments';
|
||||
import {AddTutorialComponent} from '../add-tutorial/add-tutorial.component';
|
||||
import { ScrollPanelModule } from 'primeng/scrollpanel';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
templateUrl: './home.component.html',
|
||||
styleUrls: ['./home.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class HomeComponent implements OnInit {
|
||||
content?: string;
|
||||
|
||||
tutorials?: Tutorial[];
|
||||
|
||||
constructor(private tutorialService: TutorialService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.retrieveTutorials();
|
||||
}
|
||||
retrieveTutorials(): void {
|
||||
this.tutorialService.getAll()
|
||||
.subscribe(
|
||||
data => {
|
||||
this.tutorials = data;
|
||||
console.log(data);
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
profileComponent = computed(() => AddTutorialComponent);
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {TokenStorageService} from '../../services/token-storage.service';
|
||||
import {NgForOf, NgIf} from '@angular/common';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-profile',
|
||||
templateUrl: './profile.component.html',
|
||||
styleUrls: ['./profile.component.scss'],
|
||||
standalone: false
|
||||
selector: 'app-profile',
|
||||
templateUrl: './profile.component.html',
|
||||
imports: [
|
||||
NgForOf,
|
||||
NgIf
|
||||
],
|
||||
styleUrls: ['./profile.component.scss']
|
||||
})
|
||||
export class ProfileComponent implements OnInit {
|
||||
currentUser: any;
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {AuthService} from '../../services/auth.service';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {NgIf} from '@angular/common';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-register',
|
||||
templateUrl: './register.component.html',
|
||||
styleUrls: ['./register.component.scss'],
|
||||
standalone: false
|
||||
selector: 'app-register',
|
||||
templateUrl: './register.component.html',
|
||||
imports: [
|
||||
FormsModule,
|
||||
NgIf
|
||||
],
|
||||
styleUrls: ['./register.component.scss']
|
||||
})
|
||||
export class RegisterComponent implements OnInit {
|
||||
form: any = {
|
||||
|
||||
@@ -3,13 +3,18 @@ import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import {Tutorial} from '../../models/tutorial.model';
|
||||
import {TutorialService} from '../../services/tutorial.service';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {NgIf} from '@angular/common';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-tutorial-details',
|
||||
templateUrl: './tutorial-details.component.html',
|
||||
styleUrls: ['./tutorial-details.component.scss'],
|
||||
standalone: false
|
||||
selector: 'app-tutorial-details',
|
||||
templateUrl: './tutorial-details.component.html',
|
||||
imports: [
|
||||
FormsModule,
|
||||
NgIf
|
||||
],
|
||||
styleUrls: ['./tutorial-details.component.scss']
|
||||
})
|
||||
export class TutorialDetailsComponent implements OnInit {
|
||||
|
||||
|
||||
@@ -3,12 +3,19 @@ import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import {Tutorial} from '../../models/tutorial.model';
|
||||
import {TutorialService} from '../../services/tutorial.service';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {NgIf} from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tutorials-list',
|
||||
templateUrl: './tutorials-list.component.html',
|
||||
styleUrls: ['./tutorials-list.component.scss'],
|
||||
standalone: false
|
||||
selector: 'app-tutorials-list',
|
||||
templateUrl: './tutorials-list.component.html',
|
||||
imports: [
|
||||
FormsModule,
|
||||
RouterLink,
|
||||
NgIf
|
||||
],
|
||||
styleUrls: ['./tutorials-list.component.scss']
|
||||
})
|
||||
export class TutorialsListComponent implements OnInit {
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
@for (tutorial of tutorials; track $index){
|
||||
<mat-card appearance="outlined" class="tutorial-card">
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{tutorial.title}}</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content [innerHTML]="tutorial.description">
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TutorialsComponent } from './tutorials.component';
|
||||
|
||||
describe('TutorialsComponent', () => {
|
||||
let component: TutorialsComponent;
|
||||
let fixture: ComponentFixture<TutorialsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [TutorialsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(TutorialsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
|
||||
import {Tutorial} from '../../models/tutorial.model';
|
||||
import {TutorialService} from '../../services/tutorial.service';
|
||||
import {MatCard, MatCardContent, MatCardHeader} from '@angular/material/card';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tutorials.component',
|
||||
imports: [
|
||||
MatCard,
|
||||
MatCardContent,
|
||||
MatCardHeader
|
||||
],
|
||||
templateUrl: './tutorials.component.html',
|
||||
styleUrl: './tutorials.component.scss',
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class TutorialsComponent {
|
||||
tutorials?: Tutorial[];
|
||||
|
||||
constructor(private tutorialService: TutorialService) {
|
||||
this.retrieveTutorials();
|
||||
}
|
||||
|
||||
// ngOnInit(): void {
|
||||
// this.retrieveTutorials();
|
||||
// }
|
||||
|
||||
retrieveTutorials(): void {
|
||||
this.tutorialService.getAll()
|
||||
.subscribe(
|
||||
data => {
|
||||
this.tutorials = data;
|
||||
console.log(data);
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user