diff --git a/app/Core/Template.php b/app/Core/Template.php
index 0f397fd28..fe820aa5f 100644
--- a/app/Core/Template.php
+++ b/app/Core/Template.php
@@ -680,7 +680,11 @@ public function displayNotification(): string
if (session()->exists("confettiInYourFace") && session("confettiInYourFace") === true) {
$notification .= app('blade.compiler')::render(
- '',
+ '',
[]
);
@@ -754,7 +758,10 @@ public function displayInlineNotification(): string
if (session()->exists("confettiInYourFace") && session("confettiInYourFace") === true) {
$notification .= app('blade.compiler')::render(
- '',
+ '',
[]
);
diff --git a/app/Domain/Comments/Templates/submodules/generalComment.sub.php b/app/Domain/Comments/Templates/submodules/generalComment.sub.php
index 748c8c1c6..8db5882d5 100644
--- a/app/Domain/Comments/Templates/submodules/generalComment.sub.php
+++ b/app/Domain/Comments/Templates/submodules/generalComment.sub.php
@@ -183,7 +183,10 @@ function toggleCommentBoxes(id, formHash) {
}
jQuery(".confetti").click(function(){
- confetti.start();
+ confetti({
+ spread: 70,
+ origin: { y: 1.2 },
+ });
});
function respondToVisibility(element, callback) {
diff --git a/app/Domain/Dashboard/Js/dashboardController.js b/app/Domain/Dashboard/Js/dashboardController.js
index 66bc8c40c..ae5dfa958 100644
--- a/app/Domain/Dashboard/Js/dashboardController.js
+++ b/app/Domain/Dashboard/Js/dashboardController.js
@@ -202,7 +202,7 @@ leantime.dashboardController = (function () {
label: leantime.i18n.__("label.done_todos"),
backgroundColor: leantime.dashboardController.chartColors.green,
borderColor: leantime.dashboardController.chartColors.green,
- data: actualData['done']['data'],
+ data: actualData.done.data,
fill: true,
lineTension: 0,
pointRadius:0,
@@ -211,7 +211,7 @@ leantime.dashboardController = (function () {
label: leantime.i18n.__("label.progress_todos"),
backgroundColor: leantime.dashboardController.chartColors.yellow,
borderColor: leantime.dashboardController.chartColors.yellow,
- data: actualData['progress']['data'],
+ data: actualData.progress.data,
fill: true,
lineTension: 0,
pointRadius:0,
@@ -221,7 +221,7 @@ leantime.dashboardController = (function () {
label: leantime.i18n.__("label.new_todos"),
backgroundColor: leantime.dashboardController.chartColors.red,
borderColor: leantime.dashboardController.chartColors.red,
- data: actualData['open']['data'],
+ data: actualData.open.data,
fill: true,
lineTension: 0,
pointRadius:0,
@@ -296,10 +296,10 @@ leantime.dashboardController = (function () {
jQuery("#" + id).click(
function (event) {
- chart.data.datasets[0].data = actualData['done']['data'];
+ chart.data.datasets[0].data = actualData.done.data;
- chart.data.datasets[1].data = actualData['progress']['data'];
- chart.data.datasets[2].data = actualData['open']['data'];
+ chart.data.datasets[1].data = actualData.progress.data;
+ chart.data.datasets[2].data = actualData.open.data;
chart.options.scales.y.title.text = label;
diff --git a/app/Domain/Gamecenter/Js/game-snake.js b/app/Domain/Gamecenter/Js/game-snake.js
index b85109aa4..8cedb629c 100644
--- a/app/Domain/Gamecenter/Js/game-snake.js
+++ b/app/Domain/Gamecenter/Js/game-snake.js
@@ -160,22 +160,22 @@ SNAKE.Snake = SNAKE.Snake || (function() {
// ----- public variables -----
me.snakeBody = {};
- me.snakeBody["b0"] = new SnakeBlock(); // create snake head
- me.snakeBody["b0"].row = config.startRow || 1;
- me.snakeBody["b0"].col = config.startCol || 1;
- me.snakeBody["b0"].xPos = me.snakeBody["b0"].row * playingBoard.getBlockWidth();
- me.snakeBody["b0"].yPos = me.snakeBody["b0"].col * playingBoard.getBlockHeight();
- me.snakeBody["b0"].elm = createSnakeElement();
- me.snakeBody["b0"].elmStyle = me.snakeBody["b0"].elm.style;
- playingBoard.getBoardContainer().appendChild( me.snakeBody["b0"].elm );
- me.snakeBody["b0"].elm.style.left = me.snakeBody["b0"].xPos + "px";
- me.snakeBody["b0"].elm.style.top = me.snakeBody["b0"].yPos + "px";
- me.snakeBody["b0"].next = me.snakeBody["b0"];
- me.snakeBody["b0"].prev = me.snakeBody["b0"];
+ me.snakeBody.b0 = new SnakeBlock(); // create snake head
+ me.snakeBody.b0.row = config.startRow || 1;
+ me.snakeBody.b0.col = config.startCol || 1;
+ me.snakeBody.b0.xPos = me.snakeBody.b0.row * playingBoard.getBlockWidth();
+ me.snakeBody.b0.yPos = me.snakeBody.b0.col * playingBoard.getBlockHeight();
+ me.snakeBody.b0.elm = createSnakeElement();
+ me.snakeBody.b0.elmStyle = me.snakeBody.b0.elm.style;
+ playingBoard.getBoardContainer().appendChild( me.snakeBody.b0.elm );
+ me.snakeBody.b0.elm.style.left = me.snakeBody.b0.xPos + "px";
+ me.snakeBody.b0.elm.style.top = me.snakeBody.b0.yPos + "px";
+ me.snakeBody.b0.next = me.snakeBody.b0;
+ me.snakeBody.b0.prev = me.snakeBody.b0;
me.snakeLength = 1;
- me.snakeHead = me.snakeBody["b0"];
- me.snakeTail = me.snakeBody["b0"];
+ me.snakeHead = me.snakeBody.b0;
+ me.snakeTail = me.snakeBody.b0;
me.snakeHead.elm.className = me.snakeHead.elm.className.replace(/\bsnake-snakebody-dead\b/,'');
me.snakeHead.elm.id = "snake-snakehead-alive";
me.snakeHead.elm.className += " snake-snakebody-alive";
diff --git a/app/Domain/Help/Js/helperController.js b/app/Domain/Help/Js/helperController.js
index c79db7b44..2597127d9 100644
--- a/app/Domain/Help/Js/helperController.js
+++ b/app/Domain/Help/Js/helperController.js
@@ -203,7 +203,10 @@ leantime.helperController = (function () {
scrollTo:true,
when: {
show: function() {
- confetti.start();
+ confetti({
+ spread: 70,
+ origin: { y: 1.2 },
+ });
}
},
advanceOn: '.headmenu click'
diff --git a/app/Views/Templates/sections/header.blade.php b/app/Views/Templates/sections/header.blade.php
index 3398e3ba8..16b4c9c09 100644
--- a/app/Views/Templates/sections/header.blade.php
+++ b/app/Views/Templates/sections/header.blade.php
@@ -43,6 +43,11 @@
@dispatchEvent('afterMainScriptTag')
+
+
@foreach ($themeScripts as $script)
diff --git a/package-lock.json b/package-lock.json
index b3ccb9c59..994823bb1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "leantime",
- "version": "3.1.4",
+ "version": "3.2.0-beta",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "leantime",
- "version": "3.1.4",
+ "version": "3.2.0-beta",
"license": "AGPL-3.0",
"dependencies": {
"@assuradeurengilde/fontawesome-iconpicker": "^3.2.3",
@@ -19,6 +19,7 @@
"@sentry/browser": "^7.109.0",
"@sentry/webpack-plugin": "^2.16.1",
"ajv": "^8.13.0",
+ "canvas-confetti": "^1.9.3",
"chart.js": "^3.6.0",
"chartjs-adapter-luxon": "^1.3.1",
"chosen-js": "^1.8.7",
@@ -4935,6 +4936,15 @@
}
]
},
+ "node_modules/canvas-confetti": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.3.tgz",
+ "integrity": "sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==",
+ "funding": {
+ "type": "donate",
+ "url": "https://www.paypal.me/kirilvatev"
+ }
+ },
"node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
diff --git a/package.json b/package.json
index 90a155dc6..d98c5840d 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"@sentry/browser": "^7.109.0",
"@sentry/webpack-plugin": "^2.16.1",
"ajv": "^8.13.0",
+ "canvas-confetti": "^1.9.3",
"chart.js": "^3.6.0",
"chartjs-adapter-luxon": "^1.3.1",
"chosen-js": "^1.8.7",
@@ -23,8 +24,8 @@
"datatables.net-rowgroup": "^1.4.1",
"datatables.net-rowreorder": "^1.4.1",
"fullcalendar": "^6.1.11",
- "htmx.org": "^1.9.12",
"gridstack": "^10.1.2",
+ "htmx.org": "^1.9.12",
"ical.js": "^1.5.0",
"imagesloaded": "^5.0.0",
"isotope-layout": "^3.0.6",
diff --git a/public/assets/js/libs/confetti/js/confetti.js b/public/assets/js/libs/confetti/js/confetti.js
index fb0e3c14e..da2efebf8 100644
--- a/public/assets/js/libs/confetti/js/confetti.js
+++ b/public/assets/js/libs/confetti/js/confetti.js
@@ -8,8 +8,8 @@ var confetti = (function () {
let cy = '';
let confetti = [];
- const confettiCount = 500;
- const gravity = 0.7;
+ const confettiCount = 50;
+ const gravity = 1.2;
const terminalVelocity = 5;
const drag = 0.075;
const colors = [
@@ -85,7 +85,8 @@ var confetti = (function () {
velocity: {
x: randomRange(-25, 25),
- y: randomRange(0, -50) } });
+ y: randomRange(0, -50) }
+ });
}
@@ -93,6 +94,7 @@ var confetti = (function () {
//---------Render-----------
let render = () => {
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
confetti.forEach((confetto, index) => {
diff --git a/public/dist/mix-manifest.json b/public/dist/mix-manifest.json
index 24ff592cd..5e350dc6c 100644
--- a/public/dist/mix-manifest.json
+++ b/public/dist/mix-manifest.json
@@ -1,19 +1,62 @@
{
- "/js/compiled-htmx.3.1.4.min.js": "/js/compiled-htmx.3.1.4.min.js",
- "/js/compiled-htmx-headSupport.3.1.4.min.js": "/js/compiled-htmx-headSupport.3.1.4.min.js",
- "/css/main.3.1.4.min.css": "/css/main.3.1.4.min.css",
- "/css/editor.3.1.4.min.css": "/css/editor.3.1.4.min.css",
- "/css/app.3.1.4.min.css": "/css/app.3.1.4.min.css",
- "/js/compiled-footer.3.1.4.min.js": "/js/compiled-footer.3.1.4.min.js",
- "/js/compiled-app.3.1.4.min.js": "/js/compiled-app.3.1.4.min.js",
- "/js/compiled-frameworks.3.1.4.min.js": "/js/compiled-frameworks.3.1.4.min.js",
- "/js/compiled-framework-plugins.3.1.4.min.js": "/js/compiled-framework-plugins.3.1.4.min.js",
- "/js/compiled-global-component.3.1.4.min.js": "/js/compiled-global-component.3.1.4.min.js",
- "/js/compiled-calendar-component.3.1.4.min.js": "/js/compiled-calendar-component.3.1.4.min.js",
- "/js/compiled-table-component.3.1.4.min.js": "/js/compiled-table-component.3.1.4.min.js",
- "/js/compiled-editor-component.3.1.4.min.js": "/js/compiled-editor-component.3.1.4.min.js",
- "/js/compiled-gantt-component.3.1.4.min.js": "/js/compiled-gantt-component.3.1.4.min.js",
- "/js/compiled-chart-component.3.1.4.min.js": "/js/compiled-chart-component.3.1.4.min.js",
+ "/js/Auth/Js/authController.js": "/js/Auth/Js/authController.js",
+ "/js/Calendar/Js/calendarController.js": "/js/Calendar/Js/calendarController.js",
+ "/js/Canvas/Js/canvasController.js": "/js/Canvas/Js/canvasController.js",
+ "/js/Clients/Js/clientsController.js": "/js/Clients/Js/clientsController.js",
+ "/js/Comments/Js/commentsController.js": "/js/Comments/Js/commentsController.js",
+ "/js/Cpcanvas/Js/cpCanvasController.js": "/js/Cpcanvas/Js/cpCanvasController.js",
+ "/js/Dashboard/Js/dashboardController.js": "/js/Dashboard/Js/dashboardController.js",
+ "/js/Dbmcanvas/Js/dbmCanvasController.js": "/js/Dbmcanvas/Js/dbmCanvasController.js",
+ "/js/Eacanvas/Js/eaCanvasController.js": "/js/Eacanvas/Js/eaCanvasController.js",
+ "/js/Emcanvas/Js/emCanvasController.js": "/js/Emcanvas/Js/emCanvasController.js",
+ "/js/Gamecenter/Js/game-snake.js": "/js/Gamecenter/Js/game-snake.js",
+ "/js/Goalcanvas/Js/goalCanvasController.js": "/js/Goalcanvas/Js/goalCanvasController.js",
+ "/js/Help/Js/helperController.js": "/js/Help/Js/helperController.js",
+ "/js/Help/Js/helperRepository.js": "/js/Help/Js/helperRepository.js",
+ "/js/Ideas/Js/ideasController.js": "/js/Ideas/Js/ideasController.js",
+ "/js/Insightscanvas/Js/insightsCanvasController.js": "/js/Insightscanvas/Js/insightsCanvasController.js",
+ "/js/Lbmcanvas/Js/lbmCanvasController.js": "/js/Lbmcanvas/Js/lbmCanvasController.js",
+ "/js/Leancanvas/Js/leanCanvasController.js": "/js/Leancanvas/Js/leanCanvasController.js",
+ "/js/Menu/Js/menuController.js": "/js/Menu/Js/menuController.js",
+ "/js/Menu/Js/menuRepository.js": "/js/Menu/Js/menuRepository.js",
+ "/js/Minempathycanvas/Js/risksCanvasController.js": "/js/Minempathycanvas/Js/risksCanvasController.js",
+ "/js/Obmcanvas/Js/obmCanvasController.js": "/js/Obmcanvas/Js/obmCanvasController.js",
+ "/js/Projects/Js/projectsController.js": "/js/Projects/Js/projectsController.js",
+ "/js/Reactions/Js/reactionsController.js": "/js/Reactions/Js/reactionsController.js",
+ "/js/Retroscanvas/Js/retroCanvasController.js": "/js/Retroscanvas/Js/retroCanvasController.js",
+ "/js/Riskscanvas/Js/risksCanvasController.js": "/js/Riskscanvas/Js/risksCanvasController.js",
+ "/js/Sbcanvas/Js/sbCanvasController.js": "/js/Sbcanvas/Js/sbCanvasController.js",
+ "/js/Setting/Js/settingController.js": "/js/Setting/Js/settingController.js",
+ "/js/Setting/Js/settingRepository.js": "/js/Setting/Js/settingRepository.js",
+ "/js/Setting/Js/settingService.js": "/js/Setting/Js/settingService.js",
+ "/js/Smcanvas/Js/smCanvasController.js": "/js/Smcanvas/Js/smCanvasController.js",
+ "/js/Sqcanvas/Js/sqCanvasController.js": "/js/Sqcanvas/Js/sqCanvasController.js",
+ "/js/Swotcanvas/Js/swotCanvasController.js": "/js/Swotcanvas/Js/swotCanvasController.js",
+ "/js/Tickets/Js/ticketsController.js": "/js/Tickets/Js/ticketsController.js",
+ "/js/Tickets/Js/ticketsRepository.js": "/js/Tickets/Js/ticketsRepository.js",
+ "/js/Timesheets/Js/timesheetsController.js": "/js/Timesheets/Js/timesheetsController.js",
+ "/js/Users/Js/usersController.js": "/js/Users/Js/usersController.js",
+ "/js/Users/Js/usersRepository.js": "/js/Users/Js/usersRepository.js",
+ "/js/Users/Js/usersService.js": "/js/Users/Js/usersService.js",
+ "/js/Valuecanvas/Js/valueCanvasController.js": "/js/Valuecanvas/Js/valueCanvasController.js",
+ "/js/Widgets/Js/Widgetcontroller.js": "/js/Widgets/Js/Widgetcontroller.js",
+ "/js/Wiki/Js/wikiController.js": "/js/Wiki/Js/wikiController.js",
+ "/js/compiled-htmx.3.2.0-beta.min.js": "/js/compiled-htmx.3.2.0-beta.min.js",
+ "/js/compiled-htmx-headSupport.3.2.0-beta.min.js": "/js/compiled-htmx-headSupport.3.2.0-beta.min.js",
+ "/js/authController.js": "/js/authController.js",
+ "/css/main.3.2.0-beta.min.css": "/css/main.3.2.0-beta.min.css",
+ "/css/editor.3.2.0-beta.min.css": "/css/editor.3.2.0-beta.min.css",
+ "/css/app.3.2.0-beta.min.css": "/css/app.3.2.0-beta.min.css",
+ "/js/compiled-footer.3.2.0-beta.min.js": "/js/compiled-footer.3.2.0-beta.min.js",
+ "/js/compiled-app.3.2.0-beta.min.js": "/js/compiled-app.3.2.0-beta.min.js",
+ "/js/compiled-frameworks.3.2.0-beta.min.js": "/js/compiled-frameworks.3.2.0-beta.min.js",
+ "/js/compiled-framework-plugins.3.2.0-beta.min.js": "/js/compiled-framework-plugins.3.2.0-beta.min.js",
+ "/js/compiled-global-component.3.2.0-beta.min.js": "/js/compiled-global-component.3.2.0-beta.min.js",
+ "/js/compiled-calendar-component.3.2.0-beta.min.js": "/js/compiled-calendar-component.3.2.0-beta.min.js",
+ "/js/compiled-table-component.3.2.0-beta.min.js": "/js/compiled-table-component.3.2.0-beta.min.js",
+ "/js/compiled-editor-component.3.2.0-beta.min.js": "/js/compiled-editor-component.3.2.0-beta.min.js",
+ "/js/compiled-gantt-component.3.2.0-beta.min.js": "/js/compiled-gantt-component.3.2.0-beta.min.js",
+ "/js/compiled-chart-component.3.2.0-beta.min.js": "/js/compiled-chart-component.3.2.0-beta.min.js",
"/images/03-1.png": "/images/03-1.png",
"/images/32px.png": "/images/32px.png",
"/images/40px.png": "/images/40px.png",
diff --git a/webpack.mix.js b/webpack.mix.js
index d440d9c12..63e18355e 100644
--- a/webpack.mix.js
+++ b/webpack.mix.js
@@ -3,6 +3,30 @@ const glob = require('glob');
const path = require('path');
const version = pjson.version;
+const fs = require("fs");
+
+// Helper to get all files of a given extension in a given directory and its subfolders.
+function getFilesRecursive(dir, type) {
+ // The list of files that we will return.
+ let files = []
+ // Loop everything in given location.
+ fs.readdirSync(dir).forEach(file => {
+ let fileName = `${dir}/${file}`
+ // Add if its a file and it is of the correct file type.
+ if(fs.statSync(fileName).isFile() && fileName.endsWith(type)) {
+ files.push(fileName)
+ }
+ // Process subfolder.
+ if(!fs.statSync(fileName).isFile()) {
+ // Recusively loop this function for the subfolder.
+ files = files.concat(getFilesRecursive(fileName, type))
+ }
+ })
+ return files
+}
+
+
+
let mix = require('laravel-mix');
require('laravel-mix-eslint');
require('mix-tailwindcss');
@@ -10,8 +34,22 @@ require('mix-tailwindcss');
require('dotenv').config({ path: 'config/.env' });
mix
- .setPublicPath('public/dist') // this is the URL to place assets referenced in the CSS/JS
- .setResourceRoot(`../`) // this is what to prefix the URL with
+ .setPublicPath('public/dist')
+ .setResourceRoot(`../`);
+
+/*
+
+//Draft for file based js controller loading
+getFilesRecursive('app/Domain', '.js').forEach(file => {
+ subfolder = file.match(/(.*)[\/\\]/)[1]||''; // 'src/js/libraries'
+ subfolder = subfolder.replace('app/Domain', ''); // '/libraries'
+ mix.js(file, 'js' + subfolder);
+});
+*/
+
+
+ // this is the URL to place assets referenced in the CSS/JS
+ mix // this is what to prefix the URL with
.combine('./public/assets/js/libs/prism/prism.js', `public/dist/js/compiled-footer.${version}.min.js`)
.js('./public/assets/js/app/htmx.js', `public/dist/js/compiled-htmx.${version}.min.js`)
.js('./public/assets/js/app/htmx-headSupport.js', `public/dist/js/compiled-htmx-headSupport.${version}.min.js`)
@@ -45,7 +83,7 @@ mix
"./node_modules/@popperjs/core/dist/umd/popper.js",
"./node_modules/tippy.js/dist/tippy-bundle.umd.js",
"./public/assets/js/libs/slimselect.min.js",
- "./public/assets/js/libs/confetti/js/confetti.js",
+ "./node_modules/canvas-confetti/dist/confetti.browser.js",
"./public/assets/js/libs/jquery.nyroModal/js/jquery.nyroModal.custom.js",
"./public/assets/js/libs/uppy/uppy.js",
"./node_modules/croppie/croppie.js",