Refactor admin component and update application properties for production setup
Gradle _jambotron_build aplication.properties for dev and prod
This commit is contained in:
@@ -48,3 +48,5 @@ out/
|
||||
|
||||
/logs/
|
||||
|
||||
/.idea/
|
||||
|
||||
|
||||
Generated
+5
@@ -16,5 +16,10 @@
|
||||
<option name="name" value="MavenRepo" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven" />
|
||||
<option name="name" value="maven" />
|
||||
<option name="url" value="https://jitpack.io" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
||||
+30
-56
@@ -37,20 +37,6 @@ dependencies {
|
||||
implementation("org.flywaydb:flyway-database-postgresql:10.4.1")
|
||||
|
||||
implementation 'org.springframework.ai:spring-ai-zhipuai-spring-boot-starter:1.0.0-M6'
|
||||
|
||||
|
||||
|
||||
|
||||
//implementation 'org.springframework.ai:spring-ai-starter-model-zhipuai'
|
||||
//implementation 'org.springframework.ai:spring-ai-zhipuai-spring-boot-starter'
|
||||
//implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-SNAPSHOT")
|
||||
// Replace the following with the starter dependencies of specific modules you wish to use
|
||||
//implementation 'org.springframework.ai:spring-ai-zhipuai'
|
||||
//implementation 'org.springframework.boot:spring-boot-starter-webflux'
|
||||
//implementation("org.springframework.ai:spring-ai-spring-boot-autoconfigure:1.0.0-M6")
|
||||
// https://mvnrepository.com/artifact/org.springframework.ai/spring-ai-retry
|
||||
//implementation("org.springframework.ai:spring-ai-retry:1.0.0")
|
||||
//implementation group: 'org.springframework.ai', name: 'spring-ai-spring-boot-autoconfigure', version: '1.0.0-M6'
|
||||
}
|
||||
|
||||
apply plugin: 'io.spring.dependency-management'
|
||||
@@ -60,67 +46,50 @@ apply plugin: 'io.spring.dependency-management'
|
||||
}
|
||||
}
|
||||
|
||||
// copyResouces( type:Copy
|
||||
|
||||
//tasks copyResouces( type:Copy){
|
||||
//
|
||||
// def buildDir = "${project.buildDir}"
|
||||
//
|
||||
// from "{$buildDir}/jambotron-ui/dist/jambotron-ui/browser" // Source directory
|
||||
// into "{$buildDir}/build/resources" // Target directory
|
||||
// include '**/*'
|
||||
//}
|
||||
|
||||
apply plugin: 'java'
|
||||
|
||||
/*tasks.register('copyResources', Copy) {
|
||||
from 'jambotron-ui/dist/jambotron-ui/browser'
|
||||
into 'src/main/resources/public'
|
||||
}*/
|
||||
//processResources.dependsOn(copyResources)
|
||||
//compileJava.dependsOn(copyResources)
|
||||
//bootRun.dependsOn("flywayMigrate")
|
||||
|
||||
//flyway {
|
||||
// user='admin'
|
||||
// password= 'postgrespw'
|
||||
// url = 'jdbc:postgresql://localhost:5432/jambotronDB'
|
||||
// driver = 'org.postgresql.Driver'
|
||||
// baselineOnMigrate = true
|
||||
// locations = ['filesystem:src/main/resources/db.migration/']
|
||||
//}
|
||||
|
||||
/*sourceSets {
|
||||
main {
|
||||
resources {
|
||||
srcDir 'jambotron-ui/dist/jambotron-ui/browser'
|
||||
tasks.register("bootRun_Dev") {
|
||||
group = "_jambotron_build"
|
||||
description = "Runs the Spring Boot application with the dev profile"
|
||||
doFirst {
|
||||
tasks.bootRun.configure {
|
||||
systemProperty("spring.profiles.active", "dev")
|
||||
}
|
||||
}
|
||||
}*/
|
||||
finalizedBy("bootRun")
|
||||
}
|
||||
|
||||
|
||||
|
||||
tasks.register('buildAngular_dev', Exec) {
|
||||
//dependsOn deleteStaticFolder
|
||||
group = "_jambotron_build"
|
||||
description = "Builds the Angular application in development mode"
|
||||
|
||||
workingDir './jambotron-ui' // Path to your Angular project (e.g., './angular-app')
|
||||
executable 'npm.cmd' // Use 'npm' for Unix-like systems or 'npm.cmd' for Windows
|
||||
|
||||
// Your Angular build command
|
||||
args = ['run', 'build_dev']//do not forget build_dev used port 8080 for connect to backend rest api
|
||||
//do not forget build_dev used port 8082 with proxy for connect to backend rest api
|
||||
args = ['run', 'build_dev']
|
||||
|
||||
}
|
||||
|
||||
tasks.register('buildAngular', Exec) {
|
||||
//dependsOn deleteStaticFolder
|
||||
tasks.register('buildAngular_prod', Exec) {
|
||||
group = "_jambotron_build"
|
||||
|
||||
workingDir './jambotron-ui' // Path to your Angular project (e.g., './angular-app')
|
||||
executable 'npm.cmd' // Use 'npm' for Unix-like systems or 'npm.cmd' for Windows
|
||||
|
||||
// Your Angular build command
|
||||
args = ['run', 'build']//do not forget build_dev used port 8080 for connect to backend rest api
|
||||
args = ['run', 'build']
|
||||
|
||||
}
|
||||
|
||||
|
||||
tasks.register('deleteStaticFolder', Delete) {
|
||||
dependsOn buildAngular
|
||||
tasks.register('deleteStaticFolder_prod', Delete) {
|
||||
group = "_jambotron_build"
|
||||
|
||||
dependsOn buildAngular_prod
|
||||
def dirName = "src/main/resources/static"
|
||||
file(dirName).list().each {
|
||||
f ->
|
||||
@@ -129,6 +98,8 @@ tasks.register('deleteStaticFolder', Delete) {
|
||||
}
|
||||
|
||||
tasks.register('deleteStaticFolder_dev', Delete) {
|
||||
group = "_jambotron_build"
|
||||
|
||||
dependsOn buildAngular_dev
|
||||
def dirName = "src/main/resources/static"
|
||||
file(dirName).list().each {
|
||||
@@ -137,12 +108,15 @@ tasks.register('deleteStaticFolder_dev', Delete) {
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('copyAngularBuild', Copy) {
|
||||
dependsOn deleteStaticFolder
|
||||
tasks.register('copyAngularBuild_prod', Copy) {
|
||||
group = "_jambotron_build"
|
||||
|
||||
dependsOn deleteStaticFolder_prod
|
||||
from 'jambotron-ui/dist/jambotron-ui' // Path to your Angular dist folder
|
||||
into "src/main/resources/static" // Path INSIDE the WAR
|
||||
}
|
||||
tasks.register('copyAngularBuild_dev', Copy) {
|
||||
group = "_jambotron_build"
|
||||
dependsOn deleteStaticFolder_dev
|
||||
from 'jambotron-ui/dist/jambotron-ui' // Path to your Angular dist folder
|
||||
into "src/main/resources/static" // Path INSIDE the WAR
|
||||
|
||||
@@ -76,15 +76,15 @@
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.development.ts"
|
||||
}
|
||||
]
|
||||
],
|
||||
"index": "src/index_dev.html"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
|
||||
"configurations": {
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "jambotron-ui:build:production"
|
||||
},
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"start": "ng serve --proxy-config src/proxy.conf.json",
|
||||
"start_prod": "ng serve --configuration production",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
|
||||
@@ -3,33 +3,8 @@
|
||||
>
|
||||
</app-side-bar-admin>
|
||||
<div class="pc-container">
|
||||
|
||||
<app-breadcrumb />
|
||||
|
||||
<router-outlet />
|
||||
|
||||
<router-outlet />
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!--<div class="pc-container">
|
||||
<div class="coded-wrapper">
|
||||
<div class="coded-content">
|
||||
<div class="coded-inner-content">
|
||||
<app-breadcrumb />
|
||||
<div class="main-body">
|
||||
<div class="page-wrapper">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pc-menu-overlay" (click)="closeMenu()" (keydown)="handleKeyDown($event)" tabindex="0"></div>
|
||||
</div>-->
|
||||
|
||||
|
||||
|
||||
@@ -1,32 +1,15 @@
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA, inject, OnInit} from '@angular/core';
|
||||
import {BreadcrumbComponent} from "../../components/breadcrumb/breadcrumb.component";
|
||||
import {NavBarComponent} from "../../layouts/admin-layout/nav-bar/nav-bar.component";
|
||||
import {NavigationComponent} from "../../layouts/admin-layout/navigation/navigation.component";
|
||||
import {Router, RouterLink, RouterOutlet} from "@angular/router";
|
||||
import {DOCUMENT, NgClass, NgStyle} from '@angular/common';
|
||||
import {MatDrawerContainer, MatSidenavModule} from '@angular/material/sidenav';
|
||||
import {MatButton} from '@angular/material/button';
|
||||
import {Router, RouterOutlet} from "@angular/router";
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import { ScrollPanelModule } from 'primeng/scrollpanel';
|
||||
import {MenuItem} from 'primeng/api';
|
||||
import {PanelMenu} from 'primeng/panelmenu';
|
||||
import {SideBarAdminComponent} from '../side-bar-admin.component/side-bar-admin.component';
|
||||
@Component({
|
||||
selector: 'app-admin.component',
|
||||
imports: [
|
||||
BreadcrumbComponent,
|
||||
NavBarComponent,
|
||||
NavigationComponent,
|
||||
RouterOutlet,
|
||||
NgClass,
|
||||
MatDrawerContainer,
|
||||
MatSidenavModule,
|
||||
ScrollPanelModule,
|
||||
MatButton,
|
||||
RouterLink,
|
||||
PanelMenu,
|
||||
NgStyle,
|
||||
SideBarAdminComponent,
|
||||
|
||||
SideBarAdminComponent
|
||||
],
|
||||
schemas:[CUSTOM_ELEMENTS_SCHEMA],
|
||||
templateUrl: './admin.component.html',
|
||||
@@ -38,11 +21,9 @@ export class AdminComponent implements OnInit {
|
||||
|
||||
items: MenuItem[] | undefined;
|
||||
|
||||
|
||||
constructor(private router: Router) {
|
||||
this.height = 0
|
||||
|
||||
|
||||
}
|
||||
|
||||
// public props
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
|
||||
import {MatCard, MatCardContent, MatCardHeader} from '@angular/material/card';
|
||||
import {MatCard, MatCardContent} from '@angular/material/card';
|
||||
import {MatDivider} from '@angular/material/divider';
|
||||
import {MatTab, MatTabGroup} from '@angular/material/tabs';
|
||||
import {
|
||||
@@ -22,7 +22,6 @@ import {MatIcon} from '@angular/material/icon';
|
||||
selector: 'app-system.component',
|
||||
imports: [
|
||||
MatCard,
|
||||
MatCardHeader,
|
||||
MatCardContent,
|
||||
MatDivider,
|
||||
MatTabGroup,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, model} from '@angular/core';
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA, model} from '@angular/core';
|
||||
import {UserService} from '../../services/user.service';
|
||||
import {RolesService} from '../../services/roles.service';
|
||||
import {Role} from '../../models/role';
|
||||
@@ -56,9 +56,6 @@ import {AdminModuleService} from '../admin-module.service';
|
||||
MatAutocomplete,
|
||||
MatOption,
|
||||
MatFormField,
|
||||
MatSelect,
|
||||
MatSelectTrigger,
|
||||
MatChip,
|
||||
MatChipsModule
|
||||
],
|
||||
templateUrl: './users.component.html',
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {AdminComponent} from './layouts/admin-layout/admin-layout.component';
|
||||
import {MainComponent} from './main-module/main.component/main.component';
|
||||
import {NgModule} from '@angular/core';
|
||||
|
||||
export const routes: Routes = [
|
||||
@@ -14,7 +12,6 @@ export const routes: Routes = [
|
||||
loadChildren: () =>
|
||||
import('./main-module/main.module').then((m) => m.MainModule),
|
||||
}
|
||||
|
||||
];
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes, { useHash: true}) ],
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
<!--<div>-->
|
||||
<!-- <div class="submit-form">-->
|
||||
<!-- <div *ngIf="!submitted">-->
|
||||
<!-- <div class="form-group">-->
|
||||
<!-- <label for="title">Title</label>-->
|
||||
<!-- <input-->
|
||||
<!-- type="text"-->
|
||||
<!-- class="form-control"-->
|
||||
<!-- id="title"-->
|
||||
<!-- required-->
|
||||
<!-- [(ngModel)]="tutorial.title"-->
|
||||
<!-- name="title"-->
|
||||
<!-- />-->
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- <div class="form-group">-->
|
||||
<!-- <label for="description">Description</label>-->
|
||||
<!-- <input-->
|
||||
<!-- class="form-control"-->
|
||||
<!-- id="description"-->
|
||||
<!-- required-->
|
||||
<!-- [(ngModel)]="tutorial.description"-->
|
||||
<!-- name="description"-->
|
||||
<!-- />-->
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- <button (click)="saveTutorial()" class="btn btn-success">Submit</button>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- <div *ngIf="submitted">-->
|
||||
<!-- <h4>Tutorial was submitted successfully!</h4>-->
|
||||
<!-- <button class="btn btn-success" (click)="newTutorial()">Add</button>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!--</div>-->
|
||||
|
||||
<mat-card appearance="outlined">
|
||||
<mat-card-header>
|
||||
<mat-card-title>Add 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)="saveTutorial()" *ngIf="!submitted">Save</button>
|
||||
<div *ngIf="submitted">
|
||||
<h4>Tutorial was submitted successfully!</h4>
|
||||
<button matButton (click)="newTutorial()">Add new tutorial</button>
|
||||
</div>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
@@ -1,52 +0,0 @@
|
||||
.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;*/
|
||||
}
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AddTutorialComponent } from './add-tutorial.component';
|
||||
|
||||
describe('AddTutorialComponent', () => {
|
||||
let component: AddTutorialComponent;
|
||||
let fixture: ComponentFixture<AddTutorialComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ AddTutorialComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AddTutorialComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,96 +0,0 @@
|
||||
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';
|
||||
import {MatTab, MatTabGroup} from '@angular/material/tabs';
|
||||
import {MarkdownComponent} from 'ngx-markdown';
|
||||
|
||||
@Component({
|
||||
selector: 'app-add-tutorial',
|
||||
templateUrl: './add-tutorial.component.html',
|
||||
styleUrls: ['./add-tutorial.component.scss'],
|
||||
imports: [
|
||||
MatCardActions,
|
||||
FormsModule,
|
||||
MatCard,
|
||||
MatCardHeader,
|
||||
MatCardContent,
|
||||
MatFormField,
|
||||
MatLabel,
|
||||
|
||||
MatButton,
|
||||
MatInput,
|
||||
NgIf,
|
||||
MatLabel,
|
||||
MatTabGroup,
|
||||
MatTab,
|
||||
MarkdownComponent,
|
||||
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class AddTutorialComponent implements OnInit {
|
||||
|
||||
tutorial: Tutorial = {
|
||||
title: '',
|
||||
description: '',
|
||||
published: false
|
||||
};
|
||||
submitted = false
|
||||
|
||||
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`;
|
||||
|
||||
|
||||
|
||||
constructor(private tutorialService: TutorialService) {
|
||||
this.tutorial.description = this.markdown;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
saveTutorial(): void {
|
||||
const data = {
|
||||
title: this.tutorial.title,
|
||||
description: this.tutorial.description
|
||||
};
|
||||
|
||||
/* this.tutorialService.create(data)
|
||||
.subscribe(
|
||||
response => {
|
||||
console.log(response);
|
||||
this.submitted = true;
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
});*/
|
||||
}
|
||||
|
||||
newTutorial(): void {
|
||||
this.submitted = false;
|
||||
this.tutorial = {
|
||||
title: '',
|
||||
description: '',
|
||||
published: false
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
<h2>Comments</h2>
|
||||
<p class="comment">
|
||||
Building for the web is fantastic!
|
||||
</p>
|
||||
<p class="comment">
|
||||
The new template syntax is great
|
||||
</p>
|
||||
<p class="comment">
|
||||
I agree with the other comments!
|
||||
</p>
|
||||
@@ -1,6 +0,0 @@
|
||||
.comment {
|
||||
padding: 15px;
|
||||
margin-left: 30px;
|
||||
background-color: paleturquoise;
|
||||
border-radius: 20px;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ArticleComments } from './article-comments';
|
||||
|
||||
describe('ArticleComments', () => {
|
||||
let component: ArticleComments;
|
||||
let fixture: ComponentFixture<ArticleComments>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ArticleComments]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ArticleComments);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-article-comments',
|
||||
imports: [],
|
||||
templateUrl: './article-comments.html',
|
||||
styleUrl: './article-comments.scss'
|
||||
})
|
||||
export class ArticleComments {
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
<div class="col-md-6">
|
||||
<h4>Users List</h4>
|
||||
<ul class="list-group">
|
||||
<li
|
||||
class="list-group-item"
|
||||
*ngFor="let row of rowData; let i = index"
|
||||
|
||||
>
|
||||
{{ row.username }}
|
||||
|
||||
{{ row.email}}
|
||||
{{ row.password}}
|
||||
|
||||
<form>
|
||||
<mat-form-field class="example-chip-list">
|
||||
<mat-chip-grid #chipGrid aria-label="Role selection">
|
||||
@for (role of row.roles; track $index) {
|
||||
<mat-chip-row (removed)="remove(role)">
|
||||
{{role.name}}
|
||||
<button matChipRemove [attr.aria-label]="'remove ' + role.name">
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
</mat-chip-row>
|
||||
}
|
||||
</mat-chip-grid>
|
||||
<input
|
||||
name="currentFruit"
|
||||
placeholder="Add role..."
|
||||
#fruitInput
|
||||
[(ngModel)]="currentRole"
|
||||
[matChipInputFor]="chipGrid"
|
||||
[matAutocomplete]="auto"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
[formControl]="myControl"
|
||||
(matChipInputTokenEnd)="add($event)"
|
||||
(input)="change($event,filteredRoles(row.roles))"
|
||||
/>
|
||||
<mat-autocomplete [formControl]="ac" autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="selected(row.roles,$event); ">
|
||||
@for (role of filteredRoles(row.roles); track role) {
|
||||
<mat-option [value]="role">{{role.name}}</mat-option>
|
||||
}
|
||||
</mat-autocomplete>
|
||||
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.example-chip-list {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { BoardAdminComponent } from './board-admin.component';
|
||||
|
||||
describe('BoardAdminComponent', () => {
|
||||
let component: BoardAdminComponent;
|
||||
let fixture: ComponentFixture<BoardAdminComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ BoardAdminComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BoardAdminComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,143 +0,0 @@
|
||||
import {Component, computed, CUSTOM_ELEMENTS_SCHEMA, model, OnInit} from '@angular/core';
|
||||
|
||||
import {User} from "../../models/user.model";
|
||||
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, 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'],
|
||||
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
imports: [
|
||||
MatAutocomplete,
|
||||
ReactiveFormsModule,
|
||||
MatOption,
|
||||
NgForOf,
|
||||
MatFormField,
|
||||
MatChipGrid,
|
||||
|
||||
MatChipRow,
|
||||
MatIcon,
|
||||
MatChipInput,
|
||||
MatAutocompleteTrigger
|
||||
]
|
||||
})
|
||||
export class BoardAdminComponent implements OnInit {
|
||||
private gridApi: any;
|
||||
|
||||
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
rowData?: User[];
|
||||
allRoles: any;
|
||||
|
||||
readonly currentRole = model('');
|
||||
|
||||
protected myControl = new FormControl('');
|
||||
protected ac = new FormControl('');
|
||||
|
||||
|
||||
constructor(private userService: UserService, private roleService: RolesService ) {
|
||||
this.getAllRoles();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
//this.myControl.valueChanges.pipe(
|
||||
// startWith(''),
|
||||
// map(value => this._filter(value || '')),
|
||||
//);
|
||||
|
||||
this.userService.getAdminBoard().subscribe(
|
||||
(data : any) => {
|
||||
this.rowData = data;
|
||||
},
|
||||
(err : any)=> {
|
||||
this.rowData = JSON.parse(err.error).message;
|
||||
}
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
filteredRoles(roles : Role[]):any {
|
||||
return this.allRoles.filter(
|
||||
(r:Role) => !roles.some((item) => item.id === r.id),
|
||||
);
|
||||
}
|
||||
|
||||
// private _filter(value: string): string[] {
|
||||
// const filterValue = value.toLowerCase();
|
||||
// this.ac.
|
||||
// return this.options.filter(option => option.toLowerCase().includes(filterValue));
|
||||
//}
|
||||
|
||||
getAllRoles():any{
|
||||
this.roleService.getAllRoles().subscribe(
|
||||
(data : any) => {
|
||||
this.allRoles = data;
|
||||
},
|
||||
(err : any)=> {
|
||||
this.allRoles = JSON.parse(err.error).message;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
remove(role: string): void {
|
||||
// this.fruits.update(fruits => {
|
||||
// const index = fruits.indexOf(fruit);
|
||||
// if (index < 0) {
|
||||
// return fruits;
|
||||
// }
|
||||
|
||||
// fruits.splice(index, 1);
|
||||
// this.announcer.announce(`Removed ${fruit}`);
|
||||
// return [...fruits];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
add(event: MatChipInputEvent): void {
|
||||
const value = (event.value || '').trim();
|
||||
|
||||
// Add our fruit
|
||||
if (value) {
|
||||
// this.fruits.update(fruits => [...fruits, value]);
|
||||
}
|
||||
|
||||
// Clear the input value
|
||||
this.currentRole.set('');
|
||||
}
|
||||
|
||||
selected(roles : Role[], event: MatAutocompleteSelectedEvent): void {
|
||||
|
||||
roles.push(event.option.value);
|
||||
this.currentRole.set('');
|
||||
event.option.deselect();
|
||||
}
|
||||
|
||||
|
||||
change($event: Event, roles: Role[]) {
|
||||
|
||||
roles.filter(
|
||||
(r:Role) => !roles.some((item) => item.name?.toLowerCase() === r.id),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
<p>board-moderator works!</p>
|
||||
@@ -1,25 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { BoardModeratorComponent } from './board-moderator.component';
|
||||
|
||||
describe('BoardModeratorComponent', () => {
|
||||
let component: BoardModeratorComponent;
|
||||
let fixture: ComponentFixture<BoardModeratorComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ BoardModeratorComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BoardModeratorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-board-moderator',
|
||||
templateUrl: './board-moderator.component.html',
|
||||
styleUrls: ['./board-moderator.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class BoardModeratorComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
<p>board-user works!</p>
|
||||
@@ -1,25 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { BoardUserComponent } from './board-user.component';
|
||||
|
||||
describe('BoardUserComponent', () => {
|
||||
let component: BoardUserComponent;
|
||||
let fixture: ComponentFixture<BoardUserComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ BoardUserComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BoardUserComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-board-user',
|
||||
templateUrl: './board-user.component.html',
|
||||
styleUrls: ['./board-user.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class BoardUserComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
@for (breadcrumb of navigationList; track breadcrumb; let last = $last) {
|
||||
@if (last && breadcrumb.breadcrumbs !== false) {
|
||||
<div class="page-header">
|
||||
<div class="page-block">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-md-12">
|
||||
<ul class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
@if (type === 'theme2') {
|
||||
<a [routerLink]="['/main/home']" title="Home" class="home"><i class="feather icon-home"></i></a>
|
||||
}
|
||||
@if (type === 'theme1') {
|
||||
<a [routerLink]="['/main/home']" class="home">Home</a>
|
||||
}
|
||||
</li>
|
||||
@for (breadcrumb of navigationList; track breadcrumb) {
|
||||
@if (breadcrumb.url !== false) {
|
||||
<li class="breadcrumb-item">
|
||||
<a [routerLink]="breadcrumb.url" class="f-14 f-w-600">{{ breadcrumb.title }}</a>
|
||||
</li>
|
||||
}
|
||||
@if (breadcrumb.url === false && breadcrumb.type !== 'group') {
|
||||
<li class="breadcrumb-item">
|
||||
<a href="javascript:">{{ breadcrumb.title }}</a>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="page-header-title">
|
||||
@for (breadcrumb of navigationList; track breadcrumb; let last = $last) {
|
||||
@if (last) {
|
||||
<h2 class="mb-0 f-w-600 mt-2">{{ breadcrumb.title }}</h2>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
// Angular Import
|
||||
import { Component, Input, inject, input } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NavigationEnd, Router, RouterModule, Event } from '@angular/router';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
|
||||
// project import
|
||||
//import { NavigationItem, NavigationItems } from 'src/app/theme/layouts/admin-layout/navigation/navigation';
|
||||
|
||||
// icons
|
||||
import { IconService } from '@ant-design/icons-angular';
|
||||
import { GlobalOutline, NodeExpandOutline } from '@ant-design/icons-angular/icons';
|
||||
import {NavigationItem, NavigationItems} from '../../layouts/admin-layout/navigation/navigation';
|
||||
|
||||
interface titleType {
|
||||
// eslint-disable-next-line
|
||||
url: any;
|
||||
title: string;
|
||||
breadcrumbs: unknown;
|
||||
type: string;
|
||||
link?: string | undefined;
|
||||
description?: string | undefined;
|
||||
path?: string | undefined;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-breadcrumb',
|
||||
imports: [CommonModule, RouterModule],
|
||||
templateUrl: './breadcrumb.component.html',
|
||||
styleUrls: ['./breadcrumb.component.scss']
|
||||
})
|
||||
export class BreadcrumbComponent {
|
||||
private route = inject(Router);
|
||||
private titleService = inject(Title);
|
||||
private iconService = inject(IconService);
|
||||
|
||||
// public props
|
||||
@Input() type: string;
|
||||
dashboard = input(true);
|
||||
Component = input(false);
|
||||
|
||||
navigations: NavigationItem[];
|
||||
ComponentNavigations: NavigationItem[] = [];
|
||||
breadcrumbList: Array<string> = [];
|
||||
navigationList!: titleType[];
|
||||
componentList!: titleType[];
|
||||
|
||||
// constructor
|
||||
constructor() {
|
||||
this.navigations = NavigationItems;
|
||||
this.type = 'theme1';
|
||||
this.setBreadcrumb();
|
||||
this.iconService.addIcon(...[GlobalOutline, NodeExpandOutline]);
|
||||
}
|
||||
|
||||
// public method
|
||||
setBreadcrumb() {
|
||||
this.route.events.subscribe((router: Event) => {
|
||||
if (router instanceof NavigationEnd) {
|
||||
const activeLink = router.url;
|
||||
const breadcrumbList = this.filterNavigation(this.navigations, activeLink);
|
||||
|
||||
this.navigationList = breadcrumbList;//breadcrumbList.slice(breadcrumbList.length - 1, breadcrumbList.length);
|
||||
const title = breadcrumbList[breadcrumbList.length - 1]?.title || 'Welcome';
|
||||
this.titleService.setTitle(title );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
filterNavigation(navItems: NavigationItem[], activeLink: string): titleType[] {
|
||||
for (const navItem of navItems) {
|
||||
if (navItem.type === 'item' && 'url' in navItem && navItem.url === activeLink) {
|
||||
return [
|
||||
{
|
||||
url: 'url' in navItem ? navItem.url : false,
|
||||
title: navItem.title,
|
||||
link: navItem.link,
|
||||
description: navItem.description,
|
||||
path: navItem.path,
|
||||
breadcrumbs: 'breadcrumbs' in navItem ? navItem.breadcrumbs : true,
|
||||
type: navItem.type
|
||||
}
|
||||
];
|
||||
}
|
||||
if ((navItem.type === 'group' || navItem.type === 'collapse') && 'children' in navItem) {
|
||||
const breadcrumbList = this.filterNavigation(navItem.children!, activeLink);
|
||||
if (breadcrumbList.length > 0) {
|
||||
breadcrumbList.unshift({
|
||||
url: 'url' in navItem ? navItem.url : false,
|
||||
title: navItem.title,
|
||||
link: navItem.link,
|
||||
path: navItem.path,
|
||||
description: navItem.description,
|
||||
breadcrumbs: 'breadcrumbs' in navItem ? navItem.breadcrumbs : true,
|
||||
type: navItem.type
|
||||
});
|
||||
return breadcrumbList;
|
||||
}
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<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>
|
||||
@@ -1,58 +0,0 @@
|
||||
// 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>;
|
||||
}
|
||||
+3
-5
@@ -1,9 +1,9 @@
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA, Input, OnInit, Renderer2} from '@angular/core';
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA, OnInit, Renderer2} from '@angular/core';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {MatButton} from '@angular/material/button';
|
||||
import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from '@angular/material/card';
|
||||
import {MatFormField, MatInput, MatLabel} from '@angular/material/input';
|
||||
import {AsyncPipe, NgIf, NgOptimizedImage} from '@angular/common';
|
||||
import {AsyncPipe} from '@angular/common';
|
||||
import {Image} from '../../models/image';
|
||||
import {ZhipuaiImageService} from '../../services/zhipuai-image.service';
|
||||
import {MatProgressSpinner} from '@angular/material/progress-spinner';
|
||||
@@ -25,9 +25,7 @@ import Viewer from 'viewerjs';
|
||||
MatInput,
|
||||
MatLabel,
|
||||
MatProgressSpinner,
|
||||
AsyncPipe,
|
||||
|
||||
|
||||
AsyncPipe
|
||||
],
|
||||
templateUrl: './generate-image.component.html',
|
||||
styleUrl: './generate-image.component.scss',
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
<div class="navbar-wrapper">
|
||||
<div class="m-header">
|
||||
<mat-label>Jambotron</mat-label>
|
||||
<a href="javascript:" class="b-brand">
|
||||
<img src="assets/images/logo-dark.svg" alt="theme-logo" class="logo logo-dark logo-lg" />
|
||||
</a>
|
||||
</div>
|
||||
<!-- <app-nav-content (NavCollapsedMob)="navCollapseMob()" class="scroll-div w-100 compact"></app-nav-content>-->
|
||||
<mat-nav-list>
|
||||
<a mat-list-item routerLink="user-welcome">
|
||||
<span class="entry">
|
||||
<mat-icon>house</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >Dashboard</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
<a mat-list-item routerLink="tutorials-list">
|
||||
<span class="entry">
|
||||
<mat-icon>newspaper</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >Tutorials</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
<a mat-list-item routerLink="ai-models">
|
||||
<span class="entry">
|
||||
<mat-icon>house</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >AI tools</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
<div class="example-action-buttons">
|
||||
<button matButton (click)="accordion().openAll()">Expand All</button>
|
||||
<button matButton (click)="accordion().closeAll()">Collapse All</button>
|
||||
<!-- #docregion multi -->
|
||||
<mat-accordion class="example-headers-align" multi>
|
||||
<!-- #enddocregion multi -->
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
<a mat-list-item routerLink="user-welcome">
|
||||
<span class="entry">
|
||||
<mat-icon>house</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >Dashboard</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
</mat-panel-title>
|
||||
|
||||
</mat-expansion-panel-header>
|
||||
<mat-nav-list>
|
||||
<a mat-list-item routerLink="user-welcome">
|
||||
<span class="entry">
|
||||
<mat-icon>house</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >Dashboard</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
<a mat-list-item routerLink="tutorials-list">
|
||||
<span class="entry">
|
||||
<mat-icon>newspaper</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >Tutorials</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
<a mat-list-item routerLink="ai-models">
|
||||
<span class="entry">
|
||||
<mat-icon>house</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >AI tools</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
</mat-expansion-panel>
|
||||
<!-- #docregion disabled -->
|
||||
<mat-expansion-panel disabled>
|
||||
<!-- #enddocregion disabled -->
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title> Destination </mat-panel-title>
|
||||
<mat-panel-description>
|
||||
Type the country name
|
||||
<mat-icon>map</mat-icon>
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Country</mat-label>
|
||||
<input matInput />
|
||||
</mat-form-field>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title> Day of the trip </mat-panel-title>
|
||||
<mat-panel-description>
|
||||
Inform the date you wish to travel
|
||||
<mat-icon>date_range</mat-icon>
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Date</mat-label>
|
||||
<input matInput [matDatepicker]="picker" (focus)="picker.open()" readonly />
|
||||
</mat-form-field>
|
||||
<mat-datepicker #picker></mat-datepicker>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
.entry{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding:0.75rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.example-action-buttons {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.example-headers-align .mat-expansion-panel-header-description {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.example-headers-align .mat-mdc-form-field + .mat-mdc-form-field {
|
||||
margin-left: 8px;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SideBarComponent } from './side-bar.component';
|
||||
|
||||
describe('SideBarComponent', () => {
|
||||
let component: SideBarComponent;
|
||||
let fixture: ComponentFixture<SideBarComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SideBarComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SideBarComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,79 +0,0 @@
|
||||
import {ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, viewChild} from '@angular/core';
|
||||
import {MatTree, MatTreeNode} from '@angular/material/tree';
|
||||
import {MatFormField, MatInput, MatLabel} from '@angular/material/input';
|
||||
import {MatDivider, MatListItem, MatNavList} from '@angular/material/list';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {
|
||||
MatAccordion, MatExpansionModule,
|
||||
MatExpansionPanel,
|
||||
MatExpansionPanelDescription,
|
||||
MatExpansionPanelTitle
|
||||
} from '@angular/material/expansion';
|
||||
import {MatDatepicker, MatDatepickerInput} from '@angular/material/datepicker';
|
||||
import {provideNativeDateAdapter} from '@angular/material/core';
|
||||
import {MatButton} from '@angular/material/button';
|
||||
|
||||
@Component({
|
||||
selector: 'app-side-bar',
|
||||
imports: [
|
||||
MatTree,
|
||||
MatTreeNode,
|
||||
MatLabel,
|
||||
MatNavList,
|
||||
MatListItem,
|
||||
MatIcon,
|
||||
RouterLink,
|
||||
MatExpansionPanel,
|
||||
MatExpansionPanelTitle,
|
||||
MatExpansionPanelDescription,
|
||||
MatFormField,
|
||||
MatInput,
|
||||
MatDatepickerInput,
|
||||
MatDatepicker,
|
||||
MatDivider,
|
||||
MatAccordion,
|
||||
MatButton,
|
||||
MatExpansionModule
|
||||
],
|
||||
templateUrl: './side-bar.component.html',
|
||||
styleUrl: './side-bar.component.scss',
|
||||
schemas:[CUSTOM_ELEMENTS_SCHEMA],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [provideNativeDateAdapter()],
|
||||
})
|
||||
|
||||
|
||||
|
||||
export class SideBarComponent {
|
||||
isCollapsed = false;
|
||||
|
||||
accordion = viewChild.required(MatAccordion);
|
||||
}
|
||||
|
||||
const TREE_DATA: TreeNode[] = [
|
||||
{
|
||||
name: 'Fruit',
|
||||
children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}],
|
||||
},
|
||||
{
|
||||
name: 'Vegetables',
|
||||
children: [
|
||||
{
|
||||
name: 'Green',
|
||||
children: [{name: 'Broccoli'}, {name: 'Brussels sprouts'}],
|
||||
},
|
||||
{
|
||||
name: 'Orange',
|
||||
children: [{name: 'Pumpkins'}, {name: 'Carrots'}],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
interface TreeNode {
|
||||
name: string;
|
||||
children?: TreeNode[];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>System</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<mat-divider></mat-divider>
|
||||
<mat-tab-group>
|
||||
<mat-tab label="Custom beans">
|
||||
Content 1
|
||||
<table mat-table
|
||||
[dataSource]="customBeans" multiTemplateDataRows="true" class="mat-elevation-z8">
|
||||
@for (column of displayedColumns; track column) {
|
||||
<ng-container matColumnDef="{{column}}">
|
||||
<th mat-header-cell *matHeaderCellDef>{{column}}</th>
|
||||
<td mat-cell *matCellDef="let element ; let k = dataIndex;">{{element[column]}}</td>
|
||||
</ng-container>
|
||||
}
|
||||
<ng-container matColumnDef="expand">
|
||||
<th mat-header-cell *matHeaderCellDef aria-label="row actions"> </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button
|
||||
matIconButton
|
||||
aria-label="expand row"
|
||||
(click)="toggle(element); $event.stopPropagation()"
|
||||
class="example-toggle-button"
|
||||
[class.example-toggle-button-expanded]="isExpanded(element)">
|
||||
<mat-icon>keyboard_arrow_down</mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
|
||||
<ng-container matColumnDef="expandedDetail">
|
||||
<td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplayWithExpand.length">
|
||||
<div class="example-element-detail-wrapper"
|
||||
[class.example-element-detail-wrapper-expanded]="isExpanded(element)">
|
||||
<div class="example-element-detail">
|
||||
|
||||
<mat-list role="list">
|
||||
<mat-list-item role="listitem">Name: {{element.name}}</mat-list-item>
|
||||
<mat-list-item role="listitem">Type: {{element.type}}</mat-list-item>
|
||||
</mat-list>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="columnsToDisplayWithExpand"></tr>
|
||||
<tr mat-row *matRowDef="let element; columns: columnsToDisplayWithExpand;"
|
||||
class="example-element-row"
|
||||
[class.example-expanded-row]="isExpanded(element)"
|
||||
(click)="toggle(element)">
|
||||
</tr>
|
||||
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
|
||||
</table>
|
||||
|
||||
</mat-tab>
|
||||
<mat-tab label="All beans">
|
||||
Content 2
|
||||
<table mat-table
|
||||
[dataSource]="allBeans" multiTemplateDataRows="true" class="mat-elevation-z8">
|
||||
@for (column of displayedColumns; track column) {
|
||||
<ng-container matColumnDef="{{column}}">
|
||||
<th mat-header-cell *matHeaderCellDef>{{column}}</th>
|
||||
<td mat-cell *matCellDef="let element ; let k = dataIndex;">{{element[column]}}</td>
|
||||
</ng-container>
|
||||
}
|
||||
<ng-container matColumnDef="expand">
|
||||
<th mat-header-cell *matHeaderCellDef aria-label="row actions"> </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button
|
||||
matIconButton
|
||||
aria-label="expand row"
|
||||
(click)="toggle(element); $event.stopPropagation()"
|
||||
class="example-toggle-button"
|
||||
[class.example-toggle-button-expanded]="isExpanded(element)">
|
||||
<mat-icon>keyboard_arrow_down</mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
|
||||
<ng-container matColumnDef="expandedDetail">
|
||||
<td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplayWithExpand.length">
|
||||
<div class="example-element-detail-wrapper"
|
||||
[class.example-element-detail-wrapper-expanded]="isExpanded(element)">
|
||||
<div class="example-element-detail">
|
||||
|
||||
<mat-list role="list">
|
||||
<mat-list-item role="listitem">Name: {{element.name}}</mat-list-item>
|
||||
<mat-list-item role="listitem">Type: {{element.type}}</mat-list-item>
|
||||
</mat-list>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="columnsToDisplayWithExpand"></tr>
|
||||
<tr mat-row *matRowDef="let element; columns: columnsToDisplayWithExpand;"
|
||||
class="example-element-row"
|
||||
[class.example-expanded-row]="isExpanded(element)"
|
||||
(click)="toggle(element)">
|
||||
</tr>
|
||||
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
|
||||
</table>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
@@ -1,113 +0,0 @@
|
||||
mat-card{
|
||||
margin: 20px;
|
||||
background-color: rgba(240, 248, 255, 0.7);
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
mat-card-title{
|
||||
color: cyan;
|
||||
}
|
||||
|
||||
mat-card-subtitle{
|
||||
color: #009dff;
|
||||
}
|
||||
|
||||
mat-tab{
|
||||
color:black;
|
||||
}
|
||||
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
color:lightgrey;
|
||||
}
|
||||
|
||||
|
||||
mat-list{
|
||||
//background-color: #1389d3;
|
||||
color:black;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
mat-list-item{
|
||||
margin: 10px 10px 10px 10px;
|
||||
background-color: #447694;
|
||||
|
||||
color: #009dff;
|
||||
}
|
||||
|
||||
tr.example-detail-row {
|
||||
height: 0;
|
||||
background: #fffdfd;
|
||||
}
|
||||
|
||||
tr.example-element-row {
|
||||
cursor: pointer;
|
||||
color: #1389d3;
|
||||
background: #fffdfd;
|
||||
}
|
||||
|
||||
tr.example-element-row:not(.example-expanded-row):hover {
|
||||
background: whitesmoke;
|
||||
}
|
||||
|
||||
tr.example-element-row:not(.example-expanded-row):active {
|
||||
background: #efefef;
|
||||
}
|
||||
|
||||
.example-element-row td {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
.example-element-detail-wrapper {
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
grid-template-rows: 0fr;
|
||||
grid-template-columns: 100%;
|
||||
transition: grid-template-rows 225ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.example-element-detail-wrapper-expanded {
|
||||
grid-template-rows: 1fr;
|
||||
|
||||
}
|
||||
|
||||
.example-element-detail {
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.example-element-diagram {
|
||||
min-width: 80px;
|
||||
border: 2px solid black;
|
||||
padding: 8px;
|
||||
font-weight: lighter;
|
||||
margin: 8px 0;
|
||||
height: 104px;
|
||||
}
|
||||
|
||||
.example-element-symbol {
|
||||
font-weight: bold;
|
||||
font-size: 40px;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.example-element-description {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.example-element-description-attribution {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.example-toggle-button {
|
||||
transition: transform 225ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.example-toggle-button-expanded {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SystemComponent } from './system.component';
|
||||
|
||||
describe('SystemComponent', () => {
|
||||
let component: SystemComponent;
|
||||
let fixture: ComponentFixture<SystemComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SystemComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SystemComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,148 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import {Bean} from '../../models/Bean';
|
||||
import {SystemService} from '../../services/system.service';
|
||||
import {
|
||||
MatCard,
|
||||
MatCardContent,
|
||||
MatCardHeader,
|
||||
MatCardSubtitle,
|
||||
MatCardTitle,
|
||||
MatCardTitleGroup
|
||||
} from '@angular/material/card';
|
||||
import {MatDivider} from '@angular/material/divider';
|
||||
import {
|
||||
MatCell,
|
||||
MatCellDef,
|
||||
MatColumnDef,
|
||||
MatHeaderCell,
|
||||
MatHeaderCellDef, MatHeaderRow,
|
||||
MatHeaderRowDef, MatRow, MatRowDef,
|
||||
MatTable
|
||||
} from '@angular/material/table';
|
||||
import {MatIconButton} from '@angular/material/button';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {MatList, MatListItem} from '@angular/material/list';
|
||||
import {MatTab, MatTabGroup} from '@angular/material/tabs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-system.component',
|
||||
imports: [
|
||||
MatCard,
|
||||
MatCardSubtitle,
|
||||
MatCardContent,
|
||||
MatCardHeader,
|
||||
MatCardTitle,
|
||||
MatDivider,
|
||||
MatTable,
|
||||
MatColumnDef,
|
||||
MatHeaderCell,
|
||||
MatCell,
|
||||
MatIconButton,
|
||||
MatIcon,
|
||||
MatHeaderCellDef,
|
||||
MatCellDef,
|
||||
MatHeaderRowDef,
|
||||
MatRowDef,
|
||||
MatRow,
|
||||
MatHeaderRow,
|
||||
MatList,
|
||||
MatListItem,
|
||||
MatTabGroup,
|
||||
MatTab
|
||||
],
|
||||
templateUrl: './system.component.html',
|
||||
styleUrl: './system.component.scss'
|
||||
})
|
||||
export class SystemComponent {
|
||||
|
||||
// @ViewChild(MatPaginator) paginator: MatPaginator;
|
||||
// @ViewChild(MatSort) sort: MatSort;
|
||||
|
||||
customBeans:Bean[] = [] ;
|
||||
allBeans:Bean[] = [] ;
|
||||
displayedColumns: string[] = ['shortName', 'typeShortName', 'scope'];
|
||||
|
||||
columnsToDisplayWithExpand = [...this.displayedColumns, 'expand'];
|
||||
|
||||
expandedElement: Bean | null = null;
|
||||
|
||||
resultsLength = 0;
|
||||
isLoadingResults = true;
|
||||
isRateLimitReached = false;
|
||||
|
||||
constructor(private systemService: SystemService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.retrieveBeans();
|
||||
}
|
||||
|
||||
retrieveBeans(): void {
|
||||
this.systemService.getCustomBeans()
|
||||
.subscribe(
|
||||
(data: Bean[]) => {
|
||||
this.customBeans = data;
|
||||
console.log(data);
|
||||
},
|
||||
(error: any) => {
|
||||
console.log(error);
|
||||
});
|
||||
this.systemService.getAllBeans()
|
||||
.subscribe(
|
||||
(data: Bean[]) => {
|
||||
this.allBeans = data;
|
||||
console.log(data);
|
||||
},
|
||||
(error: any) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
/** Checks whether an element is expanded. */
|
||||
isExpanded(element: Bean) {
|
||||
return this.expandedElement === element;
|
||||
}
|
||||
|
||||
/** Toggles the expanded state of an element. */
|
||||
toggle(element: Bean) {
|
||||
this.expandedElement = this.isExpanded(element) ? null : element;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ngAfterViewInit() {
|
||||
//this.exampleDatabase = new ExampleHttpDatabase(this._httpClient);
|
||||
|
||||
// If the user changes the sort order, reset back to the first page.
|
||||
/* this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0));
|
||||
|
||||
merge(this.sort.sortChange, this.paginator.page)
|
||||
.pipe(
|
||||
startWith({}),
|
||||
switchMap(() => {
|
||||
this.isLoadingResults = true;
|
||||
return this.exampleDatabase!.getRepoIssues(
|
||||
this.sort.active,
|
||||
this.sort.direction,
|
||||
this.paginator.pageIndex,
|
||||
).pipe(catchError(() => observableOf(null)));
|
||||
}),
|
||||
map(data => {
|
||||
// Flip flag to show that loading has finished.
|
||||
this.isLoadingResults = false;
|
||||
this.isRateLimitReached = data === null;
|
||||
|
||||
if (data === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Only refresh the result length if there is new data. In case of rate
|
||||
// limit errors, we do not want to reset the paginator to zero, as that
|
||||
// would prevent users from re-triggering requests.
|
||||
this.resultsLength = data.total_count;
|
||||
return data.items;
|
||||
}),
|
||||
)
|
||||
.subscribe(data => (this.data = data));*/
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
<div>
|
||||
<div *ngIf="currentTutorial.id" class="edit-form">
|
||||
<h4>Tutorial</h4>
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<label for="title">Title</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="title"
|
||||
[(ngModel)]="currentTutorial.title"
|
||||
name="title"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Description</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="description"
|
||||
[(ngModel)]="currentTutorial.description"
|
||||
name="description"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label><strong>Status:</strong></label>
|
||||
{{ currentTutorial.published ? "Published" : "Pending" }}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<button
|
||||
class="badge badge-primary mr-2"
|
||||
*ngIf="currentTutorial.published"
|
||||
(click)="updatePublished(false)"
|
||||
>
|
||||
UnPublish
|
||||
</button>
|
||||
<button
|
||||
*ngIf="!currentTutorial.published"
|
||||
class="badge badge-primary mr-2"
|
||||
(click)="updatePublished(true)"
|
||||
>
|
||||
Publish
|
||||
</button>
|
||||
|
||||
<button class="badge badge-danger mr-2" (click)="deleteTutorial()">
|
||||
Delete
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="badge badge-success mb-2"
|
||||
(click)="updateTutorial()"
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
<p>{{ message }}</p>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!currentTutorial.id">
|
||||
<br />
|
||||
<p>Cannot access this Tutorial...</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,4 +0,0 @@
|
||||
.edit-form {
|
||||
max-width: 400px;
|
||||
margin: auto;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TutorialDetailsComponent } from './tutorial-details.component';
|
||||
|
||||
describe('TutorialDetailsComponent', () => {
|
||||
let component: TutorialDetailsComponent;
|
||||
let fixture: ComponentFixture<TutorialDetailsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ TutorialDetailsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(TutorialDetailsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,96 +0,0 @@
|
||||
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',
|
||||
imports: [
|
||||
FormsModule,
|
||||
NgIf
|
||||
],
|
||||
styleUrls: ['./tutorial-details.component.scss']
|
||||
})
|
||||
export class TutorialDetailsComponent implements OnInit {
|
||||
|
||||
currentTutorial: Tutorial = {
|
||||
title: '',
|
||||
description: '',
|
||||
published: false
|
||||
};
|
||||
message = '';
|
||||
|
||||
constructor(
|
||||
private tutorialService: TutorialService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.message = '';
|
||||
this.getTutorial(this.route.snapshot.params['id']);
|
||||
}
|
||||
|
||||
getTutorial(id: string): void {
|
||||
/* this.tutorialService.get(id)
|
||||
.subscribe(
|
||||
data => {
|
||||
this.currentTutorial = data;
|
||||
console.log(data);
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
});*/
|
||||
}
|
||||
|
||||
updatePublished(status: boolean): void {
|
||||
const data = {
|
||||
title: this.currentTutorial.title,
|
||||
description: this.currentTutorial.description,
|
||||
published: status
|
||||
};
|
||||
|
||||
this.message = '';
|
||||
|
||||
/* this.tutorialService.update(this.currentTutorial.id, data)
|
||||
.subscribe(
|
||||
response => {
|
||||
this.currentTutorial.published = status;
|
||||
console.log(response);
|
||||
this.message = response.message ? response.message : 'The status was updated successfully!';
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
});*/
|
||||
}
|
||||
|
||||
updateTutorial(): void {
|
||||
/* this.message = '';
|
||||
|
||||
this.tutorialService.update(this.currentTutorial.id, this.currentTutorial)
|
||||
.subscribe(
|
||||
response => {
|
||||
console.log(response);
|
||||
this.message = response.message ? response.message : 'This tutorial was updated successfully!';
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
});*/
|
||||
}
|
||||
|
||||
deleteTutorial(): void {
|
||||
/* this.tutorialService.delete(this.currentTutorial.id)
|
||||
.subscribe(
|
||||
response => {
|
||||
console.log(response);
|
||||
this.router.navigate(['/tutorials']);
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
});*/
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
<div class="list row">
|
||||
<div class="col-md-8">
|
||||
<div class="input-group mb-3">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
placeholder="Search by title"
|
||||
[(ngModel)]="title"
|
||||
/>
|
||||
<div class="input-group-append">
|
||||
<button
|
||||
class="btn btn-outline-secondary"
|
||||
type="button"
|
||||
(click)="searchTitle()"
|
||||
>
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h4>Tutorials List</h4>
|
||||
<ul class="list-group">
|
||||
<li
|
||||
class="list-group-item"
|
||||
*ngFor="let tutorial of tutorials; let i = index"
|
||||
[class.active]="i == currentIndex"
|
||||
(click)="setActiveTutorial(tutorial, i)"
|
||||
>
|
||||
{{ tutorial.title }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<button class="m-3 btn btn-sm btn-danger" (click)="removeAllTutorials()">
|
||||
Remove All
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div *ngIf="currentTutorial.id">
|
||||
<h4>Tutorial</h4>
|
||||
<div>
|
||||
<label><strong>Title:</strong></label> {{ currentTutorial.title }}
|
||||
</div>
|
||||
<div>
|
||||
<label><strong>Description:</strong></label>
|
||||
{{ currentTutorial.description }}
|
||||
</div>
|
||||
<div>
|
||||
<label><strong>Status:</strong></label>
|
||||
{{ currentTutorial.published ? "Published" : "Pending" }}
|
||||
</div>
|
||||
|
||||
<a class="badge badge-warning" routerLink="/tutorials/{{ currentTutorial.id }}">
|
||||
Edit
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!currentTutorial">
|
||||
<br />
|
||||
<p>Please click on a Tutorial...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +0,0 @@
|
||||
.list {
|
||||
text-align: left;
|
||||
max-width: 750px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TutorialsListComponent } from './tutorials-list.component';
|
||||
|
||||
describe('TutorialsListComponent', () => {
|
||||
let component: TutorialsListComponent;
|
||||
let fixture: ComponentFixture<TutorialsListComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ TutorialsListComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(TutorialsListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,82 +0,0 @@
|
||||
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',
|
||||
imports: [
|
||||
FormsModule,
|
||||
RouterLink,
|
||||
NgIf
|
||||
],
|
||||
styleUrls: ['./tutorials-list.component.scss']
|
||||
})
|
||||
export class TutorialsListComponent implements OnInit {
|
||||
|
||||
tutorials?: Tutorial[];
|
||||
currentTutorial: Tutorial = {};
|
||||
currentIndex = -1;
|
||||
title = '';
|
||||
|
||||
constructor(private tutorialService: TutorialService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.retrieveTutorials();
|
||||
}
|
||||
|
||||
retrieveTutorials(): void {
|
||||
this.tutorialService.getAllPublic()
|
||||
.subscribe(
|
||||
(data: Tutorial[] ) => {
|
||||
this.tutorials = data;
|
||||
console.log(data);
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
refreshList(): void {
|
||||
this.retrieveTutorials();
|
||||
this.currentTutorial = {};
|
||||
this.currentIndex = -1;
|
||||
}
|
||||
|
||||
setActiveTutorial(tutorial: Tutorial, index: number): void {
|
||||
this.currentTutorial = tutorial;
|
||||
this.currentIndex = index;
|
||||
}
|
||||
|
||||
removeAllTutorials(): void {
|
||||
/* this.tutorialService.deleteAll()
|
||||
.subscribe(
|
||||
response => {
|
||||
console.log(response);
|
||||
this.refreshList();
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
});*/
|
||||
}
|
||||
|
||||
searchTitle(): void {
|
||||
this.currentTutorial = {};
|
||||
this.currentIndex = -1;
|
||||
|
||||
this.tutorialService.findByTitle(this.title)
|
||||
.subscribe(
|
||||
data => {
|
||||
this.tutorials = data;
|
||||
console.log(data);
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,8 @@ export class GlobalConstants {
|
||||
if(environment.production) {
|
||||
return `${environment.host_name}/api`;
|
||||
}else {
|
||||
return `${environment.host_name}:${environment.port}/api`;
|
||||
//return `${environment.host_name}:${environment.port}/api`;
|
||||
return `/api`; // in serve mode used proxy (proxy.conf.json)
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
<app-navigation
|
||||
class="pc-sidebar"
|
||||
[ngClass]="{
|
||||
'navbar-collapsed': navCollapsed,
|
||||
'mob-open': navCollapsedMob
|
||||
}"
|
||||
(NavCollapse)="this.navCollapsed = !this.navCollapsed"
|
||||
/>
|
||||
<app-nav-bar (NavCollapsedMob)="navMobClick()" (NavCollapse)="this.navCollapsed = !this.navCollapsed" />
|
||||
<!--<app-nav-bar>
|
||||
|
||||
</app-nav-bar>-->
|
||||
<!--<app-navigation></app-navigation>-->
|
||||
<div class="pc-container">
|
||||
<div class="coded-wrapper">
|
||||
<div class="coded-content">
|
||||
<div class="coded-inner-content">
|
||||
<app-breadcrumb />
|
||||
<div class="main-body">
|
||||
<div class="page-wrapper">
|
||||
<router-outlet />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pc-menu-overlay" (click)="closeMenu()" (keydown)="handleKeyDown($event)" tabindex="0"></div>
|
||||
</div>
|
||||
<footer class="pc-footer">
|
||||
<div class="footer-wrapper container-fluid">
|
||||
<div class="row">
|
||||
<div class="col my-1">
|
||||
<p class="m-0">
|
||||
Copyright ©
|
||||
<a href="https://codedthemes.com" target="_blank">CodedThemes</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-auto my-1">
|
||||
<ul class="list-inline footer-link mb-0">
|
||||
<li class="list-inline-item"><a href="https://codedthemes.com/" target="_blank">Home</a></li>
|
||||
<li class="list-inline-item">
|
||||
<a href="https://codedthemes.com/privacy-policy/" target="_blank">Privacy Policy</a>
|
||||
</li>
|
||||
<li class="list-inline-item"><a href="https://codedthemes.support-hub.io/" target="_blank">Contact us</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<app-configuration />
|
||||
@@ -1,51 +0,0 @@
|
||||
// Angular import
|
||||
import { Component } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
// Project import
|
||||
|
||||
import { NavBarComponent } from './nav-bar/nav-bar.component';
|
||||
import { NavigationComponent } from './navigation/navigation.component';
|
||||
import { ConfigurationComponent } from './configuration/configuration.component';
|
||||
import {BreadcrumbComponent} from '../../components/breadcrumb/breadcrumb.component';
|
||||
//import { BreadcrumbComponent } from 'src/app/theme/shared/components/breadcrumb/breadcrumb.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin',
|
||||
imports: [CommonModule, BreadcrumbComponent, NavigationComponent, NavBarComponent, RouterModule, ConfigurationComponent, NavigationComponent],
|
||||
templateUrl: './admin-layout.component.html',
|
||||
styleUrls: ['./admin-layout.component.scss']
|
||||
})
|
||||
export class AdminComponent {
|
||||
// public props
|
||||
navCollapsed: boolean = true;
|
||||
navCollapsedMob: boolean = true;
|
||||
|
||||
// public method
|
||||
navMobClick() {
|
||||
if (this.navCollapsedMob && !document.querySelector('app-navigation.pc-sidebar')?.classList.contains('mob-open')) {
|
||||
this.navCollapsedMob = !this.navCollapsedMob;
|
||||
setTimeout(() => {
|
||||
this.navCollapsedMob = !this.navCollapsedMob;
|
||||
}, 100);
|
||||
} else {
|
||||
this.navCollapsedMob = !this.navCollapsedMob;
|
||||
}
|
||||
if (document.querySelector('app-navigation.pc-sidebar')?.classList.contains('navbar-collapsed')) {
|
||||
document.querySelector('app-navigation.pc-sidebar')?.classList.remove('navbar-collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
handleKeyDown(event: KeyboardEvent): void {
|
||||
if (event.key === 'Escape') {
|
||||
this.closeMenu();
|
||||
}
|
||||
}
|
||||
|
||||
closeMenu() {
|
||||
if (document.querySelector('app-navigation.pc-sidebar')?.classList.contains('mob-open')) {
|
||||
document.querySelector('app-navigation.pc-sidebar')?.classList.remove('mob-open');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-configuration',
|
||||
imports: [],
|
||||
templateUrl: './configuration.component.html',
|
||||
styleUrl: './configuration.component.scss'
|
||||
})
|
||||
export class ConfigurationComponent {}
|
||||
@@ -1,10 +0,0 @@
|
||||
<header class="pc-header">
|
||||
<div class="header-wrapper">
|
||||
<div class="pc-mob-drp">
|
||||
<app-nav-left [navCollapsed]="navCollapsed" (NavCollapse)="navCollapse()" (NavCollapsedMob)="navCollapseMob()"></app-nav-left>
|
||||
</div>
|
||||
<div>
|
||||
<app-nav-right />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -1,3 +0,0 @@
|
||||
.pc-header{
|
||||
left: 0;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
// angular import
|
||||
import {Component, inject, OnInit, output} from '@angular/core';
|
||||
|
||||
// project import
|
||||
|
||||
import { NavLeftComponent } from './nav-left/nav-left.component';
|
||||
import { NavRightComponent } from './nav-right/nav-right.component';
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-bar',
|
||||
imports: [NavLeftComponent, NavRightComponent],
|
||||
templateUrl: './nav-bar.component.html',
|
||||
styleUrls: ['./nav-bar.component.scss']
|
||||
})
|
||||
export class NavBarComponent implements OnInit{
|
||||
private document = inject<Document>(DOCUMENT);
|
||||
// public props
|
||||
NavCollapse = output();
|
||||
NavCollapsedMob = output();
|
||||
|
||||
navCollapsed: boolean = false;
|
||||
windowWidth: number | undefined = 1000;
|
||||
navCollapsedMob: boolean;
|
||||
|
||||
// Constructor
|
||||
constructor() {
|
||||
|
||||
this.navCollapsedMob = false;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.windowWidth = this.document.defaultView?.innerWidth;
|
||||
}
|
||||
|
||||
// public method
|
||||
navCollapse() {
|
||||
if (!!this.windowWidth && this.windowWidth >= 1025) {
|
||||
this.navCollapsed = !this.navCollapsed;
|
||||
this.NavCollapse.emit();
|
||||
}
|
||||
}
|
||||
|
||||
navCollapseMob() {
|
||||
if (!!this.windowWidth && this.windowWidth < 1025) {
|
||||
this.NavCollapsedMob.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
<ul class="list-unstyled">
|
||||
<li class="pc-h-item pc-sidebar-collapse">
|
||||
<a
|
||||
href="javascript:"
|
||||
title="click to menu collapse"
|
||||
class="pc-head-link ms-0"
|
||||
[ngClass]="{ on: navCollapsed() }"
|
||||
id="sidebar-hide mobile-collapse"
|
||||
(click)="navCollapse()"
|
||||
>
|
||||
@if (navCollapsed()) {
|
||||
|
||||
<i antIcon type="menu-unfold" theme="outline"></i>
|
||||
} @else {
|
||||
<i antIcon type="menu-fold" theme="outline"></i>
|
||||
}
|
||||
</a>
|
||||
</li>
|
||||
<li class="pc-h-item pc-sidebar-popup">
|
||||
<a href="javascript:" class="pc-head-link ms-0" id="mobile-collapse1" (click)="this.NavCollapsedMob.emit()">
|
||||
<i antIcon type="menu-fold" theme="outline"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown pc-h-item d-inline-flex d-md-none" ngbDropdown>
|
||||
<a href="javascript:" class="pc-head-link dropdown-toggle arrow-none m-0" ngbDropdownToggle>
|
||||
<i class="ti ti-search"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdowm-menu-end pc-h-dropdown drp-search" ngbDropdownMenu>
|
||||
<form class="px-3">
|
||||
<div class="form-group mb-0 d-flex align-items-center">
|
||||
<i class="search f-12" antIcon type="search" theme="outline"></i>
|
||||
<input type="search" class="form-control border-0 shadow-none" placeholder="Ctrl + K" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</li>
|
||||
<li class="pc-h-item d-none d-md-inline-flex">
|
||||
<form class="header-search">
|
||||
<i class="search f-12" antIcon type="search" theme="outline"></i>
|
||||
<input type="search" class="form-control" placeholder="Ctrl + K" />
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -1,37 +0,0 @@
|
||||
// Angular import
|
||||
import {CommonModule, DOCUMENT} from '@angular/common';
|
||||
import { Component, inject, input, output } from '@angular/core';
|
||||
|
||||
// project import
|
||||
|
||||
// icons
|
||||
import { IconService, IconDirective } from '@ant-design/icons-angular';
|
||||
import { MenuUnfoldOutline, MenuFoldOutline, SearchOutline } from '@ant-design/icons-angular/icons';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-left',
|
||||
imports: [IconDirective, CommonModule],
|
||||
templateUrl: './nav-left.component.html',
|
||||
styleUrls: ['./nav-left.component.scss']
|
||||
})
|
||||
export class NavLeftComponent {
|
||||
private iconService = inject(IconService);
|
||||
private document = inject(DOCUMENT);
|
||||
|
||||
// public props
|
||||
navCollapsed = input.required<boolean>();
|
||||
NavCollapse = output();
|
||||
NavCollapsedMob = output();
|
||||
windowWidth: number | undefined = 1000;
|
||||
|
||||
// Constructor
|
||||
constructor() {
|
||||
this.windowWidth = this.document.defaultView?.innerWidth;
|
||||
this.iconService.addIcon(...[MenuUnfoldOutline, MenuFoldOutline, SearchOutline]);
|
||||
}
|
||||
|
||||
// public method
|
||||
navCollapse() {
|
||||
this.NavCollapse.emit();
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
<ul class="list-unstyled">
|
||||
<li class="pc-h-item">
|
||||
<a href="https://github.com/codedthemes/mantis-free-angular-admin-template" target="_blank" class="pc-head-link me-0 bg-gray-200">
|
||||
<i antIcon type="github" theme="outline"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown pc-h-item" ngbDropdown>
|
||||
<a href="javascript:" class="pc-head-link dropdown-toggle arrow-none me-0 bg-gray-200" data-bs-toggle="dropdown" ngbDropdownToggle>
|
||||
<i antIcon type="bell" theme="outline"></i>
|
||||
<span class="badge bg-primary pc-h-badge">3</span>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-notification dropdown-menu-end pc-h-dropdown" ngbDropdownMenu>
|
||||
<div class="dropdown-header d-flex align-items-center justify-content-between">
|
||||
<h5 class="m-0">Notification</h5>
|
||||
<a class="bg-transparent"><i class="text-success d-flex f-20" antIcon theme="outline" type="check-circle"></i></a>
|
||||
</div>
|
||||
<div class="dropdown-divider mb-0"></div>
|
||||
<ng-scrollbar style="min-height: 280px" visibility="hover">
|
||||
<div class="dropdown-header p-0 text-wrap header-notification-scroll">
|
||||
<div class="list-group list-group-flush w-100">
|
||||
<a class="list-group-item list-group-item-action">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="user-avatar bg-light-success"><i class="d-flex" antIcon theme="outline" type="gift"></i></div>
|
||||
</div>
|
||||
<div class="flex-grow-1 ms-3">
|
||||
<span class="float-end text-muted">3:00 AM</span>
|
||||
<p class="text-body mb-0">
|
||||
It's
|
||||
<b>Cristina danny's</b>
|
||||
birthday today.
|
||||
</p>
|
||||
<span class="text-muted">2 min ago</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="list-group-item list-group-item-action">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="user-avatar bg-light-primary"><i class="d-flex" antIcon theme="outline" type="message"></i></div>
|
||||
</div>
|
||||
<div class="flex-grow-1 ms-3">
|
||||
<span class="float-end text-muted">6:00 PM</span>
|
||||
<p class="text-body mb-1">
|
||||
<b>Aida Burg</b>
|
||||
commented your post.
|
||||
</p>
|
||||
<span class="text-muted">5 August</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="list-group-item list-group-item-action">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="user-avatar bg-light-danger"><i class="d-flex" antIcon theme="outline" type="setting"></i></div>
|
||||
</div>
|
||||
<div class="flex-grow-1 ms-3">
|
||||
<span class="float-end text-muted">2:45 PM</span>
|
||||
<p class="text-body mb-1">
|
||||
Your Profile is Complete
|
||||
<b>60%</b>
|
||||
</p>
|
||||
<span class="text-muted">7 hours ago</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="list-group-item list-group-item-action">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="user-avatar bg-light-primary"><i class="d-flex" antIcon theme="outline" type="phone"></i></div>
|
||||
</div>
|
||||
<div class="flex-grow-1 ms-3">
|
||||
<span class="float-end text-muted">9:10 PM</span>
|
||||
<p class="text-body mb-1">
|
||||
<b>Cristina Danny</b>
|
||||
invited to join
|
||||
<b>Meeting.</b>
|
||||
</p>
|
||||
<span class="text-muted">Daily scrum meeting time</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-scrollbar>
|
||||
<div class="dropdown-divider mt-0"></div>
|
||||
<div class="text-center py-2">
|
||||
<a href="javascript:" class="link-primary">View all</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="dropdown pc-h-item header-user-profile" ngbDropdown>
|
||||
<a href="javascript:" class="pc-head-link dropdown-toggle arrow-none me-0" ngbDropdownToggle>
|
||||
<img src="assets/images/user/avatar-2.jpg" alt="user-image" class="user-avatar me-2" />
|
||||
<span class="f-w-600">John Doe</span>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-user-profile dropdown-menu-end pc-h-dropdown" ngbDropdownMenu>
|
||||
<div class="dropdown-header">
|
||||
<div class="d-flex mb-1">
|
||||
<div class="flex-shrink-0">
|
||||
<img src="assets/images/user/avatar-2.jpg" alt="user-image" class="user-avatar wid-35" />
|
||||
</div>
|
||||
<div class="flex-grow-1 ms-3 text-start">
|
||||
<h6 class="mb-0">JWT User</h6>
|
||||
<span>UI/UX Designer</span>
|
||||
</div>
|
||||
<a href="javascript:" class="bg-transparent"><i class="d-flex f-20" antIcon theme="outline" type="login"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<ul ngbNav #nav="ngbNav" class="nav drp-tabs nav-fill nav-tabs">
|
||||
<li ngbNavItem="1">
|
||||
<a ngbNavLink>
|
||||
<i antIcon theme="outline" type="user" class="me-2"></i>
|
||||
Profile
|
||||
</a>
|
||||
<ng-template ngbNavContent>
|
||||
@for (task of profile; track task) {
|
||||
<div>
|
||||
<a href="javascript:" class="dropdown-item">
|
||||
<i class="text-muted" antIcon theme="outline" type="{{ task.icon }}"></i>
|
||||
<span>{{ task.title }}</span>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
</ng-template>
|
||||
</li>
|
||||
<li ngbNavItem="2">
|
||||
<a ngbNavLink>
|
||||
<i class="me-2" antIcon theme="outline" type="setting"></i>
|
||||
Setting
|
||||
</a>
|
||||
<ng-template ngbNavContent>
|
||||
@for (task of setting; track task) {
|
||||
<div>
|
||||
<a href="javascript:" class="dropdown-item">
|
||||
<i class="text-muted" antIcon theme="outline" type="{{ task.icon }}"></i>
|
||||
<span>{{ task.title }}</span>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
</ng-template>
|
||||
</li>
|
||||
</ul>
|
||||
<div [ngbNavOutlet]="nav"></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -1,121 +0,0 @@
|
||||
// angular import
|
||||
import {Component, inject, input, OnInit, output} from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
// project import
|
||||
|
||||
// icon
|
||||
import { IconService, IconDirective } from '@ant-design/icons-angular';
|
||||
import {
|
||||
BellOutline,
|
||||
SettingOutline,
|
||||
GiftOutline,
|
||||
MessageOutline,
|
||||
PhoneOutline,
|
||||
CheckCircleOutline,
|
||||
LogoutOutline,
|
||||
EditOutline,
|
||||
UserOutline,
|
||||
ProfileOutline,
|
||||
WalletOutline,
|
||||
QuestionCircleOutline,
|
||||
LockOutline,
|
||||
CommentOutline,
|
||||
UnorderedListOutline,
|
||||
ArrowRightOutline,
|
||||
GithubOutline
|
||||
} from '@ant-design/icons-angular/icons';
|
||||
import { NgbDropdownModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { NgScrollbarModule } from 'ngx-scrollbar';
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-right',
|
||||
imports: [IconDirective, RouterModule, NgScrollbarModule, NgbNavModule, NgbDropdownModule],
|
||||
templateUrl: './nav-right.component.html',
|
||||
styleUrls: ['./nav-right.component.scss']
|
||||
})
|
||||
export class NavRightComponent implements OnInit{
|
||||
private iconService = inject(IconService);
|
||||
private document = inject(DOCUMENT);
|
||||
//private window = inject(Window);
|
||||
styleSelectorToggle = input<boolean>();
|
||||
Customize = output();
|
||||
windowWidth: number | undefined = 1000;
|
||||
screenFull: boolean = true;
|
||||
|
||||
constructor() {
|
||||
|
||||
this.iconService.addIcon(
|
||||
...[
|
||||
CheckCircleOutline,
|
||||
GiftOutline,
|
||||
MessageOutline,
|
||||
SettingOutline,
|
||||
PhoneOutline,
|
||||
LogoutOutline,
|
||||
UserOutline,
|
||||
EditOutline,
|
||||
ProfileOutline,
|
||||
QuestionCircleOutline,
|
||||
LockOutline,
|
||||
CommentOutline,
|
||||
UnorderedListOutline,
|
||||
ArrowRightOutline,
|
||||
BellOutline,
|
||||
GithubOutline,
|
||||
WalletOutline
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.windowWidth = this.document.defaultView?.innerWidth;
|
||||
}
|
||||
|
||||
profile = [
|
||||
{
|
||||
icon: 'edit',
|
||||
title: 'Edit Profile'
|
||||
},
|
||||
{
|
||||
icon: 'user',
|
||||
title: 'View Profile'
|
||||
},
|
||||
{
|
||||
icon: 'profile',
|
||||
title: 'Social Profile'
|
||||
},
|
||||
{
|
||||
icon: 'wallet',
|
||||
title: 'Billing'
|
||||
},
|
||||
{
|
||||
icon: 'logout',
|
||||
title: 'Logout'
|
||||
}
|
||||
];
|
||||
|
||||
setting = [
|
||||
{
|
||||
icon: 'question-circle',
|
||||
title: 'Support'
|
||||
},
|
||||
{
|
||||
icon: 'user',
|
||||
title: 'Account Settings'
|
||||
},
|
||||
{
|
||||
icon: 'lock',
|
||||
title: 'Privacy Center'
|
||||
},
|
||||
{
|
||||
icon: 'comment',
|
||||
title: 'Feedback'
|
||||
},
|
||||
{
|
||||
icon: 'unordered-list',
|
||||
title: 'History'
|
||||
}
|
||||
];
|
||||
}
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
<li data-username="dashboard" class="nav-item coded-hasmenu" [routerLinkActive]="['active']">
|
||||
<a [routerLinkActive]="['active']" (click)="navCollapse($event)">
|
||||
@if (item.icon) {
|
||||
<span class="coded-micon">
|
||||
<i antIcon type="{{ item.icon }}" theme="outline"></i>
|
||||
</span>
|
||||
}
|
||||
<span class="coded-mtext">
|
||||
{{ item.title }}
|
||||
</span>
|
||||
</a>
|
||||
<ul class="coded-submenu" [routerLinkActive]="['active']" [ngClass]="item.classes!">
|
||||
@for (item of item.children; track item) {
|
||||
@if (item.type === 'item') {
|
||||
<app-nav-item [item]="item"></app-nav-item>
|
||||
} @else if (item.type === 'collapse') {
|
||||
<app-nav-collapse [item]="item"></app-nav-collapse>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
// Angular import
|
||||
import {Component, inject, Input, OnInit, output} from '@angular/core';
|
||||
import { animate, style, transition, trigger } from '@angular/animations';
|
||||
import {CommonModule, DOCUMENT} from '@angular/common';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
// project import
|
||||
import { NavigationItem } from '../../navigation';
|
||||
|
||||
import { NavItemComponent } from '../nav-item/nav-item.component';
|
||||
import { IconDirective } from '@ant-design/icons-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-collapse',
|
||||
imports: [CommonModule, IconDirective, RouterModule, NavItemComponent],
|
||||
templateUrl: './nav-collapse.component.html',
|
||||
styleUrls: ['./nav-collapse.component.scss'],
|
||||
animations: [
|
||||
trigger('slideInOut', [
|
||||
transition(':enter', [
|
||||
style({ transform: 'translateY(-100%)', display: 'block' }),
|
||||
animate('250ms ease-in', style({ transform: 'translateY(0%)' }))
|
||||
]),
|
||||
transition(':leave', [animate('250ms ease-in', style({ transform: 'translateY(-100%)' }))])
|
||||
])
|
||||
]
|
||||
})
|
||||
export class NavCollapseComponent implements OnInit{
|
||||
|
||||
private document = inject(DOCUMENT);
|
||||
|
||||
// public props
|
||||
|
||||
// Compact Menu in use For Sub Child Open in sidebar menu
|
||||
showCollapseItem = output();
|
||||
|
||||
// all Version Get Item(Component Name Take)
|
||||
@Input() item!: NavigationItem;
|
||||
|
||||
windowWidth: number | undefined = 1000;
|
||||
|
||||
// Constructor
|
||||
constructor() {
|
||||
//this.windowWidth = window.innerWidth;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.windowWidth = this.document.defaultView?.innerWidth;throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
// public method
|
||||
navCollapse(e: MouseEvent) {
|
||||
let parent = e.target as HTMLElement;
|
||||
|
||||
if (parent?.tagName === 'SPAN') {
|
||||
parent = parent.parentElement!;
|
||||
}
|
||||
|
||||
parent = (parent as HTMLElement).parentElement as HTMLElement;
|
||||
|
||||
const sections = document.querySelectorAll('.coded-hasmenu');
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
if (sections[i] !== parent) {
|
||||
sections[i].classList.remove('coded-trigger');
|
||||
}
|
||||
}
|
||||
|
||||
let first_parent = parent.parentElement;
|
||||
let pre_parent = ((parent as HTMLElement).parentElement as HTMLElement).parentElement as HTMLElement;
|
||||
if (first_parent?.classList.contains('coded-hasmenu')) {
|
||||
do {
|
||||
first_parent?.classList.add('coded-trigger');
|
||||
first_parent = ((first_parent as HTMLElement).parentElement as HTMLElement).parentElement as HTMLElement;
|
||||
} while (first_parent.classList.contains('coded-hasmenu'));
|
||||
} else if (pre_parent.classList.contains('coded-submenu')) {
|
||||
do {
|
||||
pre_parent?.parentElement?.classList.add('coded-trigger');
|
||||
pre_parent = (((pre_parent as HTMLElement).parentElement as HTMLElement).parentElement as HTMLElement).parentElement as HTMLElement;
|
||||
} while (pre_parent.classList.contains('coded-submenu'));
|
||||
}
|
||||
parent.classList.toggle('coded-trigger');
|
||||
}
|
||||
|
||||
// for Compact Menu
|
||||
subMenuCollapse(item: void) {
|
||||
this.showCollapseItem.emit(item);
|
||||
}
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
<!-- Vertical layout -->
|
||||
<ng-scrollbar style="height: calc(100vh - 49px)" visibility="hover" id="nav-ps-mantis">
|
||||
<div class="navbar-content">
|
||||
<ul class="nav coded-inner-navbar" (clickOutside)="fireOutClick()" (mouseleave)="navMob()">
|
||||
@for (item of navigations; track item) {
|
||||
@if (item.type === 'group') {
|
||||
<app-nav-group [item]="item"></app-nav-group>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</ng-scrollbar>
|
||||
-106
@@ -1,106 +0,0 @@
|
||||
// Angular import
|
||||
import { Component, OnInit, inject, output } from '@angular/core';
|
||||
import {CommonModule, DOCUMENT, Location, LocationStrategy} from '@angular/common';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
// project import
|
||||
import { NavigationItem, NavigationItems } from '../navigation';
|
||||
//import { environment } from 'src/environments/environment';
|
||||
|
||||
import { NavGroupComponent } from './nav-group/nav-group.component';
|
||||
|
||||
// icon
|
||||
import { IconService } from '@ant-design/icons-angular';
|
||||
import {
|
||||
DashboardOutline,
|
||||
CreditCardOutline,
|
||||
LoginOutline,
|
||||
QuestionOutline,
|
||||
ChromeOutline,
|
||||
FontSizeOutline,
|
||||
ProfileOutline,
|
||||
BgColorsOutline,
|
||||
AntDesignOutline
|
||||
} from '@ant-design/icons-angular/icons';
|
||||
import { NgScrollbarModule } from 'ngx-scrollbar';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-content',
|
||||
imports: [CommonModule, RouterModule, NavGroupComponent, NgScrollbarModule],
|
||||
templateUrl: './nav-content.component.html',
|
||||
styleUrls: ['./nav-content.component.scss']
|
||||
})
|
||||
export class NavContentComponent implements OnInit {
|
||||
private location = inject(Location);
|
||||
private locationStrategy = inject(LocationStrategy);
|
||||
private iconService = inject(IconService)
|
||||
private document = inject(DOCUMENT);
|
||||
|
||||
// public props
|
||||
NavCollapsedMob = output();
|
||||
|
||||
navigations: NavigationItem[];
|
||||
|
||||
// version
|
||||
title = 'Demo application for version numbering';
|
||||
//currentApplicationVersion = environment.appVersion;
|
||||
|
||||
navigation = NavigationItems;
|
||||
windowWidth: number | undefined = 1000;
|
||||
|
||||
// Constructor
|
||||
constructor() {
|
||||
this.iconService.addIcon(
|
||||
...[
|
||||
DashboardOutline,
|
||||
CreditCardOutline,
|
||||
FontSizeOutline,
|
||||
LoginOutline,
|
||||
ProfileOutline,
|
||||
BgColorsOutline,
|
||||
AntDesignOutline,
|
||||
ChromeOutline,
|
||||
QuestionOutline
|
||||
]
|
||||
);
|
||||
this.navigations = NavigationItems;
|
||||
}
|
||||
|
||||
// Life cycle events
|
||||
ngOnInit() {
|
||||
if (!!this.windowWidth && this.windowWidth < 1025) {
|
||||
(this.document.querySelector('.coded-navbar') as HTMLDivElement)?.classList.add('menupos-static');
|
||||
}
|
||||
}
|
||||
|
||||
fireOutClick() {
|
||||
let current_url = this.location.path();
|
||||
const baseHref = this.locationStrategy.getBaseHref();
|
||||
if (baseHref) {
|
||||
current_url = baseHref + this.location.path();
|
||||
}
|
||||
const link = "a.nav-link[ href='" + current_url + "' ]";
|
||||
const ele = document?.querySelector(link);
|
||||
if (ele !== null && ele !== undefined) {
|
||||
const parent = ele.parentElement;
|
||||
const up_parent = parent?.parentElement?.parentElement;
|
||||
const last_parent = up_parent?.parentElement;
|
||||
if (parent?.classList.contains('coded-hasmenu')) {
|
||||
parent.classList.add('coded-trigger');
|
||||
parent.classList.add('active');
|
||||
} else if (up_parent?.classList.contains('coded-hasmenu')) {
|
||||
up_parent.classList.add('coded-trigger');
|
||||
up_parent.classList.add('active');
|
||||
} else if (last_parent?.classList.contains('coded-hasmenu')) {
|
||||
last_parent.classList.add('coded-trigger');
|
||||
last_parent.classList.add('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
navMob() {
|
||||
if (!!this.windowWidth && this.windowWidth < 1025 && document.querySelector('app-navigation.coded-navbar')?.classList.contains('mob-open')) {
|
||||
this.NavCollapsedMob.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
<li class="nav-item coded-menu-caption">
|
||||
<label>{{ item().title }}</label>
|
||||
</li>
|
||||
@for (item of item().children; track item) {
|
||||
@if (item.type === 'collapse') {
|
||||
<app-nav-collapse [item]="item"></app-nav-collapse>
|
||||
} @else if (item.type === 'item') {
|
||||
<app-nav-item [item]="item"></app-nav-item>
|
||||
}
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
// Angular import
|
||||
import { Component, OnInit, inject, input } from '@angular/core';
|
||||
import {CommonModule, DOCUMENT, Location} from '@angular/common';
|
||||
|
||||
// project import
|
||||
import { NavigationItem } from '../../navigation';
|
||||
|
||||
import { NavCollapseComponent } from '../nav-collapse/nav-collapse.component';
|
||||
import { NavItemComponent } from '../nav-item/nav-item.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-group',
|
||||
imports: [CommonModule, NavCollapseComponent, NavItemComponent],
|
||||
templateUrl: './nav-group.component.html',
|
||||
styleUrls: ['./nav-group.component.scss']
|
||||
})
|
||||
export class NavGroupComponent implements OnInit {
|
||||
private location = inject(Location);
|
||||
private document = inject(DOCUMENT);
|
||||
// public props
|
||||
|
||||
// All Version in Group Name
|
||||
item = input.required<NavigationItem>();
|
||||
|
||||
// Life cycle events
|
||||
ngOnInit() {
|
||||
// at reload time active and trigger link
|
||||
let current_url: string | any = this.location.path();
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
if (this.location['_baseHref']) {
|
||||
// eslint-disable-next-line
|
||||
|
||||
|
||||
// @ts-ignore
|
||||
current_url = this.location['_baseHref'] + this.location.path();
|
||||
}
|
||||
|
||||
const link = "a.nav-link[ href='" + current_url + "' ]";
|
||||
//if(this.document === undefined) return;
|
||||
const ele = this.document?.querySelector(link);
|
||||
if (ele !== null && ele !== undefined) {
|
||||
const parent = ele.parentElement;
|
||||
const up_parent = parent?.parentElement?.parentElement;
|
||||
const pre_parent = up_parent?.parentElement;
|
||||
const last_parent = up_parent?.parentElement?.parentElement?.parentElement?.parentElement;
|
||||
if (parent?.classList.contains('coded-hasmenu')) {
|
||||
parent?.classList.add('coded-trigger');
|
||||
parent?.classList.add('active');
|
||||
} else if (up_parent?.classList.contains('coded-hasmenu')) {
|
||||
up_parent?.classList.add('coded-trigger');
|
||||
up_parent?.classList.add('active');
|
||||
} else if (pre_parent?.classList.contains('coded-hasmenu')) {
|
||||
pre_parent?.classList.add('coded-trigger');
|
||||
pre_parent?.classList.add('active');
|
||||
}
|
||||
|
||||
if (last_parent?.classList.contains('coded-hasmenu')) {
|
||||
last_parent?.classList.add('coded-trigger');
|
||||
if (pre_parent?.classList.contains('coded-hasmenu')) {
|
||||
pre_parent?.classList.add('coded-trigger');
|
||||
}
|
||||
}
|
||||
last_parent?.classList.add('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
@if (item.url && !item.external) {
|
||||
<li [ngClass]="item.classes!" [routerLinkActive]="['active']">
|
||||
<a [target]="item.target ? '_blank' : '_self'" [routerLink]="[item.url]" (click)="closeOtherMenu($event)">
|
||||
@if (item.icon) {
|
||||
<span class="coded-micon">
|
||||
<i antIcon type="{{ item.icon }}" theme="outline"></i>
|
||||
</span>
|
||||
}
|
||||
@if (item.icon) {
|
||||
<span class="coded-mtext">{{ item.title }}</span>
|
||||
} @else {
|
||||
{{ item.title }}
|
||||
}
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
@if (item.url && item.external) {
|
||||
<li [ngClass]="item.classes!">
|
||||
<a [target]="item.target ? '_blank' : '_self'" [href]="item.url">
|
||||
@if (item.icon) {
|
||||
<span class="coded-micon">
|
||||
<i antIcon type="{{ item.icon }}" theme="outline"></i>
|
||||
</span>
|
||||
}
|
||||
@if (item.icon) {
|
||||
<span class="coded-mtext">{{ item.title }}</span>
|
||||
} @else {
|
||||
{{ item.title }}
|
||||
}
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
// Angular import
|
||||
import {Component, inject, Input} from '@angular/core';
|
||||
import {CommonModule, DOCUMENT} from '@angular/common';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
// Project import
|
||||
import { NavigationItem } from '../../navigation';
|
||||
|
||||
import { IconDirective } from '@ant-design/icons-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-item',
|
||||
imports: [CommonModule, IconDirective, RouterModule],
|
||||
templateUrl: './nav-item.component.html',
|
||||
styleUrls: ['./nav-item.component.scss']
|
||||
})
|
||||
export class NavItemComponent {
|
||||
private document = inject(DOCUMENT);
|
||||
|
||||
// public props
|
||||
@Input() item!: NavigationItem;
|
||||
|
||||
// public method
|
||||
closeOtherMenu(event: MouseEvent) {
|
||||
const ele = event.target as HTMLElement;
|
||||
if (ele !== null && ele !== undefined) {
|
||||
const parent = ele.parentElement as HTMLElement;
|
||||
const up_parent = ((parent.parentElement as HTMLElement).parentElement as HTMLElement).parentElement as HTMLElement;
|
||||
const last_parent = up_parent.parentElement;
|
||||
const sections = this.document.querySelectorAll('.coded-hasmenu');
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
sections[i].classList.remove('active');
|
||||
sections[i].classList.remove('coded-trigger');
|
||||
}
|
||||
|
||||
if (parent.classList.contains('coded-hasmenu')) {
|
||||
parent.classList.add('coded-trigger');
|
||||
parent.classList.add('active');
|
||||
} else if (up_parent.classList.contains('coded-hasmenu')) {
|
||||
up_parent.classList.add('coded-trigger');
|
||||
up_parent.classList.add('active');
|
||||
} else if (last_parent?.classList.contains('coded-hasmenu')) {
|
||||
last_parent.classList.add('coded-trigger');
|
||||
last_parent.classList.add('active');
|
||||
}
|
||||
}
|
||||
if ((document.querySelector('app-navigation.pc-sidebar') as HTMLDivElement).classList.contains('mob-open')) {
|
||||
(document.querySelector('app-navigation.pc-sidebar') as HTMLDivElement).classList.remove('mob-open');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
<nav>
|
||||
<div class="navbar-wrapper">
|
||||
<div class="m-header">
|
||||
<a href="javascript:" class="b-brand">
|
||||
<img src="assets/images/logo-dark.svg" alt="theme-logo" class="logo logo-dark logo-lg" />
|
||||
</a>
|
||||
</div>
|
||||
<app-nav-content (NavCollapsedMob)="navCollapseMob()" class="scroll-div w-100 compact"></app-nav-content>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -1,49 +0,0 @@
|
||||
// Angular import
|
||||
import {Component, EventEmitter, inject, OnInit, Output, output} from '@angular/core';
|
||||
import {CommonModule, DOCUMENT} from '@angular/common';
|
||||
import {NavContentComponent} from './nav-content/nav-content.component';
|
||||
|
||||
// project import
|
||||
|
||||
//import { NavContentComponent } from './nav-content/nav-content.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-navigation',
|
||||
// imports: [ CommonModule],
|
||||
templateUrl: './navigation.component.html',
|
||||
imports: [
|
||||
NavContentComponent
|
||||
],
|
||||
styleUrls: ['./navigation.component.scss']
|
||||
})
|
||||
export class NavigationComponent implements OnInit{
|
||||
|
||||
private document = inject<Document>(DOCUMENT);
|
||||
|
||||
// media 1025 After Use Menu Open
|
||||
NavCollapsedMob = output();
|
||||
|
||||
navCollapsedMob:boolean;
|
||||
windowWidth: number | undefined = 1000;
|
||||
|
||||
// Constructor
|
||||
constructor() {
|
||||
//window.
|
||||
// this.windowWidth = !document ? 0 : !document.defaultView ? 0 : document.defaultView?.innerWidth;
|
||||
//this.windowWidth = document.defaultView !== null? document.defaultView.innerWidth : 1000;//window.innerWidth;
|
||||
this.navCollapsedMob = false;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.windowWidth = this.document.defaultView?.innerWidth;
|
||||
}
|
||||
|
||||
// public method
|
||||
// @Output() NavCollapse = new EventEmitter<unknown>();
|
||||
@Output() NavCollapse = new EventEmitter<unknown>();
|
||||
navCollapseMob() {
|
||||
if (!!this.windowWidth && this.windowWidth < 1025) {
|
||||
this.NavCollapsedMob.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
export interface NavigationItem {
|
||||
id: string;
|
||||
title: string;
|
||||
type: 'item' | 'collapse' | 'group';
|
||||
translate?: string;
|
||||
icon?: string;
|
||||
hidden?: boolean;
|
||||
url?: string;
|
||||
classes?: string;
|
||||
groupClasses?: string;
|
||||
exactMatch?: boolean;
|
||||
external?: boolean;
|
||||
target?: boolean;
|
||||
breadcrumbs?: boolean;
|
||||
children?: NavigationItem[];
|
||||
link?: string;
|
||||
description?: string;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
export const NavigationItems: NavigationItem[] = [
|
||||
{
|
||||
id: 'admin',
|
||||
title: 'Admin',
|
||||
type: 'group',
|
||||
icon: 'icon-navigation',
|
||||
url: '/main/admin/welcome',
|
||||
target: true,
|
||||
children: [
|
||||
{
|
||||
id: 'settings',
|
||||
title: 'Settings',
|
||||
type: 'item',
|
||||
classes: 'nav-item',
|
||||
url: '/main/admin/settings',
|
||||
icon: 'dashboard',
|
||||
// breadcrumbs: false
|
||||
},
|
||||
{
|
||||
id: 'system',
|
||||
title: 'System',
|
||||
type: 'item',
|
||||
classes: 'nav-item',
|
||||
url: '/main/admin/system',
|
||||
icon: 'dashboard',
|
||||
// breadcrumbs: false
|
||||
}
|
||||
]
|
||||
}/*,
|
||||
{
|
||||
id: 'authentication',
|
||||
title: 'Authentication',
|
||||
type: 'group',
|
||||
icon: 'icon-navigation',
|
||||
children: [
|
||||
{
|
||||
id: 'login',
|
||||
title: 'Login',
|
||||
type: 'item',
|
||||
classes: 'nav-item',
|
||||
url: '/login',
|
||||
icon: 'login',
|
||||
target: true,
|
||||
breadcrumbs: false
|
||||
},
|
||||
{
|
||||
id: 'register',
|
||||
title: 'Register',
|
||||
type: 'item',
|
||||
classes: 'nav-item',
|
||||
url: '/register',
|
||||
icon: 'profile',
|
||||
target: true,
|
||||
breadcrumbs: false
|
||||
}*/
|
||||
// ]
|
||||
// }
|
||||
/*,
|
||||
{
|
||||
id: 'utilities',
|
||||
title: 'UI Components',
|
||||
type: 'group',
|
||||
icon: 'icon-navigation',
|
||||
children: [
|
||||
{
|
||||
id: 'typography',
|
||||
title: 'Typography',
|
||||
type: 'item',
|
||||
classes: 'nav-item',
|
||||
url: '/typography',
|
||||
icon: 'font-size'
|
||||
},
|
||||
{
|
||||
id: 'color',
|
||||
title: 'Colors',
|
||||
type: 'item',
|
||||
classes: 'nav-item',
|
||||
url: '/color',
|
||||
icon: 'bg-colors'
|
||||
},
|
||||
{
|
||||
id: 'ant-icons',
|
||||
title: 'Ant Icons',
|
||||
type: 'item',
|
||||
classes: 'nav-item',
|
||||
url: 'https://ant.design/components/icon',
|
||||
icon: 'ant-design',
|
||||
target: true,
|
||||
external: true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
id: 'other',
|
||||
title: 'Other',
|
||||
type: 'group',
|
||||
icon: 'icon-navigation',
|
||||
children: [
|
||||
{
|
||||
id: 'sample-page',
|
||||
title: 'Sample Page',
|
||||
type: 'item',
|
||||
url: '/sample-page',
|
||||
classes: 'nav-item',
|
||||
icon: 'chrome'
|
||||
},
|
||||
{
|
||||
id: 'document',
|
||||
title: 'Document',
|
||||
type: 'item',
|
||||
classes: 'nav-item',
|
||||
url: 'https://codedthemes.gitbook.io/mantis-angular/',
|
||||
icon: 'question',
|
||||
target: true,
|
||||
external: true
|
||||
}
|
||||
]
|
||||
}*/
|
||||
];
|
||||
@@ -1 +0,0 @@
|
||||
<router-outlet></router-outlet>
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-guest-layout',
|
||||
imports: [RouterModule],
|
||||
templateUrl: './guest-layout.component.html',
|
||||
styleUrl: './guest-layout.component.scss'
|
||||
})
|
||||
export class GuestLayoutComponent {}
|
||||
@@ -1,9 +1,7 @@
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {HomeComponent} from '../components/home.component/home.component';
|
||||
import {MainComponent} from './main.component/main.component';
|
||||
import {TutorialsListComponent} from '../components/tutorials-list/tutorials-list.component';
|
||||
import {TutorialsComponent} from '../components/tutorials.component/tutorials.component';
|
||||
import {AddTutorialComponent} from '../components/add-tutorial/add-tutorial.component';
|
||||
import {RegisterComponent} from '../components/register/register.component';
|
||||
import {ProfileComponent} from '../components/profile/profile.component';
|
||||
import {GenerateImageComponent} from '../components/generate-image.component/generate-image.component';
|
||||
@@ -40,10 +38,6 @@ const MAIN_ROUTES: Routes =[
|
||||
path: 'tutorials',
|
||||
component: TutorialsComponent
|
||||
},
|
||||
{
|
||||
path: 'add-tutorial',
|
||||
component: AddTutorialComponent
|
||||
},
|
||||
{
|
||||
path: 'register',
|
||||
component : RegisterComponent
|
||||
|
||||
@@ -1,28 +1,13 @@
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA, OnInit, ViewChild} from '@angular/core';
|
||||
import {RouterOutlet} from '@angular/router';
|
||||
import {SideBarComponent} from '../../components/side-bar.component/side-bar.component';
|
||||
import {MatSidenav, MatSidenavContainer} from '@angular/material/sidenav';
|
||||
import {NgClass} from '@angular/common';
|
||||
import {MatListItem, MatNavList} from '@angular/material/list';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {MatSidenav} from '@angular/material/sidenav';
|
||||
import {BreakpointObserver} from '@angular/cdk/layout';
|
||||
import {MatToolbar} from '@angular/material/toolbar';
|
||||
import {MatIconButton} from '@angular/material/button';
|
||||
import {SideBarUserComponent} from '../side-bar-user.component/side-bar-user.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-user.component',
|
||||
imports: [
|
||||
RouterOutlet,
|
||||
SideBarComponent,
|
||||
MatSidenavContainer,
|
||||
NgClass,
|
||||
MatNavList,
|
||||
MatSidenav,
|
||||
MatListItem,
|
||||
MatIcon,
|
||||
MatToolbar,
|
||||
MatIconButton,
|
||||
SideBarUserComponent
|
||||
],
|
||||
templateUrl: './user.component.html',
|
||||
|
||||
@@ -3,5 +3,5 @@ export const environment = {
|
||||
port: 8080,
|
||||
fromWeb: false,
|
||||
production: false,
|
||||
host_name: 'http://localhost',
|
||||
host_name: 'http://localhost'
|
||||
};
|
||||
|
||||
@@ -9,6 +9,28 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
</head>
|
||||
<!-- Google tag (gtag.js) -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-E8484J3HQW"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'G-E8484J3HQW');
|
||||
</script>
|
||||
<!-- Google Tag Manager -->
|
||||
<script>
|
||||
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','GTM-MD79JQ92');
|
||||
</script>
|
||||
<!-- End Google Tag Manager -->
|
||||
<!-- Google Tag Manager (noscript) -->
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-MD79JQ92"
|
||||
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||
<!-- End Google Tag Manager (noscript) -->
|
||||
<body class="mat-typography">
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JambotronUi</title>
|
||||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
</head>
|
||||
<body class="mat-typography">
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +0,0 @@
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { App } from './app/app';
|
||||
import { config } from './app/app.config.server';
|
||||
|
||||
const bootstrap = () => bootstrapApplication(App, config);
|
||||
|
||||
export default bootstrap;
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"/api/**": {
|
||||
"target": "http://localhost:8082",
|
||||
"secure": false,
|
||||
"changeOrigin": true,
|
||||
"logLevel": "debug",
|
||||
"pathRewrite": {"^/api" : "http://localhost:8082/api"}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
const PROXY_CONFIG = [
|
||||
{
|
||||
context: [
|
||||
"/api"
|
||||
],
|
||||
target: "http://localhost:8082",
|
||||
secure: false
|
||||
}
|
||||
]
|
||||
module.exports = PROXY_CONFIG;
|
||||
@@ -1,71 +0,0 @@
|
||||
import {
|
||||
AngularNodeAppEngine,
|
||||
createNodeRequestHandler,
|
||||
isMainModule,
|
||||
writeResponseToNodeResponse,
|
||||
} from '@angular/ssr/node';
|
||||
import express from 'express';
|
||||
import { join } from 'node:path';
|
||||
|
||||
const browserDistFolder = join(import.meta.dirname, '../browser');
|
||||
|
||||
const app = express();
|
||||
const angularApp = new AngularNodeAppEngine();
|
||||
|
||||
/**
|
||||
* Example Express Rest API endpoints can be defined here.
|
||||
* Uncomment and define endpoints as necessary.
|
||||
*
|
||||
* Example:
|
||||
* ```ts
|
||||
* app.get('/api/{*splat}', (req, res) => {
|
||||
* // Handle API request
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
* Serve static files from /browser
|
||||
*/
|
||||
app.use(
|
||||
express.static(browserDistFolder, {
|
||||
maxAge: '1y',
|
||||
index: false,
|
||||
redirect: false,
|
||||
}),
|
||||
);
|
||||
|
||||
/**
|
||||
* Handle all other requests by rendering the Angular application.
|
||||
*/
|
||||
app.use((req, res, next) => {
|
||||
angularApp
|
||||
.handle(req)
|
||||
.then((response) =>
|
||||
response ? writeResponseToNodeResponse(response, res) : next(),
|
||||
)
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
/**
|
||||
* Start the server if this module is the main entry point.
|
||||
* The server listens on the port defined by the `PORT` environment variable, or defaults to 4000.
|
||||
*/
|
||||
if (isMainModule(import.meta.url)) {
|
||||
const port = process.env['PORT'] || 4000;
|
||||
app.listen(port, (error) => {
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.log(`Node Express server listening on http://localhost:${port}`);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Request handler used by the Angular CLI (for dev-server and during build) or Firebase Cloud Functions.
|
||||
*/
|
||||
export const reqHandler = createNodeRequestHandler(app);
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user