diff --git a/jambotron-ui/package-lock.json b/jambotron-ui/package-lock.json
index fba3123..281227c 100644
--- a/jambotron-ui/package-lock.json
+++ b/jambotron-ui/package-lock.json
@@ -19,20 +19,19 @@
"@angular/platform-server": "^20.0.0",
"@angular/router": "^20.0.0",
"@angular/ssr": "^20.0.2",
- "@ant-design/icons-angular": "19.0.0",
- "@hreimer/angular-image-viewer": "^0.14.1",
+ "@fortawesome/angular-fontawesome": "^3.0.0",
+ "@fortawesome/fontawesome-svg-core": "^6.1.1",
+ "@fortawesome/free-brands-svg-icons": "^6.1.1",
+ "@fortawesome/free-solid-svg-icons": "^6.1.1",
"@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",
+ "cropperjs": "^1.5.12",
"express": "^5.1.0",
- "file-saver": "^2.0.5",
- "ngx-filesaver": "^20.0.0",
+ "ngx-image-cropper": "^9.1.5",
"ngx-markdown": "^20.0.0",
- "ngx-scrollbar": "18.0.0",
- "primeng": "^19.1.3",
"prismjs": "^1.30.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
@@ -947,43 +946,6 @@
}
}
},
- "node_modules/@ant-design/colors": {
- "version": "7.2.1",
- "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.2.1.tgz",
- "integrity": "sha512-lCHDcEzieu4GA3n8ELeZ5VQ8pKQAWcGGLRTQ50aQM2iqPpq2evTxER84jfdPvsPAtEcZ7m44NI45edFMo8oOYQ==",
- "license": "MIT",
- "dependencies": {
- "@ant-design/fast-color": "^2.0.6"
- }
- },
- "node_modules/@ant-design/fast-color": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-2.0.6.tgz",
- "integrity": "sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.24.7"
- },
- "engines": {
- "node": ">=8.x"
- }
- },
- "node_modules/@ant-design/icons-angular": {
- "version": "19.0.0",
- "resolved": "https://registry.npmjs.org/@ant-design/icons-angular/-/icons-angular-19.0.0.tgz",
- "integrity": "sha512-bBWFA1cTZwLAFTgpozkeNIHX1nXyZuiUaRzTcAfFEt85eW1X3ypMcBfS/XEVVVzkdTw5Td+E1vwzgfuUlKiYSA==",
- "license": "MIT",
- "dependencies": {
- "@ant-design/colors": "^7.0.0",
- "tslib": "^2.0.0"
- },
- "peerDependencies": {
- "@angular/common": "^19.0.0",
- "@angular/core": "^19.0.0",
- "@angular/platform-browser": "^19.0.0",
- "rxjs": "^6.5.3 || ^7.4.0"
- }
- },
"node_modules/@antfu/install-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
@@ -2570,15 +2532,6 @@
"@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
}
},
- "node_modules/@babel/runtime": {
- "version": "7.27.6",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz",
- "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/template": {
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
@@ -2688,126 +2641,6 @@
"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",
@@ -3243,78 +3076,84 @@
"node": ">=18"
}
},
- "node_modules/@fortawesome/fontawesome-free": {
- "version": "5.15.4",
- "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz",
- "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==",
- "hasInstallScript": true,
- "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)",
- "optional": true,
+ "node_modules/@fortawesome/angular-fontawesome": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/angular-fontawesome/-/angular-fontawesome-3.0.0.tgz",
+ "integrity": "sha512-+8Dd6DoJnqArfrZ5NvjHyRL64IIkTigXclbOOcFdYQ8/WFERQUDaEU6SAV8Q0JBpJhMS1McED7YCOCAE6SIVyA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^7.0.0",
+ "tslib": "^2.8.1"
+ },
+ "peerDependencies": {
+ "@angular/core": "^20.0.0"
+ }
+ },
+ "node_modules/@fortawesome/angular-fontawesome/node_modules/@fortawesome/fontawesome-common-types": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-7.0.0.tgz",
+ "integrity": "sha512-PGMrIYXLGA5K8RWy8zwBkd4vFi4z7ubxtet6Yn13Plf6krRTwPbdlCwlcfmoX0R7B4Z643QvrtHmdQ5fNtfFCg==",
+ "license": "MIT",
"engines": {
"node": ">=6"
}
},
- "node_modules/@hreimer/angular-image-viewer": {
- "version": "0.14.1",
- "resolved": "https://registry.npmjs.org/@hreimer/angular-image-viewer/-/angular-image-viewer-0.14.1.tgz",
- "integrity": "sha512-ZVV2xizunKqqlLewrBgshJJnfJ5IdyngwtNWj8c8tnHCFaR4xh6afL02NQthAYxv2rKMcaE7zkL6ZiR7tc6tCQ==",
+ "node_modules/@fortawesome/angular-fontawesome/node_modules/@fortawesome/fontawesome-svg-core": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-7.0.0.tgz",
+ "integrity": "sha512-obBEF+zd98r/KtKVW6A+8UGWeaOoyMpl6Q9P3FzHsOnsg742aXsl8v+H/zp09qSSu/a/Hxe9LNKzbBaQq1CEbA==",
"license": "MIT",
"dependencies": {
- "tslib": "^2.3.0"
+ "@fortawesome/fontawesome-common-types": "7.0.0"
},
- "optionalDependencies": {
- "@angular/cdk": "^11.0.0 || ^12.0.0 || ^13.0.0 || ^13.0.0",
- "@angular/material": "^11.0.0 || ^12.0.0 || ^13.0.0 || ^13.0.0",
- "@fortawesome/fontawesome-free": "^5.15.4"
- },
- "peerDependencies": {
- "@angular/common": "^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0",
- "@angular/core": "^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0"
+ "engines": {
+ "node": ">=6"
}
},
- "node_modules/@hreimer/angular-image-viewer/node_modules/@angular/cdk": {
- "version": "13.3.9",
- "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-13.3.9.tgz",
- "integrity": "sha512-XCuCbeuxWFyo3EYrgEYx7eHzwl76vaWcxtWXl00ka8d+WAOtMQ6Tf1D98ybYT5uwF9889fFpXAPw98mVnlo3MA==",
+ "node_modules/@fortawesome/fontawesome-common-types": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz",
+ "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/fontawesome-svg-core": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz",
+ "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==",
"license": "MIT",
- "optional": true,
"dependencies": {
- "tslib": "^2.3.0"
+ "@fortawesome/fontawesome-common-types": "6.7.2"
},
- "optionalDependencies": {
- "parse5": "^5.0.0"
- },
- "peerDependencies": {
- "@angular/common": "^13.0.0 || ^14.0.0-0",
- "@angular/core": "^13.0.0 || ^14.0.0-0",
- "rxjs": "^6.5.3 || ^7.4.0"
+ "engines": {
+ "node": ">=6"
}
},
- "node_modules/@hreimer/angular-image-viewer/node_modules/@angular/material": {
- "version": "13.3.9",
- "resolved": "https://registry.npmjs.org/@angular/material/-/material-13.3.9.tgz",
- "integrity": "sha512-FU8lcMgo+AL8ckd27B4V097ZPoIZNRHiCe3wpgkImT1qC0YwcyXZVn0MqQTTFSdC9a/aI8wPm3AbTClJEVw5Vw==",
- "license": "MIT",
- "optional": true,
+ "node_modules/@fortawesome/free-brands-svg-icons": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.7.2.tgz",
+ "integrity": "sha512-zu0evbcRTgjKfrr77/2XX+bU+kuGfjm0LbajJHVIgBWNIDzrhpRxiCPNT8DW5AdmSsq7Mcf9D1bH0aSeSUSM+Q==",
+ "license": "(CC-BY-4.0 AND MIT)",
"dependencies": {
- "tslib": "^2.3.0"
+ "@fortawesome/fontawesome-common-types": "6.7.2"
},
- "peerDependencies": {
- "@angular/animations": "^13.0.0 || ^14.0.0-0",
- "@angular/cdk": "13.3.9",
- "@angular/common": "^13.0.0 || ^14.0.0-0",
- "@angular/core": "^13.0.0 || ^14.0.0-0",
- "@angular/forms": "^13.0.0 || ^14.0.0-0",
- "@angular/platform-browser": "^13.0.0 || ^14.0.0-0",
- "rxjs": "^6.5.3 || ^7.4.0"
+ "engines": {
+ "node": ">=6"
}
},
- "node_modules/@hreimer/angular-image-viewer/node_modules/parse5": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
- "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
- "license": "MIT",
- "optional": true
+ "node_modules/@fortawesome/free-solid-svg-icons": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz",
+ "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==",
+ "license": "(CC-BY-4.0 AND MIT)",
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.7.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
},
"node_modules/@iconify/types": {
"version": "2.0.0",
@@ -7717,14 +7556,10 @@
}
},
"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"
- }
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.6.2.tgz",
+ "integrity": "sha512-nhymn9GdnV3CqiEHJVai54TULFAE3VshJTXSqSJKa8yXAKyBKDWdhHarnlIPrshJ0WMFTGuFvG02YjLXfPiuOA==",
+ "license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.6",
@@ -9259,12 +9094,6 @@
}
}
},
- "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",
@@ -12204,17 +12033,17 @@
"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==",
+ "node_modules/ngx-image-cropper": {
+ "version": "9.1.5",
+ "resolved": "https://registry.npmjs.org/ngx-image-cropper/-/ngx-image-cropper-9.1.5.tgz",
+ "integrity": "sha512-I8MAjMREtXDALgYyeMIvcqE+WpXA4IA9Z59JsujDuqOnjFY/Mpb+8JUyVVuOa0Irp20ukDPQJZmECR4v96hTrg==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
},
"peerDependencies": {
- "@types/file-saver": "^2.0.0",
- "file-saver": "^2.0.0"
+ "@angular/common": ">=17.3.0",
+ "@angular/core": ">=17.3.0"
}
},
"node_modules/ngx-markdown": {
@@ -12241,21 +12070,6 @@
"zone.js": "~0.15.0"
}
},
- "node_modules/ngx-scrollbar": {
- "version": "18.0.0",
- "resolved": "https://registry.npmjs.org/ngx-scrollbar/-/ngx-scrollbar-18.0.0.tgz",
- "integrity": "sha512-+ykmY491x+nzXvnecJvZHvDz0YWuX1r7SYMxNG4RVHXm5Z68P/8kd/3ryLD6DXdNWmJawd4NGvqq2ZkUKb/g3A==",
- "license": "MIT",
- "dependencies": {
- "tslib": "^2.3.0"
- },
- "peerDependencies": {
- "@angular/cdk": ">=19.0.0",
- "@angular/common": ">=19.0.0",
- "@angular/core": ">=19.0.0",
- "rxjs": ">=7.0.0"
- }
- },
"node_modules/node-addon-api": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
@@ -13241,27 +13055,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/primeng": {
- "version": "19.1.3",
- "resolved": "https://registry.npmjs.org/primeng/-/primeng-19.1.3.tgz",
- "integrity": "sha512-KsrvJFblKg28kA6d4npnnABjKClmJv0CgDT/kOxFq5onQNBy4547DJzRGMba4+CMLKjHWWkYWuC+XSkPMNFrZg==",
- "license": "SEE LICENSE IN LICENSE.md",
- "dependencies": {
- "@primeuix/styled": "^0.3.2",
- "@primeuix/utils": "^0.3.2",
- "tslib": "^2.3.0"
- },
- "peerDependencies": {
- "@angular/animations": "^19.0.0",
- "@angular/cdk": "^19.0.0",
- "@angular/common": "^19.0.0",
- "@angular/core": "^19.0.0",
- "@angular/forms": "^19.0.0",
- "@angular/platform-browser": "^19.0.0",
- "@angular/router": "^19.0.0",
- "rxjs": "^6.0.0 || ^7.8.1"
- }
- },
"node_modules/prismjs": {
"version": "1.30.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
diff --git a/jambotron-ui/package.json b/jambotron-ui/package.json
index 4e9a8bc..234fc42 100644
--- a/jambotron-ui/package.json
+++ b/jambotron-ui/package.json
@@ -24,13 +24,18 @@
"@angular/platform-server": "^20.0.0",
"@angular/router": "^20.0.0",
"@angular/ssr": "^20.0.2",
+ "@fortawesome/angular-fontawesome": "^3.0.0",
+ "@fortawesome/fontawesome-svg-core": "^6.1.1",
+ "@fortawesome/free-brands-svg-icons": "^6.1.1",
+ "@fortawesome/free-solid-svg-icons": "^6.1.1",
"@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",
+ "ngx-image-cropper": "^9.1.5",
"ngx-markdown": "^20.0.0",
"prismjs": "^1.30.0",
"rxjs": "~7.8.0",
diff --git a/jambotron-ui/public/jambotron_logo.svg b/jambotron-ui/public/jambotron_logo.svg
index 9135899..e917217 100644
--- a/jambotron-ui/public/jambotron_logo.svg
+++ b/jambotron-ui/public/jambotron_logo.svg
@@ -4,6 +4,6 @@
Layer 1
jambotron
+ font-size="24" fileName="svg_1" y="27.49999" x="2.59999" stroke-width="0" stroke="#000" fill="#000000">jambotron
diff --git a/jambotron-ui/src/app/app.config.ts b/jambotron-ui/src/app/app.config.ts
index b527fc1..0f03633 100644
--- a/jambotron-ui/src/app/app.config.ts
+++ b/jambotron-ui/src/app/app.config.ts
@@ -9,7 +9,6 @@ import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideClientHydration, withEventReplay } from '@angular/platform-browser';
import {AppModule} from './app.module';
-import {providePrimeNG} from 'primeng/config';
import Aura from '@primeng/themes/aura';
import {provideAnimations} from '@angular/platform-browser/animations';
import {provideMarkdown} from 'ngx-markdown';
@@ -24,11 +23,6 @@ export const appConfig: ApplicationConfig = {
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes), provideClientHydration(withEventReplay()),
provideMarkdown(),
- importProvidersFrom(AppModule),
- providePrimeNG({
- theme: {
- preset: Aura
- }
- })
+ importProvidersFrom(AppModule)
]
};
diff --git a/jambotron-ui/src/app/app.ts b/jambotron-ui/src/app/app.ts
index 571584f..095273c 100644
--- a/jambotron-ui/src/app/app.ts
+++ b/jambotron-ui/src/app/app.ts
@@ -1,6 +1,10 @@
import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
-import { RouterOutlet } from '@angular/router';
+import {Router, RouterOutlet} from '@angular/router';
import {SpinnerComponent} from './components/spinner/spinner.component';
+import {EventBusService} from './_shared/event-bus.service';
+import {AuthService} from './services/auth.service';
+import {TokenStorageService} from './services/token-storage.service';
+import {GlobalConstants} from './global-constants';
@Component({
selector: 'app-root',
@@ -15,7 +19,26 @@ import {SpinnerComponent} from './components/spinner/spinner.component';
export class App {
protected title = 'jambotron-ui';
- constructor() {
+ constructor(
+ private eventBusService:EventBusService,
+ private authService:AuthService,
+ private tokenStorageService:TokenStorageService,
+ private router: Router
+ ) {
+ this.eventBusService.on('logout', () => {
+ console.log('eventBusService logout');
+ this.authService.logout().subscribe({
+ next: res => {
+ console.log(res);
+ this.tokenStorageService.clean();
+
+ router.navigate([GlobalConstants.DEFAULT_PAGE]).then();
+ },
+ error: err => {
+ console.log(err);
+ }
+ });
+ })
}
}
diff --git a/jambotron-ui/src/app/components/file-upload.component/file-upload.component.html b/jambotron-ui/src/app/components/file-upload.component/file-upload.component.html
index 18201d4..9f26f16 100644
--- a/jambotron-ui/src/app/components/file-upload.component/file-upload.component.html
+++ b/jambotron-ui/src/app/components/file-upload.component/file-upload.component.html
@@ -14,7 +14,7 @@
diff --git a/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.html b/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.html
new file mode 100644
index 0000000..9e394a7
--- /dev/null
+++ b/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.html
@@ -0,0 +1,103 @@
+
diff --git a/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.scss b/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.scss
new file mode 100644
index 0000000..d93e233
--- /dev/null
+++ b/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.scss
@@ -0,0 +1,179 @@
+@import "~node_modules/cropperjs/dist/cropper.css";
+
+.ngx-pe-overlay-container {
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, 0.25);
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ z-index: 99999;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ overflow: hidden;
+ padding: 1rem;
+ box-sizing: border-box;
+}
+.ngx-pe-overlay-container * {
+ box-sizing: border-box;
+}
+.ngx-pe-dialog-container {
+ position: relative;
+ border-radius: 4px;
+ overflow: hidden;
+ outline: 0;
+ width: 100%;
+ height: auto;
+ max-height: 95vh;
+ box-shadow: 0 11px 15px -7px #0003, 0 24px 38px 3px #00000024, 0 9px 46px 8px #0000001f;
+ background: #333333;
+ color: white;
+ display: flex;
+ flex-direction: column;
+}
+.ngx-pe-dialog-header {
+ padding: 1rem 1rem 1rem 1rem;
+ font-size: 1rem;
+ font-weight: 400;
+}
+.ngx-pe-dialog-body {
+ height: 100%;
+ position: relative;
+ box-sizing: border-box;
+}
+.ngx-pe-dialog-footer {
+ padding: 1rem 1rem;
+ display: flex;
+ justify-content: flex-end;
+ gap: 0.5rem;
+}
+.ngx-pe-cropper-wrapper {
+ position: relative;
+}
+.ngx-pe-img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+ max-height: 300px;
+}
+.ngx-pe-tool-bar {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+ background-color: #222;
+ box-sizing: border-box;
+ width: 100%;
+}
+.ngx-pe-tool-bar button {
+ background-color: transparent;
+ border-width: 0;
+ color: #fff;
+ cursor: pointer;
+ float: left;
+ font-size: 0.875rem;
+ height: 2.5rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 2.5rem;
+}
+.ngx-pe-tool-bar button:hover {
+ background-color: #0074d9;
+ color: #fff;
+}
+.ngx-pe-tool-bar svg {
+ width: 20px;
+ height: 20px;
+ fill: white;
+}
+.ngx-pe-btn {
+ --bs-btn-padding-y: 0.25rem;
+ --bs-btn-padding-x: 1rem;
+ --bs-btn-font-size: 0.875rem;
+ --bs-btn-border-radius: 0.25rem;
+ --bs-btn-font-weight: 400;
+ --bs-btn-line-height: 1.5;
+ --bs-btn-color: #212529;
+ --bs-btn-bg: transparent;
+ --bs-btn-border-width: 1px;
+ --bs-btn-border-color: transparent;
+ --bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+ --bs-btn-disabled-opacity: 0.65;
+ --bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb));
+ display: inline-block;
+ padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x);
+ font-size: var(--bs-btn-font-size);
+ font-weight: var(--bs-btn-font-weight);
+ line-height: var(--bs-btn-line-height);
+ color: var(--bs-btn-color);
+ text-align: center;
+ text-decoration: none;
+ vertical-align: middle;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ border: var(--bs-btn-border-width) solid var(--bs-btn-border-color);
+ border-radius: var(--bs-btn-border-radius);
+ background-color: var(--bs-btn-bg);
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+.ngx-pe-btn:hover {
+ color: var(--bs-btn-hover-color);
+ background-color: var(--bs-btn-hover-bg);
+ border-color: var(--bs-btn-hover-border-color);
+}
+.ngx-pe-btn-outline-light {
+ --bs-btn-color: #f8f9fa;
+ --bs-btn-border-color: #f8f9fa;
+ --bs-btn-hover-color: #000;
+ --bs-btn-hover-bg: #f8f9fa;
+ --bs-btn-hover-border-color: #f8f9fa;
+ --bs-btn-focus-shadow-rgb: 248, 249, 250;
+ --bs-btn-active-color: #000;
+ --bs-btn-active-bg: #f8f9fa;
+ --bs-btn-active-border-color: #f8f9fa;
+ --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --bs-btn-disabled-color: #f8f9fa;
+ --bs-btn-disabled-bg: transparent;
+ --bs-gradient: none;
+}
+.ngx-pe-btn-primary {
+ --bs-btn-color: #fff;
+ --bs-btn-bg: #0d6efd;
+ --bs-btn-border-color: #0d6efd;
+ --bs-btn-hover-color: #fff;
+ --bs-btn-hover-bg: #0b5ed7;
+ --bs-btn-hover-border-color: #0a58ca;
+ --bs-btn-focus-shadow-rgb: 49, 132, 253;
+ --bs-btn-active-color: #fff;
+ --bs-btn-active-bg: #0a58ca;
+ --bs-btn-active-border-color: #0a53be;
+ --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --bs-btn-disabled-color: #fff;
+ --bs-btn-disabled-bg: #0d6efd;
+ --bs-btn-disabled-border-color: #0d6efd;
+}
+.ngx-pe-loading {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ z-index: 2;
+ background-color: #222222;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ transition: all 10s ease;
+}
+.ngx-pe-processing {
+ background-color: rgba(34,34,34, 0.8);
+}
+.ngx-pe-loading svg {
+ width: 50px;
+}
diff --git a/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.spec.ts b/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.spec.ts
new file mode 100644
index 0000000..1beb93d
--- /dev/null
+++ b/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { PhotoEditComponent } from './photo-edit.component';
+
+describe('PhotoEditComponent', () => {
+ let component: PhotoEditComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [PhotoEditComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(PhotoEditComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.ts b/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.ts
new file mode 100644
index 0000000..d7c8779
--- /dev/null
+++ b/jambotron-ui/src/app/components/photo-edit.component/photo-edit.component.ts
@@ -0,0 +1,228 @@
+/*
+import {Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild} from '@angular/core';
+import Cropper from "cropperjs";
+import ViewMode = Cropper.ViewMode;
+import {NgIf, NgOptimizedImage} from '@angular/common';
+
+
+@Component({
+ selector: 'app-photo-edit.component',
+ imports: [
+ NgIf,
+ NgOptimizedImage
+ ],
+ templateUrl: './photo-edit.component.html',
+ styleUrl: './photo-edit.component.scss'
+})
+export class PhotoEditComponent implements OnDestroy {
+
+@ViewChild('image')
+ image!: ElementRef;
+
+private cropper!: Cropper;
+public imgUrl!: string;
+private FILES_REGEX = /\.(gif|jpe?g|tiff|png|webp|bmp)$/i;
+
+
+@Input() modalTitle:String = 'Photo Editor';
+@Input() hideModalHeader = false;
+@Input() aspectRatio = NaN;
+@Input() autoCropArea = 0.8;
+@Input() autoCrop = true;
+@Input() mask = true;
+@Input() guides = true;
+@Input() centerIndicator = true;
+@Input() viewMode:ViewMode = 0;
+@Input() modalMaxWidth = '500px';
+@Input() modalCentered = false;
+@Input() scalable = true;
+@Input() zoomable = true;
+@Input() cropBoxMovable = true;
+@Input() cropBoxResizable = true;
+@Input() darkTheme = true;
+@Input() roundCropper = false;
+@Input() canvasHeight = 400;
+
+@Input() resizeToWidth: number | any;
+@Input() resizeToHeight: number | any;
+@Input() imageSmoothingEnabled = true;
+@Input() imageSmoothingQuality: ImageSmoothingQuality = 'high';
+@Input() format: string | any;
+
+@Input() closeBtnText = 'Close';
+@Input() applyBtnText = 'Apply';
+
+ quality = 92;
+
+@Input() set imageQuality(value: number) {
+ if (value > 0 && value <= 100) {
+ this.quality = value;
+ } else {
+ this.errorEvent.error('Invalid image quality');
+ }
+ }
+
+@Output() closeEvent = new EventEmitter();
+@Output() imageCroppedEvent = new EventEmitter();
+@Output() errorEvent = new EventEmitter();
+ imageLoaded = false;
+ isProcessing = false;
+
+
+@Input() set source(data: File | string | any) {
+ if (data instanceof Event) {
+ // @ts-ignore
+ const file = (data.target).files[0];
+ if (this.FILES_REGEX.test(file.name)) {
+ if (!this.format) {
+ // @ts-ignore
+ this.format = data.target.files[0].type.split('/')[1];
+ }
+ const reader = new FileReader();
+ reader.onload = (ev: any) => {
+ this.imgUrl = ev.target.result;
+ };
+ // @ts-ignore
+ reader.readAsDataURL(data.target.files[0]);
+ } else {
+ console.log('error');
+ this.errorEvent.emit('Not supported INPUT');
+ }
+ } else if (data instanceof File) {
+ if (this.FILES_REGEX.test(data.name)) {
+ if (!this.format) {
+ this.format = data.type.split('/')[1];
+ }
+ const reader = new FileReader();
+ reader.onload = (ev: any) => {
+ this.imgUrl = ev.target.result;
+ };
+ reader.readAsDataURL(data);
+ } else {
+ this.errorEvent.emit('Not supported INPUT');
+ }
+ } else if (typeof data === 'string') {
+ if ((/^data:image\/([a-zA-Z]*);base64,([^\"]*)$/).test(data)) {
+ this.imgUrl = data;
+ if (!this.format) {
+ this.format = ((data.split(',')[0]).split(';')[0]).split(':')[1].split('/')[1];
+ }
+ } else if (this.isValidImageURL(data)) {
+ this.imgUrl = data;
+ if (!this.format) {
+ // @ts-ignore
+ this.format = data.split(/[#?]/)[0].split('.').pop().trim();
+ }
+ } else {
+ this.errorEvent.emit('Not supported URL');
+ }
+ } else {
+ this.errorEvent.emit('Not supported INPUT');
+ }
+ }
+
+ isValidImageURL(str: string) {
+ return str.match(/^http[^\?]*.(jpg|jpeg|gif|png|tiff|bmp)(\?(.*))?(\#(.*))?$/gim);
+ }
+
+ rotateRight() {
+ this.cropper.rotate(45);
+ }
+
+ rotateLeft() {
+ this.cropper.rotate(-45);
+ }
+
+ crop() {
+ this.cropper.setDragMode('crop');
+ }
+
+ move() {
+ this.cropper.setDragMode('move');
+ }
+
+ zoomIn() {
+ this.cropper.zoom(0.1);
+ }
+
+ zoomOut() {
+ this.cropper.zoom(-0.1);
+ }
+
+ flipH() {
+ this.cropper.scaleX(-this.cropper.getImageData().scaleX);
+ }
+
+ flipV() {
+ this.cropper.scaleY(-this.cropper.getImageData().scaleY);
+ }
+
+ reset() {
+ this.cropper.reset();
+ }
+
+export() {
+ this.isProcessing = true;
+ this.imageLoaded = false;
+ let cropedImage = this.cropper.getCroppedCanvas({
+ width: this.resizeToWidth,
+ height: this.resizeToHeight,
+ imageSmoothingEnabled: this.imageSmoothingEnabled,
+ imageSmoothingQuality: this.imageSmoothingQuality
+ });
+
+ const outputImage = cropedImage.toDataURL('image/' + this.format, this.quality);
+ cropedImage.toBlob((blob: any) => {
+ this.imageCroppedEvent.emit({
+ base64: outputImage,
+ file: new File([blob],
+ Date.now() + '.' + this.format,
+ {type: 'image/' + this.format})
+ });
+ this.isProcessing = false;
+ this.imageLoaded = true;
+ }, 'image/' + this.format, this.quality / 100);
+ }
+
+
+ close() {
+ this.closeEvent.emit();
+ }
+
+ onLoad() {
+ this.image.nativeElement.addEventListener('ready', () => {
+ this.imageLoaded = true;
+ });
+
+ this.cropper = new Cropper(this.image.nativeElement, {
+ aspectRatio: this.aspectRatio,
+ autoCropArea: this.autoCropArea,
+ autoCrop: this.autoCrop,
+ modal: this.mask, // black mask
+ guides: this.guides, // grid
+ center: this.centerIndicator, // center indicator
+ viewMode: this.viewMode,
+ scalable: this.scalable,
+ zoomable: this.zoomable,
+ background: false,
+ cropBoxMovable: this.cropBoxMovable,
+ cropBoxResizable: this.cropBoxResizable,
+ });
+ }
+
+ ngOnDestroy(): void {
+ console.log('destroyed');
+ }
+
+ error() {
+ this.errorEvent.emit('Error loading image');
+ }
+}
+
+export interface PhotoEditCroppedEvent {
+ base64?: string;
+ file?: File;
+}
+
+export type imageFormat = 'gif' | 'jpeg' | 'tiff' | 'png' | 'webp' | 'bmp';
+*/
diff --git a/jambotron-ui/src/app/components/photo-edit.component/photo-editor.service.spec.ts b/jambotron-ui/src/app/components/photo-edit.component/photo-editor.service.spec.ts
new file mode 100644
index 0000000..94f9a78
--- /dev/null
+++ b/jambotron-ui/src/app/components/photo-edit.component/photo-editor.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { PhotoEditorService } from './photo-editor.service';
+
+describe('PhotoEditorService', () => {
+ let service: PhotoEditorService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(PhotoEditorService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/jambotron-ui/src/app/components/photo-edit.component/photo-editor.service.ts b/jambotron-ui/src/app/components/photo-edit.component/photo-editor.service.ts
new file mode 100644
index 0000000..b524f0e
--- /dev/null
+++ b/jambotron-ui/src/app/components/photo-edit.component/photo-editor.service.ts
@@ -0,0 +1,92 @@
+/*
+import {
+ ApplicationRef,
+ ComponentFactoryResolver,
+ ComponentRef,
+ EmbeddedViewRef,
+ Injectable,
+ Injector, ViewContainerRef
+} from '@angular/core';
+import {Observable, Subject} from 'rxjs';
+import {PhotoEditComponent, PhotoEditCroppedEvent} from './photo-edit.component';
+import ViewMode = Cropper.ViewMode;
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PhotoEditorService {
+
+ private photoEditorSubscriber!: Subject;
+ private photoEditorComponentRef!: ComponentRef;
+
+
+ constructor(
+ private componentFactoryResolver: ComponentFactoryResolver,
+ private appRef: ApplicationRef,
+ private injector: Injector) {
+ }
+
+ open(source: Event | string | File | any, options?: Options): Observable {
+ const componentFactory = this.componentFactoryResolver.resolveComponentFactory(PhotoEditComponent);
+ const componentRef = componentFactory.create(this.injector);
+ this.appRef.attachView(componentRef.hostView);
+ const domElem = (componentRef.hostView as EmbeddedViewRef).rootNodes[0] as HTMLElement;
+ document.body.appendChild(domElem);
+ this.photoEditorSubscriber = new Subject();
+ this.photoEditorComponentRef = componentRef;
+ this.photoEditorComponentRef.instance.closeEvent.subscribe(() => this.close());
+ this.photoEditorComponentRef.instance.errorEvent.subscribe((data) => this.errorHandler(data));
+ this.photoEditorComponentRef.instance.imageCroppedEvent.subscribe((data) => this.export(data));
+ if (options) {
+ Object.keys(options).map(value => {
+ // @ts-ignore
+ this.photoEditorComponentRef.instance[value] = options[value];
+ })
+ }
+ this.photoEditorComponentRef.instance.source = source;
+ return this.photoEditorSubscriber.asObservable();
+ }
+
+ private errorHandler(data: any) {
+ this.photoEditorSubscriber.error(data);
+ this.close();
+ }
+
+ private close() {
+ this.photoEditorSubscriber.complete();
+ this.photoEditorComponentRef.destroy();
+ }
+
+ private export(data: any) {
+ this.photoEditorSubscriber.next(data);
+ this.close();
+ }
+
+}
+
+export interface Options {
+ aspectRatio?: number | any;
+ modalTitle?: string;
+ hideModalHeader?: boolean;
+ autoCropArea?: number;
+ autoCrop?: boolean;
+ mask?: boolean;
+ guides?: boolean;
+ centerIndicator?: boolean;
+ viewMode?: ViewMode;
+ modalMaxWidth?: string;
+ scalable?: boolean;
+ zoomable?: boolean;
+ cropBoxMovable?: boolean;
+ cropBoxResizable?: boolean;
+ roundCropper?: boolean;
+ resizeToWidth?: number | any;
+ resizeToHeight?: number | any;
+ imageSmoothingEnabled?: boolean;
+ imageSmoothingQuality?: ImageSmoothingQuality;
+ format?: string | any;
+ imageQuality?: number;
+ applyBtnText?: string;
+ closeBtnText?: string;
+}
+*/
diff --git a/jambotron-ui/src/app/components/spinner/spinner.component.html b/jambotron-ui/src/app/components/spinner/spinner.component.html
index 7a4c0db..2b74025 100644
--- a/jambotron-ui/src/app/components/spinner/spinner.component.html
+++ b/jambotron-ui/src/app/components/spinner/spinner.component.html
@@ -1,5 +1,5 @@
@if (isSpinnerVisible) {
-
+
@if (spinner() === Spinkit.skLine) {
diff --git a/jambotron-ui/src/app/helpers/auth.interceptor.ts b/jambotron-ui/src/app/helpers/auth.interceptor.ts
index be4ed85..8c1d5cf 100644
--- a/jambotron-ui/src/app/helpers/auth.interceptor.ts
+++ b/jambotron-ui/src/app/helpers/auth.interceptor.ts
@@ -24,9 +24,9 @@ export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest
, next: HttpHandler): Observable> {
- // req = req.clone({
- // withCredentials: true,
- // });
+ req = req.clone({
+ withCredentials: true,
+ });
return next.handle(req).pipe(
catchError((error) => {
@@ -59,6 +59,7 @@ export class AuthInterceptor implements HttpInterceptor {
if (error.status == '403') {
this.eventBusService.emit(new EventData('logout', null));
+ console.log('eventBusService logout');
}
return throwError(() => error);
diff --git a/jambotron-ui/src/app/models/file-info.ts b/jambotron-ui/src/app/models/file-info.ts
index fc55c33..1cf4a15 100644
--- a/jambotron-ui/src/app/models/file-info.ts
+++ b/jambotron-ui/src/app/models/file-info.ts
@@ -1,4 +1,6 @@
export class FileInfo {
name: string | undefined;
url: string | undefined;
+ mode: string | undefined;//View or CropView
+ base64string: string | undefined;
}
diff --git a/jambotron-ui/src/app/models/role.ts b/jambotron-ui/src/app/models/role.ts
index be13639..685371b 100644
--- a/jambotron-ui/src/app/models/role.ts
+++ b/jambotron-ui/src/app/models/role.ts
@@ -1,4 +1,4 @@
export class Role {
- id?:any;
+ fileName?:any;
name?:string;
}
diff --git a/jambotron-ui/src/app/models/setting.ts b/jambotron-ui/src/app/models/setting.ts
index d26db99..840554a 100644
--- a/jambotron-ui/src/app/models/setting.ts
+++ b/jambotron-ui/src/app/models/setting.ts
@@ -1,5 +1,5 @@
export class Setting {
- id?:any;
+ fileName?:any;
name?:string;
value?:boolean;
}
diff --git a/jambotron-ui/src/app/models/tutorial.model.ts b/jambotron-ui/src/app/models/tutorial.model.ts
index e41afe1..a195d0c 100644
--- a/jambotron-ui/src/app/models/tutorial.model.ts
+++ b/jambotron-ui/src/app/models/tutorial.model.ts
@@ -1,6 +1,6 @@
export class Tutorial {
isSelected?: boolean;
- id?: any;
+ fileName?: any;
title?: string;
description?: string;
published?: boolean;
diff --git a/jambotron-ui/src/app/models/user.model.ts b/jambotron-ui/src/app/models/user.model.ts
index aced2e3..4def107 100644
--- a/jambotron-ui/src/app/models/user.model.ts
+++ b/jambotron-ui/src/app/models/user.model.ts
@@ -1,5 +1,5 @@
export class User {
- id?:any;
+ fileName?:any;
username?:string;
email?:string;
password?:string;
diff --git a/jambotron-ui/src/app/modules/admin-module/admin-module.service.ts b/jambotron-ui/src/app/modules/admin-module/admin-module.service.ts
index ee2b26b..70c8954 100644
--- a/jambotron-ui/src/app/modules/admin-module/admin-module.service.ts
+++ b/jambotron-ui/src/app/modules/admin-module/admin-module.service.ts
@@ -14,7 +14,7 @@ export class AdminModuleService {
}
- updateUserRoles(id: any,data: User): Observable {
- return this.http.put(`${this.baseUrl}/users/${id}`, data);
+ updateUserRoles(fileName: any,data: User): Observable {
+ return this.http.put(`${this.baseUrl}/users/${fileName}`, data);
}
}
diff --git a/jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.ts b/jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.ts
index bd93db9..47cd514 100644
--- a/jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.ts
+++ b/jambotron-ui/src/app/modules/admin-module/admin.component/admin.component.ts
@@ -1,14 +1,11 @@
import {Component, CUSTOM_ELEMENTS_SCHEMA, inject, OnInit} from '@angular/core';
import {Router, RouterOutlet} from "@angular/router";
import {DOCUMENT} from '@angular/common';
-import { ScrollPanelModule } from 'primeng/scrollpanel';
-import {MenuItem} from 'primeng/api';
import {SideBarAdminComponent} from '../side-bar-admin.component/side-bar-admin.component';
@Component({
selector: 'app-admin.component',
imports: [
RouterOutlet,
- ScrollPanelModule,
SideBarAdminComponent
],
schemas:[CUSTOM_ELEMENTS_SCHEMA],
@@ -19,9 +16,7 @@ export class AdminComponent implements OnInit {
private document = inject(DOCUMENT);
height = 0;
- items: MenuItem[] | undefined;
-
- constructor(private router: Router) {
+ constructor(private router: Router) {
this.height = 0
}
@@ -66,30 +61,7 @@ export class AdminComponent implements OnInit {
else
this.height = 0;
- this.items = [
- {
- label: 'Admin',
- icon: 'pi pi-palette',
- command: () => {
- this.router.navigate(['/main/admin/welcome']);
- },
- items: [
- {
- label: 'Settings',
- icon: 'pi pi-eraser',
- // route: '/main/admin/settings'
- command: () => {
- this.router.navigate(['/main/admin/settings']);
- }
- },
- {
- label: 'System',
- icon: 'pi pi-heart',
- route: '/main/admin/system'
- }
- ]
- }
- ];
+
}
}
diff --git a/jambotron-ui/src/app/modules/admin-module/admin.module.ts b/jambotron-ui/src/app/modules/admin-module/admin.module.ts
index 105676b..1b9fc4e 100644
--- a/jambotron-ui/src/app/modules/admin-module/admin.module.ts
+++ b/jambotron-ui/src/app/modules/admin-module/admin.module.ts
@@ -1,15 +1,13 @@
import {CUSTOM_ELEMENTS_SCHEMA, NgModule} from '@angular/core';
-import {mainRouting} from '../main-module/main.routing';
-import {MainComponent} from '../main-module/main.component/main.component';
import {RouterModule} from '@angular/router';
import {AdminComponent} from './admin.component/admin.component';
import {adminRouting} from './admin.routing';
-import { ScrollPanelModule } from 'primeng/scrollpanel';
+
@NgModule({
declarations: [
],
- imports: [adminRouting, AdminComponent,ScrollPanelModule],
+ imports: [adminRouting, AdminComponent],
exports: [RouterModule],
schemas:[CUSTOM_ELEMENTS_SCHEMA]
})
diff --git a/jambotron-ui/src/app/modules/admin-module/users.component/users.component.ts b/jambotron-ui/src/app/modules/admin-module/users.component/users.component.ts
index b7ebcb4..fa747c8 100644
--- a/jambotron-ui/src/app/modules/admin-module/users.component/users.component.ts
+++ b/jambotron-ui/src/app/modules/admin-module/users.component/users.component.ts
@@ -85,7 +85,7 @@ export class UsersComponent {
}
saveUserRoles(user:User){
- this.adminService.updateUserRoles(user.id, user).subscribe(
+ this.adminService.updateUserRoles(user.fileName, user).subscribe(
(data:any) => {
console.log(data);
user.isEdit = false
@@ -98,13 +98,13 @@ export class UsersComponent {
isChecked(element: User, role: Role) {
let userRoles: Role[] = element.roles;
- return element.roles.some((r:Role) => r.id === role.id);
+ return element.roles.some((r:Role) => r.fileName === role.fileName);
}
onValChange(element:User, role: Role) {
let userRoles: Role[] = element.roles;
if (this.isChecked(element, role)) {
- userRoles = userRoles.filter((r:Role) => r.id !== role.id);
+ userRoles = userRoles.filter((r:Role) => r.fileName !== role.fileName);
}else {
userRoles.push(role);
}
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
index 1fc5881..babd5c0 100644
--- 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
@@ -29,9 +29,9 @@
-
+
@if (isLoggedIn) {