Skip to content

Commit

Permalink
Merge pull request #110 from lilt/3.x-development
Browse files Browse the repository at this point in the history
  • Loading branch information
hadomskyi authored Jun 6, 2023
2 parents 97d4c84 + c5cbaf4 commit 33244eb
Show file tree
Hide file tree
Showing 33 changed files with 688 additions and 48 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).

## 3.6.0 - 2023-05-24
### Added
- Introduced new job and translation status "needs attention"
- Added warning message for translation jobs exceeding field limit with
- Included warning icon for each translation exceeding field limit with
- Download Diagnostic Data button for error reporting

## 3.5.4 - 2023-05-26
### Fixed
- Merge canonical changes from the Neo field into drafts
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ composer-install:
quality:
docker-compose exec -T -u www-data cli-app sh -c "curl -L -s https://phar.phpunit.de/phpcpd.phar --output phpcpd.phar"
docker-compose exec -T -u www-data cli-app sh -c "php vendor/bin/phpcs"
docker-compose exec -T -u www-data cli-app sh -c "php phpcpd.phar src"
docker-compose exec -T -u www-data cli-app sh -c "php phpcpd.phar src --exclude /craft-lilt-plugin/src/migrations"

quality-fix:
docker-compose exec -T -u www-data cli-app sh -c "php vendor/bin/phpcbf"
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "lilt/craft-lilt-plugin",
"description": "The Lilt plugin makes it easy for you to send content to Lilt for translation right from within Craft CMS.",
"type": "craft-plugin",
"version": "3.5.4",
"version": "3.6.0",
"keywords": [
"craft",
"cms",
Expand Down
1 change: 1 addition & 0 deletions src/assets/JobFormAsset.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public function init(): void
'job-translation-review.js',
'job-try-again-button.js',
'job-target-sites.js',
'job-edit-sync-button.js',
];

$this->css = [
Expand Down
66 changes: 66 additions & 0 deletions src/assets/resources/job-edit-sync-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
CraftliltPlugin.JobEditSyncButton = Garnish.Base.extend({
/**
* JobSyncButton needed to add functionality to sync button on jobs overview page
*/
$container: null,
$_spinner: null,

init: function(container, settings) {
this.$container = $(container);
this.setSettings(settings, {});

if (this.$container.data('job-edit-sync-button')) {
console.warn('Double-instantiating a job-edit-sync-button on an element');
this.$container.data('job-edit-sync-button').destroy();
}
this.$container.data('job-edit-sync-button', this);

this._registerOnClick()
},
_registerOnClick: function() {
this.addListener(this.$container, 'click', () => {
if (this.$container.hasClass('disabled')) {
return;
}

this.sync([this.$container.data('job-id')])
})
},
sync: function(selectedJobIds) {
this.processing();

Craft.sendActionRequest(
'POST',
'craft-lilt-plugin/job/post-sync/invoke',
{data: {jobIds: selectedJobIds}},
).then(response => {
Craft.cp.displayNotice(Craft.t('app', 'Sync complete'));
this.done();
location.reload()
}).catch(exception => {
this.done();
Craft.cp.displayError(Craft.t('app',
'Can\'t sync, unexpected issue occurred'));

});
},
processing: function() {
this.$container.addClass('disabled');

this.$_spinner = $('<div class="spinner" style="float: right"></div>');
this.$container.parent().parent().prepend(this.$_spinner);
},
done: function() {
this.$_spinner.remove();
this.$container.removeClass('disabled');
},
});

/** Init #lilt-sync-jobs as JobSyncButton */
$(document).ready(
function() {
CraftliltPlugin.jobSyncButton = new CraftliltPlugin.JobEditSyncButton(
$('#lilt-job-edit-sync-button'),
);
},
);
39 changes: 38 additions & 1 deletion src/assets/resources/job-translation-review.js
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,46 @@ $(document).ready(function() {
selectable: true,
multiSelect: true,
checkboxMode: true,

onUpdateElements: function() {

const elements = CraftliltPlugin.elementIndexTranslation.view.getAllElements().get();

console.log(elements)
elements.forEach((element) => {

const title = jQuery(element).find('th');
const titleDiv = jQuery(element).find('th div');

const hasNotification = (titleDiv.length > 0 &&
titleDiv.data('has-notifications') === 1);

if(hasNotification) {

const notifications = titleDiv.data('notifications');
console.log(notifications)

const span = jQuery(
'<span class="info warning lilt-warning-span-centred translation-need-attention"></span>');

const reasons = notifications.map(notification => notification.reason);
const joinedReasons = reasons.join('<hr />');

span.on('click', function() {
new Garnish.HUD(span,
joinedReasons,
{
orientations: [
'top',
'bottom',
'right',
'left'],
});
});

title.append(span);
}
});

if (CraftliltPlugin.elementIndexTranslation !== undefined &&
CraftliltPlugin.elementIndexTranslation.view !==
undefined) {
Expand Down
9 changes: 8 additions & 1 deletion src/assets/resources/job/overview.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#details .meta.warning p{
margin: 0;
}
#details .meta.warning {
border: 2px solid #fadb5f;
padding: 19px 22px;
Expand Down Expand Up @@ -66,4 +69,8 @@
text-align: center;
font-weight: inherit;
padding-right: 15px
}
}

.translation-need-attention:before {
color: #b44d12 !important;
}
136 changes: 136 additions & 0 deletions src/controllers/GetReportDataController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?php

/**
* @link https://github.com/lilt
* @copyright Copyright (c) 2023 Lilt Devs
*/

declare(strict_types=1);

namespace lilthq\craftliltplugin\controllers;

use Craft;
use lilthq\craftliltplugin\controllers\job\AbstractJobController;
use lilthq\craftliltplugin\records\JobLogRecord;
use lilthq\craftliltplugin\records\JobRecord;
use lilthq\craftliltplugin\records\TranslationRecord;
use Throwable;
use yii\web\Response;
use craft\helpers\Json;

class GetReportDataController extends AbstractJobController
{
protected $allowAnonymous = false;

private $savePath;

/**
* @throws Throwable
* TODO: move to handler/command
*/
public function actionInvoke(?int $jobId = null): Response
{
// Path to the directory where you want to save the downloaded files
$this->savePath = sprintf(
'%s%s%s%s%s%s',
Craft::$app->getPath()->getTempPath(),
DIRECTORY_SEPARATOR,
'craft-lilt-plugin',
DIRECTORY_SEPARATOR,
uniqid(),
DIRECTORY_SEPARATOR
);

if (!file_exists($this->savePath)) {
mkdir($this->savePath, 0777, true);
}

try {
// Copy composer.json
$composerJsonPath = CRAFT_BASE_PATH . '/composer.json';
$composerJsonContents = file_get_contents($composerJsonPath);
file_put_contents($this->savePath . 'composer.json', $composerJsonContents);

// Copy composer.lock
$composerLockPath = CRAFT_BASE_PATH . '/composer.lock';
$composerLockContents = file_get_contents($composerLockPath);
file_put_contents($this->savePath . 'composer.lock', $composerLockContents);

// Copy logs
$logsPath = Craft::$app->getPath()->getLogPath();
$logFiles = glob($logsPath . '/*.log');

$logsFolderPath = $this->savePath . 'logs' . DIRECTORY_SEPARATOR;
if (!file_exists($logsFolderPath)) {
mkdir($logsFolderPath);
}
foreach ($logFiles as $logFile) {
$filename = basename($logFile);
copy($logFile, $logsFolderPath . $filename);
}

// Copy configuration YAML files
$configPath = Craft::$app->getPath()->getConfigPath();
$yamlFiles = glob($configPath . '/*.yaml');

$configFolderPath = $this->savePath . 'config' . DIRECTORY_SEPARATOR;
if (!file_exists($configFolderPath)) {
mkdir($configFolderPath);
}
foreach ($yamlFiles as $yamlFile) {
$filename = basename($yamlFile);
copy($yamlFile, $configFolderPath . $filename);
}

if (!empty($jobId)) {
$this->saveRecords(JobRecord::class, ['id' => $jobId]);
$this->saveRecords(TranslationRecord::class, ['jobId' => $jobId]);
$this->saveRecords(JobLogRecord::class, ['jobId' => $jobId]);
}

// Create a ZIP archive
$zipPath = sprintf(
'%s%s - %s.zip',
$this->savePath,
Craft::$app->sites->currentSite->name,
date('Y-m-d H:i:s')
);

$zip = new \PharData($zipPath);

$zip->buildFromDirectory($this->savePath);

// Send the ZIP file for download
return Craft::$app->getResponse()->sendFile($zipPath, null, ['forceDownload' => true]);
} catch (\Exception $e) {
// Handle any exceptions that occur during the process
$error = sprintf('An error occurred while downloading the files: %s', $e->getMessage());
Craft::error($error, __METHOD__);
die($error);
}
}

/**
* @param string $recordClass
* @param array $criteria
* @return bool
*/
public function saveRecords(string $recordClass, array $criteria = []): bool
{
if (!method_exists($recordClass, 'findAll') || !method_exists($recordClass, 'tableName')) {
return false;
}

$records = $recordClass::findAll($criteria);

$data = [];
foreach ($records as $record) {
$data[] = $record->toArray();
}

$jsonData = Json::encode($data);

$filePath = $this->savePath . $recordClass::tableName() . '.json';
return file_put_contents($filePath, $jsonData) !== false;
}
}
12 changes: 10 additions & 2 deletions src/controllers/job/GetJobEditFormController.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,28 @@ public function actionInvoke(string $jobId): Response
return (new Response())->setStatusCode(400);
}

$job = Job::findOne(['id' => (int) $jobId]);
$job = Job::findOne(['id' => (int)$jobId]);

if (!$job) {
return (new Response())->setStatusCode(404);
}

$notices = [];
if ($job->status === Job::STATUS_NEEDS_ATTENTION) {
$notices[] = "<p><strong>Warning:</strong> This job contains content that was not applied properly."
. " Please review all marked translations. </p> <br /> <p>Once all issues are resolved, "
. "please try syncing the job again.</p>";
}

return $this->renderJobForm(
$job,
[
'notices' => $notices,
'jobLogs' => Craftliltplugin::getInstance()->jobLogsRepository->findByJobId(
$job->getId()
),
'showLiltTranslateButton' => $job->getStatus() === Job::STATUS_NEW,
'showLiltSyncButton' => $job->getStatus() === Job::STATUS_READY_FOR_REVIEW,
'showLiltSyncButton' => $job->getStatus() === Job::STATUS_READY_FOR_REVIEW,
'isUnpublishedDraft' => false,
'sendToLiltActionLink' => 'craft-lilt-plugin/job/send-to-lilt/' . $jobId,
'syncFromLiltActionLink' => 'craft-lilt-plugin/job/sync-from-lilt/' . $jobId,
Expand Down
5 changes: 4 additions & 1 deletion src/controllers/job/PostSyncController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use lilthq\craftliltplugin\elements\Translation;
use lilthq\craftliltplugin\modules\ManualJobSync;
use lilthq\craftliltplugin\records\JobRecord;
use lilthq\craftliltplugin\records\TranslationNotificationsRecord;
use lilthq\craftliltplugin\records\TranslationRecord;
use yii\web\Response;

Expand Down Expand Up @@ -54,7 +55,7 @@ public function actionInvoke(): Response
continue;
}

$selectedJobIds[] = (int) $job->id;
$selectedJobIds[] = (int)$job->id;
}

sort($selectedJobIds);
Expand All @@ -69,6 +70,8 @@ public function actionInvoke(): Response
ManualJobSync::DELAY_IN_SECONDS
);

TranslationNotificationsRecord::deleteAll(['jobId' => $selectedJobIds]);

TranslationRecord::updateAll(
[
'status' => TranslationRecord::STATUS_IN_PROGRESS
Expand Down
2 changes: 2 additions & 0 deletions src/elements/Job.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Job extends Element
public const STATUS_READY_TO_PUBLISH = 'ready-to-publish';
public const STATUS_COMPLETE = 'complete';
public const STATUS_FAILED = 'failed';
public const STATUS_NEEDS_ATTENTION = 'needs-attention';


public $uid;
Expand Down Expand Up @@ -231,6 +232,7 @@ public static function statuses(): array
self::STATUS_READY_TO_PUBLISH => ['label' => 'Ready to publish', 'color' => 'purple'],
self::STATUS_COMPLETE => ['label' => 'Complete', 'color' => 'green'],
self::STATUS_FAILED => ['label' => 'Failed', 'color' => 'red'],
self::STATUS_NEEDS_ATTENTION => ['label' => 'Needs attention', 'color' => 'red'],
];
}

Expand Down
Loading

0 comments on commit 33244eb

Please sign in to comment.