feat: Update task popup to enhance description editing with CKEditor integration and improved UI

This commit is contained in:
2026-03-01 22:08:11 +01:00
parent fc97a990fb
commit 447b75bf3e
3 changed files with 187 additions and 25 deletions

View File

@@ -28,8 +28,8 @@
},
"class.Cron.php": {
"type": "-",
"size": 9593,
"lmtime": 1771237141363,
"size": 9604,
"lmtime": 1772360713752,
"modified": false
},
"class.DbModel.php": {
@@ -121,8 +121,8 @@
},
"class.Tasks.php": {
"type": "-",
"size": 26351,
"lmtime": 1772285310911,
"size": 26739,
"lmtime": 1772360724134,
"modified": false
},
"class.Users.php": {
@@ -164,8 +164,8 @@
},
"MailToTaskImporter.php": {
"type": "-",
"size": 56836,
"lmtime": 1771496082257,
"size": 56847,
"lmtime": 1772360727394,
"modified": false
},
"TaskAttachmentRepository.php": {
@@ -235,8 +235,8 @@
},
"class.Tasks.php": {
"type": "-",
"size": 29649,
"lmtime": 1772285985430,
"size": 29961,
"lmtime": 1772361497784,
"modified": false
},
"class.Users.php": {
@@ -628,8 +628,8 @@
},
"task_edit.php": {
"type": "-",
"size": 32097,
"lmtime": 1772283180543,
"size": 33540,
"lmtime": 1772361385635,
"modified": false
},
"task_popup.php": {
@@ -786,6 +786,16 @@
"size": 230708,
"lmtime": 1771920013460,
"modified": false
},
"docs": {
"migrations": {
"2026-03-01-tasks-recursive-parent-id.sql": {
"type": "-",
"size": 542,
"lmtime": 1772360740310,
"modified": false
}
}
}
}
},

View File

@@ -175,11 +175,21 @@ if ( isset( $_COOKIE[$cookie_name] ) && !isset( $_SESSION['user'] ) )
}
$user = \S::get_session('user');
$request_path = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
$request_path = is_string( $request_path ) ? rtrim( $request_path, '/' ) : '';
if ( $request_path === '' )
$request_path = '/';
if ( !$user and !in_array( $_SERVER['REQUEST_URI'], [ '/logowanie', '/rejestracja', '/users/login/', '/cron/main_view/' ] ) )
if ( !$user and !in_array( $request_path, [ '/logowanie', '/rejestracja', '/users/login', '/cron/main_view' ], true ) )
{
header( 'Location: /logowanie' );
exit;
}
if ( $user and $request_path === '/logowanie' )
{
header( 'Location: /tasks/main_view/' );
exit;
}
echo \view\Site::show();

View File

@@ -87,22 +87,31 @@
</div>
<? endforeach; endif;?>
</div>
<div class="task-tab-panel is-active" data-tab="description">
<div class="task-description-editor box">
<h3>Treść zadania</h3>
<textarea class="form-control task-description-input" rows="5"><?= htmlspecialchars( (string)$this -> task['text'] );?></textarea>
<a href="#" class="btn btn-primary btn-sm task-popup-compact-btn js-save-task-description" task_id="<?= (int)$this -> task['id'];?>" style="margin-top: 10px;">Zapisz treść</a>
<div class="task-description-view">
<? if ( $this -> task['text'] ):?>
<div class="description">
<a href="#" class="fullscreen"><i class="fa fa-expand"></i></a>
<?= $task_description_html;?>
</div>
<? else:?>
<div class="description description-empty">
Brak opisu zadania.
</div>
<? endif;?>
</div>
<? if ( $this -> task['text'] ):?>
<div class="description">
<a href="#" class="fullscreen"><i class="fa fa-expand"></i></a>
<?= $task_description_html;?>
<div class="task-description-actions">
<a href="#" class="btn btn-primary btn-sm task-popup-compact-btn js-start-edit-task-description">Edytuj</a>
</div>
<div class="task-description-editor box" style="display: none;">
<h3>Tre&#347;&#263; zadania</h3>
<textarea class="form-control task-description-input" id="task-popup-description-<?= (int)$this -> task['id'];?>" rows="5"><?= htmlspecialchars( (string)$this -> task['text'] );?></textarea>
<div class="task-description-editor-actions">
<a href="#" class="btn btn-primary btn-sm task-popup-compact-btn js-save-task-description" task_id="<?= (int)$this -> task['id'];?>">Zapisz tre&#347;&#263;</a>
<a href="#" class="btn btn-danger btn-sm task-popup-compact-btn js-cancel-edit-task-description">Anuluj</a>
</div>
<? else:?>
<div class="description description-empty">
Brak opisu zadania.
</div>
<? endif;?>
</div>
</div>
<div class="task-tab-panel" data-tab="checklist">
<div class="checklist">
@@ -510,6 +519,14 @@
.task_popup .task_details .content .left .task-description-editor {
margin-bottom: 12px;
}
.task_popup .task_details .content .left .task-description-actions {
margin: 10px 0 12px 0;
}
.task_popup .task_details .content .left .task-description-editor .task-description-editor-actions {
margin-top: 10px;
display: flex;
gap: 8px;
}
.task_popup .task_details .content .left .task-description-editor .task-description-input {
min-height: 120px;
resize: vertical;
@@ -542,6 +559,118 @@
var tab_panels = popup.find( '.task-tab-panel' );
var tab_buttons = popup.find( '.js-task-tab-btn' );
var description_view = popup.find( '.task-description-view' );
var description_actions = popup.find( '.task-description-actions' );
var description_editor_box = popup.find( '.task-description-editor' );
var description_input = popup.find( '.task-description-input' );
var initial_description_text = description_input.val() || '';
var description_editor_instance = null;
var ckeditor_base_path = '/libraries/ckeditor/';
function loadScriptOnce( src ) {
var deferred = $.Deferred();
var existing_script = document.querySelector( 'script[src="' + src + '"]' );
if ( existing_script )
{
deferred.resolve();
return deferred.promise();
}
$.getScript( src )
.done( function() { deferred.resolve(); } )
.fail( function() { deferred.reject(); } );
return deferred.promise();
}
function ensureDescriptionEditorReady( callback ) {
if ( description_editor_instance || !description_input.length )
{
if ( typeof callback === 'function' )
callback();
return;
}
window.CKEDITOR_BASEPATH = ckeditor_base_path;
if ( window.CKEDITOR )
window.CKEDITOR.basePath = ckeditor_base_path;
function initEditor() {
if ( $.fn.ckeditor )
{
description_input.ckeditor({
toolbar: 'Basic',
language: 'pl',
height: '100'
});
try
{
description_editor_instance = description_input.ckeditorGet();
}
catch ( e )
{
description_editor_instance = null;
}
}
if ( typeof callback === 'function' )
callback();
}
if ( $.fn.ckeditor )
{
initEditor();
return;
}
loadScriptOnce( ckeditor_base_path + 'ckeditor.js' )
.done( function() {
if ( window.CKEDITOR )
window.CKEDITOR.basePath = ckeditor_base_path;
loadScriptOnce( ckeditor_base_path + 'adapters/jquery.js' )
.always( function() {
initEditor();
} );
} )
.fail( function() {
if ( typeof callback === 'function' )
callback();
} );
}
function getDescriptionValue() {
if ( description_editor_instance )
{
description_editor_instance.updateElement();
}
return description_input.val();
}
function setDescriptionValue( value ) {
if ( description_editor_instance )
{
description_editor_instance.setData( value || '' );
}
description_input.val( value || '' );
}
function toggleDescriptionEditMode( is_edit ) {
description_view.toggle( !is_edit );
description_actions.toggle( !is_edit );
description_editor_box.toggle( is_edit );
if ( is_edit )
{
ensureDescriptionEditorReady( function() {
if ( description_editor_instance )
description_editor_instance.focus();
else
description_input.trigger( 'focus' );
} );
}
}
function setActiveTaskTab( tab_name ) {
if ( !tab_panels.length )
@@ -571,6 +700,17 @@
setActiveTaskTab( window.crm_task_popup_active_tab || 'description' );
popup.on( 'click', '.js-start-edit-task-description', function( e ) {
e.preventDefault();
toggleDescriptionEditMode( true );
} );
popup.on( 'click', '.js-cancel-edit-task-description', function( e ) {
e.preventDefault();
setDescriptionValue( initial_description_text );
toggleDescriptionEditMode( false );
} );
if ( $.fn.select2 )
{
var client_select = popup.find( '.task_client_select' );
@@ -774,7 +914,7 @@
e.preventDefault();
var btn = $( this );
var task_id = btn.attr( 'task_id' );
var text = popup.find( '.task-description-input' ).val();
var text = getDescriptionValue();
btn.text( 'Zapisywanie...' ).addClass( 'disabled' );
$.ajax({
@@ -786,6 +926,7 @@
if ( res.status === 'success' )
{
btn.text( 'Zapisano!' );
initial_description_text = text;
task_popup( task_id, is_task_popup_works_time_open() );
}
else
@@ -812,3 +953,4 @@
}, 1000 );
} )();
</script>