Completamento Checklists
This commit is contained in:
parent
4d3ef8cc27
commit
48149dd6d6
46
actions.php
46
actions.php
|
@ -108,6 +108,17 @@ elseif (filter('op') == 'add_nota') {
|
|||
flash()->info(tr('Nota interna aggiunta correttamente!'));
|
||||
}
|
||||
|
||||
// Rimozione data di notifica dalla nota interna
|
||||
elseif (filter('op') == 'notification_nota') {
|
||||
$id_nota = post('id_nota');
|
||||
$nota = Note::find($id_nota);
|
||||
|
||||
$nota->notification_date = null;
|
||||
$nota->save();
|
||||
|
||||
flash()->info(tr('Data di notifica rimossa dalla nota interna!'));
|
||||
}
|
||||
|
||||
// Rimozione nota interna
|
||||
elseif (filter('op') == 'delete_nota') {
|
||||
$id_nota = post('id_nota');
|
||||
|
@ -122,10 +133,14 @@ elseif (filter('op') == 'delete_nota') {
|
|||
elseif (filter('op') == 'clone_checklist') {
|
||||
$content = post('content');
|
||||
$checklist_id = post('checklist');
|
||||
$assigned_user = User::find(post('assigned_user'));
|
||||
|
||||
$users = post('assigned_users');
|
||||
$users = array_clean($users);
|
||||
|
||||
$group_id = post('group_id');
|
||||
|
||||
$checklist = Checklist::find($checklist_id);
|
||||
$checklist->copia($user, $assigned_user, $id_record);
|
||||
$checklist->copia($user, $id_record, $users, $group_id);
|
||||
}
|
||||
|
||||
// Aggiunta check alla checklist
|
||||
|
@ -133,9 +148,13 @@ elseif (filter('op') == 'add_check') {
|
|||
$content = post('content');
|
||||
$parent_id = post('parent') ?: null;
|
||||
|
||||
$assigned_user = User::find(post('assigned_user'));
|
||||
$users = post('assigned_users');
|
||||
$users = array_clean($users);
|
||||
|
||||
$check = Check::build($user, $structure, $id_record, $content, $assigned_user, $parent_id);
|
||||
$group_id = post('group_id');
|
||||
|
||||
$check = Check::build($user, $structure, $id_record, $content, $parent_id);
|
||||
$check->setAccess($users, $group_id);
|
||||
}
|
||||
|
||||
// Rimozione di un check della checklist
|
||||
|
@ -143,8 +162,10 @@ elseif (filter('op') == 'delete_check') {
|
|||
$check_id = post('check_id');
|
||||
$check = Check::find($check_id);
|
||||
|
||||
if (!empty($check)) {
|
||||
if (!empty($check) && $check->user->id == $user->id) {
|
||||
$check->delete();
|
||||
} else {
|
||||
flash()->error(tr('Impossibile eliminare il check!'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,8 +174,21 @@ elseif (filter('op') == 'toggle_check') {
|
|||
$check_id = post('check_id');
|
||||
$check = Check::find($check_id);
|
||||
|
||||
if (!empty($check)) {
|
||||
if (!empty($check) && $check->assignedUsers->pluck('id')->search($user->id) !== false) {
|
||||
$check->toggleCheck();
|
||||
} else {
|
||||
flash()->error(tr('Impossibile cambiare lo stato del check!'));
|
||||
}
|
||||
}
|
||||
|
||||
// Gestione ordine per le checklist
|
||||
elseif (filter('op') == 'sort_checks') {
|
||||
$ids = explode(',', $_POST['order']);
|
||||
$order = 0;
|
||||
|
||||
foreach ($ids as $id) {
|
||||
$dbo->query('UPDATE `zz_checks` SET `order` = '.prepare($order).' WHERE id = '.prepare($id));
|
||||
++$order;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
ajax.php
2
ajax.php
|
@ -55,7 +55,7 @@ switch (get('op')) {
|
|||
break;
|
||||
|
||||
case 'checklists':
|
||||
echo '{( "name": "checklists", "id_module": "'.$id_module.'", "id_record": "'.$id_record.'", "id_plugin": "'.$id_plugin.'" )}';
|
||||
include DOCROOT.'/plugins/checks.php';
|
||||
|
||||
break;
|
||||
|
||||
|
|
|
@ -851,39 +851,6 @@ input.small-width {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Checklist */
|
||||
ul.checklist {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.checklist li {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
padding: 12px 8px 12px 10px;
|
||||
font-size: 18px;
|
||||
transition: 0.2s;
|
||||
|
||||
/* make the list items unselectable */
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
ul.checklist li:hover {
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
ul.checklist li.checked {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
ul.checklist li.checked > .check-text {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.component-loader {
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
|
@ -898,3 +865,9 @@ ul.checklist li.checked > .check-text {
|
|||
top: 50%;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* Checklist */
|
||||
.todo-list ul {
|
||||
list-style: none;
|
||||
margin-left: 11px;
|
||||
}
|
||||
|
|
|
@ -68,15 +68,10 @@ function openLink(event, link) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Funzione per far scrollare la pagina fino a un id + focus e offset
|
||||
* Funzione per far scrollare la pagina fino a un offset
|
||||
* @param integer offset
|
||||
* @param string id
|
||||
*/
|
||||
function scrollToAndFocus(offset, id) {
|
||||
if (id) {
|
||||
offset += $('#' + id).offset().top;
|
||||
}
|
||||
|
||||
function scrollToOffset(offset) {
|
||||
$('html,body').animate({
|
||||
scrollTop: offset
|
||||
}, 'slow');
|
||||
|
@ -420,32 +415,7 @@ function submitAjax(form, data, callback, errorCallback) {
|
|||
|
||||
$("#main_loading").fadeOut();
|
||||
|
||||
// Visualizzazione messaggi
|
||||
$.ajax({
|
||||
url: globals.rootdir + '/ajax.php',
|
||||
type: 'get',
|
||||
data: {
|
||||
op: 'flash',
|
||||
},
|
||||
success: function (flash) {
|
||||
messages = JSON.parse(flash);
|
||||
|
||||
info = messages.info ? messages.info : {};
|
||||
Object.keys(info).forEach(function (element) {
|
||||
toastr["success"](info[element]);
|
||||
});
|
||||
|
||||
warning = messages.warning ? messages.warning : {};
|
||||
Object.keys(warning).forEach(function (element) {
|
||||
toastr["warning"](warning[element]);
|
||||
});
|
||||
|
||||
error = messages.error ? messages.error : {};
|
||||
Object.keys(error).forEach(function (element) {
|
||||
toastr["error"](error[element]);
|
||||
});
|
||||
}
|
||||
});
|
||||
renderMessages();
|
||||
},
|
||||
error: function (data) {
|
||||
$("#main_loading").fadeOut();
|
||||
|
@ -460,6 +430,34 @@ function submitAjax(form, data, callback, errorCallback) {
|
|||
return valid;
|
||||
}
|
||||
|
||||
function renderMessages() {
|
||||
// Visualizzazione messaggi
|
||||
$.ajax({
|
||||
url: globals.rootdir + '/ajax.php',
|
||||
type: 'get',
|
||||
data: {
|
||||
op: 'flash',
|
||||
},
|
||||
success: function (flash) {
|
||||
messages = JSON.parse(flash);
|
||||
|
||||
info = messages.info ? messages.info : {};
|
||||
Object.keys(info).forEach(function (element) {
|
||||
toastr["success"](info[element]);
|
||||
});
|
||||
|
||||
warning = messages.warning ? messages.warning : {};
|
||||
Object.keys(warning).forEach(function (element) {
|
||||
toastr["warning"](warning[element]);
|
||||
});
|
||||
|
||||
error = messages.error ? messages.error : {};
|
||||
Object.keys(error).forEach(function (element) {
|
||||
toastr["error"](error[element]);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function removeHash() {
|
||||
history.replaceState(null, null, ' ');
|
||||
}
|
||||
|
|
|
@ -17,3 +17,10 @@ String.prototype.toEnglish = function () {
|
|||
Number.prototype.toLocale = function () {
|
||||
return numeral(this).format();
|
||||
};
|
||||
|
||||
jQuery.fn.scrollTo = function(elem, speed) {
|
||||
$(this).animate({
|
||||
scrollTop: $(this).scrollTop() - $(this).offset().top + $(elem).offset().top
|
||||
}, speed == undefined ? 1000 : speed);
|
||||
return this;
|
||||
};
|
||||
|
|
|
@ -28,7 +28,7 @@ $(document).ready(function () {
|
|||
// Riporto l'utente allo scroll precedente
|
||||
if (sessionStorage['scrollTop_' + globals.id_module + '_' + globals.id_record] != undefined) {
|
||||
setTimeout(function () {
|
||||
scrollToAndFocus(sessionStorage['scrollTop_' + globals.id_module + '_' + globals.id_record]);
|
||||
scrollToOffset(sessionStorage['scrollTop_' + globals.id_module + '_' + globals.id_record]);
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
|
|
114
editor.php
114
editor.php
|
@ -93,10 +93,23 @@ if (empty($record) || !$has_access) {
|
|||
}
|
||||
|
||||
// Tab per le note interne
|
||||
if ($structure->permission != '-') {
|
||||
if ($structure->permission != '-' && $structure->use_notes) {
|
||||
$notes = $structure->recordNotes($id_record);
|
||||
|
||||
echo '
|
||||
<li class="bg-info">
|
||||
<a data-toggle="tab" href="#tab_note" id="link-tab_note">'.tr('Note interne').'</a>
|
||||
<a data-toggle="tab" href="#tab_note" id="link-tab_note">
|
||||
'.tr('Note interne').'
|
||||
<span class="badge">'.($notes->count() ?: '').'</span>
|
||||
</a>
|
||||
</li>';
|
||||
}
|
||||
|
||||
// Tab per le checklist
|
||||
if ($structure->permission != '-' && $structure->use_checklists) {
|
||||
echo '
|
||||
<li class="bg-success">
|
||||
<a data-toggle="tab" href="#tab_checks" id="link-tab_checks">'.tr('Checklist').'</a>
|
||||
</li>';
|
||||
}
|
||||
|
||||
|
@ -273,97 +286,21 @@ if (empty($record) || !$has_access) {
|
|||
});
|
||||
</script>';
|
||||
|
||||
if ($structure->permission != '-') {
|
||||
if ($structure->permission != '-' && $structure->use_notes) {
|
||||
echo '
|
||||
<div id="tab_note" class="tab-pane">';
|
||||
|
||||
$note = $structure->notes($id_record);
|
||||
if (!empty($note)) {
|
||||
echo '
|
||||
<div class="box box-warning direct-chat direct-chat-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">'.tr('Note interne').'</h3>
|
||||
</div>
|
||||
include DOCROOT.'/plugins/notes.php';
|
||||
|
||||
<div class="box-body">
|
||||
<div class="direct-chat-messages" style="height: 50vh">';
|
||||
echo '
|
||||
</div>';
|
||||
}
|
||||
|
||||
foreach ($note as $nota) {
|
||||
$utente = $nota->user;
|
||||
$nome = $utente->anagrafica ? $utente->anagrafica->ragione_sociale.' ('.$utente->username.')' : $utente->username;
|
||||
$photo = $utente->photo;
|
||||
if ($structure->permission != '-' && $structure->use_checklists) {
|
||||
echo '
|
||||
<div id="tab_checks" class="tab-pane">';
|
||||
|
||||
echo '
|
||||
<div class="direct-chat-msg '.($utente->id == $user->id ? 'right' : '').'" id="nota_'.$nota->id.'">
|
||||
<div class="direct-chat-info clearfix">
|
||||
<span class="direct-chat-name pull-left">'.$nome.'</span>
|
||||
<span class="direct-chat-timestamp pull-right">
|
||||
'.timestampFormat($nota->created_at).'
|
||||
</span>
|
||||
</div>';
|
||||
|
||||
if ($photo) {
|
||||
echo '
|
||||
<img class="direct-chat-img" src="'.$photo.'">';
|
||||
} else {
|
||||
echo '
|
||||
|
||||
<i class="fa fa-user-circle-o direct-chat-img fa-3x" alt="'.tr('OpenSTAManager').'"></i>';
|
||||
}
|
||||
|
||||
echo '
|
||||
<div class="direct-chat-text">
|
||||
<div class="pull-right">';
|
||||
|
||||
if (!empty($nota->notification_date)) {
|
||||
echo '
|
||||
<span class="label label-default tip" title="'.tr('Data di notifica').'" style="margin-right: 5px">
|
||||
<i class="fa fa-bell"></i> '.dateFormat($nota->notification_date).'
|
||||
</span>';
|
||||
}
|
||||
|
||||
if ($user->is_admin || $utente->id == $user->id) {
|
||||
echo '
|
||||
<button type="button" class="btn btn-danger btn-xs ask" data-op="delete_nota" data-id_nota="'.$nota->id.'" data-msg="'.tr('Rimuovere questa nota?').'" data-backto="record-edit">
|
||||
<i class="fa fa-trash-o"></i>
|
||||
</button>';
|
||||
}
|
||||
|
||||
echo '
|
||||
</div>
|
||||
'.$nota->content.'
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
echo '
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
} else {
|
||||
echo '
|
||||
<p>'.tr('Non sono presenti note interne').'</p>';
|
||||
}
|
||||
|
||||
if ($structure->permission == 'rw') {
|
||||
echo '
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="op" value="add_nota">
|
||||
<input type="hidden" name="backto" value="record-edit">
|
||||
|
||||
{[ "type": "date", "label": "'.tr('Data di notifica').'", "name": "data_notifica" ]}
|
||||
|
||||
{[ "type": "ckeditor", "label": "'.tr('Nuova nota').'", "name": "contenuto", "required": 1]}
|
||||
|
||||
<!-- PULSANTI -->
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-right">
|
||||
<button type="sumbit" class="btn btn-primary">
|
||||
<i class="fa fa-plus"></i> '.tr('Aggiungi').'
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>';
|
||||
}
|
||||
include DOCROOT.'/plugins/checks.php';
|
||||
|
||||
echo '
|
||||
</div>';
|
||||
|
@ -438,7 +375,8 @@ if (empty($record) || !$has_access) {
|
|||
</li>';
|
||||
}
|
||||
|
||||
echo ' </ul>';
|
||||
echo '
|
||||
</ul>';
|
||||
} else {
|
||||
echo '
|
||||
<div class="alert alert-info">
|
||||
|
|
|
@ -58,7 +58,6 @@ if (!isset($options['edit_articolo']) || !empty($options['edit_articolo'])) {
|
|||
echo '
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
console.log($(this).closest("modal"));
|
||||
$("#idarticolo").on("change", function(){
|
||||
// Autoimpostazione dei valori relativi
|
||||
if ($(this).val()) {
|
||||
|
|
|
@ -52,5 +52,16 @@ switch (post('op')) {
|
|||
|
||||
flash()->info(tr('Riga della checklist eliminata!'));
|
||||
|
||||
break;
|
||||
|
||||
case 'update_position':
|
||||
$ids = explode(',', $_POST['order']);
|
||||
$order = 0;
|
||||
|
||||
foreach ($ids as $id) {
|
||||
$dbo->query('UPDATE `zz_checklist_items` SET `order` = '.prepare($order).' WHERE id = '.prepare($id));
|
||||
++$order;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -7,26 +7,17 @@ echo '
|
|||
<input type="hidden" name="op" value="add">
|
||||
<input type="hidden" name="backto" value="record-edit">
|
||||
|
||||
<!-- DATI -->
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">'.tr('Dati').'</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "text", "label": "'.tr('Nome').'", "name": "name", "value": "$name$", "required": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "text", "label": "'.tr('Nome').'", "name": "name", "value": "$name$", "required": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "select", "label": "'.tr('Modulo del template').'", "name": "module", "values": "query=SELECT id, title AS descrizione FROM zz_modules WHERE enabled = 1", "value": "'.$record['id_module'].'", "disabled": "'.!empty($record['id_plugin']).'" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "select", "label": "'.tr('Plugin del template').'", "name": "plugin", "values": "query=SELECT id, title AS descrizione FROM zz_plugins WHERE enabled = 1", "value": "'.$record['id_plugin'].'", "disabled": "'.!empty($record['id_module']).'" ]}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
{[ "type": "select", "label": "'.tr('Modulo del template').'", "name": "module", "values": "query=SELECT id, title AS descrizione FROM zz_modules WHERE enabled = 1", "value": "'.$record['id_module'].'", "disabled": "'.!empty($record['id_plugin']).'" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "select", "label": "'.tr('Plugin del template').'", "name": "plugin", "values": "query=SELECT id, title AS descrizione FROM zz_plugins WHERE enabled = 1", "value": "'.$record['id_plugin'].'", "disabled": "'.!empty($record['id_module']).'" ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ include_once __DIR__.'/../../../core.php';
|
|||
|
||||
$manager_id = filter('manager_id');
|
||||
|
||||
$checks = $structure->checks($id_record);
|
||||
$checks = $structure->recordChecks($id_record);
|
||||
$list = [];
|
||||
foreach ($checks as $check) {
|
||||
$list[] = [
|
||||
|
@ -16,18 +16,22 @@ foreach ($checks as $check) {
|
|||
echo '
|
||||
<form action="" method="post" id="check-form">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="col-md-9">
|
||||
{[ "type": "text", "label": "'.tr('Contenuto').'", "name": "content", "required": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
{[ "type": "select", "label": "'.tr('Genitore').'", "name": "parent", "values": '.json_encode($list).' ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "select", "label": "'.tr('Genitore').'", "name": "parent", "values": '.json_encode($list).', "required": 1 ]}
|
||||
<div class="col-md-6">
|
||||
{[ "type": "select", "label": "'.tr('Utente').'", "name": "assigned_users", "ajax-source": "utenti", "multiple": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
{[ "type": "select", "label": "'.tr('Utente').'", "name": "assigned_user", "ajax-source": "utenti", "required": 1 ]}
|
||||
<div class="col-md-6">
|
||||
{[ "type": "select", "label": "'.tr('Gruppo').'", "name": "group_id", "values": "query=SELECT id, nome AS text FROM zz_groups" ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -52,18 +56,32 @@ $(document).ready(function() {
|
|||
});
|
||||
|
||||
$("#parent").change(function(){
|
||||
if ($(this).val()) {
|
||||
$("#assigned_user").val("").attr("disabled", true).attr("required", false);
|
||||
if ($(this).selectData()) {
|
||||
$("#assigned_users").val("").attr("disabled", true).attr("required", false);
|
||||
$("#group_id").val("").attr("disabled", true).attr("required", false);
|
||||
} else {
|
||||
$("#assigned_user").val("").attr("disabled", false).attr("required", true);
|
||||
$("#assigned_users").val("").attr("disabled", false).attr("required", true);
|
||||
$("#group_id").val("").attr("disabled", false).attr("required", true);
|
||||
}
|
||||
});
|
||||
|
||||
$("#assigned_user").change(function(){
|
||||
if ($(this).val()) {
|
||||
$("#assigned_users").change(function(){
|
||||
if ($(this).selectData()) {
|
||||
$("#parent").val("").attr("disabled", true).attr("required", false);
|
||||
$("#group_id").val("").attr("disabled", true).attr("required", false);
|
||||
} else {
|
||||
$("#parent").val("").attr("disabled", false).attr("required", true);
|
||||
$("#group_id").val("").attr("disabled", false).attr("required", true);
|
||||
}
|
||||
});
|
||||
|
||||
$("#group_id").change(function(){
|
||||
if ($(this).selectData()) {
|
||||
$("#parent").val("").attr("disabled", true).attr("required", false);
|
||||
$("#assigned_users").val("").attr("disabled", true).attr("required", false);
|
||||
} else {
|
||||
$("#parent").val("").attr("disabled", false).attr("required", true);
|
||||
$("#assigned_users").val("").attr("disabled", false).attr("required", true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -95,7 +113,8 @@ function addCheck(btn) {
|
|||
checklist.addCheck({
|
||||
content: $form.find("#content").val(),
|
||||
parent: $form.find("#parent").val(),
|
||||
assigned_user: $form.find("#assigned_user").val(),
|
||||
assigned_users: $form.find("#assigned_users").val(),
|
||||
group_id: $form.find("#group_id").val(),
|
||||
});
|
||||
|
||||
$form.closest(".modal").modal("hide");
|
||||
|
|
|
@ -4,7 +4,7 @@ include_once __DIR__.'/../../../core.php';
|
|||
|
||||
$manager_id = filter('manager_id');
|
||||
|
||||
$checklists = $structure->checklists();
|
||||
$checklists = $structure->checklists()->orderBy('created_at')->get();
|
||||
$list = [];
|
||||
foreach ($checklists as $checklist) {
|
||||
$list[] = [
|
||||
|
@ -16,12 +16,18 @@ foreach ($checklists as $checklist) {
|
|||
echo '
|
||||
<form action="" method="post" id="check-form">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "select", "label": "'.tr('Checklist').'", "name": "checklist", "values": '.json_encode($list).', "required": 1 ]}
|
||||
<div class="col-md-12">
|
||||
{[ "type": "select", "label": "'.tr('Checklist').'", "name": "checklist", "values": '.json_encode($list).' ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "select", "label": "'.tr('Utente').'", "name": "assigned_users", "ajax-source": "utenti", "multiple": 1 ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
{[ "type": "select", "label": "'.tr('Utente').'", "name": "assigned_user", "ajax-source": "utenti", "required": 1 ]}
|
||||
<div class="col-md-6">
|
||||
{[ "type": "select", "label": "'.tr('Gruppo').'", "name": "group_id", "values": "query=SELECT id, nome AS text FROM zz_groups" ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -44,6 +50,22 @@ $(document).ready(function() {
|
|||
$("#check-add").click(function(event){
|
||||
addChecklist(this);
|
||||
});
|
||||
|
||||
$("#assigned_users").change(function(){
|
||||
if ($(this).selectData()) {
|
||||
$("#group_id").val("").attr("disabled", true).attr("required", false);
|
||||
} else {
|
||||
$("#group_id").val("").attr("disabled", false).attr("required", true);
|
||||
}
|
||||
});
|
||||
|
||||
$("#group_id").change(function(){
|
||||
if ($(this).selectData()) {
|
||||
$("#assigned_users").val("").attr("disabled", true).attr("required", false);
|
||||
} else {
|
||||
$("#assigned_users").val("").attr("disabled", false).attr("required", true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function addChecklist(btn) {
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
use Modules\Checklists\HTMLBuilder\ChecklistManager;
|
||||
|
||||
echo '
|
||||
<form action="" method="post" id="edit-form">
|
||||
<input type="hidden" name="op" value="update">
|
||||
|
@ -91,11 +89,11 @@ echo '
|
|||
</form>
|
||||
<hr>
|
||||
|
||||
<ul class="checklist">';
|
||||
<ul class="todo-list checklist">';
|
||||
|
||||
$checks = $record->mainChecks();
|
||||
foreach ($checks as $check) {
|
||||
echo ChecklistManager::renderChecklist($check);
|
||||
echo renderChecklist($check);
|
||||
}
|
||||
|
||||
echo '
|
||||
|
@ -106,6 +104,26 @@ echo '
|
|||
echo '
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$(".checklist").sortable({
|
||||
placeholder: "sort-highlight",
|
||||
handle: ".handle",
|
||||
forcePlaceholderSize: true,
|
||||
zIndex: 999999,
|
||||
update: function(event, ui) {
|
||||
var order = [];
|
||||
$(".checklist > li").each( function(){
|
||||
order.push($(this).data("id"));
|
||||
});
|
||||
|
||||
$.post(globals.rootdir + "/actions.php", {
|
||||
id_module: globals.id_module,
|
||||
id_record: globals.id_record,
|
||||
op: "update_position",
|
||||
order: order.join(","),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$(".check-delete").click(function(event){
|
||||
var li = $(this).closest("li");
|
||||
var id = li.attr("id").replace("check_", "");
|
||||
|
|
|
@ -32,18 +32,13 @@ class Checklist {
|
|||
data: data,
|
||||
success: function() {
|
||||
$this.reload();
|
||||
|
||||
renderMessages();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
deleteCheck(id, user_id) {
|
||||
var check = this.findCheck(id);
|
||||
if (check.user_id != user_id && check.assigned_user_id != user_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
check.icon.removeClass("fa-check-square-o").addClass("fa-refresh fa-spin bg-danger").show();
|
||||
|
||||
deleteCheck(id) {
|
||||
this.request({
|
||||
op: "delete_check",
|
||||
check_id: id,
|
||||
|
@ -52,14 +47,7 @@ class Checklist {
|
|||
return true;
|
||||
}
|
||||
|
||||
toggleCheck(id, user_id) {
|
||||
var check = this.findCheck(id);
|
||||
if (check.assigned_user_id != user_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
check.icon.removeClass("fa-square-o fa-check-square-o ").addClass("fa-refresh fa-spin").show();
|
||||
|
||||
toggleCheck(id) {
|
||||
this.request({
|
||||
op: "toggle_check",
|
||||
check_id: id,
|
||||
|
@ -73,12 +61,10 @@ class Checklist {
|
|||
|
||||
return {
|
||||
item: li,
|
||||
icon: li.find(".check-icon"),
|
||||
date: li.find(".check-date"),
|
||||
text: li.find(".check-text"),
|
||||
children: li.find(".check-children"),
|
||||
user_id: li.data('user_id'),
|
||||
assigned_user_id: li.data('assigned_user_id'),
|
||||
input: li.find("input"),
|
||||
info: li.find(".badge"),
|
||||
text: li.find(".text"),
|
||||
children: li.find("ul"),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
function renderChecklist($check, $level = 0)
|
||||
{
|
||||
$user = auth()->getUser();
|
||||
$enabled = $check->assignedUsers->pluck('id')->search($user->id) !== false;
|
||||
|
||||
$result = '
|
||||
<li id="check_'.$check->id.'" class="check-item'.(!empty($check->checked_at) ? ' done' : '').'" '.(!$enabled ? 'style="opacity: 0.4"' : '').' data-id="'.$check->id.'">
|
||||
<input type="checkbox" value="'.(!empty($check->checked_at) ? '1' : '0').'" '.(!empty($check->checked_at) ? 'checked' : '').'>
|
||||
|
||||
<span class="text">'.$check->content.'</span>
|
||||
<span class="badge">'.(!empty($check->checked_at) ? timestampFormat($check->checked_at).' - '.$check->user->username : '').'</span>';
|
||||
|
||||
if ($level == 0) {
|
||||
$result .= '
|
||||
<span class="handle pull-right">
|
||||
<i class="fa fa-ellipsis-v"></i>
|
||||
<i class="fa fa-ellipsis-v"></i>
|
||||
</span>';
|
||||
}
|
||||
|
||||
$result .= '
|
||||
<div class="tools">
|
||||
<i class="fa fa-trash-o check-delete"></i>
|
||||
</div>
|
||||
|
||||
<ul class="todo-list">';
|
||||
|
||||
$children = $check->children;
|
||||
foreach ($children as $child) {
|
||||
$result .= renderChecklist($child, $level + 1);
|
||||
}
|
||||
|
||||
$result .= '
|
||||
</ul>
|
||||
</li>';
|
||||
|
||||
return $result;
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
namespace Modules\Checklists;
|
||||
|
||||
use Common\Model;
|
||||
use Models\Group;
|
||||
use Models\Module;
|
||||
use Models\Plugin;
|
||||
use Models\User;
|
||||
|
@ -20,7 +21,6 @@ class Check extends Model
|
|||
* Crea un nuovo elemento della checklist.
|
||||
*
|
||||
* @param User $user
|
||||
* @param User $assigned_user
|
||||
* @param ChecklistTrait $structure
|
||||
* @param int $id_record
|
||||
* @param string $content
|
||||
|
@ -28,19 +28,13 @@ class Check extends Model
|
|||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function build(User $user, $structure, $id_record, $content, User $assigned_user = null, $parent_id = null)
|
||||
public static function build(User $user, $structure, $id_record, $content, $parent_id = null)
|
||||
{
|
||||
$model = parent::build();
|
||||
|
||||
$model->user()->associate($user);
|
||||
$model->id_parent = $parent_id;
|
||||
|
||||
if (empty($parent_id)) {
|
||||
$model->assignedUser()->associate($assigned_user);
|
||||
} else {
|
||||
$model->assignedUser()->associate($model->parent->assignedUser);
|
||||
}
|
||||
|
||||
if ($structure instanceof Module) {
|
||||
$model->module()->associate($structure);
|
||||
} elseif ($structure instanceof Plugin) {
|
||||
|
@ -50,6 +44,9 @@ class Check extends Model
|
|||
$model->id_record = $id_record;
|
||||
$model->content = $content;
|
||||
|
||||
// Ordinamento temporaneo alla creazione
|
||||
$model->order = 99;
|
||||
|
||||
$model->save();
|
||||
|
||||
return $model;
|
||||
|
@ -71,6 +68,28 @@ class Check extends Model
|
|||
}
|
||||
}
|
||||
|
||||
public function setAccess($users, $group_id)
|
||||
{
|
||||
if (!empty($this->id_parent)) {
|
||||
$users = $this->parent->assignedUsers->pluck('id')->toArray();
|
||||
$this->assignedUsers()->sync($users);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($users)) {
|
||||
if (!empty($group_id)) {
|
||||
$group = Group::find($group_id);
|
||||
|
||||
$users = $group->users->pluck('id')->toArray();
|
||||
} else {
|
||||
$users = User::all()->pluck('id')->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
$this->assignedUsers()->sync($users);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rimozione ricorsiva gestita da MySQL.
|
||||
public function delete()
|
||||
|
@ -91,12 +110,12 @@ class Check extends Model
|
|||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'id_utente');
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function assignedUser()
|
||||
public function assignedUsers()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'id_utente_assegnato');
|
||||
return $this->belongsToMany(User::class, 'zz_check_user', 'id_check', 'id_utente');
|
||||
}
|
||||
|
||||
public function plugin()
|
||||
|
|
|
@ -30,10 +30,10 @@ class Checklist extends Model
|
|||
|
||||
public function mainChecks()
|
||||
{
|
||||
return $this->checks()->whereNull('id_parent')->orderBy('created_at')->get();
|
||||
return $this->checks()->whereNull('id_parent')->orderBy('order')->get();
|
||||
}
|
||||
|
||||
public function copia(User $user, User $assigned_user, $id_record)
|
||||
public function copia(User $user, $id_record, $users, $group_id)
|
||||
{
|
||||
$structure = $this->plugin ?: $this->module;
|
||||
|
||||
|
@ -44,7 +44,9 @@ class Checklist extends Model
|
|||
$child = $checks->shift();
|
||||
$id_parent = $child->id_parent ? $relations[$child->id_parent] : null;
|
||||
|
||||
$check = Check::build($user, $structure, $id_record, $child->content, $assigned_user, $id_parent);
|
||||
$check = Check::build($user, $structure, $id_record, $child->content, $id_parent);
|
||||
$check->setAccess($users, $group_id);
|
||||
|
||||
$relations[$child->id] = $check->id;
|
||||
|
||||
$checks = $checks->merge($child->children);
|
||||
|
|
|
@ -29,6 +29,8 @@ class ChecklistItem extends Model
|
|||
$model->id_parent = $id_parent;
|
||||
$model->content = $contenuto;
|
||||
|
||||
$model->findOrder();
|
||||
|
||||
$model->save();
|
||||
|
||||
return $model;
|
||||
|
@ -40,4 +42,9 @@ class ChecklistItem extends Model
|
|||
{
|
||||
return $this->belongsTo(Checklist::class, 'id_checklist');
|
||||
}
|
||||
|
||||
protected function findOrder()
|
||||
{
|
||||
$this->order = orderValue($this->table, 'id_checklist', $this->id_checklist);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,181 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Checklists\HTMLBuilder;
|
||||
|
||||
use HTMLBuilder\Manager\ManagerInterface;
|
||||
use Models\User;
|
||||
use Modules;
|
||||
use Plugins;
|
||||
|
||||
/**
|
||||
* Gestione delle checklist.
|
||||
*
|
||||
* @since 2.4.11
|
||||
*/
|
||||
class ChecklistManager implements ManagerInterface
|
||||
{
|
||||
/**
|
||||
* Gestione "checklists".
|
||||
* Esempio: {( "name": "checklists", "id_module": "2", "id_record": "1", "readonly": "false" )}.
|
||||
*
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function manage($options)
|
||||
{
|
||||
$module = Modules::get('Checklists');
|
||||
$structure = Plugins::get($options['id_plugin']) ?: Modules::get($options['id_module']);
|
||||
|
||||
$utente = \Auth::user();
|
||||
|
||||
// ID del form
|
||||
$manager_id = 'checklist_'.$options['id_module'].'_'.$options['id_plugin'];
|
||||
|
||||
$result = '
|
||||
<div class="panel panel-primary" id="'.$manager_id.'" style="position:relative">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">'.tr('Checklist').'</h3>
|
||||
</div>
|
||||
<div class="panel-body" style="position:relative">
|
||||
<div id="loading_'.$manager_id.'" class="text-center hide component-loader">
|
||||
<div>
|
||||
<i class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
|
||||
<span class="sr-only">'.tr('Caricamento...').'</span>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
// Form per la creazione di una nuova checklist
|
||||
if (!$options['readonly']) {
|
||||
$result .= '
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<a class="btn btn-sm btn-primary" data-href="'.$module->fileurl('components/add-check.php').'?id_module='.$options['id_module'].'&id_record='.$options['id_record'].'&id_plugin='.$options['id_plugin'].'&manager_id='.$manager_id.'" data-toggle="tooltip" data-title="'.tr('Aggiungi check').'">
|
||||
<i class="fa fa-plus"></i> '.tr('Check').'
|
||||
</a>
|
||||
|
||||
<a class="btn btn-sm btn-primary" data-href="'.$module->fileurl('components/add-checklist.php').'?id_module='.$options['id_module'].'&id_record='.$options['id_record'].'&id_plugin='.$options['id_plugin'].'&manager_id='.$manager_id.'" data-toggle="tooltip" data-title="'.tr('Aggiungi check').'">
|
||||
<i class="fa fa-plus"></i> '.tr('Checklist').'
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<br>';
|
||||
}
|
||||
|
||||
$checks = $structure->mainChecks($options['id_record']);
|
||||
$users = $checks->groupBy('id_utente_assegnato');
|
||||
|
||||
$result .= '
|
||||
<div class="row">';
|
||||
foreach ($users as $user_id => $checks) {
|
||||
$user = User::find($user_id);
|
||||
|
||||
$result .= '
|
||||
<div class="col-md-6" '.($utente->id != $user_id ? 'style="opacity: 0.5"' : '').'>
|
||||
<div class="box box-info">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">'.$user->nome_completo.'</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
<ul class="checklist">';
|
||||
|
||||
foreach ($checks as $check) {
|
||||
$result .= self::renderChecklist($check);
|
||||
}
|
||||
|
||||
$result .= '
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
$result .= '
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
$result .= '
|
||||
<script>$(document).ready(init)</script>
|
||||
|
||||
<script type="module">
|
||||
import Checklist from "./modules/checklists/js/checklist.js";
|
||||
|
||||
var checklists = checklists ? checklists : {};
|
||||
$(document).ready(function() {
|
||||
checklists["'.$manager_id.'"] = new Checklist({
|
||||
id_module: "'.$options['id_module'].'",
|
||||
id_plugin: "'.$options['id_plugin'].'",
|
||||
id_record: "'.$options['id_record'].'",
|
||||
}, "'.$manager_id.'");
|
||||
|
||||
$(".check-item").click(function(event){
|
||||
var id = $(this).attr("id").replace("check_", "");
|
||||
|
||||
var result = checklists["'.$manager_id.'"].toggleCheck(id, '.$utente->id.');
|
||||
|
||||
if (!result){
|
||||
swal("'.tr('Errore').'", "'.tr('La tua utenza non corrisponde a quella assegnata al check').'", "error");
|
||||
}
|
||||
});
|
||||
|
||||
$(".check-delete").click(function(event){
|
||||
var li = $(this).closest("li");
|
||||
var id = li.attr("id").replace("check_", "");
|
||||
|
||||
var result = checklists["'.$manager_id.'"].deleteCheck(id, '.$utente->id.');
|
||||
|
||||
if (!result){
|
||||
swal("'.tr('Errore').'", "'.tr('La tua utenza non possiede i permessi di modificare questo check').'", "error");
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
});
|
||||
});
|
||||
|
||||
function deleteCheck(id) {
|
||||
swal({
|
||||
title: "'.tr("Rimuovere l'elemento della checklist?").'",
|
||||
html: "'.tr('Tutti gli elementi figli saranno rimossi di conseguenza. Continuare?').'",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "'.tr('Procedi').'",
|
||||
type: "error",
|
||||
}).then(function (result) {
|
||||
checklists["'.$manager_id.'"].toggleCheck(id);
|
||||
});
|
||||
}
|
||||
</script>';
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function renderChecklist($check, $level = 0)
|
||||
{
|
||||
$result = '
|
||||
<li id="check_'.$check->id.'" class="check-item'.(!empty($check->checked_at) ? ' checked' : '').'" data-user_id="'.$check->id_utente.'" data-assigned_user_id="'.$check->id_utente_assegnato.'">
|
||||
'.str_repeat(' ', $level * 8).'
|
||||
|
||||
<i class="check-icon fa '.(!empty($check->checked_at) ? 'fa-check-square-o' : 'fa-square-o').'"></i>
|
||||
<span class="check-text">'.$check->content.'</span>
|
||||
|
||||
<div class="pull-right">
|
||||
<span class="badge check-date">'.timestampFormat($check->checked_at).'</span>
|
||||
<i class="fa fa-close check-delete"></i>
|
||||
</div>
|
||||
</li>
|
||||
<ul class="checklist" class="check-children">';
|
||||
|
||||
$children = $check->children;
|
||||
foreach ($children as $child) {
|
||||
$result .= self::renderChecklist($child, $level + 1);
|
||||
}
|
||||
|
||||
$result .= '
|
||||
</ul>';
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -7,18 +7,23 @@ use Modules\Checklists\Checklist;
|
|||
|
||||
trait ChecklistTrait
|
||||
{
|
||||
public function checks($id_record)
|
||||
public function checks()
|
||||
{
|
||||
return $this->hasMany(Check::class, $this->component_identifier)->where('id_record', $id_record)->orderBy('created_at')->get();
|
||||
return $this->hasMany(Check::class, $this->component_identifier);
|
||||
}
|
||||
|
||||
public function recordChecks($id_record)
|
||||
{
|
||||
return $this->checks()->where('id_record', $id_record)->orderBy('order')->get();
|
||||
}
|
||||
|
||||
public function mainChecks($id_record)
|
||||
{
|
||||
return $this->hasMany(Check::class, $this->component_identifier)->where('id_record', $id_record)->whereNull('id_parent')->orderBy('id_utente_assegnato', 'created_at')->get();
|
||||
return $this->checks()->where('id_record', $id_record)->whereNull('id_parent')->orderBy('order')->get();
|
||||
}
|
||||
|
||||
public function checklists()
|
||||
{
|
||||
return $this->hasMany(Checklist::class, $this->component_identifier)->orderBy('created_at')->get();
|
||||
return $this->hasMany(Checklist::class, $this->component_identifier);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
include_once __DIR__.'/../../../core.php';
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Models\Module;
|
||||
|
||||
if (!empty($is_title_request)) {
|
||||
echo tr('Notifiche interne');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$notes = collect();
|
||||
|
||||
$moduli = Module::getAll()->where('permission', '<>', '-');
|
||||
foreach ($moduli as $modulo) {
|
||||
$note = $modulo->notes()->where('notification_date', '>=', date('Y-m-d'))->get();
|
||||
$notes = $notes->merge($note);
|
||||
}
|
||||
|
||||
if (!empty($is_number_request)) {
|
||||
echo $notes->count();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($notes)) {
|
||||
echo '
|
||||
<p>'.tr('Non ci sono note da notificare').'.</p>';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$moduli = $notes->groupBy('id_module')->sortBy('notification_date');
|
||||
foreach ($moduli as $module_id => $note) {
|
||||
$modulo = Module::get($module_id);
|
||||
|
||||
echo '
|
||||
<h4>'.$modulo->title.'</h4>
|
||||
<table class="table table-hover">
|
||||
<tr>
|
||||
<th width="5%" >'.tr('Record').'</th>
|
||||
<th>'.tr('Contenuto').'</th>
|
||||
<th width="20%" class="text-center">'.tr('Data di notifica').'</th>
|
||||
</tr>';
|
||||
|
||||
foreach ($note as $nota) {
|
||||
echo '
|
||||
<tr>
|
||||
<td>'.$nota->id_record.'</td>
|
||||
<td>
|
||||
<span class="pull-right">'.Modules::link($module_id, $nota->id_record, null, null, null, true, 'tab_note').'</span>
|
||||
|
||||
'.$nota->content.'
|
||||
|
||||
<small>'.$nota->user->nome_completo.'</small>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
'.$nota->notification_date.'
|
||||
('.Carbon::parse($nota->notification_date)->diffForHumans().')
|
||||
</td>
|
||||
</tr>';
|
||||
}
|
||||
|
||||
echo '
|
||||
</table>';
|
||||
}
|
|
@ -9,7 +9,7 @@ if (!empty($rs)) {
|
|||
<table class="table table-hover">
|
||||
<tr>
|
||||
<th width="50%">'.tr('Attività').'</th>
|
||||
<th width="15%">'.tr('Data richiesta').'</th>
|
||||
<th width="15%" class="text-center">'.tr('Data richiesta').'</th>
|
||||
</tr>';
|
||||
|
||||
foreach ($rs as $r) {
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
include_once __DIR__.'/../core.php';
|
||||
|
||||
$checklist_module = Modules::get('Checklists');
|
||||
$checks_id = 'checklist_'.$id_module.'_'.$id_plugin;
|
||||
|
||||
echo '
|
||||
<div class="box box-primary" id="'.$checks_id.'">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">'.tr('Checklist').'</h3>
|
||||
</div>
|
||||
<div class="box-body" style="position:relative">
|
||||
<div id="loading_'.$checks_id.'" class="text-center hide component-loader">
|
||||
<div>
|
||||
<i class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
|
||||
<span class="sr-only">'.tr('Caricamento...').'</span>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
// Form per la creazione di una nuova checklist
|
||||
if ($structure->permission == 'rw') {
|
||||
echo '
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<a class="btn btn-sm btn-primary" data-href="'.$checklist_module->fileurl('components/add-check.php').'?id_module='.$id_module.'&id_record='.$id_record.'&id_plugin='.$id_plugin.'&manager_id='.$checks_id.'" data-toggle="tooltip" data-title="'.tr('Aggiungi check').'">
|
||||
<i class="fa fa-plus"></i> '.tr('Check').'
|
||||
</a>
|
||||
|
||||
<a class="btn btn-sm btn-primary" data-href="'.$checklist_module->fileurl('components/add-checklist.php').'?id_module='.$id_module.'&id_record='.$id_record.'&id_plugin='.$id_plugin.'&manager_id='.$checks_id.'" data-toggle="tooltip" data-title="'.tr('Aggiungi check').'">
|
||||
<i class="fa fa-plus"></i> '.tr('Checklist').'
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<br>';
|
||||
}
|
||||
|
||||
$checks = $structure->mainChecks($id_record);
|
||||
|
||||
echo '
|
||||
<ul class="todo-list checklist">';
|
||||
|
||||
foreach ($checks as $check) {
|
||||
echo renderChecklist($check);
|
||||
}
|
||||
|
||||
echo '
|
||||
</ul>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
echo '
|
||||
<script>$(document).ready(init)</script>
|
||||
|
||||
<script type="module">
|
||||
import Checklist from "./modules/checklists/js/checklist.js";
|
||||
|
||||
var checklists = checklists ? checklists : {};
|
||||
$(document).ready(function() {
|
||||
checklists["'.$checks_id.'"] = new Checklist({
|
||||
id_module: "'.$id_module.'",
|
||||
id_plugin: "'.$id_plugin.'",
|
||||
id_record: "'.$id_record.'",
|
||||
}, "'.$checks_id.'");
|
||||
|
||||
$(".checklist").sortable({
|
||||
placeholder: "sort-highlight",
|
||||
handle: ".handle",
|
||||
forcePlaceholderSize: true,
|
||||
zIndex: 999999,
|
||||
update: function(event, ui) {
|
||||
var order = [];
|
||||
$(".checklist > li").each( function(){
|
||||
order.push($(this).data("id"));
|
||||
});
|
||||
|
||||
$.post(globals.rootdir + "/actions.php", {
|
||||
id_module: "'.$id_module.'",
|
||||
id_plugin: "'.$id_plugin.'",
|
||||
id_record: "'.$id_record.'",
|
||||
op: "sort_checks",
|
||||
order: order.join(","),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$(".checklist").todoList({
|
||||
onCheck : function () {
|
||||
var id = $(this).parent().data("id");
|
||||
|
||||
checklists["'.$checks_id.'"].toggleCheck(id);
|
||||
},
|
||||
onUnCheck: function () {
|
||||
var id = $(this).parent().data("id");
|
||||
|
||||
checklists["'.$checks_id.'"].toggleCheck(id);
|
||||
}
|
||||
});
|
||||
|
||||
$(".check-delete").click(function(event){
|
||||
var li = $(this).closest("li");
|
||||
var id = li.data("id");
|
||||
|
||||
swal({
|
||||
title: "'.tr("Rimuovere l'elemento della checklist?").'",
|
||||
html: "'.tr('Tutti gli elementi figli saranno rimossi di conseguenza. Continuare?').'",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "'.tr('Procedi').'",
|
||||
type: "error",
|
||||
}).then(function (result) {
|
||||
checklists["'.$checks_id.'"].deleteCheck(id);
|
||||
});
|
||||
|
||||
event.stopPropagation();
|
||||
});
|
||||
});
|
||||
</script>';
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
include_once __DIR__.'/../core.php';
|
||||
|
||||
if (!empty($notes)) {
|
||||
echo '
|
||||
<div class="box box-warning direct-chat direct-chat-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">'.tr('Note interne').'</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
<div class="direct-chat-messages" style="height: 50vh">';
|
||||
|
||||
foreach ($notes as $nota) {
|
||||
$utente = $nota->user;
|
||||
$photo = $utente->photo;
|
||||
|
||||
echo '
|
||||
<div class="direct-chat-msg '.($utente->id == $user->id ? 'right' : '').'" id="nota_'.$nota->id.'">
|
||||
<div class="direct-chat-info clearfix">
|
||||
<span class="direct-chat-name pull-left">'.$utente->nome_completo.'</span>
|
||||
<span class="direct-chat-timestamp pull-right">
|
||||
'.timestampFormat($nota->created_at).'
|
||||
</span>
|
||||
</div>';
|
||||
|
||||
if ($photo) {
|
||||
echo '
|
||||
<img class="direct-chat-img" src="'.$photo.'">';
|
||||
} else {
|
||||
echo '
|
||||
|
||||
<i class="fa fa-user-circle-o direct-chat-img fa-3x" alt="'.tr('OpenSTAManager').'"></i>';
|
||||
}
|
||||
|
||||
echo '
|
||||
<div class="direct-chat-text">
|
||||
<div class="pull-right">';
|
||||
|
||||
if (!empty($nota->notification_date)) {
|
||||
echo '
|
||||
<span class="label label-default tip" title="'.tr('Data di notifica').'" style="margin-right: 5px">
|
||||
<i class="fa fa-bell"></i> '.dateFormat($nota->notification_date).'
|
||||
</span>
|
||||
|
||||
<button type="button" class="btn btn-info btn-xs ask" data-op="notification_nota" data-id_nota="'.$nota->id.'" data-msg="'.tr('Rimuovere la data di notifica da questa nota?').'" data-backto="record-edit" data-button="'.tr('Rimuovi').'" data-class="btn btn-lg btn-warning">
|
||||
<i class="fa fa-eye"></i>
|
||||
</button>';
|
||||
}
|
||||
|
||||
if ($user->is_admin || $utente->id == $user->id) {
|
||||
echo '
|
||||
<button type="button" class="btn btn-danger btn-xs ask" data-op="delete_nota" data-id_nota="'.$nota->id.'" data-msg="'.tr('Rimuovere questa nota?').'" data-backto="record-edit">
|
||||
<i class="fa fa-trash-o"></i>
|
||||
</button>';
|
||||
}
|
||||
|
||||
echo '
|
||||
</div>
|
||||
'.$nota->content.'
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
echo '
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
} else {
|
||||
echo '
|
||||
<p>'.tr('Non sono presenti note interne').'</p>';
|
||||
}
|
||||
|
||||
if ($structure->permission == 'rw') {
|
||||
echo '
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="op" value="add_nota">
|
||||
<input type="hidden" name="backto" value="record-edit">
|
||||
|
||||
{[ "type": "date", "label": "'.tr('Data di notifica').'", "name": "data_notifica" ]}
|
||||
|
||||
{[ "type": "ckeditor", "label": "'.tr('Nuova nota').'", "name": "contenuto", "required": 1]}
|
||||
|
||||
<!-- PULSANTI -->
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-right">
|
||||
<button type="sumbit" class="btn btn-primary">
|
||||
<i class="fa fa-plus"></i> '.tr('Aggiungi').'
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>';
|
||||
}
|
|
@ -75,7 +75,6 @@ class HTMLBuilder
|
|||
protected static $managers = [
|
||||
'list' => [
|
||||
'filelist_and_upload' => Manager\FileManager::class,
|
||||
'checklists' => \Modules\Checklists\HTMLBuilder\ChecklistManager::class,
|
||||
'button' => Manager\ButtonManager::class,
|
||||
'csrf' => Manager\CSRFManager::class,
|
||||
'custom_fields' => Manager\FieldManager::class,
|
||||
|
|
|
@ -91,11 +91,42 @@ class WidgetManager implements ManagerInterface
|
|||
}
|
||||
}
|
||||
|
||||
// Generazione del codice HTML
|
||||
return $this->render($widget, $widget['text'], $value);
|
||||
}
|
||||
|
||||
protected function chart($widget, $number = null)
|
||||
{
|
||||
$content = null;
|
||||
if (!empty($widget['php_include'])) {
|
||||
$is_title_request = true;
|
||||
|
||||
ob_start();
|
||||
include DOCROOT.'/'.$widget['php_include'];
|
||||
$content = ob_get_clean();
|
||||
}
|
||||
|
||||
return $this->render($widget, $content, $number);
|
||||
}
|
||||
|
||||
protected function custom($widget)
|
||||
{
|
||||
$content = null;
|
||||
if (!empty($widget['php_include'])) {
|
||||
$is_number_request = true;
|
||||
ob_start();
|
||||
include DOCROOT.'/'.$widget['php_include'];
|
||||
$content = ob_get_clean();
|
||||
}
|
||||
|
||||
return $this->chart($widget, $content);
|
||||
}
|
||||
|
||||
protected function render($widget, $title, $number = null)
|
||||
{
|
||||
$result = '
|
||||
<button type="button" class="close" onclick="if(confirm(\'Disabilitare questo widget?\')) { $.post( \''.ROOTDIR.'/actions.php?id_module='.self::getModule()->id.'\', { op: \'disable_widget\', id: \''.$widget['id'].'\' }, function(response){ location.reload(); }); };" >
|
||||
<span aria-hidden="true">×</span><span class="sr-only">'.tr('Chiudi').'</span>
|
||||
</button>';
|
||||
<button type="button" class="close" onclick="if(confirm(\'Disabilitare questo widget?\')) { $.post( \''.ROOTDIR.'/actions.php?id_module='.self::getModule()->id.'\', { op: \'disable_widget\', id: \''.$widget['id'].'\' }, function(response){ location.reload(); }); };" >
|
||||
<span aria-hidden="true">×</span><span class="sr-only">'.tr('Chiudi').'</span>
|
||||
</button>';
|
||||
|
||||
if (!empty($widget['more_link'])) {
|
||||
$result .= '
|
||||
|
@ -124,21 +155,36 @@ class WidgetManager implements ManagerInterface
|
|||
}
|
||||
|
||||
$result .= '
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon" style="background-color:'.$widget['bgcolor'].'">
|
||||
<i class="'.$widget['icon'].'"></i>
|
||||
</span>
|
||||
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text'.(!empty($widget['help']) ? ' tip' : '').'"'.(!empty($widget['help']) ? ' title="'.prepareToField($widget['help']).'" data-position="bottom"' : '').'>
|
||||
'.$widget['text'].'
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon" style="background-color:'.$widget['bgcolor'].'">';
|
||||
|
||||
'.(!empty($widget['help']) ? '<i class="fa fa-question-circle-o"></i>' : '').'
|
||||
</span>
|
||||
<span class="info-box-number">'.$value.'</span>
|
||||
</div>
|
||||
if (!empty($widget['icon'])) {
|
||||
$result .= '
|
||||
<i class="'.$widget['icon'].'"></i>';
|
||||
}
|
||||
|
||||
$result .= '
|
||||
</span>
|
||||
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text'.(!empty($widget['help']) ? ' tip' : '').'"'.(!empty($widget['help']) ? ' title="'.prepareToField($widget['help']).'" data-position="bottom"' : '').'>
|
||||
'.$title.'
|
||||
|
||||
'.(!empty($widget['help']) ? '<i class="fa fa-question-circle-o"></i>' : '').'
|
||||
</span>';
|
||||
|
||||
if (isset($number)) {
|
||||
$result .= '
|
||||
<span class="info-box-number">'.$number.'</span>';
|
||||
}
|
||||
|
||||
$result .= '
|
||||
</div>';
|
||||
|
||||
$result .= '
|
||||
</div>';
|
||||
|
||||
if (!empty($widget['more_link'])) {
|
||||
$result .= '
|
||||
</a>';
|
||||
|
@ -150,57 +196,6 @@ class WidgetManager implements ManagerInterface
|
|||
return $result;
|
||||
}
|
||||
|
||||
protected function chart($widget)
|
||||
{
|
||||
return $this->custom($widget);
|
||||
}
|
||||
|
||||
protected function custom($widget)
|
||||
{
|
||||
$result = '
|
||||
<button type="button" class="close" onclick="if(confirm(\'Disabilitare questo widget?\')) { $.post( \''.ROOTDIR.'/actions.php?id_module='.self::getModule()->id.'\', { op: \'disable_widget\', id: \''.$widget['id'].'\' }, function(response){ location.reload(); }); };" >
|
||||
<span aria-hidden="true">×</span><span class="sr-only">'.tr('Chiudi').'</span>
|
||||
</button>';
|
||||
|
||||
$result .= '
|
||||
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon" style="background-color:'.$widget['bgcolor'].'">';
|
||||
|
||||
if (!empty($widget['icon'])) {
|
||||
$result .= '
|
||||
<i class="'.$widget['icon'].'"></i>';
|
||||
}
|
||||
|
||||
$result .= '
|
||||
</span>
|
||||
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">';
|
||||
|
||||
if (!empty($widget['php_include'])) {
|
||||
$result_ob = '';
|
||||
|
||||
ob_start();
|
||||
|
||||
include DOCROOT.'/'.$widget['php_include'];
|
||||
$result_ob = ob_get_contents();
|
||||
|
||||
ob_end_clean();
|
||||
|
||||
$result .= $result_ob;
|
||||
}
|
||||
|
||||
$result .= '
|
||||
</span>
|
||||
</div>';
|
||||
|
||||
$result .= '
|
||||
</div>';
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function group($options)
|
||||
{
|
||||
$query = 'SELECT id FROM zz_widgets WHERE id_module = '.prepare($options['id_module']).' AND (|position|) AND enabled = 1 ORDER BY `order` ASC';
|
||||
|
|
|
@ -6,8 +6,13 @@ use Models\Note;
|
|||
|
||||
trait NoteTrait
|
||||
{
|
||||
public function notes($id_record)
|
||||
public function notes()
|
||||
{
|
||||
return $this->hasMany(Note::class, $this->component_identifier)->where('id_record', $id_record)->orderBy('created_at')->get();
|
||||
return $this->hasMany(Note::class, $this->component_identifier);
|
||||
}
|
||||
|
||||
public function recordNotes($id_record)
|
||||
{
|
||||
return $this->notes()->where('id_record', $id_record)->orderBy('created_at')->get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,9 @@ trait StoreTrait
|
|||
->orWhere(self::$name, $identifier)
|
||||
->first();
|
||||
|
||||
self::$collection->push($result);
|
||||
if (!empty($result)) {
|
||||
self::$collection->push($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
|
|
@ -80,7 +80,6 @@ class Autofill
|
|||
$result = '';
|
||||
|
||||
$number = $this->getAdditionalNumber();
|
||||
//dd($this->space, $number);exit();
|
||||
|
||||
for ($i = 0; $i < $number; ++$i) {
|
||||
$result .= '
|
||||
|
|
|
@ -28,7 +28,7 @@ INSERT INTO `zz_hooks` (`id`, `name`, `class`, `frequency`, `id_module`) VALUES
|
|||
(NULL, 'Ricevute', 'Modules\\Aggiornamenti\\UpdateHook', '7 day', (SELECT `id` FROM `zz_modules` WHERE `name` = 'Aggiornamenti'));
|
||||
|
||||
--
|
||||
-- Aggiunta nuovi campi per tracciamento sedi
|
||||
-- Aggiunta nuovi campi per tracciamento sedi
|
||||
--
|
||||
ALTER TABLE `mg_movimenti` ADD `idsede_azienda` INT NOT NULL AFTER `idautomezzo`, ADD `idsede_controparte` INT NOT NULL AFTER `idsede_azienda`;
|
||||
|
||||
|
@ -106,7 +106,7 @@ UPDATE `zz_views` SET `query` = 'CONCAT_WS(co_movimenti_modelli.nome, co_movimen
|
|||
|
||||
UPDATE `co_movimenti_modelli` SET `nome` = `descrizione` WHERE `nome` = '';
|
||||
|
||||
-- Rimuovo le interruzioni di riga per descrizioni vuote
|
||||
-- Rimuovo le interruzioni di riga per descrizioni vuote
|
||||
-- UPDATE `in_interventi` SET `descrizione` = REPLACE(`descrizione`, '\n', '') where `descrizione` LIKE '%\n';
|
||||
|
||||
-- Aggiunto tabella co_tipi_scadenze
|
||||
|
@ -181,6 +181,7 @@ UPDATE `in_interventi_tecnici` INNER JOIN `in_tipiintervento` ON `in_interventi_
|
|||
ALTER TABLE `in_interventi_tecnici` CHANGE `idtipointervento` `idtipointervento` INT(11) NOT NULL, ADD FOREIGN KEY (`idtipointervento`) REFERENCES `in_tipiintervento`(`idtipointervento`);
|
||||
|
||||
UPDATE `in_tariffe` INNER JOIN `in_tipiintervento` ON `in_tariffe`.`idtipointervento` = `in_tipiintervento`.`codice` SET `in_tariffe`.`idtipointervento` = `in_tipiintervento`.`idtipointervento`;
|
||||
DELETE FROM `in_tariffe` WHERE `idtipointervento` NOT IN (SELECT `idtipointervento` FROM `in_tipiintervento`);
|
||||
ALTER TABLE `in_tariffe` CHANGE `idtipointervento` `idtipointervento` INT(11) NOT NULL, ADD FOREIGN KEY (`idtipointervento`) REFERENCES `in_tipiintervento`(`idtipointervento`);
|
||||
|
||||
-- Ottimizzazione query Fatture
|
||||
|
|
|
@ -212,19 +212,27 @@ CREATE TABLE IF NOT EXISTS `zz_checks` (
|
|||
`id_module` int(11),
|
||||
`id_plugin` int(11),
|
||||
`id_record` int(11) NOT NULL,
|
||||
`id_utente` int(11) NOT NULL,
|
||||
`id_utente_assegnato` int(11) NOT NULL,
|
||||
`created_by` int(11) NOT NULL,
|
||||
`checked_at` TIMESTAMP NULL,
|
||||
`content` TEXT,
|
||||
`id_parent` int(11),
|
||||
`order` int(11),
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`id_module`) REFERENCES `zz_modules`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`id_plugin`) REFERENCES `zz_plugins`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`id_utente`) REFERENCES `zz_users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`id_utente_assegnato`) REFERENCES `zz_users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`created_by`) REFERENCES `zz_users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`id_parent`) REFERENCES `zz_checks`(`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `zz_check_user` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`id_utente` int(11) NOT NULL,
|
||||
`id_check` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`id_utente`) REFERENCES `zz_users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`id_check`) REFERENCES `zz_checks`(`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `zz_checklists` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255),
|
||||
|
@ -240,11 +248,18 @@ CREATE TABLE IF NOT EXISTS `zz_checklist_items` (
|
|||
`id_checklist` int(11),
|
||||
`content` TEXT,
|
||||
`id_parent` int(11),
|
||||
`order` int(11),
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`id_checklist`) REFERENCES `zz_checklists`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`id_parent`) REFERENCES `zz_checklist_items`(`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
-- Gestione di note e checklists
|
||||
ALTER TABLE `zz_modules` ADD `use_notes` BOOLEAN DEFAULT FALSE, ADD `use_checklists` BOOLEAN DEFAULT FALSE;
|
||||
UPDATE `zz_modules` SET `use_notes` = 1 WHERE `name` IN ('Anagrafiche', 'Interventi', 'Preventivi', 'Contratti', 'Fatture di vendita', 'Fatture di acquisto', 'Scadenzario', 'Ordini cliente', 'Ordini fornitore', 'Articoli', 'Ddt di vendita', 'Ddt di acquisto', 'MyImpianti');
|
||||
UPDATE `zz_modules` SET `use_checklists` = 1 WHERE `name` IN ('Interventi', 'MyImpianti');
|
||||
|
||||
-- Modulo per i template delle Checklist
|
||||
INSERT INTO `zz_modules` (`id`, `name`, `title`, `directory`, `options`, `options2`, `icon`, `version`, `compatibility`, `order`, `parent`, `default`, `enabled`) VALUES (NULL, 'Checklists', 'Checklists', 'checklists', 'SELECT |select| FROM `zz_checklists` WHERE 1=1 HAVING 2=2', '', 'fa fa-check-square-o', '2.4.11', '2.4.11', '1', (SELECT `id` FROM `zz_modules` t WHERE t.`name` = 'Strumenti'), '1', '1');
|
||||
|
||||
INSERT INTO `zz_views` (`id_module`, `name`, `query`, `order`, `search`, `slow`, `default`, `visible`) VALUES
|
||||
|
@ -264,3 +279,6 @@ UPDATE `zz_prints` SET `options` = '{"pricing": true, "last-page-footer": true}'
|
|||
UPDATE `zz_prints` SET `options` = '{"pricing": false, "last-page-footer": true}' WHERE `zz_prints`.`name` = 'Preventivo (senza costi)';
|
||||
UPDATE `zz_prints` SET `options` = '{"pricing": true, "last-page-footer": true}' WHERE `zz_prints`.`name` = 'Contratto';
|
||||
UPDATE `zz_prints` SET `options` = '{"pricing": false, "last-page-footer": true}' WHERE `zz_prints`.`name` = 'Contratto (senza costi)';
|
||||
|
||||
-- Widget per le notifiche delle note interne
|
||||
INSERT INTO `zz_widgets` (`id`, `name`, `type`, `id_module`, `location`, `class`, `query`, `bgcolor`, `icon`, `print_link`, `more_link`, `more_link_type`, `php_include`, `text`, `enabled`, `order`) VALUES (NULL, 'Note interne', 'custom', (SELECT `id` FROM `zz_modules` WHERE `name` = 'Dashboard'), 'controller_top', 'col-md-12', NULL, '#4ccc4c', 'fa fa-file-text-o ', '', './modules/dashboard/widgets/notifiche.php', 'popup', './modules/dashboard/widgets/notifiche.php', 'Notifiche interne', '1', '1');
|
||||
|
|
|
@ -81,6 +81,10 @@ return [
|
|||
'or_tipiordine',
|
||||
'zz_api_resources',
|
||||
'zz_currencies',
|
||||
'zz_checks',
|
||||
'zz_check_user',
|
||||
'zz_checklists',
|
||||
'zz_checklist_items',
|
||||
'zz_documenti',
|
||||
'zz_documenti_categorie',
|
||||
'zz_email_print',
|
||||
|
@ -96,6 +100,7 @@ return [
|
|||
'zz_logs',
|
||||
'zz_modules',
|
||||
'zz_operations',
|
||||
'zz_notes',
|
||||
'zz_permissions',
|
||||
'zz_plugins',
|
||||
'zz_prints',
|
||||
|
|
Loading…
Reference in New Issue