feat: Add recursive task handling and lightbox for task images

This commit is contained in:
2026-02-16 11:34:38 +01:00
parent 6e7f452c08
commit b4370076a3
5 changed files with 90 additions and 7 deletions

View File

@@ -84,6 +84,10 @@ class Cron
}
}
/* sprawdzenie daty ostatniego powtórzenia */
if ( $row['recursive_last_date'] and $new_date_end > $row['recursive_last_date'] )
continue;
$days_reminder = explode( ',', $row['reminders_interval'] );
$max_days_reminder = max( $days_reminder );
@@ -97,7 +101,7 @@ class Cron
$row['show_in_calendar'] ? $show_in_calendar = 'on' : $show_in_calendar = 'off';
$new_task_id = \factory\Tasks::task_save(
null, $row['id'], $row['created_by'], $row['name'], $row['text'], $new_date_start, $new_date_end, $row['project_id'], $row['client_id'], $row['pay_rate'], $row['reminders_interval'], $row['recursively'] ? 'on' : 'off', $row['frequency'], $row['period'], $task_users, $row['date_end_month_day'], $row['date_start_month_day'], null, $row['status_change_mail'], true, $status, $show_in_calendar, $row['priority']
null, $row['id'], $row['created_by'], $row['name'], $row['text'], $new_date_start, $new_date_end, $row['project_id'], $row['client_id'], $row['pay_rate'], $row['reminders_interval'], $row['recursively'] ? 'on' : 'off', $row['frequency'], $row['period'], $task_users, $row['date_end_month_day'], $row['date_start_month_day'], null, $row['status_change_mail'], true, $status, $show_in_calendar, $row['priority'], $row['recursive_last_date']
);
if ( $new_task_id ) {

View File

@@ -415,10 +415,11 @@ class Tasks
$values['send_email_notification'] = isset( $values['send_email_notification'] ) ? $values['send_email_notification'] : 'off';
$values['users'] = isset( $values['users'] ) ? $values['users'] : [];
$values['priority'] = isset( $values['priority'] ) && $values['priority'] !== '' ? $values['priority'] : 0;
$values['recursive_last_date'] = isset( $values['recursive_last_date'] ) ? $values['recursive_last_date'] : null;
$status = \Controllers\TasksController::resolveTaskStatusForSave( $values );
if ( $id = \factory\Tasks::task_save(
$values['id'], null, $user['id'], $values['name'], $values['text'], $values['date_start'], $values['date_end'], $values['project_id'], $values['client_id'], $values['pay_rate'], $values['reminders_interval'], $values['recursively'], $values['frequency'], $values['period'], $values['users'], null, null, $values['send_email_notification'], $values['status_change_mail'], false, $status, $values['show_in_calendar'], $values['priority']
$values['id'], null, $user['id'], $values['name'], $values['text'], $values['date_start'], $values['date_end'], $values['project_id'], $values['client_id'], $values['pay_rate'], $values['reminders_interval'], $values['recursively'], $values['frequency'], $values['period'], $values['users'], null, null, $values['send_email_notification'], $values['status_change_mail'], false, $status, $values['show_in_calendar'], $values['priority'], $values['recursive_last_date']
) )
{
\factory\Tasks::clear_task_opened( $id );

View File

@@ -447,7 +447,7 @@ class Tasks
}
// przy zmianach pamiętać o zadaniach z CRON
static public function task_save( $task_id, $parent_id = null, $user_id, $name, $text, $date_start, $date_end, $project_id, $client_id, $pay_rate, $reminders_interval, $recursively, $frequency, $period, $users, $date_end_month_day = null, $date_start_month_day = null, $send_email_notification = false, $status_change_mail, $rescursive = false, $status = 0, $show_in_calendar, $priority = 0 )
static public function task_save( $task_id, $parent_id = null, $user_id, $name, $text, $date_start, $date_end, $project_id, $client_id, $pay_rate, $reminders_interval, $recursively, $frequency, $period, $users, $date_end_month_day = null, $date_start_month_day = null, $send_email_notification = false, $status_change_mail, $rescursive = false, $status = 0, $show_in_calendar, $priority = 0, $recursive_last_date = null )
{
global $mdb;
@@ -476,6 +476,7 @@ class Tasks
'status' => $status,
'show_in_calendar' => self::isEnabled( $show_in_calendar ) ? 1 : 0,
'priority' => $priority,
'recursive_last_date' => $recursive_last_date != '' ? $recursive_last_date : null,
] );
$id = $mdb -> id();
@@ -518,6 +519,7 @@ class Tasks
'status' => $status,
'show_in_calendar' => self::isEnabled( $show_in_calendar ) ? 1 : 0,
'priority' => $priority,
'recursive_last_date' => $recursive_last_date != '' ? $recursive_last_date : null,
], [
'AND' => [
'id' => $task_id

View File

@@ -203,6 +203,12 @@ if ( is_array( $this -> priorities ) )
</select>
</div>
</div>
<div class="form_group recursive-detail" style="<?= $this -> task[ 'recursively' ] ? '' : 'display: none;';?>">
<label class="label">Powtarzaj do (opcjonalnie):</label>
<div class="input">
<input type="text" class="form-control datetime" name="recursive_last_date" style="max-width: 200px;" value="<?= $this -> task[ 'recursive_last_date' ];?>" autocomplete="off" placeholder="RRRR-MM-DD">
</div>
</div>
<?=
\Html::input_switch( [
'label' => 'Powiadom użytkowników mailem',
@@ -264,10 +270,11 @@ echo $grid -> draw();
$(document).ready(function ()
{
function toggleRecursiveDetails() {
if ( $( '#recursively' ).is( ':checked' ) )
$( '#recursive-details' ).show();
else
$( '#recursive-details' ).hide();
if ( $( '#recursively' ).is( ':checked' ) ) {
$( '#recursive-details, .recursive-detail' ).show();
} else {
$( '#recursive-details, .recursive-detail' ).hide();
}
}
$('input[type="checkbox"]').iCheck({

View File

@@ -284,6 +284,50 @@
.task_popup .task_details .content .right .client .select2-container--bootstrap-5.select2-container--open .select2-selection {
border-color: #6690f4;
}
/* Lightbox - powiększanie zdjęć w opisie */
.task_popup .task_details .description img {
cursor: zoom-in;
transition: opacity .2s ease;
}
.task_popup .task_details .description img:hover {
opacity: .85;
}
.task-img-lightbox {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
background: rgba(0,0,0,.85);
display: flex;
align-items: center;
justify-content: center;
cursor: zoom-out;
animation: taskLightboxIn .2s ease;
}
@keyframes taskLightboxIn {
from { opacity: 0; }
to { opacity: 1; }
}
.task-img-lightbox img {
max-width: 90vw;
max-height: 90vh;
border-radius: 4px;
box-shadow: 0 0 40px rgba(0,0,0,.5);
object-fit: contain;
}
.task-img-lightbox .lightbox-close {
position: absolute;
top: 16px;
right: 24px;
color: #fff;
font-size: 32px;
cursor: pointer;
line-height: 1;
text-shadow: 0 0 8px rgba(0,0,0,.6);
}
</style>
<script type="text/javascript">
( function() {
@@ -360,6 +404,31 @@
renderTime();
// Lightbox kliknięcie na zdjęcie w opisie
popup.on( 'click', '.description img', function( e ) {
e.preventDefault();
e.stopPropagation();
var src = $( this ).attr( 'src' );
if ( !src ) return;
var $overlay = $( '<div class="task-img-lightbox">' +
'<span class="lightbox-close">&times;</span>' +
'<img src="' + src + '">' +
'</div>' );
$( 'body' ).append( $overlay );
$overlay.on( 'click', function() {
$overlay.remove();
});
$( document ).one( 'keydown.taskLightbox', function( ev ) {
if ( ev.key === 'Escape' ) {
$overlay.remove();
}
});
});
var interval_id = setInterval( function() {
if ( !document.body.contains( popup.get( 0 ) ) )
{