diff --git a/.gitignore b/.gitignore index 8fd54ef..81d5aae 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ out/ /.idea/ +/uploads/ diff --git a/build.gradle b/build.gradle index 8627d74..abbfed1 100644 --- a/build.gradle +++ b/build.gradle @@ -37,6 +37,7 @@ 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:spring-mock:2.0.8' } apply plugin: 'io.spring.dependency-management' diff --git a/jambotron-ui/angular.json b/jambotron-ui/angular.json index dce0468..341a2c7 100644 --- a/jambotron-ui/angular.json +++ b/jambotron-ui/angular.json @@ -38,10 +38,34 @@ ], "styles": [ "@angular/material/prebuilt-themes/azure-blue.css", - "src/styles.scss" + "src/styles.scss", + "node_modules/prismjs/themes/prism-okaidia.css", + "node_modules/prismjs/plugins/line-numbers/prism-line-numbers.css", + "node_modules/prismjs/plugins/line-highlight/prism-line-highlight.css", + "node_modules/prismjs/plugins/command-line/prism-command-line.css", + + "node_modules/bootstrap/dist/css/bootstrap.css", + "node_modules/bootstrap-markdown/css/bootstrap-markdown.min.css", + "node_modules/font-awesome/css/font-awesome.css" + + ], "scripts": [ - "node_modules/viewerjs/dist/viewer.min.js" + "node_modules/viewerjs/dist/viewer.min.js", + "node_modules/prismjs/prism.js", + "node_modules/prismjs/components/prism-csharp.min.js", + "node_modules/prismjs/components/prism-css.min.js", + "node_modules/prismjs/components/prism-javascript.min.js", + "node_modules/prismjs/components/prism-typescript.min.js", + "node_modules/prismjs/components/prism-java.js", + "node_modules/prismjs/plugins/line-numbers/prism-line-numbers.js", + "node_modules/prismjs/plugins/line-highlight/prism-line-highlight.js", + "node_modules/prismjs/plugins/command-line/prism-command-line.js", + + + "node_modules/jquery/dist/jquery.js", + "node_modules/bootstrap-markdown/js/bootstrap-markdown.js" + ] }, diff --git a/jambotron-ui/package-lock.json b/jambotron-ui/package-lock.json index 2224499..fba3123 100644 --- a/jambotron-ui/package-lock.json +++ b/jambotron-ui/package-lock.json @@ -24,8 +24,12 @@ "@ng-bootstrap/ng-bootstrap": "19.0.0", "@popperjs/core": "2.11.8", "@primeng/themes": "^19.1.3", + "angular-markdown-editor": "^3.1.1", "bootstrap": "5.3.6", + "cropperjs": "^2.0.1", "express": "^5.1.0", + "file-saver": "^2.0.5", + "ngx-filesaver": "^20.0.0", "ngx-markdown": "^20.0.0", "ngx-scrollbar": "18.0.0", "primeng": "^19.1.3", @@ -40,6 +44,7 @@ "@angular/cli": "^20.0.2", "@angular/compiler-cli": "^20.0.0", "@types/express": "^5.0.1", + "@types/file-saver": "^2.0.7", "@types/jasmine": "~5.1.0", "@types/node": "^20.17.19", "jasmine-core": "~5.7.0", @@ -2683,6 +2688,126 @@ "node": ">=0.1.90" } }, + "node_modules/@cropper/element": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cropper/element/-/element-2.0.1.tgz", + "integrity": "sha512-Jn1hR7XWzWQM/QfXRGMGzdkJ2gG/UcLdQPZQ7OKs0JiFfRzKpzu4u/nYrXHeH3MM2iOslLqh2kqYju6mjZLMJQ==", + "license": "MIT", + "dependencies": { + "@cropper/utils": "^2.0.1" + } + }, + "node_modules/@cropper/element-canvas": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cropper/element-canvas/-/element-canvas-2.0.1.tgz", + "integrity": "sha512-OKxq/O0HL9W2JegOsc2zh1NRpERZcLM5+M8aQ/eXdmMcfi1lzosPftag3Irp6pTsVpwV6B6ypIxKESzJ4ci9Fw==", + "license": "MIT", + "dependencies": { + "@cropper/element": "^2.0.1", + "@cropper/utils": "^2.0.1" + } + }, + "node_modules/@cropper/element-crosshair": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cropper/element-crosshair/-/element-crosshair-2.0.1.tgz", + "integrity": "sha512-bS5msU9cTU/jf1/kDw+QJmEM9/rw8IgOdpolR85iMVUCR8sRcLa0wgom42MBHcpBYB6hvL5YfiOeXZ7lHIYMpw==", + "license": "MIT", + "dependencies": { + "@cropper/element": "^2.0.1", + "@cropper/utils": "^2.0.1" + } + }, + "node_modules/@cropper/element-grid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cropper/element-grid/-/element-grid-2.0.1.tgz", + "integrity": "sha512-ayqCvYQJ+GVT31HhFpttzHabW1T/LsIwLJY5PLTMG0cEZLw/E8ihg8mxctjZbo852D7oEePbz6/2SeuCb1018Q==", + "license": "MIT", + "dependencies": { + "@cropper/element": "^2.0.1", + "@cropper/utils": "^2.0.1" + } + }, + "node_modules/@cropper/element-handle": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cropper/element-handle/-/element-handle-2.0.1.tgz", + "integrity": "sha512-fdifyyPIaR9S2eQ7qPHuM8fX8uToAfBsi8vQlR9EM+oJkDNil0uO4rWyArLWEtlr0/q7U0OvsufcuJ7ffqfmpg==", + "license": "MIT", + "dependencies": { + "@cropper/element": "^2.0.1", + "@cropper/utils": "^2.0.1" + } + }, + "node_modules/@cropper/element-image": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cropper/element-image/-/element-image-2.0.1.tgz", + "integrity": "sha512-gPj5Sl2T8Cno198Cz3F3TDfcYoALW3yJ3fV6PHXmhMnX8sBkL7J441do7Vwkg0mEd2CogCtTLAf+p7ljdV0kgA==", + "license": "MIT", + "dependencies": { + "@cropper/element": "^2.0.1", + "@cropper/element-canvas": "^2.0.1", + "@cropper/utils": "^2.0.1" + } + }, + "node_modules/@cropper/element-selection": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cropper/element-selection/-/element-selection-2.0.1.tgz", + "integrity": "sha512-atv+Aeq2N2eWawelIRPGh1kYFdNrpb0QkUPPheGxz1ImfxpLdcHO9gb9T5noQijizUW2G0pNvts4ZaITQ0I71Q==", + "license": "MIT", + "dependencies": { + "@cropper/element": "^2.0.1", + "@cropper/element-canvas": "^2.0.1", + "@cropper/element-image": "^2.0.1", + "@cropper/utils": "^2.0.1" + } + }, + "node_modules/@cropper/element-shade": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cropper/element-shade/-/element-shade-2.0.1.tgz", + "integrity": "sha512-YIYgJ690NdFQ6wJLRFh/EySNVxGFKArncQ4FrsJ3yHU+ShgtOKz4FpjFLpqJRJB9swoVbD3WKTimGyzXrwjZrQ==", + "license": "MIT", + "dependencies": { + "@cropper/element": "^2.0.1", + "@cropper/element-canvas": "^2.0.1", + "@cropper/element-selection": "^2.0.1", + "@cropper/utils": "^2.0.1" + } + }, + "node_modules/@cropper/element-viewer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cropper/element-viewer/-/element-viewer-2.0.1.tgz", + "integrity": "sha512-HDj25l08pWi/AO6El/OqfQHBpBC4Lh5NEnQN1SOldsmxEwt27Ubv6ndDsF8LkTK7XPwjjZRpyQPyfig4w8L2JQ==", + "license": "MIT", + "dependencies": { + "@cropper/element": "^2.0.1", + "@cropper/element-canvas": "^2.0.1", + "@cropper/element-image": "^2.0.1", + "@cropper/element-selection": "^2.0.1", + "@cropper/utils": "^2.0.1" + } + }, + "node_modules/@cropper/elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cropper/elements/-/elements-2.0.1.tgz", + "integrity": "sha512-paFbBLXTKXNngn1yDi2ZIf+FO1pIEQXyBntmqOjuxqtG73KuEKv633wsJPFpj958bgcfSakgBbF80j+3nHbPug==", + "license": "MIT", + "dependencies": { + "@cropper/element": "^2.0.1", + "@cropper/element-canvas": "^2.0.1", + "@cropper/element-crosshair": "^2.0.1", + "@cropper/element-grid": "^2.0.1", + "@cropper/element-handle": "^2.0.1", + "@cropper/element-image": "^2.0.1", + "@cropper/element-selection": "^2.0.1", + "@cropper/element-shade": "^2.0.1", + "@cropper/element-viewer": "^2.0.1" + } + }, + "node_modules/@cropper/utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cropper/utils/-/utils-2.0.1.tgz", + "integrity": "sha512-A9RnAFmgNF5aZk5q2VZnFnHtXWu1kPyEN0LVsX8wJ2LBRu2nyETKwz+ZXVsVWliktToCaYojHKrS+6/HODyEZA==", + "license": "MIT" + }, "node_modules/@discoveryjs/json-ext": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", @@ -5822,6 +5947,13 @@ "@types/send": "*" } }, + "node_modules/@types/file-saver": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz", + "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/geojson": { "version": "7946.0.16", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", @@ -6286,6 +6418,27 @@ "ajv": "^8.8.2" } }, + "node_modules/angular-markdown-editor": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/angular-markdown-editor/-/angular-markdown-editor-3.1.1.tgz", + "integrity": "sha512-0Ho8HZaR95guBwZHDPw9k4Ac2zKW4hr1kl676uaoBsMZ82YHcl3VNb2TTwwui5qtcUWYmdXA++2DmZInj2GIlA==", + "license": "MIT", + "dependencies": { + "bootstrap": ">=4.6.2", + "bootstrap-markdown": "github:refactory-id/bootstrap-markdown", + "font-awesome": "^4.7.0", + "jquery": "^3.7.0", + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=14.17.0", + "npm": ">=6.14.13" + }, + "funding": { + "type": "ko_fi", + "url": "https://ko-fi.com/ghiscoding" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -6623,6 +6776,11 @@ "@popperjs/core": "^2.11.8" } }, + "node_modules/bootstrap-markdown": { + "version": "2.10.0", + "resolved": "git+ssh://git@github.com/refactory-id/bootstrap-markdown.git#a496d34b9bd34451c8315a850472f794c8df7d53", + "license": "Apache-2.0" + }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -7558,6 +7716,16 @@ } } }, + "node_modules/cropperjs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-2.0.1.tgz", + "integrity": "sha512-hiJwk2SCPZqxMA7aR3byzLpYUqOrQo+ihMk8k/WRm/xe/LX8wNzAIzMwEB/NEGJYA6sbewxW9TUlrRUYi/2Ipg==", + "license": "MIT", + "dependencies": { + "@cropper/elements": "^2.0.1", + "@cropper/utils": "^2.0.1" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -9091,6 +9259,12 @@ } } }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==", + "license": "MIT" + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -9176,6 +9350,15 @@ } } }, + "node_modules/font-awesome": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", + "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==", + "license": "(OFL-1.1 AND MIT)", + "engines": { + "node": ">=0.10.3" + } + }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -10307,6 +10490,12 @@ "jiti": "bin/jiti.js" } }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -12015,6 +12204,19 @@ "dev": true, "license": "MIT" }, + "node_modules/ngx-filesaver": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/ngx-filesaver/-/ngx-filesaver-20.0.0.tgz", + "integrity": "sha512-84vRFGko1BmpyerAmLLggjx5ZiHvaWadJKlb2n0hOZlnzlTNZeI3zHKY9vqtIRkxCX70vWHTB8JwV5VvvkB2uQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@types/file-saver": "^2.0.0", + "file-saver": "^2.0.0" + } + }, "node_modules/ngx-markdown": { "version": "20.0.0", "resolved": "https://registry.npmjs.org/ngx-markdown/-/ngx-markdown-20.0.0.tgz", diff --git a/jambotron-ui/package.json b/jambotron-ui/package.json index 12eda64..f976e95 100644 --- a/jambotron-ui/package.json +++ b/jambotron-ui/package.json @@ -7,7 +7,7 @@ "start_prod": "ng serve --configuration production", "build": "ng build", "watch": "ng build --watch --configuration development", - "build_dev":"ng build --configuration development", + "build_dev": "ng build --configuration development", "test": "ng test", "serve:ssr:jambotron-ui": "node dist/jambotron-ui/server/server.mjs" }, @@ -29,8 +29,12 @@ "@ng-bootstrap/ng-bootstrap": "19.0.0", "@popperjs/core": "2.11.8", "@primeng/themes": "^19.1.3", + "angular-markdown-editor": "^3.1.1", "bootstrap": "5.3.6", + "cropperjs": "^2.0.1", "express": "^5.1.0", + "file-saver": "^2.0.5", + "ngx-filesaver": "^20.0.0", "ngx-markdown": "^20.0.0", "ngx-scrollbar": "18.0.0", "primeng": "^19.1.3", @@ -45,6 +49,7 @@ "@angular/cli": "^20.0.2", "@angular/compiler-cli": "^20.0.0", "@types/express": "^5.0.1", + "@types/file-saver": "^2.0.7", "@types/jasmine": "~5.1.0", "@types/node": "^20.17.19", "jasmine-core": "~5.7.0", diff --git a/jambotron-ui/src/app/app.config.server.ts b/jambotron-ui/src/app/app.config.server.ts deleted file mode 100644 index 41031f1..0000000 --- a/jambotron-ui/src/app/app.config.server.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { mergeApplicationConfig, ApplicationConfig } from '@angular/core'; -import { provideServerRendering, withRoutes } from '@angular/ssr'; -import { appConfig } from './app.config'; -import { serverRoutes } from './app.routes.server'; - -const serverConfig: ApplicationConfig = { - providers: [ - provideServerRendering(withRoutes(serverRoutes)) - ] -}; - -export const config = mergeApplicationConfig(appConfig, serverConfig); diff --git a/jambotron-ui/src/app/app.config.ts b/jambotron-ui/src/app/app.config.ts index ffe0624..b527fc1 100644 --- a/jambotron-ui/src/app/app.config.ts +++ b/jambotron-ui/src/app/app.config.ts @@ -14,10 +14,6 @@ import Aura from '@primeng/themes/aura'; import {provideAnimations} from '@angular/platform-browser/animations'; import {provideMarkdown} from 'ngx-markdown'; -import 'prismjs'; -import 'prismjs/components/prism-typescript.min.js'; -import 'prismjs/plugins/line-numbers/prism-line-numbers.js'; -import 'prismjs/plugins/line-highlight/prism-line-highlight.js'; import {authInterceptorProviders} from './helpers/auth.interceptor'; export const appConfig: ApplicationConfig = { diff --git a/jambotron-ui/src/app/app.html b/jambotron-ui/src/app/app.html index 0680b43..c6957c2 100644 --- a/jambotron-ui/src/app/app.html +++ b/jambotron-ui/src/app/app.html @@ -1 +1,2 @@ + diff --git a/jambotron-ui/src/app/app.module.ts b/jambotron-ui/src/app/app.module.ts index 08f57c9..6ef61e8 100644 --- a/jambotron-ui/src/app/app.module.ts +++ b/jambotron-ui/src/app/app.module.ts @@ -7,15 +7,16 @@ import { BrowserAnimationsModule } import { MatIconModule } from '@angular/material/icon'; import {HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi} from '@angular/common/http'; -import {MainComponent} from './main-module/main.component/main.component'; +import {MainComponent} from './modules/main-module/main.component/main.component'; import {authInterceptorProviders} from './helpers/auth.interceptor'; -import {AdminComponent} from './admin-module/admin.component/admin.component'; -import {AdminWelcomeComponent} from './admin-module/admin-welcome.component/admin-welcome.component'; -import {SettingsComponent} from './admin-module/settings.component/settings.component'; -import {SystemComponent} from './admin-module/system.component/system.component'; +import {AdminComponent} from './modules/admin-module/admin.component/admin.component'; +import {AdminWelcomeComponent} from './modules/admin-module/admin-welcome.component/admin-welcome.component'; +import {SettingsComponent} from './modules/admin-module/settings.component/settings.component'; +import {SystemComponent} from './modules/admin-module/system.component/system.component'; import {AppRoutingModule} from './app.routes'; import {App} from './app'; import {CustomHttpInterceptor} from './helpers/custom-http-interceptor'; +import {AngularMarkdownEditorModule} from 'angular-markdown-editor'; @NgModule({ @@ -32,7 +33,7 @@ import {CustomHttpInterceptor} from './helpers/custom-http-interceptor'; AdminWelcomeComponent, SettingsComponent, SystemComponent, - + AngularMarkdownEditorModule.forRoot({ iconlibrary: 'fa' }) ], providers: [ authInterceptorProviders,provideHttpClient(withInterceptorsFromDi()),{ diff --git a/jambotron-ui/src/app/app.routes.server.ts b/jambotron-ui/src/app/app.routes.server.ts deleted file mode 100644 index ffd37b1..0000000 --- a/jambotron-ui/src/app/app.routes.server.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { RenderMode, ServerRoute } from '@angular/ssr'; - -export const serverRoutes: ServerRoute[] = [ - { - path: '**', - renderMode: RenderMode.Prerender - } -]; diff --git a/jambotron-ui/src/app/app.routes.ts b/jambotron-ui/src/app/app.routes.ts index e93be04..8f9c71e 100644 --- a/jambotron-ui/src/app/app.routes.ts +++ b/jambotron-ui/src/app/app.routes.ts @@ -1,16 +1,17 @@ import {RouterModule, Routes} from '@angular/router'; import {NgModule} from '@angular/core'; +import {environment} from '../environments/environment'; export const routes: Routes = [ { path: '', - redirectTo: 'main/generate-image', + redirectTo: environment.default_page, pathMatch: 'full' }, { path: 'main', loadChildren: () => - import('./main-module/main.module').then((m) => m.MainModule), + import('./modules/main-module/main.module').then((m) => m.MainModule), } ]; @NgModule({ diff --git a/jambotron-ui/src/app/app.ts b/jambotron-ui/src/app/app.ts index 23348c4..571584f 100644 --- a/jambotron-ui/src/app/app.ts +++ b/jambotron-ui/src/app/app.ts @@ -1,13 +1,16 @@ -import { Component } from '@angular/core'; +import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'; import { RouterOutlet } from '@angular/router'; +import {SpinnerComponent} from './components/spinner/spinner.component'; @Component({ selector: 'app-root', templateUrl: './app.html', imports: [ - RouterOutlet + RouterOutlet, + SpinnerComponent ], - styleUrl: './app.scss' + styleUrl: './app.scss', + schemas:[CUSTOM_ELEMENTS_SCHEMA] }) export class App { protected title = 'jambotron-ui'; diff --git a/jambotron-ui/src/app/components/dialog/dialog.component.ts b/jambotron-ui/src/app/components/dialog/dialog.component.ts deleted file mode 100644 index c9f8128..0000000 --- a/jambotron-ui/src/app/components/dialog/dialog.component.ts +++ /dev/null @@ -1,74 +0,0 @@ -import {ChangeDetectionStrategy, Component, EventEmitter, Inject, inject, Output, signal} from '@angular/core'; -import {MatButtonModule} from "@angular/material/button"; -import { - MAT_DIALOG_DATA, - MatDialogActions, - MatDialogClose, - MatDialogContent, - MatDialogRef, - MatDialogTitle -} from "@angular/material/dialog"; - - -import {MatFormField, MatLabel, MatSuffix} from "@angular/material/form-field"; -import {MatInput} from "@angular/material/input"; -import {FormsModule} from "@angular/forms"; -import {MatIcon} from "@angular/material/icon"; -import {DialogLoginData} from '../../main-module/main.component/main.component'; -import {MatSnackBar} from '@angular/material/snack-bar'; - - - - -@Component({ - selector: 'app-dialog', - imports: [MatButtonModule, MatLabel, MatDialogActions, MatDialogClose, MatDialogTitle, MatDialogContent, MatFormField, MatInput, FormsModule, MatIcon, MatSuffix], - - templateUrl: './dialog.component.html', - styleUrl: './dialog.component.scss', - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class DialogComponent { - readonly dialogRef = inject(MatDialogRef); - hide = signal(true); - - @Output() loginClicked = new EventEmitter(); - @Output() signupClicked = new EventEmitter(); - - private _snackBar = inject(MatSnackBar); - durationInSeconds = 5; - - - constructor( - @Inject(MAT_DIALOG_DATA) public data:DialogLoginData) { - - } - - openLoginFailedSnackBar(errorMessage : string = "Login failed.") { - this._snackBar.open(errorMessage , "", { - duration: this.durationInSeconds * 1000, - }); - } - - onNoClick() { - this.dialogRef.close(); - } - - - clickEvent(event: MouseEvent) { - this.hide.set(!this.hide()); - event.stopPropagation(); - } - - login() { - this.loginClicked.emit(this.data); - - } - - signup() { - this.signupClicked.emit(); - } -} - - - diff --git a/jambotron-ui/src/app/components/generate-image.component/generate-image.component.ts b/jambotron-ui/src/app/components/generate-image.component/generate-image.component.ts index 38a5c5b..2ad49b4 100644 --- a/jambotron-ui/src/app/components/generate-image.component/generate-image.component.ts +++ b/jambotron-ui/src/app/components/generate-image.component/generate-image.component.ts @@ -5,7 +5,7 @@ import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from '@angular/m import {MatFormField, MatInput, MatLabel} from '@angular/material/input'; import {AsyncPipe} from '@angular/common'; import {Image} from '../../models/image'; -import {ZhipuaiImageService} from '../../services/zhipuai-image.service'; +import {ZhipuaiImageService} from '../../modules/ai-module/zhipuai-image.service'; import {MatProgressSpinner} from '@angular/material/progress-spinner'; import {SpinnerService} from '../../services/spinner.service'; @@ -50,11 +50,6 @@ export class GenerateImageComponent implements OnInit { ngOnInit(): void { - const img = this.renderer.selectRootElement('img'); - this.viewer = new Viewer(img, { - inline: true, - }); - this.viewer.zoomTo(1); } @@ -77,11 +72,4 @@ export class GenerateImageComponent implements OnInit { this.viewer.update(); }) } - - zoomPlus(){ - this.viewer.zoomTo(5); - } - zoomMinus(){ - this.viewer.zoomTo(-5); - } } diff --git a/jambotron-ui/src/app/components/home.component/home.component.html b/jambotron-ui/src/app/components/home.component/home.component.html deleted file mode 100644 index f3f751c..0000000 --- a/jambotron-ui/src/app/components/home.component/home.component.html +++ /dev/null @@ -1,50 +0,0 @@ -

dfsdgdsgsdg

- -

dfsdgdsgsdg

-

dfsdgdsgsdg

-

dfsdgdsgsdg

-

dfsdgdsgsdg

-

dfsdgdsgsdg

dfsdgdsgsdg

-

dfsdgdsgsdg

-

dfsdgdsgsdg

-

dfsdgdsgsdg

-

dfsdgdsgsdg

-

dfsdgdsgsdg

dfsdgdsgsdg

-

dfsdgdsgsdg

-

dfsdgdsgsdg

-

dfsdgdsgsdg

- - - - - - - diff --git a/jambotron-ui/src/app/components/home.component/home.component.ts b/jambotron-ui/src/app/components/home.component/home.component.ts deleted file mode 100644 index 9b001f7..0000000 --- a/jambotron-ui/src/app/components/home.component/home.component.ts +++ /dev/null @@ -1,76 +0,0 @@ -import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'; -import {MatFormField, MatInput, MatLabel} from '@angular/material/input'; -import {AngularImageViewerModule, CustomImageEvent, ImageViewerConfig} from '@hreimer/angular-image-viewer'; - -import {ZhipuaiImageService} from '../../services/zhipuai-image.service'; -import {MatButton} from '@angular/material/button'; - - -import {FormsModule} from '@angular/forms'; -import {CommonModule} from '@angular/common'; -import {BrowserModule} from '@angular/platform-browser'; -import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from '@angular/material/card'; -import {Image} from '../../models/image'; - -@Component({ - selector: 'app-home.component', - imports: [ - - AngularImageViewerModule, - FormsModule - ], - templateUrl: './home.component.html', - styleUrl: './home.component.scss', - schemas :[CUSTOM_ELEMENTS_SCHEMA] -}) - -export class HomeComponent { - - query : string = ''; - - images = []; - image: Image = { - url: '' - }; - imageIndexOne = 0; - - config: ImageViewerConfig = { customBtns: [{ name: 'print', icon: { - classes: 'fas fa-paperclip', - text: 'link' - } }, { name: 'link', icon: { - classes: 'fas fa-paperclip', - text: 'link' - } }] }; - - submitted: boolean = false; - - constructor(private zhipuaiImageService: ZhipuaiImageService) { - - } - - handleEvent(event: CustomImageEvent) { - console.log(`${event.name} has been click on img ${event.imageIndex + 1}`); - - switch (event.name) { - case 'print': - console.log('run print logic'); - break; - } - } - generateImage(){ - this.zhipuaiImageService.generate(this.query).subscribe( - data => { - this.image = data; - // @ts-ignore - this.images = [this.image.url]; - - - console.log(data); - }, - error => { - console.log(error); - } - ) - } - -} diff --git a/jambotron-ui/src/app/components/login/login.component.html b/jambotron-ui/src/app/components/login/login.component.html deleted file mode 100644 index a4d4501..0000000 --- a/jambotron-ui/src/app/components/login/login.component.html +++ /dev/null @@ -1,75 +0,0 @@ -
-
- -
-
- - - -
-
- - - -
-
- -
-
- -
-
- -
- Logged in as {{ roles }}. -
-
-
diff --git a/jambotron-ui/src/app/components/login/login.component.scss b/jambotron-ui/src/app/components/login/login.component.scss deleted file mode 100644 index 8b13789..0000000 --- a/jambotron-ui/src/app/components/login/login.component.scss +++ /dev/null @@ -1 +0,0 @@ - diff --git a/jambotron-ui/src/app/components/login/login.component.ts b/jambotron-ui/src/app/components/login/login.component.ts deleted file mode 100644 index b9518e7..0000000 --- a/jambotron-ui/src/app/components/login/login.component.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import {FormsModule} from "@angular/forms"; -import {NgIf} from "@angular/common"; -import {AuthService} from '../../services/auth.service'; -import {TokenStorageService} from '../../services/token-storage.service'; - -@Component({ - selector: 'app-login', - templateUrl: './login.component.html', - imports: [ - FormsModule, - NgIf - ], - styleUrls: ['./login.component.scss'] -}) -export class LoginComponent implements OnInit { - - form: any = { - username: null, - password: null - }; - isLoggedIn = false; - isLoginFailed = false; - errorMessage = ''; - roles: string[] = []; - - constructor(private authService: AuthService, private tokenStorage: TokenStorageService) { } - - ngOnInit(): void { - if (this.tokenStorage.getToken()) { - this.isLoggedIn = true; - this.roles = this.tokenStorage.getUser().roles; - } - } - - onSubmit(): void { - const { username, password } = this.form; - - this.authService.login(username, password).subscribe( - data => { - this.tokenStorage.saveToken(data.accessToken); - this.tokenStorage.saveUser(data); - - this.isLoginFailed = false; - this.isLoggedIn = true; - this.roles = this.tokenStorage.getUser().roles; - this.reloadPage(); - }, - err => { - this.errorMessage = err.error.message; - this.isLoginFailed = true; - } - ); - } - - reloadPage(): void { - window.location.reload(); - } -} diff --git a/jambotron-ui/src/app/components/profile/profile.component.html b/jambotron-ui/src/app/components/profile/profile.component.html deleted file mode 100644 index d6c4144..0000000 --- a/jambotron-ui/src/app/components/profile/profile.component.html +++ /dev/null @@ -1,26 +0,0 @@ -
-
-

- {{ currentUser.username }} Profile -

-
-

- Token: - {{ currentUser.accessToken.substring(0, 20) }} ... - {{ currentUser.accessToken.substr(currentUser.accessToken.length - 20) }} -

-

- Email: - {{ currentUser.email }} -

- Roles: -
    -
  • - {{ role }} -
  • -
-
- - - Please login. - \ No newline at end of file diff --git a/jambotron-ui/src/app/components/profile/profile.component.ts b/jambotron-ui/src/app/components/profile/profile.component.ts deleted file mode 100644 index 8cad428..0000000 --- a/jambotron-ui/src/app/components/profile/profile.component.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import {TokenStorageService} from '../../services/token-storage.service'; -import {NgForOf, NgIf} from '@angular/common'; - - -@Component({ - selector: 'app-profile', - templateUrl: './profile.component.html', - imports: [ - NgForOf, - NgIf - ], - styleUrls: ['./profile.component.scss'] -}) -export class ProfileComponent implements OnInit { - currentUser: any; - - constructor(private token: TokenStorageService) { } - - ngOnInit(): void { - this.currentUser = this.token.getUser(); - } -} diff --git a/jambotron-ui/src/app/components/register/register.component.html b/jambotron-ui/src/app/components/register/register.component.html deleted file mode 100644 index 59c36ee..0000000 --- a/jambotron-ui/src/app/components/register/register.component.html +++ /dev/null @@ -1,89 +0,0 @@ -
-
- -
-
- - -
-
Username is required
-
- Username must be at least 3 characters -
-
- Username must be at most 20 characters -
-
-
-
- - -
-
Email is required
-
- Email must be a valid email address -
-
-
-
- - -
-
Password is required
-
- Password must be at least 6 characters -
-
-
-
- -
- -
- Signup failed!
{{ errorMessage }} -
-
- -
- Your registration is successful! -
-
-
diff --git a/jambotron-ui/src/app/components/register/register.component.scss b/jambotron-ui/src/app/components/register/register.component.scss deleted file mode 100644 index 8b13789..0000000 --- a/jambotron-ui/src/app/components/register/register.component.scss +++ /dev/null @@ -1 +0,0 @@ - diff --git a/jambotron-ui/src/app/components/register/register.component.spec.ts b/jambotron-ui/src/app/components/register/register.component.spec.ts deleted file mode 100644 index f6db869..0000000 --- a/jambotron-ui/src/app/components/register/register.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { RegisterComponent } from './register.component'; - -describe('RegisterComponent', () => { - let component: RegisterComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ RegisterComponent ] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(RegisterComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/jambotron-ui/src/app/components/register/register.component.ts b/jambotron-ui/src/app/components/register/register.component.ts deleted file mode 100644 index 65d3c7e..0000000 --- a/jambotron-ui/src/app/components/register/register.component.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import {AuthService} from '../../services/auth.service'; -import {FormsModule} from '@angular/forms'; -import {NgIf} from '@angular/common'; - - -@Component({ - selector: 'app-register', - templateUrl: './register.component.html', - imports: [ - FormsModule, - NgIf - ], - styleUrls: ['./register.component.scss'] -}) -export class RegisterComponent implements OnInit { - form: any = { - username: null, - email: null, - password: null - }; - isSuccessful = false; - isSignUpFailed = false; - errorMessage = ''; - - constructor(private authService: AuthService) { } - - ngOnInit(): void { - } - - onSubmit(): void { - const { username, email, password } = this.form; - - this.authService.register(username, email, password).subscribe( - data => { - console.log(data); - this.isSuccessful = true; - this.isSignUpFailed = false; - }, - err => { - this.errorMessage = err.error.message; - this.isSignUpFailed = true; - } - ); - } -} diff --git a/jambotron-ui/src/app/components/tutorials.component/tutorials.component.ts b/jambotron-ui/src/app/components/tutorials.component/tutorials.component.ts index d539f0d..34ad1a1 100644 --- a/jambotron-ui/src/app/components/tutorials.component/tutorials.component.ts +++ b/jambotron-ui/src/app/components/tutorials.component/tutorials.component.ts @@ -1,6 +1,6 @@ import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'; import {Tutorial} from '../../models/tutorial.model'; -import {TutorialService} from '../../services/tutorial.service'; + import {MatCard, MatCardContent, MatCardHeader} from '@angular/material/card'; import {MarkdownComponent} from 'ngx-markdown'; import {authInterceptorProviders} from '../../helpers/auth.interceptor'; @@ -26,9 +26,9 @@ import {CustomHttpInterceptor} from '../../helpers/custom-http-interceptor'; }) export class TutorialsComponent { tutorials?: Tutorial[]; - +/* constructor(private tutorialService: TutorialService) { - this.retrieveTutorials(); + // this.retrieveTutorials(); } // ngOnInit(): void { @@ -45,5 +45,5 @@ export class TutorialsComponent { console.log(error); } ); - } + }*/ } diff --git a/jambotron-ui/src/app/directives/column-resize.directive.spec.ts b/jambotron-ui/src/app/directives/column-resize.directive.spec.ts deleted file mode 100644 index 181e843..0000000 --- a/jambotron-ui/src/app/directives/column-resize.directive.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ColumnResizeDirective } from './column-resize.directive'; - -describe('ColumnResizeDirective', () => { - it('should create an instance', () => { - const directive = new ColumnResizeDirective(); - expect(directive).toBeTruthy(); - }); -}); diff --git a/jambotron-ui/src/app/directives/column-resize.directive.ts b/jambotron-ui/src/app/directives/column-resize.directive.ts deleted file mode 100644 index c842abf..0000000 --- a/jambotron-ui/src/app/directives/column-resize.directive.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { - Directive, - ElementRef, - OnDestroy, - OnInit, - Renderer2, - NgZone, - Input, -} from '@angular/core'; -import { Subject, fromEvent, takeUntil } from 'rxjs'; - -@Directive({ - selector: '[appColumnResize]', -}) -export class ColumnResizeDirective implements OnInit, OnDestroy { - @Input() resizableTable: HTMLElement | null = null; - - private isResizing = false; - private startX!: number; - private startWidth!: number; - private column: HTMLElement; - private table: HTMLElement | null = null; - private resizer!: HTMLElement; - private destroy$ = new Subject(); - - constructor( - private el: ElementRef, - private renderer: Renderer2, - private zone: NgZone - ) { - this.column = this.el.nativeElement; - } - - ngOnInit() { - this.table = this.resizableTable || this.findParentTable(this.column); - - if (!this.table) { - console.error( - 'Parent table not found. Make sure the directive is applied to a th element within a table.' - ); - return; - } - - this.createResizer(); - this.initializeResizeListener(); - } - - private createResizer() { - this.resizer = this.renderer.createElement('div'); - this.renderer.addClass(this.resizer, 'column-resizer'); - this.renderer.setStyle(this.resizer, 'position', 'absolute'); - this.renderer.setStyle(this.resizer, 'right', '0'); - this.renderer.setStyle(this.resizer, 'top', '0'); - this.renderer.setStyle(this.resizer, 'height', '100%'); - this.renderer.setStyle(this.resizer, 'width', '5px'); - this.renderer.setStyle(this.resizer, 'cursor', 'col-resize'); - this.renderer.appendChild(this.column, this.resizer); - } - - private initializeResizeListener() { - this.zone.runOutsideAngular(() => { - fromEvent(this.resizer, 'mousedown') - .pipe(takeUntil(this.destroy$)) - .subscribe((e: Event) => this.onMouseDown(e as MouseEvent)); - - fromEvent(document, 'mousemove') - .pipe(takeUntil(this.destroy$)) - .subscribe((e: Event) => this.onMouseMove(e as MouseEvent)); - - fromEvent(document, 'mouseup') - .pipe(takeUntil(this.destroy$)) - .subscribe(() => this.onMouseUp()); - }); - } - - private onMouseDown(e: MouseEvent) { - e.preventDefault(); - this.isResizing = true; - this.startX = e.pageX; - this.startWidth = this.column.offsetWidth; - this.renderer.addClass(this.column, 'resizing'); - if (this.table) { - this.renderer.addClass(this.table, 'resizing'); - } - } - - private onMouseMove(e: MouseEvent) { - if (!this.isResizing) return; - const width = this.startWidth + (e.pageX - this.startX); - this.renderer.setStyle(this.column, 'width', `${width}px`); - } - - private onMouseUp() { - if (!this.isResizing) return; - this.isResizing = false; - this.renderer.removeClass(this.column, 'resizing'); - if (this.table) { - this.renderer.removeClass(this.table, 'resizing'); - } - } - - private findParentTable(element: HTMLElement): HTMLElement | null { - while (element && element.tagName !== 'TABLE') { - element = element.parentElement as HTMLElement; - if (!element) return null; - } - return element; - } - - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - } -} diff --git a/jambotron-ui/src/app/global-constants.ts b/jambotron-ui/src/app/global-constants.ts index b5bd4e4..22b2bd4 100644 --- a/jambotron-ui/src/app/global-constants.ts +++ b/jambotron-ui/src/app/global-constants.ts @@ -2,6 +2,14 @@ import {environment} from '../environments/environment'; export class GlobalConstants { + public static readonly TITLE = (() => { + return environment.title; + })(); + + public static readonly DEFAULT_PAGE = (() => { + return environment.default_page; + })(); + public static readonly API_URL = (() => { // ... calculate the value and return it diff --git a/jambotron-ui/src/app/models/file-info.spec.ts b/jambotron-ui/src/app/models/file-info.spec.ts new file mode 100644 index 0000000..0a4e521 --- /dev/null +++ b/jambotron-ui/src/app/models/file-info.spec.ts @@ -0,0 +1,7 @@ +import { FileInfo } from './file-info'; + +describe('FileInfo', () => { + it('should create an instance', () => { + expect(new FileInfo()).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/models/file-info.ts b/jambotron-ui/src/app/models/file-info.ts new file mode 100644 index 0000000..fc55c33 --- /dev/null +++ b/jambotron-ui/src/app/models/file-info.ts @@ -0,0 +1,4 @@ +export class FileInfo { + name: string | undefined; + url: string | undefined; +} diff --git a/jambotron-ui/src/app/models/image.ts b/jambotron-ui/src/app/models/image.ts index cf7f79b..fc813b8 100644 --- a/jambotron-ui/src/app/models/image.ts +++ b/jambotron-ui/src/app/models/image.ts @@ -1,5 +1,5 @@ export class Image { url?:string; - b64Json?:boolean; + b64string?:string; } diff --git a/jambotron-ui/src/app/models/tutorial.model.ts b/jambotron-ui/src/app/models/tutorial.model.ts index 3596a56..e41afe1 100644 --- a/jambotron-ui/src/app/models/tutorial.model.ts +++ b/jambotron-ui/src/app/models/tutorial.model.ts @@ -8,6 +8,8 @@ export class Tutorial { modified?: Date; tobepublished?: boolean; isEdit?: boolean; + titleimage?: string; + body?: string; } diff --git a/jambotron-ui/src/app/admin-module/admin-module.service.spec.ts b/jambotron-ui/src/app/modules/admin-module/admin-module.service.spec.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/admin-module.service.spec.ts rename to jambotron-ui/src/app/modules/admin-module/admin-module.service.spec.ts diff --git a/jambotron-ui/src/app/admin-module/admin-module.service.ts b/jambotron-ui/src/app/modules/admin-module/admin-module.service.ts similarity index 80% rename from jambotron-ui/src/app/admin-module/admin-module.service.ts rename to jambotron-ui/src/app/modules/admin-module/admin-module.service.ts index 3776756..ee2b26b 100644 --- a/jambotron-ui/src/app/admin-module/admin-module.service.ts +++ b/jambotron-ui/src/app/modules/admin-module/admin-module.service.ts @@ -1,8 +1,8 @@ import { Injectable } from '@angular/core'; import {Observable} from 'rxjs'; import {HttpClient} from '@angular/common/http'; -import {User} from '../models/user.model'; -import {GlobalConstants} from '../global-constants'; +import {User} from '../../models/user.model'; +import {GlobalConstants} from '../../global-constants'; @Injectable({ providedIn: 'root' diff --git a/jambotron-ui/src/app/admin-module/admin-welcome.component/admin-welcome.component.html b/jambotron-ui/src/app/modules/admin-module/admin-welcome.component/admin-welcome.component.html similarity index 100% rename from jambotron-ui/src/app/admin-module/admin-welcome.component/admin-welcome.component.html rename to jambotron-ui/src/app/modules/admin-module/admin-welcome.component/admin-welcome.component.html diff --git a/jambotron-ui/src/app/admin-module/admin-welcome.component/admin-welcome.component.scss b/jambotron-ui/src/app/modules/admin-module/admin-welcome.component/admin-welcome.component.scss similarity index 100% rename from jambotron-ui/src/app/admin-module/admin-welcome.component/admin-welcome.component.scss rename to jambotron-ui/src/app/modules/admin-module/admin-welcome.component/admin-welcome.component.scss diff --git a/jambotron-ui/src/app/admin-module/admin-welcome.component/admin-welcome.component.spec.ts b/jambotron-ui/src/app/modules/admin-module/admin-welcome.component/admin-welcome.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/admin-welcome.component/admin-welcome.component.spec.ts rename to jambotron-ui/src/app/modules/admin-module/admin-welcome.component/admin-welcome.component.spec.ts diff --git a/jambotron-ui/src/app/admin-module/admin-welcome.component/admin-welcome.component.ts b/jambotron-ui/src/app/modules/admin-module/admin-welcome.component/admin-welcome.component.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/admin-welcome.component/admin-welcome.component.ts rename to jambotron-ui/src/app/modules/admin-module/admin-welcome.component/admin-welcome.component.ts diff --git a/jambotron-ui/src/app/admin-module/admin.component/admin.component.html b/jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.html similarity index 100% rename from jambotron-ui/src/app/admin-module/admin.component/admin.component.html rename to jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.html diff --git a/jambotron-ui/src/app/admin-module/admin.component/admin.component.scss b/jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.scss similarity index 100% rename from jambotron-ui/src/app/admin-module/admin.component/admin.component.scss rename to jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.scss diff --git a/jambotron-ui/src/app/admin-module/admin.component/admin.component.spec.ts b/jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/admin.component/admin.component.spec.ts rename to jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.spec.ts diff --git a/jambotron-ui/src/app/admin-module/admin.component/admin.component.ts b/jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/admin.component/admin.component.ts rename to jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.ts diff --git a/jambotron-ui/src/app/admin-module/admin.module.ts b/jambotron-ui/src/app/modules/admin-module/admin.module.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/admin.module.ts rename to jambotron-ui/src/app/modules/admin-module/admin.module.ts diff --git a/jambotron-ui/src/app/admin-module/admin.routing.ts b/jambotron-ui/src/app/modules/admin-module/admin.routing.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/admin.routing.ts rename to jambotron-ui/src/app/modules/admin-module/admin.routing.ts diff --git a/jambotron-ui/src/app/admin-module/settings.component/settings.component.html b/jambotron-ui/src/app/modules/admin-module/settings.component/settings.component.html similarity index 100% rename from jambotron-ui/src/app/admin-module/settings.component/settings.component.html rename to jambotron-ui/src/app/modules/admin-module/settings.component/settings.component.html diff --git a/jambotron-ui/src/app/admin-module/settings.component/settings.component.scss b/jambotron-ui/src/app/modules/admin-module/settings.component/settings.component.scss similarity index 100% rename from jambotron-ui/src/app/admin-module/settings.component/settings.component.scss rename to jambotron-ui/src/app/modules/admin-module/settings.component/settings.component.scss diff --git a/jambotron-ui/src/app/admin-module/settings.component/settings.component.spec.ts b/jambotron-ui/src/app/modules/admin-module/settings.component/settings.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/settings.component/settings.component.spec.ts rename to jambotron-ui/src/app/modules/admin-module/settings.component/settings.component.spec.ts diff --git a/jambotron-ui/src/app/admin-module/settings.component/settings.component.ts b/jambotron-ui/src/app/modules/admin-module/settings.component/settings.component.ts similarity index 82% rename from jambotron-ui/src/app/admin-module/settings.component/settings.component.ts rename to jambotron-ui/src/app/modules/admin-module/settings.component/settings.component.ts index 1209c58..b728cab 100644 --- a/jambotron-ui/src/app/admin-module/settings.component/settings.component.ts +++ b/jambotron-ui/src/app/modules/admin-module/settings.component/settings.component.ts @@ -11,11 +11,8 @@ import { MatHeaderRowDef, MatRow, MatRowDef, MatTable } from '@angular/material/table'; -import {MatIconButton} from '@angular/material/button'; -import {MatList, MatListItem} from '@angular/material/list'; -import {Bean} from '../../models/Bean'; -import {SystemService} from '../../services/system.service'; -import {NameValueItem} from '../../models/name-value-item'; +import {SystemService} from '../../../services/system.service'; +import {NameValueItem} from '../../../models/name-value-item'; @Component({ selector: 'app-settings.component', diff --git a/jambotron-ui/src/app/admin-module/side-bar-admin.component/side-bar-admin.component.html b/jambotron-ui/src/app/modules/admin-module/side-bar-admin.component/side-bar-admin.component.html similarity index 100% rename from jambotron-ui/src/app/admin-module/side-bar-admin.component/side-bar-admin.component.html rename to jambotron-ui/src/app/modules/admin-module/side-bar-admin.component/side-bar-admin.component.html diff --git a/jambotron-ui/src/app/admin-module/side-bar-admin.component/side-bar-admin.component.scss b/jambotron-ui/src/app/modules/admin-module/side-bar-admin.component/side-bar-admin.component.scss similarity index 100% rename from jambotron-ui/src/app/admin-module/side-bar-admin.component/side-bar-admin.component.scss rename to jambotron-ui/src/app/modules/admin-module/side-bar-admin.component/side-bar-admin.component.scss diff --git a/jambotron-ui/src/app/admin-module/side-bar-admin.component/side-bar-admin.component.spec.ts b/jambotron-ui/src/app/modules/admin-module/side-bar-admin.component/side-bar-admin.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/side-bar-admin.component/side-bar-admin.component.spec.ts rename to jambotron-ui/src/app/modules/admin-module/side-bar-admin.component/side-bar-admin.component.spec.ts diff --git a/jambotron-ui/src/app/admin-module/side-bar-admin.component/side-bar-admin.component.ts b/jambotron-ui/src/app/modules/admin-module/side-bar-admin.component/side-bar-admin.component.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/side-bar-admin.component/side-bar-admin.component.ts rename to jambotron-ui/src/app/modules/admin-module/side-bar-admin.component/side-bar-admin.component.ts diff --git a/jambotron-ui/src/app/admin-module/system.component/system.component.html b/jambotron-ui/src/app/modules/admin-module/system.component/system.component.html similarity index 100% rename from jambotron-ui/src/app/admin-module/system.component/system.component.html rename to jambotron-ui/src/app/modules/admin-module/system.component/system.component.html diff --git a/jambotron-ui/src/app/admin-module/system.component/system.component.scss b/jambotron-ui/src/app/modules/admin-module/system.component/system.component.scss similarity index 100% rename from jambotron-ui/src/app/admin-module/system.component/system.component.scss rename to jambotron-ui/src/app/modules/admin-module/system.component/system.component.scss diff --git a/jambotron-ui/src/app/admin-module/system.component/system.component.spec.ts b/jambotron-ui/src/app/modules/admin-module/system.component/system.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/system.component/system.component.spec.ts rename to jambotron-ui/src/app/modules/admin-module/system.component/system.component.spec.ts diff --git a/jambotron-ui/src/app/admin-module/system.component/system.component.ts b/jambotron-ui/src/app/modules/admin-module/system.component/system.component.ts similarity index 97% rename from jambotron-ui/src/app/admin-module/system.component/system.component.ts rename to jambotron-ui/src/app/modules/admin-module/system.component/system.component.ts index 2f07b2c..22b2009 100644 --- a/jambotron-ui/src/app/admin-module/system.component/system.component.ts +++ b/jambotron-ui/src/app/modules/admin-module/system.component/system.component.ts @@ -14,8 +14,8 @@ import { } from '@angular/material/table'; import {MatList, MatListItem} from '@angular/material/list'; import {MatIconButton} from '@angular/material/button'; -import {SystemService} from '../../services/system.service'; -import {Bean} from '../../models/Bean'; +import {SystemService} from '../../../services/system.service'; +import {Bean} from '../../../models/Bean'; import {MatIcon} from '@angular/material/icon'; @Component({ diff --git a/jambotron-ui/src/app/admin-module/users.component/users.component.html b/jambotron-ui/src/app/modules/admin-module/users.component/users.component.html similarity index 100% rename from jambotron-ui/src/app/admin-module/users.component/users.component.html rename to jambotron-ui/src/app/modules/admin-module/users.component/users.component.html diff --git a/jambotron-ui/src/app/admin-module/users.component/users.component.scss b/jambotron-ui/src/app/modules/admin-module/users.component/users.component.scss similarity index 100% rename from jambotron-ui/src/app/admin-module/users.component/users.component.scss rename to jambotron-ui/src/app/modules/admin-module/users.component/users.component.scss diff --git a/jambotron-ui/src/app/admin-module/users.component/users.component.spec.ts b/jambotron-ui/src/app/modules/admin-module/users.component/users.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/admin-module/users.component/users.component.spec.ts rename to jambotron-ui/src/app/modules/admin-module/users.component/users.component.spec.ts diff --git a/jambotron-ui/src/app/admin-module/users.component/users.component.ts b/jambotron-ui/src/app/modules/admin-module/users.component/users.component.ts similarity index 95% rename from jambotron-ui/src/app/admin-module/users.component/users.component.ts rename to jambotron-ui/src/app/modules/admin-module/users.component/users.component.ts index 1a72747..8725efb 100644 --- a/jambotron-ui/src/app/admin-module/users.component/users.component.ts +++ b/jambotron-ui/src/app/modules/admin-module/users.component/users.component.ts @@ -1,8 +1,8 @@ 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'; -import {User} from '../../models/user.model'; +import {UserService} from '../../../services/user.service'; +import {RolesService} from '../../../services/roles.service'; +import {Role} from '../../../models/role'; +import {User} from '../../../models/user.model'; import { MatCell, MatCellDef, MatColumnDef, diff --git a/jambotron-ui/src/app/modules/ai-module/ai-main.component/ai-main.component.html b/jambotron-ui/src/app/modules/ai-module/ai-main.component/ai-main.component.html new file mode 100644 index 0000000..0680b43 --- /dev/null +++ b/jambotron-ui/src/app/modules/ai-module/ai-main.component/ai-main.component.html @@ -0,0 +1 @@ + diff --git a/jambotron-ui/src/app/components/home.component/home.component.scss b/jambotron-ui/src/app/modules/ai-module/ai-main.component/ai-main.component.scss similarity index 100% rename from jambotron-ui/src/app/components/home.component/home.component.scss rename to jambotron-ui/src/app/modules/ai-module/ai-main.component/ai-main.component.scss diff --git a/jambotron-ui/src/app/components/home.component/home.component.spec.ts b/jambotron-ui/src/app/modules/ai-module/ai-main.component/ai-main.component.spec.ts similarity index 55% rename from jambotron-ui/src/app/components/home.component/home.component.spec.ts rename to jambotron-ui/src/app/modules/ai-module/ai-main.component/ai-main.component.spec.ts index 1191557..8757d60 100644 --- a/jambotron-ui/src/app/components/home.component/home.component.spec.ts +++ b/jambotron-ui/src/app/modules/ai-module/ai-main.component/ai-main.component.spec.ts @@ -1,18 +1,18 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { HomeComponent } from './home.component'; +import { AiMainComponent } from './ai-main.component'; -describe('HomeComponent', () => { - let component: HomeComponent; - let fixture: ComponentFixture; +describe('AiMainComponent', () => { + let component: AiMainComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [HomeComponent] + imports: [AiMainComponent] }) .compileComponents(); - fixture = TestBed.createComponent(HomeComponent); + fixture = TestBed.createComponent(AiMainComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/jambotron-ui/src/app/modules/ai-module/ai-main.component/ai-main.component.ts b/jambotron-ui/src/app/modules/ai-module/ai-main.component/ai-main.component.ts new file mode 100644 index 0000000..7e7559a --- /dev/null +++ b/jambotron-ui/src/app/modules/ai-module/ai-main.component/ai-main.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import {RouterOutlet} from '@angular/router'; + +@Component({ + selector: 'app-ai-main.component', + imports: [ + RouterOutlet + ], + templateUrl: './ai-main.component.html', + styleUrl: './ai-main.component.scss' +}) +export class AiMainComponent { + +} diff --git a/jambotron-ui/src/app/modules/ai-module/ai-welcome.component/ai-welcome.component.html b/jambotron-ui/src/app/modules/ai-module/ai-welcome.component/ai-welcome.component.html new file mode 100644 index 0000000..2eb2466 --- /dev/null +++ b/jambotron-ui/src/app/modules/ai-module/ai-welcome.component/ai-welcome.component.html @@ -0,0 +1 @@ +

ai-welcome.component works!

diff --git a/jambotron-ui/src/app/components/profile/profile.component.scss b/jambotron-ui/src/app/modules/ai-module/ai-welcome.component/ai-welcome.component.scss similarity index 100% rename from jambotron-ui/src/app/components/profile/profile.component.scss rename to jambotron-ui/src/app/modules/ai-module/ai-welcome.component/ai-welcome.component.scss diff --git a/jambotron-ui/src/app/components/login/login.component.spec.ts b/jambotron-ui/src/app/modules/ai-module/ai-welcome.component/ai-welcome.component.spec.ts similarity index 53% rename from jambotron-ui/src/app/components/login/login.component.spec.ts rename to jambotron-ui/src/app/modules/ai-module/ai-welcome.component/ai-welcome.component.spec.ts index d2c0e6c..b90e25f 100644 --- a/jambotron-ui/src/app/components/login/login.component.spec.ts +++ b/jambotron-ui/src/app/modules/ai-module/ai-welcome.component/ai-welcome.component.spec.ts @@ -1,20 +1,18 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { LoginComponent } from './login.component'; +import { AiWelcomeComponent } from './ai-welcome.component'; -describe('LoginComponent', () => { - let component: LoginComponent; - let fixture: ComponentFixture; +describe('AiWelcomeComponent', () => { + let component: AiWelcomeComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ LoginComponent ] + imports: [AiWelcomeComponent] }) .compileComponents(); - }); - beforeEach(() => { - fixture = TestBed.createComponent(LoginComponent); + fixture = TestBed.createComponent(AiWelcomeComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/jambotron-ui/src/app/modules/ai-module/ai-welcome.component/ai-welcome.component.ts b/jambotron-ui/src/app/modules/ai-module/ai-welcome.component/ai-welcome.component.ts new file mode 100644 index 0000000..f152488 --- /dev/null +++ b/jambotron-ui/src/app/modules/ai-module/ai-welcome.component/ai-welcome.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-ai-welcome.component', + imports: [], + templateUrl: './ai-welcome.component.html', + styleUrl: './ai-welcome.component.scss' +}) +export class AiWelcomeComponent { + +} diff --git a/jambotron-ui/src/app/modules/ai-module/ai.module.ts b/jambotron-ui/src/app/modules/ai-module/ai.module.ts new file mode 100644 index 0000000..a72727b --- /dev/null +++ b/jambotron-ui/src/app/modules/ai-module/ai.module.ts @@ -0,0 +1,21 @@ +import {NgModule} from '@angular/core'; +import {moderatorRouting} from '../moderator-module/moderator.routing'; +import {ModeratorComponent} from '../moderator-module/moderator.component/moderator.component'; +import {CommonModule} from '@angular/common'; +import {AiWelcomeComponent} from './ai-welcome.component/ai-welcome.component'; +import {AiMainComponent} from './ai-main.component/ai-main.component'; +import {aiRouting} from './ai.routing'; + +import {MatDialogModule} from "@angular/material/dialog"; + +@NgModule({ + declarations: [], + imports: [ + aiRouting, + AiMainComponent, + CommonModule, + + MatDialogModule + ] +}) +export class AiModule { } diff --git a/jambotron-ui/src/app/modules/ai-module/ai.routing.ts b/jambotron-ui/src/app/modules/ai-module/ai.routing.ts new file mode 100644 index 0000000..44ee87b --- /dev/null +++ b/jambotron-ui/src/app/modules/ai-module/ai.routing.ts @@ -0,0 +1,22 @@ +import {RouterModule, Routes} from '@angular/router'; +import {AiMainComponent} from './ai-main.component/ai-main.component'; + +const AI_ROUTES: Routes = [ + { + path: '', + component: AiMainComponent, + + children: [ + { + path: 'ai-welcome', + loadComponent: () => import('../ai-module/ai-welcome.component/ai-welcome.component').then((c) => c.AiWelcomeComponent), + }, + { + path: 'generate-image', + loadComponent: () => import('../ai-module/generate-image.component/generate-image.component').then((c) => c.GenerateImageComponent) + } + ] + } +]; + +export const aiRouting = RouterModule.forChild(AI_ROUTES); diff --git a/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.html b/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.html new file mode 100644 index 0000000..1fc5881 --- /dev/null +++ b/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.html @@ -0,0 +1,49 @@ +
+ + + Generate image + + + + Query + + + + + + @if (spinnerService.visibility | async) { + + } @else { + + } + + + +@for (image of images; track image) { + + +
+ + + + + + @if (isLoggedIn) { + + } + + +
+
+ + +
+} +
+ diff --git a/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.scss b/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.scss new file mode 100644 index 0000000..6004a05 --- /dev/null +++ b/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.scss @@ -0,0 +1,42 @@ +.generate-image-view { + margin-right: 12px; + padding: 20px 22px 18px 22px; + margin-top: 81px; + margin-left: 12px; + background-color: #e7edf3c2; + backdrop-filter: blur(8px); +} + +.image-container{ + width: 100%; + height: 100%; + +} +.image-container .image-toolbar +{ + background-color: rgba(153,153,153,0); + + color: white; + position: absolute; + left : 50%; + top: 5%; + transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + padding: 0px 2px; + border: none; + border-radius: 5px; +} +.image-container .menu-spacer { + flex: 1 1 auto; +} + +.image-container .image-file-name { + padding-left: 10px; +} + +.mat-mdc-mini-fab{ + margin: 5px; +} +.example-full-width { + width: 100%; +} diff --git a/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.spec.ts b/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.spec.ts new file mode 100644 index 0000000..255f5e0 --- /dev/null +++ b/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GenerateImageComponent } from './generate-image.component'; + +describe('GenerateImageComponent', () => { + let component: GenerateImageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [GenerateImageComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(GenerateImageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.ts b/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.ts new file mode 100644 index 0000000..00b772c --- /dev/null +++ b/jambotron-ui/src/app/modules/ai-module/generate-image.component/generate-image.component.ts @@ -0,0 +1,126 @@ +import {Component, CUSTOM_ELEMENTS_SCHEMA, Inject, inject, Renderer2} from '@angular/core'; +import {AsyncPipe, DOCUMENT, NgOptimizedImage} from "@angular/common"; +import {FormsModule} from "@angular/forms"; +import {MatButton, MatMiniFabButton} from "@angular/material/button"; +import { + MatCard, + MatCardActions, + MatCardContent, + MatCardHeader, + MatCardImage, + MatCardXlImage +} from "@angular/material/card"; +import {MatFormField, MatInput, MatLabel} from "@angular/material/input"; +import {Image} from '../../../models/image'; +import {ZhipuaiImageService} from '../zhipuai-image.service'; +import {SpinnerService} from '../../../services/spinner.service'; +import {MatProgressSpinner} from '@angular/material/progress-spinner'; + +import {FileUploadService} from '../../../services/file-upload-api.service'; +import {Observable, Subscription} from 'rxjs'; +import {HttpClient, HttpResponse} from '@angular/common/http'; +import {MatToolbar, MatToolbarRow} from '@angular/material/toolbar'; +import {MatIcon} from '@angular/material/icon'; +import {MatTooltip} from '@angular/material/tooltip'; +import {AuthService} from '../../../services/auth.service'; +import {TokenStorageService} from '../../../services/token-storage.service'; +import {FileInfo} from '../../../models/file-info'; +import {UserApiService} from '../../user-module/user-api.service'; +import {MatProgressBar} from '@angular/material/progress-bar'; + + +@Component({ + selector: 'app-generate-image.component', + imports: [ + AsyncPipe, + FormsModule, + MatButton, + MatCard, + MatCardActions, + MatCardContent, + MatCardHeader, + MatFormField, + MatInput, + MatLabel, + MatProgressSpinner, + NgOptimizedImage, + MatCardXlImage, + MatCardImage, + MatToolbarRow, + MatToolbar, + MatIcon, + MatMiniFabButton, + MatTooltip, + MatProgressBar + + + ], + templateUrl: './generate-image.component.html', + styleUrl: './generate-image.component.scss', + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) +export class GenerateImageComponent { + + isSpinnerVisible = false; + + query : string = ''; + + images: Image[] = []; + image: Image = { + url: '' + }; + + currentFile?: File; + message = ''; + + + isLoggedIn = false; + + private storageService: TokenStorageService = inject(TokenStorageService); + + constructor( + private zhipuaiImageService: ZhipuaiImageService, + public spinnerService: SpinnerService, + private uploadService: FileUploadService, + private userApiService:UserApiService, + + + ) { + + + this.isLoggedIn = this.storageService.isLoggedIn(); + } + + generateImage(){ + this.zhipuaiImageService.generate(this.query).subscribe( + data => { + + this.image = data; + + this.images.unshift(this.image); + + // this.output.file = data.; + console.log(data); + }, + error => { + console.log(error); + } + ) + } + + + save(url: string | undefined) { + let requestUrl:string = url?url:""; + console.log(requestUrl); + this.userApiService.saveZhipuaiImage(requestUrl).subscribe(data =>{ + console.log(data); + },error =>{ + console.log(error); + }); + } + + + +} + + diff --git a/jambotron-ui/src/app/services/zhipuai-image.service.spec.ts b/jambotron-ui/src/app/modules/ai-module/zhipuai-image.service.spec.ts similarity index 100% rename from jambotron-ui/src/app/services/zhipuai-image.service.spec.ts rename to jambotron-ui/src/app/modules/ai-module/zhipuai-image.service.spec.ts diff --git a/jambotron-ui/src/app/services/zhipuai-image.service.ts b/jambotron-ui/src/app/modules/ai-module/zhipuai-image.service.ts similarity index 68% rename from jambotron-ui/src/app/services/zhipuai-image.service.ts rename to jambotron-ui/src/app/modules/ai-module/zhipuai-image.service.ts index 6dc015c..7bf9cff 100644 --- a/jambotron-ui/src/app/services/zhipuai-image.service.ts +++ b/jambotron-ui/src/app/modules/ai-module/zhipuai-image.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core'; import {Observable} from 'rxjs'; -import {Tutorial} from '../models/tutorial.model'; +import {Tutorial} from '../../models/tutorial.model'; import {HttpClient} from '@angular/common/http'; -import {Image} from '../models/image'; -import {SpinnerService} from './spinner.service'; -import {GlobalConstants} from '../global-constants'; +import {Image} from '../../models/image'; +import {SpinnerService} from '../../services/spinner.service'; +import {GlobalConstants} from '../../global-constants'; diff --git a/jambotron-ui/src/app/components/dialog/dialog.component.html b/jambotron-ui/src/app/modules/main-module/main.component/dialog-login.component/dialog-login.component.html similarity index 100% rename from jambotron-ui/src/app/components/dialog/dialog.component.html rename to jambotron-ui/src/app/modules/main-module/main.component/dialog-login.component/dialog-login.component.html diff --git a/jambotron-ui/src/app/components/dialog-signup.component/dialog-signup.component.scss b/jambotron-ui/src/app/modules/main-module/main.component/dialog-login.component/dialog-login.component.scss similarity index 100% rename from jambotron-ui/src/app/components/dialog-signup.component/dialog-signup.component.scss rename to jambotron-ui/src/app/modules/main-module/main.component/dialog-login.component/dialog-login.component.scss diff --git a/jambotron-ui/src/app/components/profile/profile.component.spec.ts b/jambotron-ui/src/app/modules/main-module/main.component/dialog-login.component/dialog-login.component.spec.ts similarity index 51% rename from jambotron-ui/src/app/components/profile/profile.component.spec.ts rename to jambotron-ui/src/app/modules/main-module/main.component/dialog-login.component/dialog-login.component.spec.ts index e88012e..af9ec3b 100644 --- a/jambotron-ui/src/app/components/profile/profile.component.spec.ts +++ b/jambotron-ui/src/app/modules/main-module/main.component/dialog-login.component/dialog-login.component.spec.ts @@ -1,20 +1,18 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ProfileComponent } from './profile.component'; +import { DialogLoginComponent } from './dialog-login.component'; -describe('ProfileComponent', () => { - let component: ProfileComponent; - let fixture: ComponentFixture; +describe('DialogLoginComponent', () => { + let component: DialogLoginComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ ProfileComponent ] + imports: [DialogLoginComponent] }) .compileComponents(); - }); - beforeEach(() => { - fixture = TestBed.createComponent(ProfileComponent); + fixture = TestBed.createComponent(DialogLoginComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/jambotron-ui/src/app/modules/main-module/main.component/dialog-login.component/dialog-login.component.ts b/jambotron-ui/src/app/modules/main-module/main.component/dialog-login.component/dialog-login.component.ts new file mode 100644 index 0000000..229151c --- /dev/null +++ b/jambotron-ui/src/app/modules/main-module/main.component/dialog-login.component/dialog-login.component.ts @@ -0,0 +1,86 @@ +import { + ChangeDetectionStrategy, + Component, + CUSTOM_ELEMENTS_SCHEMA, + EventEmitter, Inject, + inject, + Output, + signal +} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {MatButton, MatIconButton} from '@angular/material/button'; +import { + MAT_DIALOG_DATA, + MatDialogActions, + MatDialogClose, + MatDialogContent, + MatDialogRef, + MatDialogTitle +} from '@angular/material/dialog'; +import {MatFormField, MatInput, MatLabel, MatSuffix} from '@angular/material/input'; +import {MatIcon} from '@angular/material/icon'; +import {MatSnackBar} from '@angular/material/snack-bar'; +import {DialogLoginData} from '../main.component'; + +@Component({ + selector: 'app-dialog-login.component', + imports: [ + FormsModule, + MatButton, + MatDialogActions, + MatDialogClose, + MatDialogContent, + MatDialogTitle, + MatFormField, + MatIcon, + MatIconButton, + MatInput, + MatLabel, + MatSuffix + ], + templateUrl: './dialog-login.component.html', + styleUrl: './dialog-login.component.scss', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class DialogLoginComponent { + readonly dialogRef = inject(MatDialogRef); + hide = signal(true); + + @Output() loginClicked = new EventEmitter(); + @Output() signupClicked = new EventEmitter(); + + private _snackBar = inject(MatSnackBar); + durationInSeconds = 5; + + + constructor( + @Inject(MAT_DIALOG_DATA) public data:DialogLoginData) { + + } + + openLoginFailedSnackBar(errorMessage : string = "Login failed.") { + this._snackBar.open(errorMessage , "", { + duration: this.durationInSeconds * 1000, + }); + } + + onNoClick() { + this.dialogRef.close(); + } + + + clickEvent(event: MouseEvent) { + this.hide.set(!this.hide()); + event.stopPropagation(); + } + + login() { + this.loginClicked.emit(this.data); + + } + + signup() { + this.signupClicked.emit(); + } +} diff --git a/jambotron-ui/src/app/components/dialog-signup.component/dialog-signup.component.html b/jambotron-ui/src/app/modules/main-module/main.component/dialog-signup.component/dialog-signup.component.html similarity index 100% rename from jambotron-ui/src/app/components/dialog-signup.component/dialog-signup.component.html rename to jambotron-ui/src/app/modules/main-module/main.component/dialog-signup.component/dialog-signup.component.html diff --git a/jambotron-ui/src/app/components/dialog/dialog.component.scss b/jambotron-ui/src/app/modules/main-module/main.component/dialog-signup.component/dialog-signup.component.scss similarity index 100% rename from jambotron-ui/src/app/components/dialog/dialog.component.scss rename to jambotron-ui/src/app/modules/main-module/main.component/dialog-signup.component/dialog-signup.component.scss diff --git a/jambotron-ui/src/app/components/dialog-signup.component/dialog-signup.component.spec.ts b/jambotron-ui/src/app/modules/main-module/main.component/dialog-signup.component/dialog-signup.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/components/dialog-signup.component/dialog-signup.component.spec.ts rename to jambotron-ui/src/app/modules/main-module/main.component/dialog-signup.component/dialog-signup.component.spec.ts diff --git a/jambotron-ui/src/app/components/dialog-signup.component/dialog-signup.component.ts b/jambotron-ui/src/app/modules/main-module/main.component/dialog-signup.component/dialog-signup.component.ts similarity index 97% rename from jambotron-ui/src/app/components/dialog-signup.component/dialog-signup.component.ts rename to jambotron-ui/src/app/modules/main-module/main.component/dialog-signup.component/dialog-signup.component.ts index 2d052e9..451be40 100644 --- a/jambotron-ui/src/app/components/dialog-signup.component/dialog-signup.component.ts +++ b/jambotron-ui/src/app/modules/main-module/main.component/dialog-signup.component/dialog-signup.component.ts @@ -22,7 +22,7 @@ import { import {MatFormField, MatInput, MatLabel, MatSuffix} from '@angular/material/input'; import {MatIcon} from '@angular/material/icon'; import {MatSnackBar} from '@angular/material/snack-bar'; -import {DialogSignupData} from '../../main-module/main.component/main.component'; +import {DialogSignupData} from '../main.component'; import {ErrorStateMatcher} from '@angular/material/core'; @Component({ diff --git a/jambotron-ui/src/app/main-module/main.component/main.component.html b/jambotron-ui/src/app/modules/main-module/main.component/main.component.html similarity index 88% rename from jambotron-ui/src/app/main-module/main.component/main.component.html rename to jambotron-ui/src/app/modules/main-module/main.component/main.component.html index e115b74..d4c3725 100644 --- a/jambotron-ui/src/app/main-module/main.component/main.component.html +++ b/jambotron-ui/src/app/modules/main-module/main.component/main.component.html @@ -1,15 +1,13 @@ - + - - @if (isLoggedIn) { - - } @@ -58,6 +56,8 @@ } + +
diff --git a/jambotron-ui/src/app/main-module/main.component/main.component.scss b/jambotron-ui/src/app/modules/main-module/main.component/main.component.scss similarity index 73% rename from jambotron-ui/src/app/main-module/main.component/main.component.scss rename to jambotron-ui/src/app/modules/main-module/main.component/main.component.scss index fe0674f..bf054c9 100644 --- a/jambotron-ui/src/app/main-module/main.component/main.component.scss +++ b/jambotron-ui/src/app/modules/main-module/main.component/main.component.scss @@ -16,7 +16,11 @@ mat-toolbar{ } .mat-mdc-raised-button:not(:disabled){ color: rgba(24, 255, 255, 0.96); - background-color: rgba(24,255,255,0.04); + background-color: rgba(24, 255, 255, 0); +} +.mat-mdc-button:not(:disabled){ + color: rgba(24, 255, 255, 0.96); + background-color: rgba(24, 255, 255, 0); } .mat-mdc-mini-fab{ margin: 5px; diff --git a/jambotron-ui/src/app/main-module/main.component/main.component.spec.ts b/jambotron-ui/src/app/modules/main-module/main.component/main.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/main-module/main.component/main.component.spec.ts rename to jambotron-ui/src/app/modules/main-module/main.component/main.component.spec.ts diff --git a/jambotron-ui/src/app/main-module/main.component/main.component.ts b/jambotron-ui/src/app/modules/main-module/main.component/main.component.ts similarity index 89% rename from jambotron-ui/src/app/main-module/main.component/main.component.ts rename to jambotron-ui/src/app/modules/main-module/main.component/main.component.ts index 0d9927a..7d719d4 100644 --- a/jambotron-ui/src/app/main-module/main.component/main.component.ts +++ b/jambotron-ui/src/app/modules/main-module/main.component/main.component.ts @@ -1,35 +1,30 @@ import {Component, CUSTOM_ELEMENTS_SCHEMA, inject, OnInit} from '@angular/core'; -//import {NavigationComponent} from '../navigation/navigation.component'; - import {Router, RouterLink, RouterOutlet} from '@angular/router'; import {MatToolbar} from '@angular/material/toolbar'; import {MatButton, MatFabButton, MatMiniFabButton} from '@angular/material/button'; -import {IconDirective, IconService} from '@ant-design/icons-angular'; import {MatDialog} from '@angular/material/dialog'; import {Subscription} from 'rxjs'; -import {TokenStorageService} from '../../services/token-storage.service'; -import {AuthService} from '../../services/auth.service'; -import {EventBusService} from '../../_shared/event-bus.service'; -import {DialogComponent} from '../../components/dialog/dialog.component'; - +import {TokenStorageService} from '../../../services/token-storage.service'; +import {AuthService} from '../../../services/auth.service'; +import {EventBusService} from '../../../_shared/event-bus.service'; import {CommonModule} from '@angular/common'; import {MatIcon} from '@angular/material/icon'; import {MatMenu, MatMenuItem, MatMenuTrigger} from '@angular/material/menu'; import {MatTooltip} from '@angular/material/tooltip'; -import {DialogSignupComponent} from '../../components/dialog-signup.component/dialog-signup.component'; import {MatLabel} from '@angular/material/input'; import {HttpClient} from '@angular/common/http'; -import { environment } from '../../../environments/environment'; +import { environment } from '../../../../environments/environment'; +import {DialogLoginComponent} from './dialog-login.component/dialog-login.component'; +import {DialogSignupComponent} from './dialog-signup.component/dialog-signup.component'; +import {GlobalConstants} from '../../../global-constants'; @Component({ selector: 'app-main.component', imports: [ - MatToolbar, MatButton, RouterLink, - RouterOutlet, CommonModule, MatIcon, @@ -39,13 +34,14 @@ import { environment } from '../../../environments/environment'; MatMenuItem, MatTooltip, MatLabel - ], schemas: [ CUSTOM_ELEMENTS_SCHEMA ], templateUrl: './main.component.html', styleUrl: './main.component.scss' }) export class MainComponent implements OnInit{ + title = GlobalConstants.TITLE; + // public props navCollapsed: boolean = false; navCollapsedMob: boolean = false; @@ -76,8 +72,6 @@ export class MainComponent implements OnInit{ } ngOnInit(): void { - - this.refreshToolbar(); this.eventBusSub = this.eventBusService.on('logout', () => { @@ -140,7 +134,7 @@ export class MainComponent implements OnInit{ this.storageService.clean(); //window.location.reload(); - this.router.navigate([environment.default_page]).then(() => { + this.router.navigate([GlobalConstants.DEFAULT_PAGE]).then(() => { window.location.reload(); }); //window.location.reload(); @@ -153,7 +147,7 @@ export class MainComponent implements OnInit{ openLoginDialog(enterAnimationDuration: string, exitAnimationDuration: string) { - let dialogLoginRef = this.dialog.open(DialogComponent, { + let dialogLoginRef = this.dialog.open(DialogLoginComponent, { width: '350px', enterAnimationDuration, exitAnimationDuration, @@ -187,7 +181,7 @@ export class MainComponent implements OnInit{ dialogLoginRef.close() - this.router.navigate(['main/tutorials']); + this.router.navigate([GlobalConstants.DEFAULT_PAGE]); }, err => { dialogLoginRef.componentInstance.openLoginFailedSnackBar(err.error.message); diff --git a/jambotron-ui/src/app/main-module/main.module.ts b/jambotron-ui/src/app/modules/main-module/main.module.ts similarity index 58% rename from jambotron-ui/src/app/main-module/main.module.ts rename to jambotron-ui/src/app/modules/main-module/main.module.ts index 0f580af..8393405 100644 --- a/jambotron-ui/src/app/main-module/main.module.ts +++ b/jambotron-ui/src/app/modules/main-module/main.module.ts @@ -2,14 +2,9 @@ import {RouterModule} from '@angular/router'; import {MainComponent} from './main.component/main.component'; import {mainRouting} from './main.routing'; import {NgModule} from '@angular/core'; -import {CommonModule} from '@angular/common'; - import {HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi} from '@angular/common/http'; -import {CustomHttpInterceptor} from '../helpers/custom-http-interceptor'; -import {AngularImageViewerModule} from '@hreimer/angular-image-viewer'; -import {BrowserModule} from '@angular/platform-browser'; -import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; -import {authInterceptorProviders} from '../helpers/auth.interceptor'; +import {CustomHttpInterceptor} from '../../helpers/custom-http-interceptor'; +import {authInterceptorProviders} from '../../helpers/auth.interceptor'; @NgModule({ declarations: [ @@ -17,10 +12,7 @@ import {authInterceptorProviders} from '../helpers/auth.interceptor'; ], imports: [ mainRouting, - MainComponent, - - - + MainComponent ], exports: [RouterModule], providers: [authInterceptorProviders,provideHttpClient(withInterceptorsFromDi()),{ diff --git a/jambotron-ui/src/app/main-module/main.routing.ts b/jambotron-ui/src/app/modules/main-module/main.routing.ts similarity index 51% rename from jambotron-ui/src/app/main-module/main.routing.ts rename to jambotron-ui/src/app/modules/main-module/main.routing.ts index 2309bd0..6662926 100644 --- a/jambotron-ui/src/app/main-module/main.routing.ts +++ b/jambotron-ui/src/app/modules/main-module/main.routing.ts @@ -1,16 +1,21 @@ import {RouterModule, Routes} from '@angular/router'; -import {HomeComponent} from '../components/home.component/home.component'; import {MainComponent} from './main.component/main.component'; -import {TutorialsComponent} from '../components/tutorials.component/tutorials.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'; const MAIN_ROUTES: Routes =[ { path: '', component: MainComponent, children: [ + { + path: 'tutorials', + loadChildren: () => + import('../tutorials-module/tutorials.module').then((m) => m.TutorialsModule), + }, + { + path: 'ai', + loadChildren: () => + import('../ai-module/ai.module').then((m) => m.AiModule), + }, { path: 'admin', loadChildren: () => @@ -25,26 +30,6 @@ const MAIN_ROUTES: Routes =[ path: 'moderator', loadChildren: () => import('../moderator-module/moderator.module').then((m) => m.ModeratorModule), - }, - { - path: 'home', - component: HomeComponent - }, - { - path: 'generate-image', - component: GenerateImageComponent - }, - { - path: 'tutorials', - component: TutorialsComponent - }, - { - path: 'register', - component : RegisterComponent - }, - { - path: 'profile', - component : ProfileComponent } ], } diff --git a/jambotron-ui/src/app/moderator-module/moderator-api.service.spec.ts b/jambotron-ui/src/app/modules/moderator-module/moderator-api.service.spec.ts similarity index 100% rename from jambotron-ui/src/app/moderator-module/moderator-api.service.spec.ts rename to jambotron-ui/src/app/modules/moderator-module/moderator-api.service.spec.ts diff --git a/jambotron-ui/src/app/moderator-module/moderator-api.service.ts b/jambotron-ui/src/app/modules/moderator-module/moderator-api.service.ts similarity index 79% rename from jambotron-ui/src/app/moderator-module/moderator-api.service.ts rename to jambotron-ui/src/app/modules/moderator-module/moderator-api.service.ts index aef4bc6..26a95ed 100644 --- a/jambotron-ui/src/app/moderator-module/moderator-api.service.ts +++ b/jambotron-ui/src/app/modules/moderator-module/moderator-api.service.ts @@ -1,8 +1,8 @@ import { Injectable } from '@angular/core'; -import {HttpClient, HttpHeaders} from '@angular/common/http'; +import {HttpClient} from '@angular/common/http'; import {Observable} from 'rxjs'; -import {Tutorial} from '../models/tutorial.model'; -import {GlobalConstants} from '../global-constants'; +import {Tutorial} from '../../models/tutorial.model'; +import {GlobalConstants} from '../../global-constants'; @Injectable({ providedIn: 'root' diff --git a/jambotron-ui/src/app/moderator-module/moderator-welcome.component/moderator-welcome.component.html b/jambotron-ui/src/app/modules/moderator-module/moderator-welcome.component/moderator-welcome.component.html similarity index 100% rename from jambotron-ui/src/app/moderator-module/moderator-welcome.component/moderator-welcome.component.html rename to jambotron-ui/src/app/modules/moderator-module/moderator-welcome.component/moderator-welcome.component.html diff --git a/jambotron-ui/src/app/moderator-module/moderator-welcome.component/moderator-welcome.component.scss b/jambotron-ui/src/app/modules/moderator-module/moderator-welcome.component/moderator-welcome.component.scss similarity index 100% rename from jambotron-ui/src/app/moderator-module/moderator-welcome.component/moderator-welcome.component.scss rename to jambotron-ui/src/app/modules/moderator-module/moderator-welcome.component/moderator-welcome.component.scss diff --git a/jambotron-ui/src/app/moderator-module/moderator-welcome.component/moderator-welcome.component.spec.ts b/jambotron-ui/src/app/modules/moderator-module/moderator-welcome.component/moderator-welcome.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/moderator-module/moderator-welcome.component/moderator-welcome.component.spec.ts rename to jambotron-ui/src/app/modules/moderator-module/moderator-welcome.component/moderator-welcome.component.spec.ts diff --git a/jambotron-ui/src/app/moderator-module/moderator-welcome.component/moderator-welcome.component.ts b/jambotron-ui/src/app/modules/moderator-module/moderator-welcome.component/moderator-welcome.component.ts similarity index 100% rename from jambotron-ui/src/app/moderator-module/moderator-welcome.component/moderator-welcome.component.ts rename to jambotron-ui/src/app/modules/moderator-module/moderator-welcome.component/moderator-welcome.component.ts diff --git a/jambotron-ui/src/app/moderator-module/moderator.component/moderator.component.html b/jambotron-ui/src/app/modules/moderator-module/moderator.component/moderator.component.html similarity index 100% rename from jambotron-ui/src/app/moderator-module/moderator.component/moderator.component.html rename to jambotron-ui/src/app/modules/moderator-module/moderator.component/moderator.component.html diff --git a/jambotron-ui/src/app/moderator-module/moderator.component/moderator.component.scss b/jambotron-ui/src/app/modules/moderator-module/moderator.component/moderator.component.scss similarity index 100% rename from jambotron-ui/src/app/moderator-module/moderator.component/moderator.component.scss rename to jambotron-ui/src/app/modules/moderator-module/moderator.component/moderator.component.scss diff --git a/jambotron-ui/src/app/moderator-module/moderator.component/moderator.component.spec.ts b/jambotron-ui/src/app/modules/moderator-module/moderator.component/moderator.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/moderator-module/moderator.component/moderator.component.spec.ts rename to jambotron-ui/src/app/modules/moderator-module/moderator.component/moderator.component.spec.ts diff --git a/jambotron-ui/src/app/moderator-module/moderator.component/moderator.component.ts b/jambotron-ui/src/app/modules/moderator-module/moderator.component/moderator.component.ts similarity index 100% rename from jambotron-ui/src/app/moderator-module/moderator.component/moderator.component.ts rename to jambotron-ui/src/app/modules/moderator-module/moderator.component/moderator.component.ts diff --git a/jambotron-ui/src/app/moderator-module/moderator.module.ts b/jambotron-ui/src/app/modules/moderator-module/moderator.module.ts similarity index 100% rename from jambotron-ui/src/app/moderator-module/moderator.module.ts rename to jambotron-ui/src/app/modules/moderator-module/moderator.module.ts diff --git a/jambotron-ui/src/app/moderator-module/moderator.routing.spec.ts b/jambotron-ui/src/app/modules/moderator-module/moderator.routing.spec.ts similarity index 100% rename from jambotron-ui/src/app/moderator-module/moderator.routing.spec.ts rename to jambotron-ui/src/app/modules/moderator-module/moderator.routing.spec.ts diff --git a/jambotron-ui/src/app/moderator-module/moderator.routing.ts b/jambotron-ui/src/app/modules/moderator-module/moderator.routing.ts similarity index 92% rename from jambotron-ui/src/app/moderator-module/moderator.routing.ts rename to jambotron-ui/src/app/modules/moderator-module/moderator.routing.ts index d053a68..de5f280 100644 --- a/jambotron-ui/src/app/moderator-module/moderator.routing.ts +++ b/jambotron-ui/src/app/modules/moderator-module/moderator.routing.ts @@ -1,5 +1,5 @@ import {RouterModule, Routes} from '@angular/router'; -import {UserComponent} from '../user-module/user.component/user.component'; + import {ModeratorComponent} from './moderator.component/moderator.component'; const MODERATOR_ROUTES: Routes = [ diff --git a/jambotron-ui/src/app/moderator-module/side-bar-moderator.component/side-bar-moderator.component.html b/jambotron-ui/src/app/modules/moderator-module/side-bar-moderator.component/side-bar-moderator.component.html similarity index 100% rename from jambotron-ui/src/app/moderator-module/side-bar-moderator.component/side-bar-moderator.component.html rename to jambotron-ui/src/app/modules/moderator-module/side-bar-moderator.component/side-bar-moderator.component.html diff --git a/jambotron-ui/src/app/moderator-module/side-bar-moderator.component/side-bar-moderator.component.scss b/jambotron-ui/src/app/modules/moderator-module/side-bar-moderator.component/side-bar-moderator.component.scss similarity index 100% rename from jambotron-ui/src/app/moderator-module/side-bar-moderator.component/side-bar-moderator.component.scss rename to jambotron-ui/src/app/modules/moderator-module/side-bar-moderator.component/side-bar-moderator.component.scss diff --git a/jambotron-ui/src/app/moderator-module/side-bar-moderator.component/side-bar-moderator.component.spec.ts b/jambotron-ui/src/app/modules/moderator-module/side-bar-moderator.component/side-bar-moderator.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/moderator-module/side-bar-moderator.component/side-bar-moderator.component.spec.ts rename to jambotron-ui/src/app/modules/moderator-module/side-bar-moderator.component/side-bar-moderator.component.spec.ts diff --git a/jambotron-ui/src/app/moderator-module/side-bar-moderator.component/side-bar-moderator.component.ts b/jambotron-ui/src/app/modules/moderator-module/side-bar-moderator.component/side-bar-moderator.component.ts similarity index 100% rename from jambotron-ui/src/app/moderator-module/side-bar-moderator.component/side-bar-moderator.component.ts rename to jambotron-ui/src/app/modules/moderator-module/side-bar-moderator.component/side-bar-moderator.component.ts diff --git a/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.html b/jambotron-ui/src/app/modules/moderator-module/tutorial-preview.component/tutorial-preview.component.html similarity index 100% rename from jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.html rename to jambotron-ui/src/app/modules/moderator-module/tutorial-preview.component/tutorial-preview.component.html diff --git a/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.scss b/jambotron-ui/src/app/modules/moderator-module/tutorial-preview.component/tutorial-preview.component.scss similarity index 100% rename from jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.scss rename to jambotron-ui/src/app/modules/moderator-module/tutorial-preview.component/tutorial-preview.component.scss diff --git a/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.spec.ts b/jambotron-ui/src/app/modules/moderator-module/tutorial-preview.component/tutorial-preview.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.spec.ts rename to jambotron-ui/src/app/modules/moderator-module/tutorial-preview.component/tutorial-preview.component.spec.ts diff --git a/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.ts b/jambotron-ui/src/app/modules/moderator-module/tutorial-preview.component/tutorial-preview.component.ts similarity index 95% rename from jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.ts rename to jambotron-ui/src/app/modules/moderator-module/tutorial-preview.component/tutorial-preview.component.ts index ae41432..5c075ae 100644 --- a/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.ts +++ b/jambotron-ui/src/app/modules/moderator-module/tutorial-preview.component/tutorial-preview.component.ts @@ -6,8 +6,7 @@ import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from "@angular/m import {MatError, MatFormField, MatInput, MatLabel} from "@angular/material/input"; import {MatTab, MatTabGroup} from "@angular/material/tabs"; import {ActivatedRoute, RouterLink} from "@angular/router"; -import {Tutorial} from '../../models/tutorial.model'; -import {UserApiService} from '../../user-module/user-api.service'; +import {Tutorial} from '../../../models/tutorial.model'; import {ModeratorApiService} from '../moderator-api.service'; @Component({ diff --git a/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.html b/jambotron-ui/src/app/modules/moderator-module/tutorials-list.component/tutorials-list.component.html similarity index 100% rename from jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.html rename to jambotron-ui/src/app/modules/moderator-module/tutorials-list.component/tutorials-list.component.html diff --git a/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.scss b/jambotron-ui/src/app/modules/moderator-module/tutorials-list.component/tutorials-list.component.scss similarity index 100% rename from jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.scss rename to jambotron-ui/src/app/modules/moderator-module/tutorials-list.component/tutorials-list.component.scss diff --git a/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.spec.ts b/jambotron-ui/src/app/modules/moderator-module/tutorials-list.component/tutorials-list.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.spec.ts rename to jambotron-ui/src/app/modules/moderator-module/tutorials-list.component/tutorials-list.component.spec.ts diff --git a/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.ts b/jambotron-ui/src/app/modules/moderator-module/tutorials-list.component/tutorials-list.component.ts similarity index 88% rename from jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.ts rename to jambotron-ui/src/app/modules/moderator-module/tutorials-list.component/tutorials-list.component.ts index 61322a1..9c51eb1 100644 --- a/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.ts +++ b/jambotron-ui/src/app/modules/moderator-module/tutorials-list.component/tutorials-list.component.ts @@ -10,16 +10,14 @@ import { MatRow, MatRowDef, MatTable, MatTableDataSource } from "@angular/material/table"; -import {MatCheckbox} from "@angular/material/checkbox"; import {MatSlideToggle} from "@angular/material/slide-toggle"; import {Router, RouterLink} from "@angular/router"; -import {Tutorial} from '../../models/tutorial.model'; -import {EventData} from '../../_shared/event.class'; +import {Tutorial} from '../../../models/tutorial.model'; +import {EventData} from '../../../_shared/event.class'; import {ModeratorApiService} from '../moderator-api.service'; -import {TokenStorageService} from '../../services/token-storage.service'; -import {EventBusService} from '../../_shared/event-bus.service'; -import {AuthService} from '../../services/auth.service'; -import {HttpHeaders} from '@angular/common/http'; +import {TokenStorageService} from '../../../services/token-storage.service'; +import {EventBusService} from '../../../_shared/event-bus.service'; +import {AuthService} from '../../../services/auth.service'; @Component({ selector: 'app-tutorials-list.component', diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.html b/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.html new file mode 100644 index 0000000..f6a9b13 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.html @@ -0,0 +1,5 @@ +
+ + +
+ diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.scss b/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.scss new file mode 100644 index 0000000..b1babdc --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.scss @@ -0,0 +1,17 @@ +.tutorial-view { + margin-right: 12px; + padding: 20px 12px 12px 31px; + margin-top: 81px; + margin-left: 12px; + background-color: #e7edf3c2; + backdrop-filter: blur(8px); + + display: flex; + flex-wrap: nowrap; + flex-direction: column; + align-items: center; +} + +.tutorial-body{ + width: 100%; +} diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.spec.ts b/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.spec.ts new file mode 100644 index 0000000..0cadd22 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TutorialViewComponent } from './tutorial-view.component'; + +describe('TutorialViewComponent', () => { + let component: TutorialViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TutorialViewComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TutorialViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.ts b/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.ts new file mode 100644 index 0000000..bea5513 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorial-view.component/tutorial-view.component.ts @@ -0,0 +1,35 @@ +import { Component } from '@angular/core'; +import {ModeratorApiService} from '../../moderator-module/moderator-api.service'; +import {ActivatedRoute} from '@angular/router'; +import {TutorialsApiService} from '../tutorials-api.service'; +import {Tutorial} from '../../../models/tutorial.model'; +import {MarkdownComponent} from 'ngx-markdown'; + +@Component({ + selector: 'app-tutorial-view.component', + imports: [ + MarkdownComponent + ], + templateUrl: './tutorial-view.component.html', + styleUrl: './tutorial-view.component.scss' +}) +export class TutorialViewComponent { + private id: string | null | undefined; + tutorial: Tutorial = new Tutorial(); + + constructor(private tutorialsApiService: TutorialsApiService, private route: ActivatedRoute) { + + this.route.queryParams + .subscribe(params => { + console.log(params); + this.id = params['id']; + console.log(this.id); + }); + + this.tutorialsApiService.getTutorial(this.id).subscribe( + data => { + this.tutorial = data; + } + ); + } +} diff --git a/jambotron-ui/src/app/services/tutorial.service.spec.ts b/jambotron-ui/src/app/modules/tutorials-module/tutorials-api.service.spec.ts similarity index 51% rename from jambotron-ui/src/app/services/tutorial.service.spec.ts rename to jambotron-ui/src/app/modules/tutorials-module/tutorials-api.service.spec.ts index 2a5e71f..e752372 100644 --- a/jambotron-ui/src/app/services/tutorial.service.spec.ts +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials-api.service.spec.ts @@ -1,13 +1,13 @@ import { TestBed } from '@angular/core/testing'; -import { TutorialService } from './tutorial.service'; +import { TutorialsApiService } from './tutorials-api.service'; -describe('TutorialService', () => { - let service: TutorialService; +describe('TutorialsApiService', () => { + let service: TutorialsApiService; beforeEach(() => { TestBed.configureTestingModule({}); - service = TestBed.inject(TutorialService); + service = TestBed.inject(TutorialsApiService); }); it('should be created', () => { diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials-api.service.ts b/jambotron-ui/src/app/modules/tutorials-module/tutorials-api.service.ts new file mode 100644 index 0000000..1294704 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials-api.service.ts @@ -0,0 +1,22 @@ +import { Injectable } from '@angular/core'; +import {GlobalConstants} from '../../global-constants'; +import {HttpClient} from '@angular/common/http'; +import {Observable} from 'rxjs'; +import {Tutorial} from '../../models/tutorial.model'; + +@Injectable({ + providedIn: 'root' +}) +export class TutorialsApiService { + + baseUrl = `${GlobalConstants.API_URL}/public`; + + constructor(private http: HttpClient) { } + + getAllPublic(): Observable { + return this.http.get(`${this.baseUrl}/tutorials`); + } + + getTutorial(id: string | null | undefined): Observable { + return this.http.get(`${this.baseUrl}/tutorial-get/${id}`); + }} diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.html b/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.html new file mode 100644 index 0000000..555bb13 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.html @@ -0,0 +1,14 @@ +
+ @for(tutorial of tutorials; track $index){ + + Photo of a + + + + + + + + } + +
diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.scss b/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.scss new file mode 100644 index 0000000..7929a90 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.scss @@ -0,0 +1,38 @@ +//mat-card{ +// width: 20%; +//} + +.container-card-view{ + display: grid; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + gap: 24px; + width: 100%; + height: 200px; + object-fit: cover; + padding: 24px; + //width: 100%; + //height: 100%; + //padding-top: 20px; + //display: flex; + //flex-wrap: wrap; + //flex-direction: row; + //align-content: flex-start; + //justify-content: space-around; + //align-items: center; +} + +.container { + padding: 24px; +} + +img { + width: 100%; + height: 200px; + object-fit: cover; +} + +.responsive-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + gap: 24px; +} diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.spec.ts b/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.spec.ts new file mode 100644 index 0000000..7d850b2 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TutorialsCardViewComponent } from './tutorials-card-view.component'; + +describe('TutorialsCardViewComponent', () => { + let component: TutorialsCardViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TutorialsCardViewComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TutorialsCardViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.ts b/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.ts new file mode 100644 index 0000000..568f8f0 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials-card-view.component/tutorials-card-view.component.ts @@ -0,0 +1,38 @@ +import { Component } from '@angular/core'; +import {Tutorial} from '../../../models/tutorial.model'; +import {MatCard, MatCardActions, MatCardImage} from '@angular/material/card'; +import {RouterLink} from '@angular/router'; +import {MatButton} from '@angular/material/button'; +import {TutorialsApiService} from '../tutorials-api.service'; + +@Component({ + selector: 'app-tutorials-card-view.component', + imports: [ + MatCard, + MatCardActions, + RouterLink, + MatButton, + MatCardImage + ], + templateUrl: './tutorials-card-view.component.html', + styleUrl: './tutorials-card-view.component.scss' +}) +export class TutorialsCardViewComponent { + tutorials: Tutorial[] = []; + + constructor(private tutorialsApiService: TutorialsApiService) { + this.retrieveTutorials(); + } + + retrieveTutorials(): void { + this.tutorialsApiService.getAllPublic().subscribe( + (data : Tutorial[]) =>{ + this.tutorials = data; + console.log(data); + }, + error => { + console.log(error); + } + ); + } +} diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials-welcome.component/tutorials-welcome.component.html b/jambotron-ui/src/app/modules/tutorials-module/tutorials-welcome.component/tutorials-welcome.component.html new file mode 100644 index 0000000..1e9583c --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials-welcome.component/tutorials-welcome.component.html @@ -0,0 +1 @@ +

tutorials-welcome.component works!

diff --git a/jambotron-ui/src/app/user-module/ai-models.component/ai-models.component.scss b/jambotron-ui/src/app/modules/tutorials-module/tutorials-welcome.component/tutorials-welcome.component.scss similarity index 100% rename from jambotron-ui/src/app/user-module/ai-models.component/ai-models.component.scss rename to jambotron-ui/src/app/modules/tutorials-module/tutorials-welcome.component/tutorials-welcome.component.scss diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials-welcome.component/tutorials-welcome.component.spec.ts b/jambotron-ui/src/app/modules/tutorials-module/tutorials-welcome.component/tutorials-welcome.component.spec.ts new file mode 100644 index 0000000..47c5c99 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials-welcome.component/tutorials-welcome.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TutorialsWelcomeComponent } from './tutorials-welcome.component'; + +describe('TutorialsWelcomeComponent', () => { + let component: TutorialsWelcomeComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TutorialsWelcomeComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TutorialsWelcomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials-welcome.component/tutorials-welcome.component.ts b/jambotron-ui/src/app/modules/tutorials-module/tutorials-welcome.component/tutorials-welcome.component.ts new file mode 100644 index 0000000..fffacac --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials-welcome.component/tutorials-welcome.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-tutorials-welcome.component', + imports: [], + templateUrl: './tutorials-welcome.component.html', + styleUrl: './tutorials-welcome.component.scss' +}) +export class TutorialsWelcomeComponent { + +} diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials.component/tutorials.component.html b/jambotron-ui/src/app/modules/tutorials-module/tutorials.component/tutorials.component.html new file mode 100644 index 0000000..0680b43 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials.component/tutorials.component.html @@ -0,0 +1 @@ + diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials.component/tutorials.component.scss b/jambotron-ui/src/app/modules/tutorials-module/tutorials.component/tutorials.component.scss new file mode 100644 index 0000000..e88c9f5 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials.component/tutorials.component.scss @@ -0,0 +1,9 @@ + +.router_outlet{ + width: 100%; + height: 100%; + +} + + + diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials.component/tutorials.component.ts b/jambotron-ui/src/app/modules/tutorials-module/tutorials.component/tutorials.component.ts new file mode 100644 index 0000000..3942b31 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials.component/tutorials.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import {RouterOutlet} from '@angular/router'; + +@Component({ + selector: 'app-tutorials.component', + imports: [ + RouterOutlet + ], + templateUrl: './tutorials.component.html', + styleUrl: './tutorials.component.scss' +}) +export class TutorialsComponent { + +} diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials.module.ts b/jambotron-ui/src/app/modules/tutorials-module/tutorials.module.ts new file mode 100644 index 0000000..b2d60c5 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials.module.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import {tutorialsRouting} from './tutorials.routing'; +import {TutorialsComponent} from './tutorials.component/tutorials.component'; + +@NgModule({ + declarations: [], + imports: [ + tutorialsRouting, + TutorialsComponent, + CommonModule + ] +}) +export class TutorialsModule { } diff --git a/jambotron-ui/src/app/modules/tutorials-module/tutorials.routing.ts b/jambotron-ui/src/app/modules/tutorials-module/tutorials.routing.ts new file mode 100644 index 0000000..adbdc38 --- /dev/null +++ b/jambotron-ui/src/app/modules/tutorials-module/tutorials.routing.ts @@ -0,0 +1,26 @@ +import {RouterModule, Routes} from '@angular/router'; +import {TutorialsComponent} from './tutorials.component/tutorials.component'; + +const TUTORIALS_ROUTES: Routes = [ + { + path: '', + component: TutorialsComponent, + + children: [ + { + path: 'tutorials-welcome', + loadComponent: () => import('../tutorials-module/tutorials-welcome.component/tutorials-welcome.component').then((c) => c.TutorialsWelcomeComponent), + }, + { + path: 'tutorials-all', + loadComponent: () => import('../tutorials-module/tutorials-card-view.component/tutorials-card-view.component').then((c) => c.TutorialsCardViewComponent) + }, + { + path: 'tutorial-view', + loadComponent: () => import('./tutorial-view.component/tutorial-view.component').then((c) => c.TutorialViewComponent) + } + ] + } +]; + +export const tutorialsRouting = RouterModule.forChild(TUTORIALS_ROUTES); diff --git a/jambotron-ui/src/app/user-module/ai-models.component/ai-models.component.html b/jambotron-ui/src/app/modules/user-module/ai-models.component/ai-models.component.html similarity index 100% rename from jambotron-ui/src/app/user-module/ai-models.component/ai-models.component.html rename to jambotron-ui/src/app/modules/user-module/ai-models.component/ai-models.component.html diff --git a/jambotron-ui/src/app/user-module/user-welcome.component/user-welcome.component.scss b/jambotron-ui/src/app/modules/user-module/ai-models.component/ai-models.component.scss similarity index 100% rename from jambotron-ui/src/app/user-module/user-welcome.component/user-welcome.component.scss rename to jambotron-ui/src/app/modules/user-module/ai-models.component/ai-models.component.scss diff --git a/jambotron-ui/src/app/user-module/ai-models.component/ai-models.component.spec.ts b/jambotron-ui/src/app/modules/user-module/ai-models.component/ai-models.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/user-module/ai-models.component/ai-models.component.spec.ts rename to jambotron-ui/src/app/modules/user-module/ai-models.component/ai-models.component.spec.ts diff --git a/jambotron-ui/src/app/user-module/ai-models.component/ai-models.component.ts b/jambotron-ui/src/app/modules/user-module/ai-models.component/ai-models.component.ts similarity index 100% rename from jambotron-ui/src/app/user-module/ai-models.component/ai-models.component.ts rename to jambotron-ui/src/app/modules/user-module/ai-models.component/ai-models.component.ts diff --git a/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.html b/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.html new file mode 100644 index 0000000..ba7a007 --- /dev/null +++ b/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.html @@ -0,0 +1,26 @@ +

Hi

+
+ + + @for (fileInfo of fileInfos; track fileInfo){ + + + + + + {{fileInfo.name}} + + + + } + + + +
+
+ + + + +
+ diff --git a/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.scss b/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.scss new file mode 100644 index 0000000..ad0d4e1 --- /dev/null +++ b/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.scss @@ -0,0 +1,28 @@ +.menu-spacer { + flex: 1 1 auto; +} + +.mat-dialog-content{ + min-height: 300px; + min-width: 300px; + + height: 75%; + width: 75%; +} +.mdc-dialog--open .mat-mdc-dialog-inner-container +{ + opacity: 1; + width: 600px; +} + +.mat-mdc-dialog-container { + width: 600px; + height: 500px; + display: block; + box-sizing: border-box; + max-height: inherit; + min-height: inherit; + min-width: inherit; + max-width: inherit; + outline: 0; +} diff --git a/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.spec.ts b/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.spec.ts new file mode 100644 index 0000000..6b51f49 --- /dev/null +++ b/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DialogSelectImageComponent } from './dialog-select-image.component'; + +describe('DialogSelectImageComponent', () => { + let component: DialogSelectImageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [DialogSelectImageComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DialogSelectImageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.ts b/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.ts new file mode 100644 index 0000000..d030b1a --- /dev/null +++ b/jambotron-ui/src/app/modules/user-module/dialog-select-image.component/dialog-select-image.component.ts @@ -0,0 +1,58 @@ +import {Component, EventEmitter, inject, Output} from '@angular/core'; +import { + MatDialogActions, + MatDialogClose, + MatDialogContent, + MatDialogRef, + MatDialogTitle +} from '@angular/material/dialog'; +import {MatButton} from '@angular/material/button'; +import {MatListItem, MatNavList} from '@angular/material/list'; +import {RouterLink} from '@angular/router'; +import {FileInfo} from '../../../models/file-info'; +import {UserApiService} from '../user-api.service'; + +@Component({ + selector: 'app-dialog-select-image.component', + imports: [ + MatDialogContent, + MatDialogTitle, + MatButton, + MatDialogActions, + MatDialogClose, + + MatListItem, + MatNavList, + + ], + templateUrl: './dialog-select-image.component.html', + styleUrl: './dialog-select-image.component.scss' +}) +export class DialogSelectImageComponent { + fileInfos?: FileInfo[] = []; + + @Output() uploadClicked = new EventEmitter(); + @Output() selectClicked = new EventEmitter(); + + readonly dialogRef = inject(MatDialogRef); + + constructor(private userApiService: UserApiService) { + this.userApiService.getImages().subscribe(data => { + this.fileInfos = data; + console.log(data); + }); + } + upload() { + + this.uploadClicked.emit(); + + } + + onNoClick() { + this.dialogRef.close(); + } + + select(fileInfo:FileInfo) { + this.selectClicked.emit(fileInfo); + } +} diff --git a/jambotron-ui/src/app/modules/user-module/images.component/images.component.html b/jambotron-ui/src/app/modules/user-module/images.component/images.component.html new file mode 100644 index 0000000..1f1aeef --- /dev/null +++ b/jambotron-ui/src/app/modules/user-module/images.component/images.component.html @@ -0,0 +1,28 @@ +

images.component works!

+ +
+ + + @for (fileInfo of fileInfos; track fileInfo) { + + +
+ + + + + + + + + +
+
+ + +
+ } +
diff --git a/jambotron-ui/src/app/modules/user-module/images.component/images.component.scss b/jambotron-ui/src/app/modules/user-module/images.component/images.component.scss new file mode 100644 index 0000000..0928c5a --- /dev/null +++ b/jambotron-ui/src/app/modules/user-module/images.component/images.component.scss @@ -0,0 +1,31 @@ + +.image-container{ + width: 100%; + height: 100%; + +} +.image-container .image-toolbar +{ + background-color: rgba(153,153,153,0); + + color: white; + position: absolute; + left : 50%; + top: 5%; + transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + padding: 0px 2px; + border: none; + border-radius: 5px; +} +.image-container .menu-spacer { + flex: 1 1 auto; +} + +.image-container .image-file-name { + padding-left: 10px; +} + +.mat-mdc-mini-fab{ + margin: 5px; +} diff --git a/jambotron-ui/src/app/components/dialog/dialog.component.spec.ts b/jambotron-ui/src/app/modules/user-module/images.component/images.component.spec.ts similarity index 55% rename from jambotron-ui/src/app/components/dialog/dialog.component.spec.ts rename to jambotron-ui/src/app/modules/user-module/images.component/images.component.spec.ts index 8fd87c4..144618e 100644 --- a/jambotron-ui/src/app/components/dialog/dialog.component.spec.ts +++ b/jambotron-ui/src/app/modules/user-module/images.component/images.component.spec.ts @@ -1,18 +1,18 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { DialogComponent } from './dialog.component'; +import { ImagesComponent } from './images.component'; -describe('DialogComponent', () => { - let component: DialogComponent; - let fixture: ComponentFixture; +describe('ImagesComponent', () => { + let component: ImagesComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [DialogComponent] + imports: [ImagesComponent] }) .compileComponents(); - fixture = TestBed.createComponent(DialogComponent); + fixture = TestBed.createComponent(ImagesComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/jambotron-ui/src/app/modules/user-module/images.component/images.component.ts b/jambotron-ui/src/app/modules/user-module/images.component/images.component.ts new file mode 100644 index 0000000..5d63db3 --- /dev/null +++ b/jambotron-ui/src/app/modules/user-module/images.component/images.component.ts @@ -0,0 +1,41 @@ +import {Component, CUSTOM_ELEMENTS_SCHEMA, inject} from '@angular/core'; +import {MatCard, MatCardContent, MatCardHeader} from '@angular/material/card'; +import {MatMiniFabButton} from '@angular/material/button'; +import {MatToolbar, MatToolbarRow} from '@angular/material/toolbar'; +import {MatTooltip} from '@angular/material/tooltip'; +import {MatIcon} from '@angular/material/icon'; +import {FileInfo} from '../../../models/file-info'; +import {UserApiService} from '../user-api.service'; +import {MatDialog} from '@angular/material/dialog'; + +@Component({ + selector: 'app-images.component', + imports: [ + MatCard, + MatCardContent, + MatCardHeader, + MatIcon, + MatMiniFabButton, + MatToolbar, + MatToolbarRow, + MatTooltip + ], + templateUrl: './images.component.html', + styleUrl: './images.component.scss', + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) +export class ImagesComponent { + fileInfos?: FileInfo[] = []; + + + constructor(private userApiService: UserApiService) { + this.userApiService.getImages().subscribe(data =>{ + this.fileInfos = data; + console.log(data); + }); + } + + downloadImage(url: string | undefined) { + + } +} diff --git a/jambotron-ui/src/app/user-module/side-bar-user.component/side-bar-user.component.html b/jambotron-ui/src/app/modules/user-module/side-bar-user.component/side-bar-user.component.html similarity index 68% rename from jambotron-ui/src/app/user-module/side-bar-user.component/side-bar-user.component.html rename to jambotron-ui/src/app/modules/user-module/side-bar-user.component/side-bar-user.component.html index c086fd8..d1ecbaf 100644 --- a/jambotron-ui/src/app/user-module/side-bar-user.component/side-bar-user.component.html +++ b/jambotron-ui/src/app/modules/user-module/side-bar-user.component/side-bar-user.component.html @@ -15,5 +15,13 @@ } + + + imagesmode + @if (!isCollapsed) { + Images + } + + diff --git a/jambotron-ui/src/app/user-module/side-bar-user.component/side-bar-user.component.scss b/jambotron-ui/src/app/modules/user-module/side-bar-user.component/side-bar-user.component.scss similarity index 100% rename from jambotron-ui/src/app/user-module/side-bar-user.component/side-bar-user.component.scss rename to jambotron-ui/src/app/modules/user-module/side-bar-user.component/side-bar-user.component.scss diff --git a/jambotron-ui/src/app/user-module/side-bar-user.component/side-bar-user.component.spec.ts b/jambotron-ui/src/app/modules/user-module/side-bar-user.component/side-bar-user.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/user-module/side-bar-user.component/side-bar-user.component.spec.ts rename to jambotron-ui/src/app/modules/user-module/side-bar-user.component/side-bar-user.component.spec.ts diff --git a/jambotron-ui/src/app/user-module/side-bar-user.component/side-bar-user.component.ts b/jambotron-ui/src/app/modules/user-module/side-bar-user.component/side-bar-user.component.ts similarity index 100% rename from jambotron-ui/src/app/user-module/side-bar-user.component/side-bar-user.component.ts rename to jambotron-ui/src/app/modules/user-module/side-bar-user.component/side-bar-user.component.ts diff --git a/jambotron-ui/src/app/modules/user-module/tutorial-add.component/tutorial-add.component.html b/jambotron-ui/src/app/modules/user-module/tutorial-add.component/tutorial-add.component.html new file mode 100644 index 0000000..6dacd62 --- /dev/null +++ b/jambotron-ui/src/app/modules/user-module/tutorial-add.component/tutorial-add.component.html @@ -0,0 +1,93 @@ + + + Add tutorial + + + + Title + + + + + Use title image + + + + + +
+ Description + + +
+
+
+ + +
+ +
+ +
+
+ + + + + + + +
+
+
+ Body + + +
+
+
+ + +
+
+ +
+ +
+ + + + + + + +
+
+ +
+ + @if (submitted){ +
+

Tutorial was submitted successfully!

+ +
+ } @else { + + } +
+
+ diff --git a/jambotron-ui/src/app/user-module/tutorial-add.component/tutorial-add.component.scss b/jambotron-ui/src/app/modules/user-module/tutorial-add.component/tutorial-add.component.scss similarity index 88% rename from jambotron-ui/src/app/user-module/tutorial-add.component/tutorial-add.component.scss rename to jambotron-ui/src/app/modules/user-module/tutorial-add.component/tutorial-add.component.scss index ab4c093..b5cf161 100644 --- a/jambotron-ui/src/app/user-module/tutorial-add.component/tutorial-add.component.scss +++ b/jambotron-ui/src/app/modules/user-module/tutorial-add.component/tutorial-add.component.scss @@ -3,6 +3,12 @@ margin: auto; } +.markdown-editor{ + max-width: 300px; +} +.markdown-editor-container{ + display: flex; +} mat-card{ margin: 20px; } diff --git a/jambotron-ui/src/app/user-module/tutorial-add.component/tutorial-add.component.spec.ts b/jambotron-ui/src/app/modules/user-module/tutorial-add.component/tutorial-add.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/user-module/tutorial-add.component/tutorial-add.component.spec.ts rename to jambotron-ui/src/app/modules/user-module/tutorial-add.component/tutorial-add.component.spec.ts diff --git a/jambotron-ui/src/app/modules/user-module/tutorial-add.component/tutorial-add.component.ts b/jambotron-ui/src/app/modules/user-module/tutorial-add.component/tutorial-add.component.ts new file mode 100644 index 0000000..34a29e9 --- /dev/null +++ b/jambotron-ui/src/app/modules/user-module/tutorial-add.component/tutorial-add.component.ts @@ -0,0 +1,202 @@ +import {Component, CUSTOM_ELEMENTS_SCHEMA, inject, OnInit} from '@angular/core'; +import {UserApiService} from '../user-api.service'; +import {TokenStorageService} from '../../../services/token-storage.service'; +import {EventBusService} from '../../../_shared/event-bus.service'; +import {Router} from '@angular/router'; +import {AuthService} from '../../../services/auth.service'; +import {Tutorial} from '../../../models/tutorial.model'; +import {MarkdownComponent, MarkdownService} from 'ngx-markdown'; +import {MatButton} from '@angular/material/button'; +import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from '@angular/material/card'; +import {MatFormField, MatInput, MatLabel} from '@angular/material/input'; +import {MatTab, MatTabGroup} from '@angular/material/tabs'; +import {FormBuilder, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {AngularMarkdownEditorModule, EditorInstance, EditorOption} from 'angular-markdown-editor'; +import {DialogLoginComponent} from '../../main-module/main.component/dialog-login.component/dialog-login.component'; +import {GlobalConstants} from '../../../global-constants'; +import {MatDialog} from '@angular/material/dialog'; +import {DialogSelectImageComponent} from '../dialog-select-image.component/dialog-select-image.component'; + +@Component({ + selector: 'app-tutorial-add.component', + imports: [ + MarkdownComponent, + MatButton, + MatCard, + MatCardActions, + MatCardContent, + MatCardHeader, + MatFormField, + MatInput, + MatLabel, + MatTab, + MatTabGroup, + ReactiveFormsModule, + FormsModule, + AngularMarkdownEditorModule + ], + templateUrl: './tutorial-add.component.html', + styleUrl: './tutorial-add.component.scss', + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) +export class TutorialAddComponent implements OnInit{ + + tutorial: Tutorial = new Tutorial(); + submitted = false; + bsEditorInstance!: EditorInstance; + markdownText = ''; + showEditor = true; + tutorialForm!: FormGroup; + editorOptions!: EditorOption; + + readonly dialog = inject(MatDialog); + + 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 fb: FormBuilder, + private markdownService: MarkdownService, + private userApiService: UserApiService, + private storageService: TokenStorageService, + private eventBusService: EventBusService, + private router: Router, + private authService: AuthService + ) { + + this.tutorial.description = this.markdown; + this.tutorial.body = this.markdown; + } + + ngOnInit(): void { + this.editorOptions = { + autofocus: false, + iconlibrary: 'fa', + savable: false, + onFullscreenExit: (e) => this.hidePreview(), + onShow: (e) => this.bsEditorInstance = e, + parser: (val) => this.parse(val) + }; + this.buildForm(this.tutorial.description); + + } + + buildForm(markdownText: string | undefined) { + this.tutorialForm = this.fb.group({ + body: [markdownText], + isPreview: [true] + }); + } + selectImage() { + throw new Error('Method not implemented.'); + } + /** highlight all code found, needs to be wrapped in timer to work properly */ + highlight() { + setTimeout(() => { + this.markdownService.highlight(); + }); + } + + hidePreview() { + if (this.bsEditorInstance && this.bsEditorInstance.hidePreview) { + this.bsEditorInstance.hidePreview(); + } + } + + showFullScreen(isFullScreen: boolean) { + if (this.bsEditorInstance && this.bsEditorInstance.setFullscreen) { + this.bsEditorInstance.showPreview(); + this.bsEditorInstance.setFullscreen(isFullScreen); + } + } + + parse(inputValue: string) { + const markedOutput = this.markdownService.parse(inputValue.trim()); + this.highlight(); + + return markedOutput; + } + + onFormChanges(): void { + this.tutorialForm.valueChanges.subscribe(formData => { + if (formData) { + this.markdownText = formData.body; + } + }); + } + + saveTutorial(): void { + const data = { + title: this.tutorial.title, + description: this.tutorial.description, + body: this.tutorial.body, + published: this.tutorial.published, + titleimage: this.tutorial.titleimage, + created: new Date(), + modified: new Date(), + tobepublished: false, + isEdit: false, + isAdmin: false, + isSuperAdmin: false, + isUser: false, + }; + + this.userApiService.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 + }; + } + + openSelectImageDialog(enterAnimationDuration: string, exitAnimationDuration: string) { + + let dialogSelectRef = this.dialog.open(DialogSelectImageComponent, { + height: '500px', + width: '600px', + enterAnimationDuration, + exitAnimationDuration, + // data: {username: this.dialogLoginData.username, password: this.dialogLoginData.password} + }); + dialogSelectRef.componentInstance.uploadClicked.subscribe(result => { + dialogSelectRef.close(); + //this.openSignupDialog(enterAnimationDuration, exitAnimationDuration); + }) + + const dialogSelectSubscription = dialogSelectRef.componentInstance.selectClicked + .subscribe(result => { + console.log('Got the data!', result); + + if (result == null) { + return; + } + this.tutorial.titleimage = result.url; + + }); + } +} diff --git a/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.html b/jambotron-ui/src/app/modules/user-module/tutorial-edit.component/tutorial-edit.component.html similarity index 100% rename from jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.html rename to jambotron-ui/src/app/modules/user-module/tutorial-edit.component/tutorial-edit.component.html diff --git a/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.scss b/jambotron-ui/src/app/modules/user-module/tutorial-edit.component/tutorial-edit.component.scss similarity index 100% rename from jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.scss rename to jambotron-ui/src/app/modules/user-module/tutorial-edit.component/tutorial-edit.component.scss diff --git a/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.spec.ts b/jambotron-ui/src/app/modules/user-module/tutorial-edit.component/tutorial-edit.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.spec.ts rename to jambotron-ui/src/app/modules/user-module/tutorial-edit.component/tutorial-edit.component.spec.ts diff --git a/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.ts b/jambotron-ui/src/app/modules/user-module/tutorial-edit.component/tutorial-edit.component.ts similarity index 94% rename from jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.ts rename to jambotron-ui/src/app/modules/user-module/tutorial-edit.component/tutorial-edit.component.ts index b6119e3..9898445 100644 --- a/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.ts +++ b/jambotron-ui/src/app/modules/user-module/tutorial-edit.component/tutorial-edit.component.ts @@ -5,9 +5,9 @@ import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from '@angular/m import {MatError, MatFormField, MatInput, MatLabel} from '@angular/material/input'; import {MatTab, MatTabGroup} from '@angular/material/tabs'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {Tutorial} from '../../models/tutorial.model'; +import {Tutorial} from '../../../models/tutorial.model'; import {UserApiService} from '../user-api.service'; -import {ActivatedRoute, Router, RouterLink} from '@angular/router'; +import {ActivatedRoute, RouterLink} from '@angular/router'; @Component({ selector: 'app-tutorial-edit.component', diff --git a/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.html b/jambotron-ui/src/app/modules/user-module/tutorials-list.component/tutorials-list.component.html similarity index 100% rename from jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.html rename to jambotron-ui/src/app/modules/user-module/tutorials-list.component/tutorials-list.component.html diff --git a/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.scss b/jambotron-ui/src/app/modules/user-module/tutorials-list.component/tutorials-list.component.scss similarity index 100% rename from jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.scss rename to jambotron-ui/src/app/modules/user-module/tutorials-list.component/tutorials-list.component.scss diff --git a/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.spec.ts b/jambotron-ui/src/app/modules/user-module/tutorials-list.component/tutorials-list.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.spec.ts rename to jambotron-ui/src/app/modules/user-module/tutorials-list.component/tutorials-list.component.spec.ts diff --git a/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.ts b/jambotron-ui/src/app/modules/user-module/tutorials-list.component/tutorials-list.component.ts similarity index 89% rename from jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.ts rename to jambotron-ui/src/app/modules/user-module/tutorials-list.component/tutorials-list.component.ts index a30172c..37e4ed5 100644 --- a/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.ts +++ b/jambotron-ui/src/app/modules/user-module/tutorials-list.component/tutorials-list.component.ts @@ -1,16 +1,12 @@ import {Component, CUSTOM_ELEMENTS_SCHEMA, OnInit} from '@angular/core'; -import {MatList, MatListItem} from '@angular/material/list'; -import {Tutorial} from '../../models/tutorial.model'; -import {TutorialService} from '../../services/tutorial.service'; +import {Tutorial} from '../../../models/tutorial.model'; import {UserApiService} from '../user-api.service'; import {MatButton} from '@angular/material/button'; -import {MatLine, MatOption} from '@angular/material/core'; -import {MatIcon} from '@angular/material/icon'; -import {TokenStorageService} from '../../services/token-storage.service'; -import {EventBusService} from '../../_shared/event-bus.service'; -import {EventData} from '../../_shared/event.class'; +import {TokenStorageService} from '../../../services/token-storage.service'; +import {EventBusService} from '../../../_shared/event-bus.service'; +import {EventData} from '../../../_shared/event.class'; import {Router, RouterLink} from '@angular/router'; -import {AuthService} from '../../services/auth.service'; +import {AuthService} from '../../../services/auth.service'; import {FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms'; import { MatCell, diff --git a/jambotron-ui/src/app/user-module/user-api.service.spec.ts b/jambotron-ui/src/app/modules/user-module/user-api.service.spec.ts similarity index 100% rename from jambotron-ui/src/app/user-module/user-api.service.spec.ts rename to jambotron-ui/src/app/modules/user-module/user-api.service.spec.ts diff --git a/jambotron-ui/src/app/user-module/user-api.service.ts b/jambotron-ui/src/app/modules/user-module/user-api.service.ts similarity index 74% rename from jambotron-ui/src/app/user-module/user-api.service.ts rename to jambotron-ui/src/app/modules/user-module/user-api.service.ts index 81c4484..0675f18 100644 --- a/jambotron-ui/src/app/user-module/user-api.service.ts +++ b/jambotron-ui/src/app/modules/user-module/user-api.service.ts @@ -1,8 +1,9 @@ import { Injectable } from '@angular/core'; import {forkJoin, Observable} from 'rxjs'; -import {Tutorial} from '../models/tutorial.model'; +import {Tutorial} from '../../models/tutorial.model'; import {HttpClient, HttpHeaders} from '@angular/common/http'; -import {GlobalConstants} from '../global-constants'; +import {GlobalConstants} from '../../global-constants'; +import {FileInfo} from '../../models/file-info'; @Injectable({ providedIn: 'root' @@ -10,11 +11,18 @@ import {GlobalConstants} from '../global-constants'; export class UserApiService { baseUrl = `${GlobalConstants.API_URL}/user`; - constructor(private http: HttpClient) { } + saveZhipuaiImage(url: string): Observable { + return this.http.post(`${this.baseUrl}/saveZhipuAiImage`, {imageUrl:url}); + } + + getImages(): Observable { + return this.http.get(`${this.baseUrl}/getImages`); + } + getUserAllTutorials(): Observable { return this.http.get(`${this.baseUrl}/tutorials`); } diff --git a/jambotron-ui/src/app/user-module/user-welcome.component/user-welcome.component.html b/jambotron-ui/src/app/modules/user-module/user-welcome.component/user-welcome.component.html similarity index 100% rename from jambotron-ui/src/app/user-module/user-welcome.component/user-welcome.component.html rename to jambotron-ui/src/app/modules/user-module/user-welcome.component/user-welcome.component.html diff --git a/jambotron-ui/src/app/modules/user-module/user-welcome.component/user-welcome.component.scss b/jambotron-ui/src/app/modules/user-module/user-welcome.component/user-welcome.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/jambotron-ui/src/app/user-module/user-welcome.component/user-welcome.component.spec.ts b/jambotron-ui/src/app/modules/user-module/user-welcome.component/user-welcome.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/user-module/user-welcome.component/user-welcome.component.spec.ts rename to jambotron-ui/src/app/modules/user-module/user-welcome.component/user-welcome.component.spec.ts diff --git a/jambotron-ui/src/app/user-module/user-welcome.component/user-welcome.component.ts b/jambotron-ui/src/app/modules/user-module/user-welcome.component/user-welcome.component.ts similarity index 100% rename from jambotron-ui/src/app/user-module/user-welcome.component/user-welcome.component.ts rename to jambotron-ui/src/app/modules/user-module/user-welcome.component/user-welcome.component.ts diff --git a/jambotron-ui/src/app/user-module/user.component/user.component.html b/jambotron-ui/src/app/modules/user-module/user.component/user.component.html similarity index 100% rename from jambotron-ui/src/app/user-module/user.component/user.component.html rename to jambotron-ui/src/app/modules/user-module/user.component/user.component.html diff --git a/jambotron-ui/src/app/user-module/user.component/user.component.scss b/jambotron-ui/src/app/modules/user-module/user.component/user.component.scss similarity index 100% rename from jambotron-ui/src/app/user-module/user.component/user.component.scss rename to jambotron-ui/src/app/modules/user-module/user.component/user.component.scss diff --git a/jambotron-ui/src/app/user-module/user.component/user.component.spec.ts b/jambotron-ui/src/app/modules/user-module/user.component/user.component.spec.ts similarity index 100% rename from jambotron-ui/src/app/user-module/user.component/user.component.spec.ts rename to jambotron-ui/src/app/modules/user-module/user.component/user.component.spec.ts diff --git a/jambotron-ui/src/app/user-module/user.component/user.component.ts b/jambotron-ui/src/app/modules/user-module/user.component/user.component.ts similarity index 100% rename from jambotron-ui/src/app/user-module/user.component/user.component.ts rename to jambotron-ui/src/app/modules/user-module/user.component/user.component.ts diff --git a/jambotron-ui/src/app/user-module/user.module.ts b/jambotron-ui/src/app/modules/user-module/user.module.ts similarity index 72% rename from jambotron-ui/src/app/user-module/user.module.ts rename to jambotron-ui/src/app/modules/user-module/user.module.ts index 7255d3c..93853ae 100644 --- a/jambotron-ui/src/app/user-module/user.module.ts +++ b/jambotron-ui/src/app/modules/user-module/user.module.ts @@ -2,6 +2,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import {userRouting} from './user.routing'; import {UserComponent} from './user.component/user.component'; +import {AngularMarkdownEditorModule} from 'angular-markdown-editor'; @@ -10,7 +11,8 @@ import {UserComponent} from './user.component/user.component'; imports: [ userRouting, UserComponent, - CommonModule + CommonModule, + AngularMarkdownEditorModule ] }) export class UserModule { } diff --git a/jambotron-ui/src/app/user-module/user.routing.spec.ts b/jambotron-ui/src/app/modules/user-module/user.routing.spec.ts similarity index 100% rename from jambotron-ui/src/app/user-module/user.routing.spec.ts rename to jambotron-ui/src/app/modules/user-module/user.routing.spec.ts diff --git a/jambotron-ui/src/app/user-module/user.routing.ts b/jambotron-ui/src/app/modules/user-module/user.routing.ts similarity index 88% rename from jambotron-ui/src/app/user-module/user.routing.ts rename to jambotron-ui/src/app/modules/user-module/user.routing.ts index 728a19d..b5c87f3 100644 --- a/jambotron-ui/src/app/user-module/user.routing.ts +++ b/jambotron-ui/src/app/modules/user-module/user.routing.ts @@ -27,6 +27,10 @@ const USER_ROUTES: Routes = [ { path: 'ai-models', loadComponent: () => import('../user-module/ai-models.component/ai-models.component').then((c) => c.AiModelsComponent) + }, + { + path: 'images', + loadComponent: () => import('../user-module/images.component/images.component').then((c) => c.ImagesComponent) } ] } diff --git a/jambotron-ui/src/app/services/file-upload-api.service.spec.ts b/jambotron-ui/src/app/services/file-upload-api.service.spec.ts new file mode 100644 index 0000000..bc34a28 --- /dev/null +++ b/jambotron-ui/src/app/services/file-upload-api.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { FileUploadApiService } from './file-upload-api.service'; + +describe('FileUploadApiService', () => { + let service: FileUploadApiService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(FileUploadApiService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/services/file-upload-api.service.ts b/jambotron-ui/src/app/services/file-upload-api.service.ts new file mode 100644 index 0000000..06c48de --- /dev/null +++ b/jambotron-ui/src/app/services/file-upload-api.service.ts @@ -0,0 +1,29 @@ +import { Injectable } from '@angular/core'; +import {GlobalConstants} from '../global-constants'; +import {HttpClient, HttpEvent, HttpRequest} from '@angular/common/http'; +import {Observable} from 'rxjs'; +import {FileInfo} from '../models/file-info'; + +@Injectable({ + providedIn: 'root' +}) +export class FileUploadService { + private baseUrl = GlobalConstants.API_URL + '/file'; + + constructor(private http: HttpClient) {} + + upload(file: File): Observable> { + const formData: FormData = new FormData(); + formData.append('file', file); + + const req = new HttpRequest('POST', `${this.baseUrl}/upload`, formData, { + responseType: 'json', + }); + + return this.http.request(req); + } + + getFiles(): Observable { + return this.http.get(`${this.baseUrl}/files`); + } +} diff --git a/jambotron-ui/src/app/services/tutorial.service.ts b/jambotron-ui/src/app/services/tutorial.service.ts deleted file mode 100644 index 269c292..0000000 --- a/jambotron-ui/src/app/services/tutorial.service.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { Observable } from 'rxjs'; -import { Tutorial } from '../models/tutorial.model'; -import {GlobalConstants} from '../global-constants'; - -const baseUrl = `${GlobalConstants.API_URL}/public/tutorials`; - -@Injectable({ - providedIn: 'root' -}) -export class TutorialService { - - constructor(private http: HttpClient) { } - - getAllPublic(): Observable { - return this.http.get(baseUrl); - } - - // - // get(id: any): Observable { - // return this.http.get(`${baseUrl}/${id}`); - // } - // - // create(data: any): Observable { - // return this.http.post(baseUrl, data); - // } - // - // - // update(id: any, data: any): Observable { - // return this.http.put(`${baseUrl}/${id}`, data); - // } - // - // delete(id: any): Observable { - // return this.http.delete(`${baseUrl}/${id}`); - // } - // - // deleteAll(): Observable { - // return this.http.delete(baseUrl); - // } - - findByTitle(title: any): Observable { - return this.http.get(`${baseUrl}?title=${title}`); - } -} diff --git a/jambotron-ui/src/app/user-module/tutorial-add.component/tutorial-add.component.html b/jambotron-ui/src/app/user-module/tutorial-add.component/tutorial-add.component.html deleted file mode 100644 index aff86e0..0000000 --- a/jambotron-ui/src/app/user-module/tutorial-add.component/tutorial-add.component.html +++ /dev/null @@ -1,34 +0,0 @@ - - - Add tutorial - - - - Title - - - - - - - - - - - - - - - - - - - -
-

Tutorial was submitted successfully!

- -
-
-
- diff --git a/jambotron-ui/src/app/user-module/tutorial-add.component/tutorial-add.component.ts b/jambotron-ui/src/app/user-module/tutorial-add.component/tutorial-add.component.ts deleted file mode 100644 index 1394347..0000000 --- a/jambotron-ui/src/app/user-module/tutorial-add.component/tutorial-add.component.ts +++ /dev/null @@ -1,91 +0,0 @@ -import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'; -import {UserApiService} from '../user-api.service'; -import {TokenStorageService} from '../../services/token-storage.service'; -import {EventBusService} from '../../_shared/event-bus.service'; -import {Router} from '@angular/router'; -import {AuthService} from '../../services/auth.service'; -import {Tutorial} from '../../models/tutorial.model'; -import {MarkdownComponent} from 'ngx-markdown'; -import {MatButton} from '@angular/material/button'; -import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from '@angular/material/card'; -import {MatFormField, MatInput, MatLabel} from '@angular/material/input'; -import {MatTab, MatTabGroup} from '@angular/material/tabs'; -import {NgIf} from '@angular/common'; -import {FormsModule, ReactiveFormsModule} from '@angular/forms'; - -@Component({ - selector: 'app-tutorial-add.component', - imports: [ - MarkdownComponent, - MatButton, - MatCard, - MatCardActions, - MatCardContent, - MatCardHeader, - MatFormField, - MatInput, - MatLabel, - MatTab, - MatTabGroup, - NgIf, - ReactiveFormsModule, - FormsModule - ], - templateUrl: './tutorial-add.component.html', - styleUrl: './tutorial-add.component.scss', - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class TutorialAddComponent { - tutorial: Tutorial = new Tutorial(); - 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 userApiService: UserApiService, - private storageService: TokenStorageService, - private eventBusService: EventBusService, - private router: Router, private authService: AuthService) { - - this.tutorial.description = this.markdown; - } - saveTutorial(): void { - const data = { - title: this.tutorial.title, - description: this.tutorial.description - }; - - this.userApiService.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 - }; - } -} diff --git a/jambotron-ui/src/environments/environment.development.ts b/jambotron-ui/src/environments/environment.development.ts index ab54751..2c5c033 100644 --- a/jambotron-ui/src/environments/environment.development.ts +++ b/jambotron-ui/src/environments/environment.development.ts @@ -1,7 +1,8 @@ export const environment = { - default_page: 'main/generate-image', + default_page: 'main/tutorials/tutorials-all', port: 8080, fromWeb: false, production: false, - host_name: 'http://localhost' + host_name: 'http://localhost', + title: 'JAMBOTRON.RUN.PLACE (dev)' }; diff --git a/jambotron-ui/src/environments/environment.prod.ts b/jambotron-ui/src/environments/environment.prod.ts index 1673ad0..4154dc1 100644 --- a/jambotron-ui/src/environments/environment.prod.ts +++ b/jambotron-ui/src/environments/environment.prod.ts @@ -1,7 +1,8 @@ export const environment = { - default_page: 'main/generate-image', + default_page: 'main/tutorials/tutorials-all', port: 8081, production: true, fromWeb: true, - host_name: 'https://jambotron.run.place' + host_name: 'https://jambotron.run.place', + title: 'JAMBOTRON.RUN.PLACE' }; diff --git a/jambotron-ui/src/environments/environment.ts b/jambotron-ui/src/environments/environment.ts index 038a3fc..ef44e66 100644 --- a/jambotron-ui/src/environments/environment.ts +++ b/jambotron-ui/src/environments/environment.ts @@ -1,7 +1,8 @@ export const environment = { - default_page: 'main/generate-image', + default_page: 'main/tutorials/tutorials-all', port: 8080, production: true, fromWeb: false, - host_name: 'http://localhost' + host_name: 'http://localhost', + title: 'Jambotron' }; diff --git a/jambotron-ui/src/proxy.config.js b/jambotron-ui/src/proxy.config.js deleted file mode 100644 index d1cf3e7..0000000 --- a/jambotron-ui/src/proxy.config.js +++ /dev/null @@ -1,10 +0,0 @@ -const PROXY_CONFIG = [ - { - context: [ -"/api" -], -target: "http://localhost:8082", - secure: false -} -] -module.exports = PROXY_CONFIG; diff --git a/jambotron-ui/src/styles.scss b/jambotron-ui/src/styles.scss index 0421915..ac9efef 100644 --- a/jambotron-ui/src/styles.scss +++ b/jambotron-ui/src/styles.scss @@ -63,3 +63,5 @@ body { padding-top: 60px; scroll-padding-inline: 40%; } + + diff --git a/src/main/java/com/jambotronGroup/jambotron/JambotronApplication.java b/src/main/java/com/jambotronGroup/jambotron/JambotronApplication.java index a2779a5..413376c 100644 --- a/src/main/java/com/jambotronGroup/jambotron/JambotronApplication.java +++ b/src/main/java/com/jambotronGroup/jambotron/JambotronApplication.java @@ -1,11 +1,14 @@ package com.jambotronGroup.jambotron; +import com.jambotronGroup.jambotron.fileUpload.FilesStorageService; +import jakarta.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.Marker; import org.slf4j.event.Level; import org.slf4j.helpers.BasicMarker; +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Import; @@ -13,7 +16,9 @@ import org.springframework.context.annotation.Import; import java.util.Iterator; @SpringBootApplication -public class JambotronApplication { +public class JambotronApplication implements CommandLineRunner { + @Resource + FilesStorageService storageService; private static final Logger logger = LoggerFactory.getLogger(JambotronApplication.class); public static void main(String[] args) { @@ -25,5 +30,9 @@ public class JambotronApplication { logger.debug("Application Run. This is a debug message."); logger.info("Application Run. This is an info message."); } - + @Override + public void run(String... arg) throws Exception { +// storageService.deleteAll(); + storageService.init(); + } } diff --git a/src/main/java/com/jambotronGroup/jambotron/ZhiPuAi/ImageController.java b/src/main/java/com/jambotronGroup/jambotron/ZhiPuAi/ImageController.java index a844230..a99c396 100644 --- a/src/main/java/com/jambotronGroup/jambotron/ZhiPuAi/ImageController.java +++ b/src/main/java/com/jambotronGroup/jambotron/ZhiPuAi/ImageController.java @@ -1,5 +1,7 @@ package com.jambotronGroup.jambotron.ZhiPuAi; +import com.jambotronGroup.jambotron.controllers.FilesController; +import com.jambotronGroup.jambotron.fileUpload.FilesStorageService; import com.jambotronGroup.jambotron.model.NameValueItem; import org.springframework.ai.image.Image; import org.springframework.ai.image.ImagePrompt; @@ -8,8 +10,18 @@ import org.springframework.ai.zhipuai.ZhiPuAiImageModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Path; import java.util.List; //@CrossOrigin(origins = "http://localhost:4200, https://pony-sincere-chimp.ngrok-free.app/", @@ -21,6 +33,9 @@ import java.util.List; @RequestMapping("/api/public/zhipuai") public class ImageController { + @Autowired + FilesStorageService storageService; + @Autowired ZhiPuAiImageService _zhiPuAiImageService; @@ -30,7 +45,6 @@ public class ImageController { Image returnValue = _zhiPuAiImageService.generateImage(query).getResult().getOutput(); //userRepository.findAll().forEach(users::add); - if (returnValue == null) { return new ResponseEntity<>(HttpStatus.NO_CONTENT); } diff --git a/src/main/java/com/jambotronGroup/jambotron/controllers/FilesController.java b/src/main/java/com/jambotronGroup/jambotron/controllers/FilesController.java new file mode 100644 index 0000000..b47f4d8 --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/controllers/FilesController.java @@ -0,0 +1,155 @@ +package com.jambotronGroup.jambotron.controllers; + +import com.jambotronGroup.jambotron.fileUpload.FilesStorageService; +import com.jambotronGroup.jambotron.fileUpload.ResponseMessage; +import com.jambotronGroup.jambotron.model.FileInfo; +import com.jambotronGroup.jambotron.model.User; +import com.jambotronGroup.jambotron.payload.request.SaveZhipuAiImageRequest; +import com.jambotronGroup.jambotron.security.AuthenticationFacade; +import com.jambotronGroup.jambotron.system.SystemServiceImpl; +import jakarta.validation.Valid; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import java.util.stream.Collectors; + +@Controller +//@CrossOrigin("http://localhost:8081") +public class FilesController { + + private static final Logger logger = LoggerFactory.getLogger(FilesController.class); + + + @Autowired + AuthenticationFacade authenticationFacade; + @Autowired + FilesStorageService storageService; + + @PostMapping("/api/user/saveZhipuAiImage") + public ResponseEntity saveZhipuAiImage(@Valid @RequestBody SaveZhipuAiImageRequest request) { + + if (request.getImageUrl() == null || request.getImageUrl().isEmpty()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseMessage("URL cannot be empty")); + } + + String url = request.getImageUrl(); + + String message = ""; + + + RestTemplate restTemplate = new RestTemplate(); + + try { + // Make a GET request to fetch the image as a byte array + ResponseEntity response = restTemplate.getForEntity(url, byte[].class); + + if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { + // Save the image to a file + + int lastSlashIndex = url.lastIndexOf("/"); + String fileName = (lastSlashIndex != -1) ? url.substring(lastSlashIndex + 1) : url; + + MultipartFile multipartFile = new MockMultipartFile( + fileName, // Name of the file + fileName, // Original filename + "application/octet-stream", // Content type + response.getBody() // File content + ); + + User user = authenticationFacade.getUser(); + + storageService.save(user.getId().toString(), multipartFile); + + message = "Uploaded the file successfully: " + fileName; + + } else { + + message = "Failed to download image. HTTP Status: " + response.getStatusCode(); + System.err.println(message); + return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message)); + } + } catch (Exception e) { + message = "Error fetching the image from URL: " + url + ". Error: " + e.getMessage(); + System.err.println(message); + return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message)); + } + return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message)); + } + + @PostMapping("/api/file/upload") + public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file) { + String message = ""; + try { + storageService.save(file); + + message = "Uploaded the file successfully: " + file.getOriginalFilename(); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message)); + } catch (Exception e) { + message = "Could not upload the file: " + file.getOriginalFilename() + ". Error: " + e.getMessage(); + return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message)); + } + } + + @GetMapping("/api/user/getImages") + public ResponseEntity> getImages() { + + User user = authenticationFacade.getUser(); + + List fileInfos = storageService.loadUserImages(user.getId().toString()).map(path -> { + String filename = path.getFileName().toString(); + String url = MvcUriComponentsBuilder + .fromMethodName(FilesController.class, "getUserImage", path.getFileName().toString()).build().toString(); + + return new FileInfo(filename, url); + }).collect(Collectors.toList()); + + return ResponseEntity.status(HttpStatus.OK).body(fileInfos); + } + + + @GetMapping("/api/file/files") + public ResponseEntity> getListFiles() { + List fileInfos = storageService.loadAll().map(path -> { + String filename = path.getFileName().toString(); + String url = MvcUriComponentsBuilder + .fromMethodName(FilesController.class, "getFile", path.getFileName().toString()).build().toString(); + + return new FileInfo(filename, url); + }).collect(Collectors.toList()); + + return ResponseEntity.status(HttpStatus.OK).body(fileInfos); + } + + @GetMapping("/files/{filename:.+}") + @ResponseBody + public ResponseEntity getFile(@PathVariable String filename) { + Resource file = storageService.load(filename); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"").body(file); + } + + @GetMapping("/api/user/user-images/{filename:.+}") + @ResponseBody + public ResponseEntity getUserImage(@PathVariable String filename) { + User user = authenticationFacade.getUser(); + Resource file = storageService.loadUserImage(user.getId().toString(),filename); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"").body(file); + } +} \ No newline at end of file diff --git a/src/main/java/com/jambotronGroup/jambotron/controllers/TutorialController.java b/src/main/java/com/jambotronGroup/jambotron/controllers/TutorialController.java index c4ae116..99d9bf3 100644 --- a/src/main/java/com/jambotronGroup/jambotron/controllers/TutorialController.java +++ b/src/main/java/com/jambotronGroup/jambotron/controllers/TutorialController.java @@ -1,6 +1,8 @@ package com.jambotronGroup.jambotron.controllers; +import com.jambotronGroup.jambotron.fileUpload.FilesStorageService; +import com.jambotronGroup.jambotron.fileUpload.FilesStorageServiceImpl; import com.jambotronGroup.jambotron.model.Tutorial; import com.jambotronGroup.jambotron.model.User; import com.jambotronGroup.jambotron.repository.TutorialRepository; @@ -14,7 +16,9 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; +import java.nio.file.Path; import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.*; @@ -33,6 +37,44 @@ public class TutorialController { @Autowired TutorialRepository tutorialRepository; + @Autowired + FilesStorageService filesStorageService; + + //--------------------public methods---------------------------- + + @GetMapping("/public/tutorials") + public ResponseEntity> getAllTutorials(@RequestParam(required = false) String title) { + try { + List tutorials = new ArrayList(); + + tutorialRepository.findByPublished(true).forEach(tutorials::add); + + if (tutorials.isEmpty()) { + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + return new ResponseEntity<>(tutorials, HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + @GetMapping("public/tutorial-get/{id}") + public ResponseEntity getPublicTutorial(@PathVariable("id") long id) { + + Optional tutorialData = tutorialRepository.findById(id); + + if (tutorialData.isPresent() && tutorialData.get().isPublished()) { + + return new ResponseEntity(tutorialData.get(), HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + + + //--------------------user methods---------------------------- + @GetMapping("/user/tutorials") public ResponseEntity> getUserTutorials(@RequestParam(required = false) String title) { try { @@ -60,49 +102,26 @@ public class TutorialController { } } - - @GetMapping("/public/tutorials") - public ResponseEntity> getAllTutorials(@RequestParam(required = false) String title) { - try { - List tutorials = new ArrayList(); - - tutorialRepository.findByPublished(true).forEach(tutorials::add); - - if (tutorials.isEmpty()) { - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - - return new ResponseEntity<>(tutorials, HttpStatus.OK); - } catch (Exception e) { - return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); - } - } - - @GetMapping("/moderator/tutorials") - public ResponseEntity> getBePublishedTutorials(@RequestParam(required = false) String title) { - try { - List tutorials = new ArrayList(); - - tutorialRepository.findBytobepublished(true).forEach(tutorials::add); - - if (tutorials.isEmpty()) { - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - - return new ResponseEntity<>(tutorials, HttpStatus.OK); - } catch (Exception e) { - return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); - } - } - - @PostMapping("user/tutorial-add") - public ResponseEntity createTutorial(@RequestBody Tutorial tutorial) { + @PostMapping("user/tutorial-add") + public ResponseEntity createTutorial(@RequestBody Tutorial tutorial) throws Exception { // not work from white IP port 80 to docker container port 8080 or 8081 //UserDetails userDetails = authenticationFacade.getUserDetails(); User user = authenticationFacade.getUser(); + + String newFilename = FilesStorageServiceImpl.getFileNameFromUrl(tutorial.getTitleimage()); + Path path= filesStorageService.moveFile( + user.getId().toString(), + tutorial.getTitleimage(), + String.format("Tutorial_%s",newFilename ) + ); + + String url = MvcUriComponentsBuilder + .fromMethodName(FilesController.class, "getFile", path.getFileName().toString()).build().toString(); + + try { Tutorial newTutorial =new Tutorial( tutorial.getTitle(), @@ -111,11 +130,13 @@ public class TutorialController { false, user, Timestamp.valueOf(LocalDateTime.now()), - Timestamp.valueOf(LocalDateTime.now()) + Timestamp.valueOf(LocalDateTime.now()), + url, + tutorial.getBody() ); Tutorial _tutorial = tutorialRepository - .save(newTutorial); + .save(newTutorial); return new ResponseEntity<>(_tutorial, HttpStatus.CREATED); } catch (Exception e) { return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); @@ -124,21 +145,13 @@ public class TutorialController { @GetMapping("user/tutorial-get/{id}") public ResponseEntity getTutorial(@PathVariable("id") long id) { + + User user = userRepository.findById(authenticationFacade.getUserDetails().getId()).get(); + Optional tutorialData = tutorialRepository.findById(id); - if (tutorialData.isPresent()) { - return new ResponseEntity(tutorialData.get(), HttpStatus.OK); - } else { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } - } - - @GetMapping("moderator/tutorial-get/{id}") - public ResponseEntity getBePublishedTutorial(@PathVariable("id") long id) { - Optional tutorialData = tutorialRepository.findById(id); - - if (tutorialData.isPresent()) { + if (tutorialData.isPresent() && tutorialData.get().getUser().getId() == user.getId()) { return new ResponseEntity(tutorialData.get(), HttpStatus.OK); } else { @@ -170,30 +183,6 @@ public class TutorialController { } } - @PutMapping("moderator/tutorial-update/{id}") - public ResponseEntity moderatorUpdateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) { - Optional tutorialData = tutorialRepository.findById(id); - Map map = new LinkedHashMap(); - if (tutorialData.isPresent()) { - Tutorial servTutorial = tutorialData.get(); - servTutorial.setTitle(tutorial.getTitle()); - servTutorial.setDescription(tutorial.getDescription()); - servTutorial.setPublished(tutorial.isPublished()); - servTutorial.setTobepublished(tutorial.isTobepublished()); - try { - servTutorial = tutorialRepository.save(servTutorial); - } catch (Exception e) { - - map.put("status", 0); - map.put("message", e.getMessage()); - return new ResponseEntity<>(map,HttpStatus.INTERNAL_SERVER_ERROR); - } - return new ResponseEntity<>(servTutorial, HttpStatus.OK); - } else { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } - } - @DeleteMapping("user/tutorials/{id}") public ResponseEntity deleteTutorial(@PathVariable("id") long id) { try { @@ -204,6 +193,64 @@ public class TutorialController { } } + + //--------------------moderator methods---------------------------- + + @GetMapping("/moderator/tutorials") + public ResponseEntity> getBePublishedTutorials(@RequestParam(required = false) String title) { + try { + List tutorials = new ArrayList(); + + tutorialRepository.findBytobepublished(true).forEach(tutorials::add); + + if (tutorials.isEmpty()) { + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + return new ResponseEntity<>(tutorials, HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + @GetMapping("moderator/tutorial-get/{id}") + public ResponseEntity getBePublishedTutorial(@PathVariable("id") long id) { + Optional tutorialData = tutorialRepository.findById(id); + + if (tutorialData.isPresent()) { + + return new ResponseEntity(tutorialData.get(), HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + + @PutMapping("moderator/tutorial-update/{id}") + public ResponseEntity moderatorUpdateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) { + Optional tutorialData = tutorialRepository.findById(id); + Map map = new LinkedHashMap(); + if (tutorialData.isPresent()) { + Tutorial servTutorial = tutorialData.get(); + servTutorial.setTitle(tutorial.getTitle()); + servTutorial.setDescription(tutorial.getDescription()); + servTutorial.setPublished(tutorial.isPublished()); + servTutorial.setTobepublished(tutorial.isTobepublished()); + try { + servTutorial = tutorialRepository.save(servTutorial); + } catch (Exception e) { + + map.put("status", 0); + map.put("message", e.getMessage()); + return new ResponseEntity<>(map,HttpStatus.INTERNAL_SERVER_ERROR); + } + return new ResponseEntity<>(servTutorial, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + +/* + @DeleteMapping("/tutorials") public ResponseEntity deleteAllTutorials() { try { @@ -228,5 +275,6 @@ public class TutorialController { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } +*/ } \ No newline at end of file diff --git a/src/main/java/com/jambotronGroup/jambotron/fileUpload/FileUploadExceptionAdvice.java b/src/main/java/com/jambotronGroup/jambotron/fileUpload/FileUploadExceptionAdvice.java new file mode 100644 index 0000000..080beb2 --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/fileUpload/FileUploadExceptionAdvice.java @@ -0,0 +1,19 @@ +package com.jambotronGroup.jambotron.fileUpload; + + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.multipart.MaxUploadSizeExceededException; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +@ControllerAdvice +public class FileUploadExceptionAdvice extends ResponseEntityExceptionHandler { + + +// @ExceptionHandler(MaxUploadSizeExceededException.class) +// public ResponseEntity handleMaxSizeException(MaxUploadSizeExceededException exc) { +// return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage("File too large!")); +// } +} \ No newline at end of file diff --git a/src/main/java/com/jambotronGroup/jambotron/fileUpload/FilesStorageService.java b/src/main/java/com/jambotronGroup/jambotron/fileUpload/FilesStorageService.java new file mode 100644 index 0000000..606f005 --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/fileUpload/FilesStorageService.java @@ -0,0 +1,28 @@ +package com.jambotronGroup.jambotron.fileUpload; + +import org.springframework.core.io.Resource; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.nio.file.Path; +import java.util.stream.Stream; + +public interface FilesStorageService { + public void init(); + + public void save(String userID,MultipartFile file); + + public void save(MultipartFile file); + + public Resource load(String filename); + + public Resource loadUserImage(String userID, String filename); + + public void deleteAll(); + + public Stream loadAll(); + + public Stream loadUserImages(String userID); + + public Path moveFile(String userID, String url, String newFilename) throws Exception; +} \ No newline at end of file diff --git a/src/main/java/com/jambotronGroup/jambotron/fileUpload/FilesStorageServiceImpl.java b/src/main/java/com/jambotronGroup/jambotron/fileUpload/FilesStorageServiceImpl.java new file mode 100644 index 0000000..aae255c --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/fileUpload/FilesStorageServiceImpl.java @@ -0,0 +1,148 @@ +package com.jambotronGroup.jambotron.fileUpload; + + +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; +import org.springframework.stereotype.Service; +import org.springframework.util.FileSystemUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Stream; + +@Service +public class FilesStorageServiceImpl implements FilesStorageService { + + private final Path root = Paths.get("uploads/user-images/"); + + private final Path rootPublic = Paths.get("uploads/public-images/"); + + @Override + public void init() { + try { + Files.createDirectories(root); + Files.createDirectories(rootPublic); + } catch (IOException e) { + throw new RuntimeException("Could not initialize folder for upload!"); + } + } + + public static String getFileNameFromUrl(String urlString) throws Exception { + URL url = new URL(urlString); // Create a URL object + String path = url.getPath(); // Get the path from the URL + return path.substring(path.lastIndexOf('/') + 1); // Extract the file name + } + + @Override + public Path moveFile(String userID, String url, String newFilename) throws Exception { + + String filename = FilesStorageServiceImpl.getFileNameFromUrl(url); + + try { + Path sourcePath = this.root.resolve(userID).resolve(filename); + Path targetPath = this.rootPublic.resolve(newFilename); + Files.copy(sourcePath, targetPath, java.nio.file.StandardCopyOption.REPLACE_EXISTING); + + } catch (IOException e) { + throw new RuntimeException("Could not move the file: " + e.getMessage()); + } + + return this.rootPublic.resolve(newFilename); + } + + @Override + public void save(String userID,MultipartFile file) { + try { + Path path = this.root.resolve(userID); + path.toFile().mkdirs(); // Ensure user directory exists + + Files.copy(file.getInputStream(), path.resolve(file.getOriginalFilename()), + java.nio.file.StandardCopyOption.REPLACE_EXISTING); + } catch (Exception e) { + if (e instanceof FileAlreadyExistsException) { + throw new RuntimeException("A file of that name already exists."); + } + + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public void save(MultipartFile file) { + try { + Files.copy(file.getInputStream(), this.root.resolve(file.getOriginalFilename()), + java.nio.file.StandardCopyOption.REPLACE_EXISTING); + } catch (Exception e) { + if (e instanceof FileAlreadyExistsException) { + throw new RuntimeException("A file of that name already exists."); + } + + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public Resource load(String filename) { + try { + Path file = rootPublic.resolve(filename); + Resource resource = new UrlResource(file.toUri()); + + if (resource.exists() || resource.isReadable()) { + return resource; + } else { + throw new RuntimeException("Could not read the file!"); + } + } catch (MalformedURLException e) { + throw new RuntimeException("Error: " + e.getMessage()); + } + } + + @Override + public Resource loadUserImage(String userID,String filename) { + try { + Path file = root.resolve(filename); + Path userPath = this.root.resolve(userID); + file = userPath.resolve(filename); + Resource resource = new UrlResource(file.toUri()); + + if (resource.exists() || resource.isReadable()) { + return resource; + } else { + throw new RuntimeException("Could not read the file!"); + } + } catch (MalformedURLException e) { + throw new RuntimeException("Error: " + e.getMessage()); + } + } + + @Override + public void deleteAll() { + FileSystemUtils.deleteRecursively(root.toFile()); + } + + @Override + public Stream loadAll() { + try { + return Files.walk(this.root, 1).filter(path -> !path.equals(this.root)).map(this.root::relativize); + } catch (IOException e) { + throw new RuntimeException("Could not load the files!"); + } + } + + @Override + public Stream loadUserImages(String userID) { + Path userPath = this.root.resolve(userID); + userPath.toFile().mkdirs(); + try { + return Files.walk(userPath, 1).filter(path -> !path.equals(userPath)).map(userPath::relativize); + } catch (IOException e) { + throw new RuntimeException("Could not load the files!"); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/jambotronGroup/jambotron/fileUpload/ResponseMessage.java b/src/main/java/com/jambotronGroup/jambotron/fileUpload/ResponseMessage.java new file mode 100644 index 0000000..978fb01 --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/fileUpload/ResponseMessage.java @@ -0,0 +1,18 @@ +package com.jambotronGroup.jambotron.fileUpload; + +public class ResponseMessage { + private String message; + + public ResponseMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} \ No newline at end of file diff --git a/src/main/java/com/jambotronGroup/jambotron/model/Bean.java b/src/main/java/com/jambotronGroup/jambotron/model/Bean.java index c51da42..4df2633 100644 --- a/src/main/java/com/jambotronGroup/jambotron/model/Bean.java +++ b/src/main/java/com/jambotronGroup/jambotron/model/Bean.java @@ -20,6 +20,10 @@ public class Bean { private String typeShortName; private String scope; + public Bean() { + // Default constructor + } + public Bean(String name, String type, String scope) { this.name = name; this.type = type; diff --git a/src/main/java/com/jambotronGroup/jambotron/model/DataBaseSettings.java b/src/main/java/com/jambotronGroup/jambotron/model/DataBaseSettings.java index 7c8d2dd..5b7b3ba 100644 --- a/src/main/java/com/jambotronGroup/jambotron/model/DataBaseSettings.java +++ b/src/main/java/com/jambotronGroup/jambotron/model/DataBaseSettings.java @@ -23,7 +23,9 @@ public class DataBaseSettings { private String password; - + public DataBaseSettings() { + // Default constructor + } public DataBaseSettings(String name) { this.name = name; diff --git a/src/main/java/com/jambotronGroup/jambotron/model/FileInfo.java b/src/main/java/com/jambotronGroup/jambotron/model/FileInfo.java new file mode 100644 index 0000000..83ca3ef --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/model/FileInfo.java @@ -0,0 +1,27 @@ +package com.jambotronGroup.jambotron.model; + +public class FileInfo { + private String name; + private String url; + + public FileInfo(String name, String url) { + this.name = name; + this.url = url; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return this.url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/src/main/java/com/jambotronGroup/jambotron/model/NameValueItem.java b/src/main/java/com/jambotronGroup/jambotron/model/NameValueItem.java index b7e66c4..53a6825 100644 --- a/src/main/java/com/jambotronGroup/jambotron/model/NameValueItem.java +++ b/src/main/java/com/jambotronGroup/jambotron/model/NameValueItem.java @@ -6,6 +6,10 @@ import jakarta.persistence.Id; @Entity public class NameValueItem { + public NameValueItem() { + // Default constructor + } + public NameValueItem(String name, String value){ _name = name; _value = value; diff --git a/src/main/java/com/jambotronGroup/jambotron/model/Tutorial.java b/src/main/java/com/jambotronGroup/jambotron/model/Tutorial.java index f8fca87..75a1cd3 100644 --- a/src/main/java/com/jambotronGroup/jambotron/model/Tutorial.java +++ b/src/main/java/com/jambotronGroup/jambotron/model/Tutorial.java @@ -1,5 +1,6 @@ package com.jambotronGroup.jambotron.model; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import jakarta.persistence.*; import java.sql.Timestamp; @@ -7,6 +8,7 @@ import java.sql.Timestamp; @Entity @Table(name = "tutorials") +@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) public class Tutorial { @Id @@ -25,7 +27,7 @@ public class Tutorial { @Column(name = "tobepublished") private boolean tobepublished; - @ManyToOne(fetch = FetchType.LAZY, optional = false) + @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "userID", nullable = false) private User user; @@ -35,13 +37,17 @@ public class Tutorial { @Column(name = "modified") private java.sql.Timestamp modified; + @Column(name = "titleimage") + private String titleimage; + @Column(name = "body") + private String body; public Tutorial() { } - public Tutorial(String title, String description, boolean published, boolean tobepublished, User user, Timestamp created, Timestamp modified) { + public Tutorial(String title, String description, boolean published, boolean tobepublished, User user, Timestamp created, Timestamp modified, String titleimage, String body) { this.title = title; this.description = description; this.published = published; @@ -49,6 +55,8 @@ public class Tutorial { this.user = user; this.created = created; this.modified = modified; + this.titleimage = titleimage; + this.body = body; } public long getId() { @@ -103,8 +111,28 @@ public class Tutorial { return modified; } + public User getUser() { + return user; + } + @Override public String toString() { return "Tutorial [id=" + id + ", title=" + title + ", desc=" + description + ", published=" + published + "]"; } + + public String getTitleimage() { + return titleimage; + } + + public void setTitleimage(String titleimage) { + this.titleimage = titleimage; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } } \ No newline at end of file diff --git a/src/main/java/com/jambotronGroup/jambotron/payload/request/SaveZhipuAiImageRequest.java b/src/main/java/com/jambotronGroup/jambotron/payload/request/SaveZhipuAiImageRequest.java new file mode 100644 index 0000000..5b41f0d --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/payload/request/SaveZhipuAiImageRequest.java @@ -0,0 +1,18 @@ +package com.jambotronGroup.jambotron.payload.request; + +import jakarta.validation.constraints.NotBlank; + +public class SaveZhipuAiImageRequest { + @NotBlank + private String imageUrl; + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + +} diff --git a/src/main/java/com/jambotronGroup/jambotron/security/AuthenticationFacade.java b/src/main/java/com/jambotronGroup/jambotron/security/AuthenticationFacade.java index da5406c..7cbfc2a 100644 --- a/src/main/java/com/jambotronGroup/jambotron/security/AuthenticationFacade.java +++ b/src/main/java/com/jambotronGroup/jambotron/security/AuthenticationFacade.java @@ -41,7 +41,6 @@ public class AuthenticationFacade implements IAuthenticationFacade { } if (!(authentication.getPrincipal() instanceof UserDetails)) { - throw new IllegalStateException("Authentication principal is not an instance of UserDetails"); } UserDetails userDetails = (UserDetails) authentication.getPrincipal(); @@ -53,21 +52,8 @@ public class AuthenticationFacade implements IAuthenticationFacade { @Override public com.jambotronGroup.jambotron.model.User getUser() { - User returnValue = null; - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (!(authentication.getPrincipal() instanceof UserDetails)) { - logger.info("Authentication principal is not an instance of UserDetails, returning null"); - logger.info(authentication.toString()); - - Optional user = userRepository.findByUsername(authentication.getPrincipal().toString()); - - returnValue = user.get(); - }else{ - UserDetails userDetails = (UserDetails) authentication.getPrincipal(); - UserDetailsImpl userDetailsImpl = (UserDetailsImpl) userDetails; - returnValue = userRepository.findById(userDetailsImpl.getId()).get(); - } + User returnValue = userRepository.findById(this.getUserDetails().getId()).get(); return returnValue; } diff --git a/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java b/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java index 4d09088..19ccd31 100644 --- a/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java +++ b/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java @@ -23,8 +23,12 @@ import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import java.nio.file.Path; +import java.nio.file.Paths; + import static org.springframework.security.config.Customizer.withDefaults; @Configuration @@ -46,6 +50,8 @@ public class WebSecurityConfig implements WebMvcConfigurer {// extends WebSecuri @Autowired private AuthEntryPointJwt unauthorizedHandler; + + @Bean public AuthTokenFilter authenticationJwtTokenFilter() { return new AuthTokenFilter(); @@ -96,9 +102,14 @@ public class WebSecurityConfig implements WebMvcConfigurer {// extends WebSecuri .requestMatchers("/*").permitAll() .requestMatchers("/resources/**").permitAll() + .requestMatchers("/tutorials-images/**").permitAll() + + .requestMatchers("/files/**").permitAll() + .requestMatchers("/api/auth/**").permitAll() // Allow public access to tutorials (without login) - .requestMatchers("/api/public/tutorials").permitAll() + .requestMatchers("/api/public/**").permitAll() + //.requestMatchers("/api/public/tutorials").permitAll() //.requestMatchers("/api/public/tutorials/**").permitAll() //TODO: need check the puth .requestMatchers("/api/public/zhipuai/image/**").permitAll() @@ -111,47 +122,8 @@ public class WebSecurityConfig implements WebMvcConfigurer {// extends WebSecuri .anyRequest().authenticated() - - /* // Allow access to specific API endpoints without authentication - .requestMatchers("/api/auth/**").permitAll() - - // Allow access to specific resources - - .requestMatchers("/*", "/home", "/resources/**").permitAll() - .requestMatchers("/resources/public/media/**").permitAll() - .requestMatchers("/resources/public/browser/**").permitAll() - .requestMatchers("/media/**").permitAll() - - .requestMatchers("/main/**").permitAll() - .requestMatchers("/api/test/**").permitAll() - - .requestMatchers("/api/tutorials").permitAll() - - - - .requestMatchers("/api/users").permitAll() - .requestMatchers("/api/users/**").permitAll() - - .requestMatchers("/api/roles").permitAll() - .requestMatchers("/api/roles/**").permitAll() - - .requestMatchers("/api/tutorials/**").permitAll() - - .requestMatchers("/api/settings").permitAll() - .requestMatchers("/api/system/**").permitAll() -*/ - - ); - /* if(_environment.getProperty("app.cors_enabled") != null && - _environment.getProperty("app.cors_enabled").equalsIgnoreCase("true")) { - http.cors(withDefaults()); - } else { - http.cors(cors -> cors.disable()); - }*/ - - if(_environment.getProperty("server.port") != null && _environment.getProperty("server.port").equalsIgnoreCase("443")) { http.redirectToHttps(withDefaults()); @@ -164,18 +136,20 @@ public class WebSecurityConfig implements WebMvcConfigurer {// extends WebSecuri return http.build(); } -/* @Bean - public CorsFilter corsFilter() { - CorsConfiguration corsConfiguration = new CorsConfiguration(); - corsConfiguration.setAllowCredentials(true); // Allow credentials - corsConfiguration.addAllowedOrigin("http://localhost:4200/"); - corsConfiguration.addAllowedHeader("*"); // Allow all headers + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + exposeDirectory("tutorials-images", registry); + } - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - source.registerCorsConfiguration("/**", corsConfiguration); // Apply to all endpoints + private void exposeDirectory(String dirName, ResourceHandlerRegistry registry) { + Path uploadDir = Paths.get(dirName); + String uploadPath = uploadDir.toFile().getAbsolutePath(); + + if (dirName.startsWith("../")) dirName = dirName.replace("../", ""); + + registry.addResourceHandler("/" + dirName + "/**").addResourceLocations("file:/"+ uploadPath + "/"); + } - return new CorsFilter(source); - }*/ } diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index bb2346c..ec0b3a8 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -34,3 +34,10 @@ app.jwtSecret= ======================spring=back==================== app.jwtExpirationMs= 800000 app.jwtCookieName=springangularts +#=============File Upload Configurations======================== +spring.servlet.multipart.max-file-size=50MB +spring.servlet.multipart.max-request-size=50MB + + +server.tomcat.max-swallow-size=100MB +#============= \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 70951bf..c171f29 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -45,6 +45,11 @@ spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect spring.jpa.show-sql=true +#=============Zhipuai Configurations======================== + +spring.ai.zhipuai.base-url=https://open.bigmodel.cn/api/paas/v4/images/generations +spring.ai.zhipuai.api-key = 628447c8c65845a48a7226391464a2ea.Dw8ci6TiW0BRF5LI + #==================Custom App Properties===================== app.jwtSecret= ======================spring=back==================== @@ -52,7 +57,10 @@ app.jwtExpirationMs= 800000 app.jwtCookieName=springangularts -#=============Zhipuai Configurations======================== +#=============File Upload Configurations======================== +spring.servlet.multipart.max-file-size=50MB +spring.servlet.multipart.max-request-size=50MB -spring.ai.zhipuai.base-url=https://open.bigmodel.cn/api/paas/v4/images/generations -spring.ai.zhipuai.api-key = 628447c8c65845a48a7226391464a2ea.Dw8ci6TiW0BRF5LI +server.tomcat.max-swallow-size=100MB + +#============= diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 11710b4..31a9236 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,4 @@ +#bootJar with profile prod spring.profiles.active=prod +#spring.profiles.active=dev diff --git a/src/main/resources/db/migration/V9__title_image.sql b/src/main/resources/db/migration/V9__title_image.sql new file mode 100644 index 0000000..862d17f --- /dev/null +++ b/src/main/resources/db/migration/V9__title_image.sql @@ -0,0 +1,9 @@ +ALTER TABLE IF EXISTS public.tutorials DROP COLUMN IF EXISTS titleimage; + +ALTER TABLE IF EXISTS public.tutorials + ADD COLUMN titleimage text COLLATE pg_catalog."default"; + +ALTER TABLE IF EXISTS public.tutorials DROP COLUMN IF EXISTS body; + +ALTER TABLE IF EXISTS public.tutorials + ADD COLUMN body text COLLATE pg_catalog."default"; \ No newline at end of file