From 70b5a47eefcfed680d7ac6beb1734d019f5562cb Mon Sep 17 00:00:00 2001 From: farukvukovic <104840615+farukvukovic@users.noreply.github.com> Date: Thu, 5 Feb 2026 08:32:26 +0100 Subject: [PATCH 01/19] #5958 pinned ticket stayed pinned --- app/Domain/Tickets/Services/Tickets.php | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/app/Domain/Tickets/Services/Tickets.php b/app/Domain/Tickets/Services/Tickets.php index 4dfe948a04..72a15c356f 100644 --- a/app/Domain/Tickets/Services/Tickets.php +++ b/app/Domain/Tickets/Services/Tickets.php @@ -1739,16 +1739,28 @@ public function addTicket($values): array|int|bool */ public function updateTicket($values): array|bool { - if (! isset($values['headline'])) { - $currentTicket = $this->getTicket($values['id']); + $currentTicket = $this->getTicket($values['id']); - if (! $currentTicket) { - return ['msg' => 'This ticket id does not exist within your leantime account.', 'type' => 'error']; - } + if (! $currentTicket) { + return ['msg' => 'This ticket id does not exist within your leantime account.', 'type' => 'error']; + } + if (! isset($values['headline'])) { $values['headline'] = $currentTicket->headline; } + if (isset($values['status']) && session()->exists('currentProject')) { + $oldStatus = $currentTicket->status; + $newStatus = (int) $values['status']; + + if ($oldStatus != $newStatus) { + $projectId = (int) session('currentProject'); + if ($this->isTicketPinned($values['id'], $projectId)) { + $this->unpinTicket($values['id'], $projectId); + } + } + } + $values = [ 'id' => $values['id'], 'headline' => $values['headline'] ?? '', From ea179fe5355d0bd49684a3a5c0ac68f366a60c4d Mon Sep 17 00:00:00 2001 From: Haris Macic Date: Fri, 6 Feb 2026 12:21:03 +0100 Subject: [PATCH 02/19] #5841 Remove session deletion from dockerfile --- Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index f818cf71aa..2ad398122e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -399,9 +399,6 @@ rm -rf /var/www/html/storage/framework/viewPaths.php || true find /var/www/html/storage/framework/cache -type f ! -name '.gitignore' -delete 2>/dev/null || true find /var/www/html/storage/framework/cache -type d -empty -delete 2>/dev/null || true -find /var/www/html/storage/framework/sessions -type f ! -name '.gitignore' -delete 2>/dev/null || true -find /var/www/html/storage/framework/sessions -type d -empty -delete 2>/dev/null || true - find /var/www/html/storage/framework/views -type f ! -name '.gitignore' -delete 2>/dev/null || true find /var/www/html/storage/framework/views -type d -empty -delete 2>/dev/null || true From 3a6261de7ef114fa8deb01912d4e70ef59e0c619 Mon Sep 17 00:00:00 2001 From: Haris Macic Date: Fri, 6 Feb 2026 16:36:21 +0100 Subject: [PATCH 03/19] #5612 Add listener to type change and write the change in the ticket history --- .../submodules/ticketDetails.sub.php | 13 +++- .../Timesheets/Js/timesheetsController.js | 63 ++++++++++--------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/app/Domain/Tickets/Templates/submodules/ticketDetails.sub.php b/app/Domain/Tickets/Templates/submodules/ticketDetails.sub.php index ae5f9f7e41..ffe510e619 100644 --- a/app/Domain/Tickets/Templates/submodules/ticketDetails.sub.php +++ b/app/Domain/Tickets/Templates/submodules/ticketDetails.sub.php @@ -307,7 +307,7 @@ function loadStatusHistory(ticketId) { }); } - $('#status-select, #priority, #storypoints, #editorId, #deadline').on('change', function() { + $('#status-select, #priority, #storypoints, #editorId, #deadline, #type',).on('change', function() { var changedElementId = $(this).attr('id'); const ticketId = $('#status-change-log').data('ticket-id'); const oldStatusKey = $(this).data('old-status'); @@ -425,7 +425,16 @@ class="accordion-toggle"
- type ?? '')) { diff --git a/app/Domain/Timesheets/Js/timesheetsController.js b/app/Domain/Timesheets/Js/timesheetsController.js index f066ce562e..d89fd27a26 100644 --- a/app/Domain/Timesheets/Js/timesheetsController.js +++ b/app/Domain/Timesheets/Js/timesheetsController.js @@ -5,27 +5,27 @@ leantime.timesheetsController = (function () { jQuery(document).ready(function () { var allTimesheets = jQuery("#allTimesheetsTable").DataTable({ "language": { - "decimal": leantime.i18n.__("datatables.decimal"), - "emptyTable": leantime.i18n.__("datatables.emptyTable"), - "info": leantime.i18n.__("datatables.info"), - "infoEmpty": leantime.i18n.__("datatables.infoEmpty"), - "infoFiltered": leantime.i18n.__("datatables.infoFiltered"), - "infoPostFix": leantime.i18n.__("datatables.infoPostFix"), - "thousands": leantime.i18n.__("datatables.thousands"), - "lengthMenu": leantime.i18n.__("datatables.lengthMenu"), + "decimal": leantime.i18n.__("datatables.decimal"), + "emptyTable": leantime.i18n.__("datatables.emptyTable"), + "info": leantime.i18n.__("datatables.info"), + "infoEmpty": leantime.i18n.__("datatables.infoEmpty"), + "infoFiltered": leantime.i18n.__("datatables.infoFiltered"), + "infoPostFix": leantime.i18n.__("datatables.infoPostFix"), + "thousands": leantime.i18n.__("datatables.thousands"), + "lengthMenu": leantime.i18n.__("datatables.lengthMenu"), "loadingRecords": leantime.i18n.__("datatables.loadingRecords"), - "processing": leantime.i18n.__("datatables.processing"), - "search": leantime.i18n.__("datatables.search"), - "zeroRecords": leantime.i18n.__("datatables.zeroRecords"), + "processing": leantime.i18n.__("datatables.processing"), + "search": leantime.i18n.__("datatables.search"), + "zeroRecords": leantime.i18n.__("datatables.zeroRecords"), "paginate": { - "first": leantime.i18n.__("datatables.first"), - "last": leantime.i18n.__("datatables.last"), - "next": leantime.i18n.__("datatables.next"), - "previous": leantime.i18n.__("datatables.previous"), + "first": leantime.i18n.__("datatables.first"), + "last": leantime.i18n.__("datatables.last"), + "next": leantime.i18n.__("datatables.next"), + "previous": leantime.i18n.__("datatables.previous"), }, "aria": { - "sortAscending": leantime.i18n.__("datatables.sortAscending"), - "sortDescending":leantime.i18n.__("datatables.sortDescending"), + "sortAscending": leantime.i18n.__("datatables.sortAscending"), + "sortDescending": leantime.i18n.__("datatables.sortDescending"), }, "buttons": { colvis: leantime.i18n.__("datatables.buttons.colvis"), @@ -43,7 +43,7 @@ leantime.timesheetsController = (function () { // CUSTOM: Enable searching for modern search component "searching": true, "stateSave": true, - "displayLength":100, + "displayLength": 100, }); @@ -60,7 +60,7 @@ leantime.timesheetsController = (function () { orthogonal: 'export', columns: ':visible', format: { - body: function ( data, row, column, node ) { + body: function (data, row, column, node) { // Use the export formatter if available if (typeof window.leantime !== 'undefined' && typeof window.leantime.timesheetsExport !== 'undefined' && @@ -69,7 +69,7 @@ leantime.timesheetsController = (function () { } // Fallback to original logic - if ( typeof jQuery(node).data('order') !== 'undefined') { + if (typeof jQuery(node).data('order') !== 'undefined') { data = jQuery(node).data('order'); } return data; @@ -99,7 +99,7 @@ leantime.timesheetsController = (function () { } } - jQuery('#allTimesheetsTable').on('column-visibility.dt', function ( e, settings, column, state ) { + jQuery('#allTimesheetsTable').on('column-visibility.dt', function (e, settings, column, state) { allTimesheets.draw(false); }); @@ -113,8 +113,8 @@ leantime.timesheetsController = (function () { var initEditTimeModal = function () { var canvasoptions = { sizes: { - minW: 700, - maxW: 1000, + minW: 700, + maxW: 1000, minH: 1000, }, resizable: false, @@ -122,25 +122,26 @@ leantime.timesheetsController = (function () { callbacks: { beforeShowCont: function () { jQuery(".showDialogOnLoad").show(); + if (closeModal === true) { closeModal = false; location.reload(); } }, - afterShowCont: function () { - jQuery(".editTimeModal").nyroModal(canvasoptions); - }, beforeClose: function () { location.reload(); } }, titleFromIframe: true - }; - jQuery(".editTimeModal").nyroModal(canvasoptions); + jQuery(document).on('click', '.editTimeModal', function (e) { + e.preventDefault(); + jQuery(this).nyroModal(canvasoptions); + }); }; + /** * Format hours according to user preference */ @@ -204,8 +205,8 @@ leantime.timesheetsController = (function () { // Make public what you want to have public, everything else is private return { - initTimesheetsTable:initTimesheetsTable, - initEditTimeModal:initEditTimeModal, - formatHours:formatHours, + initTimesheetsTable: initTimesheetsTable, + initEditTimeModal: initEditTimeModal, + formatHours: formatHours, }; })(); From 1921908922c331d6cdf92769474611f79cbbcb0c Mon Sep 17 00:00:00 2001 From: Haris Macic Date: Fri, 6 Feb 2026 16:55:22 +0100 Subject: [PATCH 04/19] #5612 Add listener to project, milestone, sprint, related to, so we can have it in changelog --- .../submodules/ticketDetails.sub.php | 82 ++++++++++++++----- 1 file changed, 61 insertions(+), 21 deletions(-) diff --git a/app/Domain/Tickets/Templates/submodules/ticketDetails.sub.php b/app/Domain/Tickets/Templates/submodules/ticketDetails.sub.php index ffe510e619..75149f4e4e 100644 --- a/app/Domain/Tickets/Templates/submodules/ticketDetails.sub.php +++ b/app/Domain/Tickets/Templates/submodules/ticketDetails.sub.php @@ -307,7 +307,7 @@ function loadStatusHistory(ticketId) { }); } - $('#status-select, #priority, #storypoints, #editorId, #deadline, #type',).on('change', function() { + $('#status-select, #priority, #storypoints, #editorId, #deadline, #type, select[name="projectId"], #milestoneid, #sprint-select, #dependingTicketId').on('change', function() { var changedElementId = $(this).attr('id'); const ticketId = $('#status-change-log').data('ticket-id'); const oldStatusKey = $(this).data('old-status'); @@ -450,7 +450,16 @@ class="accordion-toggle"
-