From 890f3a32c503ac47b7dbea1c643c2d71a1c58aa5 Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Sun, 22 Mar 2026 23:55:14 +0100 Subject: [PATCH] update --- .claude/memory/MEMORY.md | 3 + .claude/memory/feedback_polish.md | 10 ++ autoload/controls/class.Tasks.php | 23 +++++ templates/tasks/task_work_logs_popup.php | 81 ++++++++++++++++ templates/tasks/work-time.php | 118 ++++++++++++++++++++++- templates/wiki/main-view.php | 45 +++------ 6 files changed, 245 insertions(+), 35 deletions(-) create mode 100644 .claude/memory/MEMORY.md create mode 100644 .claude/memory/feedback_polish.md create mode 100644 templates/tasks/task_work_logs_popup.php diff --git a/.claude/memory/MEMORY.md b/.claude/memory/MEMORY.md new file mode 100644 index 0000000..5437754 --- /dev/null +++ b/.claude/memory/MEMORY.md @@ -0,0 +1,3 @@ +# Memory Index + +- [feedback_polish.md](feedback_polish.md) — Komunikacja po polsku diff --git a/.claude/memory/feedback_polish.md b/.claude/memory/feedback_polish.md new file mode 100644 index 0000000..1fd8b8d --- /dev/null +++ b/.claude/memory/feedback_polish.md @@ -0,0 +1,10 @@ +--- +name: Komunikacja po polsku +description: Użytkownik chce, żeby Claude pisał do niego po polsku +type: feedback +--- + +Zawsze komunikuj się z użytkownikiem po polsku. + +**Why:** Użytkownik wyraźnie poprosił o komunikację w języku polskim. +**How to apply:** Wszystkie odpowiedzi, pytania i podsumowania pisz po polsku. diff --git a/autoload/controls/class.Tasks.php b/autoload/controls/class.Tasks.php index 417fa8f..4afeb52 100644 --- a/autoload/controls/class.Tasks.php +++ b/autoload/controls/class.Tasks.php @@ -593,6 +593,29 @@ class Tasks exit; } + static public function task_work_logs_popup() + { + global $user; + + if ( !$user ) + { + header( 'Location: /logowanie' ); + exit; + } + + $task_id = (int)\S::get( 'task_id' ); + $task = \factory\Tasks::task_details( $task_id, $user['id'] ); + + if ( !is_array( $task ) ) + $task = [ 'id' => $task_id, 'name' => '' ]; + + echo \Tpl::view( 'tasks/task_work_logs_popup', [ + 'task' => $task, + 'task_works' => \factory\Tasks::task_works( $task_id ) + ] ); + exit; + } + static public function task_attachment_upload() { global $user; diff --git a/templates/tasks/task_work_logs_popup.php b/templates/tasks/task_work_logs_popup.php new file mode 100644 index 0000000..aeec490 --- /dev/null +++ b/templates/tasks/task_work_logs_popup.php @@ -0,0 +1,81 @@ + +
+
+
Zadanie: task['name'] ?? '' ), ENT_QUOTES, 'UTF-8' );?>
+
ID: task['id'] ?? 0 );?>
+
+ + task_works ) and count( $this -> task_works ) ):?> +
+ + + + + + + + + + + task_works as $work ):?> + + + + + + + + +
UżytkownikStartKoniecAkcja
+ + + + + zapisz +
+
+ +
Brak wpisów time trackingu dla tego zadania.
+ +
diff --git a/templates/tasks/work-time.php b/templates/tasks/work-time.php index 9ca8077..348762b 100644 --- a/templates/tasks/work-time.php +++ b/templates/tasks/work-time.php @@ -157,7 +157,11 @@ usort( $billing_clients, function( $a, $b ) { - + + + + + zamknij zadanie @@ -250,6 +254,54 @@ usort( $billing_clients, function( $a, $b ) { onConfirm(); } + function showPopupMessage( message ) { + if ( typeof $.alert === 'function' ) + { + $.alert({ + title: 'Informacja', + content: message + }); + return; + } + + alert( message ); + } + + function openWorkLogsPopup( task_id, task_name ) { + $.ajax({ + type: 'POST', + cache: false, + url: '/tasks/task_work_logs_popup/', + data: { + task_id: task_id + }, + success: function( response ) { + if ( typeof $.confirm !== 'function' ) + { + showPopupMessage( 'Brak obsługi popupu w tej konfiguracji.' ); + return; + } + + $.confirm({ + title: 'Time tracking: ' + task_name, + content: response, + type: 'blue', + boxWidth: '980px', + useBootstrap: false, + backgroundDismiss: true, + buttons: { + close: { + text: 'Zamknij' + } + } + }); + }, + error: function() { + showPopupMessage( 'Nie udało się pobrać wpisów time trackingu.' ); + } + }); + } + $( 'body' ).on( 'click', '.toggle-billing-details', function(e){ e.preventDefault(); @@ -279,6 +331,70 @@ usort( $billing_clients, function( $a, $b ) { }); }); + $( 'body' ).on( 'click', '.open-work-logs-popup', function(e){ + e.preventDefault(); + var task_id = parseInt( $( this ).attr( 'task-id' ), 10 ) || 0; + var task_name = $( this ).attr( 'task-name' ) || ( 'Zadanie #' + task_id ); + + if ( !task_id ) + { + showPopupMessage( 'Brak identyfikatora zadania.' ); + return; + } + + openWorkLogsPopup( task_id, task_name ); + }); + + $( 'body' ).on( 'click', '.js-save-work-log', function(e){ + e.preventDefault(); + + var button = $( this ); + var row = button.closest( '.js-work-log-row' ); + var task_work_id = parseInt( button.attr( 'task_work_id' ), 10 ) || 0; + var date_start = row.find( '.js-work-log-start' ).val(); + var date_end = row.find( '.js-work-log-end' ).val(); + + if ( !task_work_id ) + { + showPopupMessage( 'Brak identyfikatora wpisu.' ); + return; + } + + if ( !date_start || !date_end ) + { + showPopupMessage( 'Uzupełnij datę start i koniec.' ); + return; + } + + button.attr( 'disabled', 'disabled' ); + + $.when( + $.ajax({ + type: 'POST', + cache: false, + url: '/tasks/change_task_work_date_start/', + data: { + task_work_id: task_work_id, + date_start: date_start + } + }), + $.ajax({ + type: 'POST', + cache: false, + url: '/tasks/change_task_work_date_end/', + data: { + task_work_id: task_work_id, + date_end: date_end + } + }) + ).done( function() { + window.location.reload(); + }).fail( function() { + button.removeAttr( 'disabled' ); + showPopupMessage( 'Nie udało się zapisać zmian wpisu.' ); + }); + }); + $( 'body' ).on( 'click', '.close-task', function(e){ e.preventDefault(); diff --git a/templates/wiki/main-view.php b/templates/wiki/main-view.php index 6a2193f..aa45b00 100644 --- a/templates/wiki/main-view.php +++ b/templates/wiki/main-view.php @@ -35,9 +35,6 @@ categories ) and count( $this -> categories ) ):?> categories as $category ):?> - - - 170 ) $category_preview = substr( $category_preview, 0, 170 ) . '...';?>
- -
- -
Brak podglądu treści.
-
@@ -77,18 +69,10 @@ categories ) and count( $this -> categories ) ):?> categories as $category ):?> - - - 170 ) $category_preview = substr( $category_preview, 0, 170 ) . '...';?>
- -
- -
Brak podglądu treści.
-
@@ -154,21 +138,22 @@ .wiki-main .wiki-categories-grid { display: grid; - gap: 12px; - grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); + gap: 14px; + grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); } .wiki-main .wiki-card { display: flex; flex-direction: column; - gap: 10px; + gap: 12px; border: 1px solid var(--wiki-border); border-radius: 10px; - padding: 12px; + padding: 14px; background: #fff; transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease; min-width: 0; overflow: hidden; + min-height: 96px; } .wiki-main .wiki-card:hover { @@ -197,20 +182,6 @@ text-decoration: underline; } - .wiki-main .wiki-card-preview { - color: var(--wiki-text); - font-size: 13px; - line-height: 1.45; - min-height: 38px; - overflow-wrap: anywhere; - word-break: break-word; - } - - .wiki-main .wiki-card-preview-empty { - color: var(--wiki-muted); - font-style: italic; - } - .wiki-main .wiki-card-bottom { display: flex; align-items: center; @@ -271,6 +242,12 @@ max-width: none; } } + + @media (min-width: 1400px) { + .wiki-main .wiki-categories-grid { + grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); + } + }