feat: Add wiki integration to task management
- Implemented a multi-select dropdown for associating tasks with wiki entries in the task edit form. - Enhanced task popup to display related wiki entries with visibility controls based on user permissions. - Updated the wiki main view to support bulk actions for categories, including deletion and search functionality. - Created a new database migration for establishing many-to-many relationships between tasks and wiki entries. - Improved styling for wiki components to enhance user experience. - Added a new AGENTS.md file to outline communication and change management protocols.
This commit is contained in:
@@ -35,6 +35,23 @@ if ( is_array( $this -> clients ) )
|
||||
foreach ( $this -> clients as $client )
|
||||
$clients[ $client[ 'id' ] ] = $client[ 'firm' ];
|
||||
|
||||
$wiki_categories = ( isset( $this -> wiki_categories ) and is_array( $this -> wiki_categories ) ) ? $this -> wiki_categories : [];
|
||||
$current_user_id = isset( $this -> user['id'] ) ? (int)$this -> user['id'] : 0;
|
||||
if ( !count( $wiki_categories ) and $current_user_id > 0 )
|
||||
$wiki_categories = \factory\Wiki::get_categories_for_user( $current_user_id );
|
||||
if ( !count( $wiki_categories ) )
|
||||
$wiki_categories = \factory\Wiki::get_all_categories();
|
||||
$task_wiki_ids = isset( $this -> task['wiki_ids'] ) && is_array( $this -> task['wiki_ids'] ) ? array_map( 'intval', $this -> task['wiki_ids'] ) : [];
|
||||
$wiki_values = [];
|
||||
if ( is_array( $wiki_categories ) )
|
||||
foreach ( $wiki_categories as $wiki_category )
|
||||
{
|
||||
$wiki_id = isset( $wiki_category['id'] ) ? (int)$wiki_category['id'] : 0;
|
||||
if ( !$wiki_id )
|
||||
continue;
|
||||
$wiki_values[ $wiki_id ] = isset( $wiki_category['name'] ) ? (string)$wiki_category['name'] : (string)$wiki_id;
|
||||
}
|
||||
|
||||
$parent_tasks = [ 0 => '--- wybierz zadanie nadrzędne ---' ];
|
||||
if ( is_array( $this -> parent_tasks ) )
|
||||
foreach ( $this -> parent_tasks as $parent_task )
|
||||
@@ -130,6 +147,20 @@ ob_start();
|
||||
'values' => $parent_tasks
|
||||
] );
|
||||
?>
|
||||
<div class="form_group">
|
||||
<label class="label">Powiazane Wiki:</label>
|
||||
<div class="input">
|
||||
<? if ( is_array( $wiki_categories ) and count( $wiki_categories ) ):?>
|
||||
<select name="wiki_ids[]" id="wiki_ids" class="form-control" multiple>
|
||||
<? foreach ( $wiki_values as $wiki_id => $wiki_name ):?>
|
||||
<option value="<?= (int)$wiki_id;?>" <? if ( in_array( (int)$wiki_id, $task_wiki_ids ) ):?>selected="selected"<? endif;?>><?= htmlspecialchars( $wiki_name );?></option>
|
||||
<? endforeach;?>
|
||||
</select>
|
||||
<? else:?>
|
||||
<div class="task-wiki-empty">Brak dostepnych wpisow Wiki.</div>
|
||||
<? endif;?>
|
||||
</div>
|
||||
</div>
|
||||
<?= \Html::select( [
|
||||
'label' => 'Status',
|
||||
'name' => 'status',
|
||||
@@ -434,6 +465,29 @@ ob_start();
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#wiki_ids + .select2-container {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
#wiki_ids + .select2-container .select2-selection--multiple {
|
||||
min-height: 38px;
|
||||
border: 1px solid #cfd8e3;
|
||||
border-radius: 4px;
|
||||
padding: 2px 6px;
|
||||
}
|
||||
|
||||
#wiki_ids + .select2-container .select2-selection__choice {
|
||||
margin-top: 4px;
|
||||
max-width: 100%;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.task-wiki-empty {
|
||||
color: #6b7280;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.task-edit-message {
|
||||
margin: 12px 0 16px 0;
|
||||
padding: 12px 16px;
|
||||
@@ -957,12 +1011,12 @@ echo $grid -> draw();
|
||||
height: '100'
|
||||
});
|
||||
|
||||
$( '#project_id, #client_id, #status, #parent_id, #priority' ).select2({
|
||||
$( '#project_id, #client_id, #status, #parent_id, #priority, #wiki_ids' ).select2({
|
||||
theme: 'bootstrap-5',
|
||||
minimumResultsForSearch: 0
|
||||
});
|
||||
|
||||
$( '#project_id, #client_id, #status, #parent_id, #priority' ).on( 'select2:open', function() {
|
||||
$( '#project_id, #client_id, #status, #parent_id, #priority, #wiki_ids' ).on( 'select2:open', function() {
|
||||
setTimeout( function() {
|
||||
var search_field = document.querySelector( '.select2-container--open .select2-search__field' );
|
||||
if ( search_field )
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
$checklist_count = is_array( $this -> task['actions'] ) ? count( $this -> task['actions'] ) : 0;
|
||||
$comments_count = is_array( $this -> task['comments'] ) ? count( $this -> task['comments'] ) : 0;
|
||||
$attachments_count = is_array( $this -> task_attachments ) ? count( $this -> task_attachments ) : 0;
|
||||
$popup_wiki_data = \factory\Tasks::task_wiki_entries_for_user( (int)$this -> task['id'], (int)$this -> user['id'] );
|
||||
$task_wiki_entries = isset( $popup_wiki_data['entries'] ) && is_array( $popup_wiki_data['entries'] ) ? $popup_wiki_data['entries'] : [];
|
||||
$wiki_visible_count = isset( $popup_wiki_data['visible_count'] ) ? (int)$popup_wiki_data['visible_count'] : 0;
|
||||
$wiki_hidden_count = isset( $popup_wiki_data['hidden_count'] ) ? (int)$popup_wiki_data['hidden_count'] : 0;
|
||||
?>
|
||||
<?
|
||||
$task_description_html = htmlspecialchars_decode( (string)$this -> task['text'] );
|
||||
@@ -74,6 +78,7 @@
|
||||
<a href="#" class="js-task-tab-btn" data-tab="checklist" role="tab" aria-selected="false">Lista kontrolna (<?= (int)$checklist_count;?>)</a>
|
||||
<a href="#" class="js-task-tab-btn" data-tab="comments" role="tab" aria-selected="false">Komentarze (<?= (int)$comments_count;?>)</a>
|
||||
<a href="#" class="js-task-tab-btn" data-tab="attachments" role="tab" aria-selected="false">Załączniki (<?= (int)$attachments_count;?>)</a>
|
||||
<a href="#" class="js-task-tab-btn" data-tab="wiki" role="tab" aria-selected="false">Wiki (<?= (int)$wiki_visible_count;?>)</a>
|
||||
<? if ( $this -> user['id'] == 1 ):?>
|
||||
<a href="#" class="js-task-tab-btn" data-tab="users" role="tab" aria-selected="false">Uczestnicy</a>
|
||||
<? endif;?>
|
||||
@@ -177,6 +182,35 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="task-tab-panel" data-tab="wiki">
|
||||
<div class="box">
|
||||
<h3>Powiazane wpisy Wiki</h3>
|
||||
<? if ( $wiki_hidden_count > 0 ):?>
|
||||
<div class="alert alert-warning" style="margin-bottom: 12px;">
|
||||
Nie masz dostepu do <?= (int)$wiki_hidden_count;?> powiazanych wpisow Wiki.
|
||||
</div>
|
||||
<? endif;?>
|
||||
<? if ( is_array( $task_wiki_entries ) and count( $task_wiki_entries ) ):?>
|
||||
<div class="task-wiki-list">
|
||||
<? foreach ( $task_wiki_entries as $wiki_entry ):?>
|
||||
<div class="task-wiki-entry">
|
||||
<h4><?= htmlspecialchars( (string)$wiki_entry['name'] );?></h4>
|
||||
<div class="task-wiki-content">
|
||||
<?= (string)$wiki_entry['text'];?>
|
||||
<? if ( $this -> user['id'] == 1 or $this -> user['id'] == 3 ):?>
|
||||
<? if ( isset( $wiki_entry['text_admin'] ) and (string)$wiki_entry['text_admin'] !== '' ):?>
|
||||
<div class="task-wiki-admin"><?= (string)$wiki_entry['text_admin'];?></div>
|
||||
<? endif;?>
|
||||
<? endif;?>
|
||||
</div>
|
||||
</div>
|
||||
<? endforeach;?>
|
||||
</div>
|
||||
<? else:?>
|
||||
<div class="task-wiki-empty">Brak widocznych wpisow Wiki dla tego zadania.</div>
|
||||
<? endif;?>
|
||||
</div>
|
||||
</div>
|
||||
<? if ( $this -> user['id'] == 1 ):?>
|
||||
<div class="task-tab-panel" data-tab="users">
|
||||
<div class="task-users-edit">
|
||||
@@ -407,6 +441,36 @@
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.task_popup .task_details .task-wiki-list {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
.task_popup .task_details .task-wiki-entry {
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
background: #fff;
|
||||
}
|
||||
.task_popup .task_details .task-wiki-entry h4 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #1f3d72;
|
||||
}
|
||||
.task_popup .task_details .task-wiki-content {
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.task_popup .task_details .task-wiki-admin {
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px dashed #d1d5db;
|
||||
}
|
||||
.task_popup .task_details .task-wiki-empty {
|
||||
color: #6b7280;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Lightbox - powiększanie zdjęć w opisie */
|
||||
.task_popup .task_details .description img {
|
||||
cursor: zoom-in;
|
||||
@@ -676,8 +740,16 @@
|
||||
if ( !tab_panels.length )
|
||||
return;
|
||||
|
||||
var allowed_tabs = [ 'description', 'checklist', 'comments', 'attachments', 'users' ];
|
||||
var selected_tab = allowed_tabs.indexOf( tab_name ) >= 0 ? tab_name : 'description';
|
||||
var available_tabs = [];
|
||||
tab_buttons.each( function() {
|
||||
var tab = $( this ).attr( 'data-tab' );
|
||||
if ( tab )
|
||||
available_tabs.push( tab );
|
||||
});
|
||||
|
||||
var selected_tab = available_tabs.indexOf( tab_name ) >= 0 ? tab_name : 'description';
|
||||
if ( available_tabs.indexOf( selected_tab ) < 0 && available_tabs.length )
|
||||
selected_tab = available_tabs[0];
|
||||
|
||||
tab_panels.each( function() {
|
||||
var panel = $( this );
|
||||
|
||||
Reference in New Issue
Block a user