return $this->render('create', compact('model', 'entities', 'taskEntity', 'tasksType', 'taskStatus', 'taskAlertLevels'));
}
+
+ public function actionCreateAjax()
+ {
+ $model = new Task();
+
+ // Если это AJAX-запрос на загрузку формы
+ if (Yii::$app->request->isAjax && !Yii::$app->request->isPost) {
+ $taskEntity = TaskEntity::find()->all();
+ $tasksType = TasksType::find()->all();
+ $taskStatus = TaskStatus::find()->all();
+ $taskAlertLevels = TaskAlertLevel::find()->all();
+ $entities = []; // TaskService::getEntitiesByAlias(EntityType::findOne($model->entity_type)->alias);
+ $canUpdateAll = true;
+ $canUpdateStatusAndDuration = true;
+ // Возвращаем HTML формы для рендеринга в модальном окне
+ return $this->renderAjax('_form', compact('model', 'entities', 'taskEntity', 'tasksType', 'taskStatus', 'taskAlertLevels', 'canUpdateAll', 'canUpdateStatusAndDuration'));
+ }
+
+ // Если это POST-запрос для сохранения данных
+ if ($this->request->isPost) {
+ if ($model->load($this->request->post()) && $model->save()) {
+ // Обработка taskUsers
+ $taskUsers = Yii::$app->request->post('taskUsers');
+ TaskUsers::deleteAll(['task_id' => $model->id]);
+ if ($taskUsers) {
+ foreach ($taskUsers as $taskUser) {
+ $taskUserRecord = new TaskUsers();
+ $taskUserRecord->admin_id = $taskUser;
+ $taskUserRecord->task_id = $model->id;
+ $taskUserRecord->save(false);
+ }
+ }
+
+ // Обработка taskViewers
+ $taskViewers = Yii::$app->request->post('taskViewers');
+ TaskViewers::deleteAll(['task_id' => $model->id]);
+ if ($taskViewers) {
+ foreach ($taskViewers as $taskViewer) {
+ $taskViewerRecord = new TaskViewers();
+ $taskViewerRecord->admin_id = $taskViewer;
+ $taskViewerRecord->task_id = $model->id;
+ $taskViewerRecord->save(false);
+ }
+ }
+
+ // Обновляем и сохраняем остальные данные
+ $model->created_at = date("Y-m-d H:i:s");
+ $model->group_id = 1;
+ $model->is_completed = 0;
+ $model->result = '';
+ $model->created_by = Yii::$app->user->id; // Используем текущего пользователя
+
+ // Сохранение файлов
+ $model->files = UploadedFile::getInstances($model, 'files');
+ if ($model->files) {
+ foreach ($model->files as $file) {
+ FileService::saveUploadedFile($file, "task", $model->id);
+ }
+ }
+
+ // Уведомляем о смене статуса задачи
+ TaskService::informStatusChange($model->id);
+
+ // Если это AJAX-запрос, возвращаем успешный результат
+ if (Yii::$app->request->isAjax) {
+ return $this->asJson(['success' => true]);
+ }
+
+ // В случае не AJAX-запроса, редиректим на страницу задачи
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ // Если форма содержит ошибки валидации, возвращаем их
+ if (Yii::$app->request->isAjax) {
+ return $this->renderAjax('_form', compact('model'));
+ }
+ }
+
+ // Если запрос не AJAX и не POST, просто отрендерим страницу создания
+ return $this->render('create', compact('model'));
+ }
+
/**
* Updates an existing Task model.
* If update is successful, the browser will be redirected to the 'view' page.
$reply_markup_updated_by = self::getReplyMarkupUpdatedBy($task->id);
$reply_markup_info = self::getReplyMarkupInfo();
if ($updatedByAfter != $updatedByBefore) {
+ try {
TelegramService::sendMessage($updatedByBefore, $msg, $reply_markup_info);
+ } catch (\Exception $e) {
+
+ error_log("Error sending message to created_by: " . $e->getMessage());
+ }
}
if (in_array($task->status, [-1, 1, 2, 3, 4, 6])) {
+ try {
TelegramService::sendMessage($updatedByAfter, $msg, $reply_markup_updated_by);
+ } catch (\Exception $e) {
+
+ error_log("Error sending message to created_by: " . $e->getMessage());
+ }
} else {
+ try {
TelegramService::sendMessage($updatedByAfter, $msg, $reply_markup_info);
+ } catch (\Exception $e) {
+
+ error_log("Error sending message to created_by: " . $e->getMessage());
+}
}
}
$reply_markup_controller = self::getReplyMarkupController($task->id);
$reply_markup_info = self::getReplyMarkupInfo();
if ($controllerAfter != $controllerBefore) {
+ try {
TelegramService::sendMessage($controllerBefore, $msg, $reply_markup_info);
+ } catch (\Exception $e) {
+
+ error_log("Error sending message to created_by: " . $e->getMessage());
+ }
}
if ($task->status == 5) {
+ try {
TelegramService::sendMessage($controllerAfter, $msg, $reply_markup_controller);
+ } catch (\Exception $e) {
+
+ error_log("Error sending message to created_by: " . $e->getMessage());
+}
} else {
+ try {
TelegramService::sendMessage($controllerAfter, $msg, $reply_markup_info);
+ } catch (\Exception $e) {
+
+ error_log("Error sending message to created_by: " . $e->getMessage());
+}
}
}
}
\ No newline at end of file
/* @var $this yii\web\View */
/* @var $dataProvider yii\data\ActiveDataProvider */
-$this->title = 'Ð\97адаÑ\87и';
+$this->title = 'СпиÑ\81ок задаÑ\87';
$this->params['breadcrumbs'][] = $this->title;
?>
-<div class="task-index">
+<div class="task-index p-4">
+
+ <div class="row">
+ <p>
+ <a href="<?= Url::to(['/task/four-columns']) ?>" class="btn btn-link">Доска задач</a>
+ </p>
+ </div>
<h1><?= Html::encode($this->title) ?></h1>
- <p>
- <?= Html::a('Создать задачу', ['create'], ['class' => 'btn btn-success']) ?>
- </p>
+ <div class="row">
+ <p>
+ <?= Html::a('Создать задачу', ['create'], ['class' => 'btn btn-success']) ?>
+ </p>
+ </div>
+
<?= GridView::widget([
return Html::a($model->name, ['/crud/task/view', 'id' => $model->id], ['class' => 'btn btn-link']);
}
],
- 'description:ntext',
+ [
+ 'attribute' => 'description',
+ 'format' => 'raw',
+ 'value' => function ($model) {
+ $fullText = Html::encode($model->description); // Полный текст
+ $shortText = mb_substr($model->description, 0, 50); // Обрезаем до 50 символов
+
+ // Если текст длиннее 50 символов, добавляем кнопку для показа полного текста
+ if (mb_strlen($model->description) > 50) {
+ return '
+ <div>
+ <span class="short-text">' . Html::encode($shortText) . '...</span>
+ <span class="full-text" style="display:none;">' . $fullText . '</span>
+ <a href="javascript:void(0);" class="toggle-text btn btn-link" data-id="' . $model->id . '">Больше</a>
+ </div>';
+ } else {
+ return Html::encode($shortText); // Если текст короткий, возвращаем как есть
+ }
+ },
+ ],
'group_id',
//'entity_id',
[
}
],
],
- ]); ?>
+ ]);
+ $this->registerJs("
+ $(document).on('click', '.toggle-text', function() {
+ var link = $(this);
+ var shortText = link.siblings('.short-text');
+ var fullText = link.siblings('.full-text');
+
+ if (fullText.is(':visible')) {
+ fullText.hide();
+ shortText.show();
+ link.text('Больше');
+ } else {
+ fullText.show();
+ shortText.hide();
+ link.text('Меньше');
+ }
+ });
+");
+ ?>
</div>
use yii\helpers\Url;
use yii\widgets\DetailView;
use yii\widgets\ActiveForm;
-
+use yii\helpers\HtmlPurifier;
use yii_app\helpers\PrintBlockHelper;
use yii_app\services\FileService;
-
-use \yii_app\services\DateTimeService;
+use yii_app\services\DateTimeService;
/* @var $this yii\web\View */
/* @var $model yii_app\records\Task */
?>
-<div class="m-5">
-
-<div class="row">
- <div class="col-2">
- <a href="<?= \yii\helpers\Url::to(['/crud/task']) ?>" class="btn btn-link">Назад</a>
- </div>
-</div>
+<div class="container-fluid p-4">
+ <div class="row">
+ <!-- Левая панель: основная часть задачи -->
+ <div class="col-md-8">
+
+ <!-- Кнопки Назад, Редактировать, Удалить -->
+ <div class="d-flex justify-content-start mb-3">
+ <a href="<?= Url::to(['/crud/task']) ?>" class="btn btn-link">К списку</a>
+ <a href="<?= Url::to(['/task/four-columns']) ?>" class="btn btn-link">Доска задач</a>
+ <?= Html::a('Редактировать', ['update', 'id' => $model->id], ['class' => 'btn btn-primary ml-2']) ?>
+ <?= Html::a('Удалить', ['delete', 'id' => $model->id], [
+ 'class' => 'btn btn-danger ml-2',
+ 'data' => [
+ 'confirm' => 'Вы уверены, что хотите удалить эту запись?',
+ 'method' => 'post',
+ ],
+ ]) ?>
+ </div>
-<div class="task-view">
-
- <h1><?= Html::encode($this->title) ?></h1>
-
- <p>
- <?= Html::a('Редактировать', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
- <?= Html::a('Удалить', ['delete', 'id' => $model->id], [
- 'class' => 'btn btn-danger',
- 'data' => [
- 'confirm' => 'Вы уверены, что хотите удалить эту запись?',
- 'method' => 'post',
- ],
- ]) ?>
- </p>
-
- <?= DetailView::widget([
- 'model' => $model,
- 'attributes' => [
- 'id',
- 'name',
- 'description:ntext',
- 'group_id',
- [
- 'label' => 'Тип сущности',
- 'value' => $model->taskEntity->name ?? $model->entity_type,
- ],
- [
- 'label' => 'Сущность',
- 'value' => $model->taskEntity->alias == 'lesson' ? $model->lesson->name : ($model->taskEntity->alias == 'store' ? $model->store->name : $model->entity_id),
- ],
- [
- 'label' => 'Тип задачи',
- 'value' => $model->taskType->name ?? $model->task_type_id,
- ],
- [
- 'label' => 'Статус',
- 'value' => $model->statusEntity->name ?? $model->status,
- ],
- 'prioritet',
- //'duration',
- [
- 'label' => 'Duration',
- 'value' => $model->durationField,
- 'contentOptions' => ['class' => 'bg-red'],
- 'captionOptions' => ['tooltip' => 'Tooltip'],
- ],
- 'is_completed',
- 'data_start',
- 'data_end',
- 'result:ntext',
- 'deadline',
- [
- 'label' => 'Исполнитель',
- 'value' => $model->updatedBy->name ?? "---",
- ],
- [
- 'label' => 'Контроллёр',
- 'value' => $model->controller->name ?? "---",
- ],
- [
- 'label' => 'Уровень важности',
- 'value' => $model->alertLevel->name ?? "---",
- ],
- [
- 'label' => 'Создатель',
- 'value' => $model->createdBy->name ?? "---",
- ],
- [
- 'label' => 'Время создания',
- 'value' => DateTimeService::formatHuman($model->created_at),
- ],
- [
- 'label' => 'Время обновления',
- 'value' => $model->updated_at ? DateTimeService::formatHuman($model->updated_at) : '---',
- ],
- [
- 'label' => 'Время закрытия',
- 'value' => $model->closed_at ? DateTimeService::formatHuman($model->closed_at) : '---',
- ],
- [
- 'label' => 'Кем закрыта',
- 'value' => $model->closedBy->name ?? '---',
- ],
- ],
- ]) ?>
-
- <?php if ($model->attachedFiles): ?>
- <div class="row">
- <?php foreach($model->attachedFiles as $file): ?>
- <div class="col-2">
- <?php if ($file->file_type == 'image'): ?>
- <img width=100 src="<?= FileService::padWithSlash($file->url) ?>" alt="img" onclick="window.open(this.src, '_blank');" />
- <?php else: ?>
- <a href="<?= Url::to(['/files/download', 'url' => $file->url]) ?>" class="btn btn-link" target="_blank" data-pjax="0"><?= basename($file->url)?></a>
- <?php endif; ?>
- </div>
- <?php endforeach; ?>
- </div>
- <?php endif; ?>
+ <!-- Даты создания и обновления -->
+ <div class="mb-3">
+ <span><strong>Создано:</strong> <?= DateTimeService::formatHuman($model->created_at) ?></span>,
+ <span><strong>Обновлено:</strong> <?= $model->updated_at ? DateTimeService::formatHuman($model->updated_at) : '---' ?></span>
+ </div>
- <?php if ($comment): ?>
- <?php $commentForm = ActiveForm::begin(['id' => 'comment-form', 'options' => ['enctype' => 'multipart/form-data']]) ?>
- <?php PrintBlockHelper::printBlock('Комментарий', $commentForm->field($comment, 'msg')->textInput()->label(false)) ?>
+ <!-- Заголовок задачи -->
+ <h1><?= Html::encode($this->title) ?></h1>
- <?php PrintBlockHelper::printBlock('Медиа файлы',
- '<div class="mediaFiles"><button onclick="addMediaFile(); return false;" class="btn btn-success btn-sm">Добавить медиа файлы к комментарию</button></div>'); ?>
+ <!-- Описание задачи -->
+ <p><?= HtmlPurifier::process(nl2br($model->description)) ?></p>
- <div class="form-group">
- <?= Html::submitButton('Сохранить комментарий', ['class' => 'btn btn-success btn']) ?>
- </div>
- <?php ActiveForm::end() ?>
- <?php endif; ?>
- <?php if (isset($model->comments)): ?>
- <?php foreach ($model->comments as $cmnt): ?>
- <div class="row">
- <div class="col-3 text-right">
- <?= $cmnt->createdBy->name ?> (<?= \yii_app\services\DateTimeService::formatHuman($cmnt->created_at) ?>):
+ <!-- Форма добавления комментария -->
+ <h3>Добавить комментарий</h3>
+ <?php if ($comment): ?>
+ <?php $commentForm = ActiveForm::begin(['id' => 'comment-form', 'options' => ['enctype' => 'multipart/form-data']]) ?>
+ <div class="mb-3">
+ <?= $commentForm->field($comment, 'msg')->textarea(['rows' => 5])->label(false) ?>
</div>
- <div class="col-9">
- <?= $cmnt->msg ?>
- <?php if (isset($cmnt->attachedFiles)): ?>
- <?php foreach ($cmnt->attachedFiles as $file): ?>
- <?php if ($file->file_type == 'image'): ?>
- <?= Html::a(basename($file->url), [$file->url], ['class' => 'btn btn-link', 'target' => '_blank']) ?>
- <?php else: ?>
- <?= Html::a(basename($file->url), ['/files/download', 'url' => $file->url], ['class' => 'btn btn-link']) ?>
- <?php endif; ?>
- <?php endforeach; ?>
- <?php endif; ?>
+
+ <!-- Медиа файлы -->
+ <div class="mb-3">
+ <?= $commentForm->field($comment, 'files[]')->fileInput(['multiple' => true])->label('Прикрепить медиафайлы') ?>
</div>
- </div>
- <?php endforeach; ?>
- <?php endif; ?>
+ <div class="mb-3">
+ <?= Html::submitButton('Сохранить комментарий', ['class' => 'btn btn-success']) ?>
+ </div>
+ <?php ActiveForm::end() ?>
+ <?php endif; ?>
+
+
+
+ <!-- Комментарии -->
+ <h3>Комментарии</h3>
+ <?php if (isset($model->comments)): ?>
+ <?php foreach ($model->comments as $cmnt): ?>
+ <div class="row mb-2">
+ <div class="col-3 text-right">
+ <?= Html::encode($cmnt->createdBy->name) ?> (<?= DateTimeService::formatHuman($cmnt->created_at) ?>):
+ </div>
+ <div class="col-9">
+ <?= HtmlPurifier::process(nl2br($cmnt->msg)) ?>
+ <?php if (isset($cmnt->attachedFiles)): ?>
+ <?php foreach ($cmnt->attachedFiles as $file): ?>
+ <?php if ($file->file_type == 'image'): ?>
+ <img src="<?= FileService::padWithSlash($file->url) ?>" alt="image" style="max-width: 100px;">
+ <?php else: ?>
+ <?= Html::a(basename($file->url), ['/files/download', 'url' => $file->url], ['class' => 'btn btn-link']) ?>
+ <?php endif; ?>
+ <?php endforeach; ?>
+ <?php endif; ?>
+ </div>
+ </div>
+ <?php endforeach; ?>
+ <?php endif; ?>
+ </div>
+ <!-- Правая панель: дополнительная информация -->
+ <div class="col-md-4" style="border-left: 1px solid #ccc;">
+ <h3>Дополнительная информация</h3>
+ <table class="table table-striped table-bordered">
+ <tbody>
+ <tr>
+ <td><strong>Тип задачи:</strong></td>
+ <td><?= Html::encode($model->taskType->name ?? $model->task_type_id) ?></td>
+ </tr>
+ <tr>
+ <td><strong>Статус:</strong></td>
+ <td><?= Html::encode($model->statusEntity->name ?? $model->status) ?></td>
+ </tr>
+ <tr>
+ <td><strong>Приоритет:</strong></td>
+ <td><?= Html::encode($model->prioritet) ?></td>
+ </tr>
+ <tr>
+ <td><strong>Исполнитель:</strong></td>
+ <td><?= Html::encode($model->updatedBy->name ?? '---') ?></td>
+ </tr>
+ <tr>
+ <td><strong>Контроллер:</strong></td>
+ <td><?= Html::encode($model->controller->name ?? '---') ?></td>
+ </tr>
+ <tr>
+ <td><strong>Создатель:</strong></td>
+ <td><?= Html::encode($model->createdBy->name ?? '---') ?></td>
+ </tr>
+ <tr>
+ <td><strong>Дата начала:</strong></td>
+ <td><?= DateTimeService::formatHuman($model->data_start) ?></td>
+ </tr>
+ <tr>
+ <td><strong>Дата завершения:</strong></td>
+ <td><?= DateTimeService::formatHuman($model->data_end) ?></td>
+ </tr>
+ <tr>
+ <td><strong>Дедлайн:</strong></td>
+ <td><?= DateTimeService::formatHuman($model->deadline) ?></td>
+ </tr>
+ <tr>
+ <td><strong>Уровень важности:</strong></td>
+ <td><?= Html::encode($model->alertLevel->name ?? '---') ?></td>
+ </tr>
+ <tr>
+ <td><strong>Кем закрыта:</strong></td>
+ <td><?= Html::encode($model->closedBy->name ?? '---') ?></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
</div>
-</div>
\ No newline at end of file
<?php
+use yii\bootstrap\Modal;
use yii\widgets\ActiveForm;
use yii\helpers\Html;
<div class="col-4 text-end">
<!-- Кнопка для создания задачи -->
<?= Html::a('Создать задачу', ['/crud/task/create'], ['class' => 'btn btn-success', 'target' => '_blank', 'data-pjax' => '0']) ?>
+ <!-- Кнопка для открытия модального окна -->
+ <?= Html::button('Создать задачу', [
+ 'class' => 'btn btn-success',
+ 'id' => 'create-task-button',
+ ]) ?>
+
+ <!-- Модальное окно -->
+ <?php Modal::begin([
+ 'header' => '<h2>Создать задачу</h2>',
+ 'id' => 'create-task-modal',
+ 'size' => 'modal-lg', // Размер модального окна
+ 'footer' => '', // Убираем футер, так как не нужен
+ ]); ?>
+
+ <div id="create-task-content">
+ <!-- Здесь будет загружена форма через AJAX -->
+ </div>
+
+ <?php Modal::end(); ?>
+
</div>
</div>
/// Функция для управления видимостью задач
function toggleTasks() {
- if ($('#activeTasksToggle').is(':checked')) {
- // Скрываем задачи с статусами -1 и 6
- $('.dragulaCard[data-status="-1"], .dragulaCard[data-status="6"]').find('[data-task_id]').hide();
- } else {
- // Показываем задачи с статусами -1 и 6
- $('.dragulaCard[data-status="-1"], .dragulaCard[data-status="6"]').find('[data-task_id]').show();
- }
- }
+ if ($('#activeTasksToggle').is(':checked')) {
+
+
+ // Скрываем первый и последний дочерние элементы в #title-row и #column-row
+ $('#title-row').children(':first-child').hide();
+ $('#title-row').children(':last-child').hide();
+ $('#column-row').children(':first-child').hide();
+ $('#column-row').children(':last-child').hide();
+ } else {
+
+
+ // Показываем первый и последний дочерние элементы в #title-row и #column-row
+ $('#title-row').children(':first-child').show();
+ $('#title-row').children(':last-child').show();
+ $('#column-row').children(':first-child').show();
+ $('#column-row').children(':last-child').show();
+ }
+}
// Изначально скрываем задачи с data-status = -1 или 6, если тумблер выключен
toggleTasks();
$('#activeTasksToggle').on('change', function() {
toggleTasks();
});
+
+
+
+ // Когда пользователь нажимает на кнопку "Создать задачу"
+$('#create-task-button').on('click', function() {
+ // Открываем модальное окно
+ $('#create-task-modal').modal('show')
+ .find('#create-task-content') // Загружаем контент формы в модальное окно
+ .load('/crud/task/create-ajax'); // URL на экшен, который выводит форму создания задачи
+});
+
+// Обработка формы создания задачи после отправки
+$(document).on('beforeSubmit', '#create-task-form', function(e) {
+ e.preventDefault();
+
+ var form = $(this);
+
+ // AJAX-запрос для отправки формы
+ $.ajax({
+ url: form.attr('action'),
+ type: 'POST',
+ data: form.serialize(),
+ success: function(response) {
+ // Если успешно, закрываем модальное окно
+ if (response.success) {
+ $('#create-task-modal').modal('hide');
+ // Тут можно добавить обновление списка задач или другое действие
+ } else {
+ // Если есть ошибки валидации, обновляем контент модального окна
+ $('#create-task-content').html(response);
+ }
+ },
+ error: function() {
+ alert('Ошибка при создании задачи');
+ }
+ });
+
+ return false; // Предотвращаем стандартную отправку формы
+});
JS;
$this->registerJs($script);
?>
<div class="card mt-2">
- <div class="row g-0 d-flex justify-content-between">
+ <div class="row g-0 d-flex justify-content-between" id="title-row">
<?php if (isset($taskStatuses)): //<div class="col-1 font-weight-bold"></div> ?>
<?php foreach ($taskStatuses as $ind => $taskStatusName):?>
<?php if ($ind > -2 && $ind < 7): ?>
<?php endforeach; ?>
<?php endif; ?>
</div>
- <div class="row g-0 d-flex justify-content-between">
+ <div class="row g-0 d-flex justify-content-between" id="column-row">
<?php if (isset($taskStatuses)): // <div class="col-1 font-weight-bold"></div> ?>
<?php foreach ($taskStatuses as $ind => $taskStatusName):?>
<?php if ($ind > -2 && $ind < 7): ?>