diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json
index b2d19c8..90a3af1 100644
--- a/.vscode/ftp-kr.sync.cache.json
+++ b/.vscode/ftp-kr.sync.cache.json
@@ -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
+ }
+ }
}
}
},
diff --git a/index.php b/index.php
index 941991e..cd03fe0 100644
--- a/index.php
+++ b/index.php
@@ -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();
diff --git a/templates/tasks/task_popup.php b/templates/tasks/task_popup.php
index 58a5590..52ad683 100644
--- a/templates/tasks/task_popup.php
+++ b/templates/tasks/task_popup.php
@@ -87,22 +87,31 @@
endforeach; endif;?>
+
-
-
Treść zadania
-
-
+
+ if ( $this -> task['text'] ):?>
+
+
+ = $task_description_html;?>
+
+ else:?>
+
+ Brak opisu zadania.
+
+ endif;?>
- if ( $this -> task['text'] ):?>
-
-
- = $task_description_html;?>
+
+
+
+
+
Treść zadania
+
+
+
+
- else:?>
-
- Brak opisu zadania.
-
- endif;?>
+
@@ -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 );
} )();
+