Skip to content

Commit

Permalink
[FEATURE] Better readable usage stats / silent return on lower severity
Browse files Browse the repository at this point in the history
Refs web-vision#343

[FEATURE] Make translation limits more readable

[FEATURE] Follow up: More readable quota in toolbar

[FEATURE] Replace severity numbers with constants

[FEATURE] Enable color changes for DeepL action icon

Action icons dont have a fixed color set, in order to let TYPO3 set
the desired color - black in list actions, white in toolbar infos.

Change the DeepL SVG to not use black in all places.

[FEATURE] Determine severity based on quota usage

Calculate the message severity based on the API quota usage rate.
Matching popular quota warning levels if will notify above 90% usage,
and shown an error when the limit is exceeded.

Hide the flashmessage after a translation if the severity is low.

Refs web-vision#343

[FEATURE] Make widget more compact and use severity

Use severity levels in widget as well and reduce the height
to prevent unused whitespace.
  • Loading branch information
pixelbrackets authored and calien666 committed Nov 20, 2024
1 parent d82b991 commit 000df87
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 53 deletions.
54 changes: 48 additions & 6 deletions Classes/Event/Listener/UsageToolBarEventListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use TYPO3\CMS\Backend\Backend\Event\SystemInformationToolbarCollectorEvent;
use TYPO3\CMS\Backend\Toolbar\Enumeration\InformationStatus;
use TYPO3\CMS\Core\Localization\LanguageService;
use WebVision\WvDeepltranslate\Exception\ApiKeyNotSetException;
use WebVision\WvDeepltranslate\Service\UsageService;
Expand Down Expand Up @@ -40,19 +41,60 @@ public function __invoke(SystemInformationToolbarCollectorEvent $systemInformati
}
return;
}

$title = $this->getLanguageService()->sL(
'LLL:EXT:wv_deepltranslate/Resources/Private/Language/locallang.xlf:usages.toolbar-label'
);
$message = $this->getLanguageService()->sL(
'LLL:EXT:wv_deepltranslate/Resources/Private/Language/locallang.xlf:usages.toolbar.message'
);

$severity = $this->determineSeverity($usage->character->count, $usage->character->limit);

$systemInformation->getToolbarItem()->addSystemInformation(
$this->getLanguageService()->sL('LLL:EXT:wv_deepltranslate/Resources/Private/Language/locallang.xlf:usages.toolbar-label'),
sprintf(
'%d / %d',
$usage->character->count,
$usage->character->limit
),
$title,
sprintf($message, $this->formatNumber($usage->character->count), $this->formatNumber($usage->character->limit)),
'actions-localize-deepl',
$severity
);
}

private function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}

/**
* Make large API limits easier to read
*
* @param int $number Any large integer - 5000000
* @return string Formated, better readable string variant of the integer - 5.000.000
*/
private function formatNumber(int $number): string
{
return number_format($number, 0, ',', '.');
}


/**
* Calculate the message severity based on the quota usage rate
*
* @param int $characterCount Already translated characters in the current billing period
* @param int $characterLimit Total character limit in the current billing period
* @return string Severity level
*/
private function determineSeverity(int $characterCount, int $characterLimit): string
{
$quotaUtilization = ($characterCount / $characterLimit) * 100;
if ($quotaUtilization >= 100) {
return InformationStatus::STATUS_ERROR;
}
if ($quotaUtilization >= 98) {
return InformationStatus::STATUS_WARNING;
}
if ($quotaUtilization >= 90) {
return InformationStatus::STATUS_INFO;
}
return InformationStatus::STATUS_NOTICE;
}
}
53 changes: 45 additions & 8 deletions Classes/Hooks/UsageProcessAfterFinishHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,26 @@ public function processCmdmap_afterFinish(DataHandler $dataHandler): void
return;
}

$label = $this->getLanguageService()->sL(
$title = $this->getLanguageService()->sL(
'LLL:EXT:wv_deepltranslate/Resources/Private/Language/locallang.xlf:usages.flashmassage.title'
);
$message = $this->getLanguageService()->sL(
'LLL:EXT:wv_deepltranslate/Resources/Private/Language/locallang.xlf:usages.flashmassage.limit.description'
);

$severity = $this->determineSeverity($usage->character->count, $usage->character->limit);
// Reduce noise - Don't bother editors with low quota usage messages
if ($severity === FlashMessage::NOTICE) {
return;
}

$flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
$notificationQueue = $flashMessageService->getMessageQueueByIdentifier();

$severity = -1; // Info
if ($this->usageService->isTranslateLimitExceeded()) {
$severity = 1; // Warning
}

$flashMessage = GeneralUtility::makeInstance(
FlashMessage::class,
sprintf($label, $usage->character->count, $usage->character->limit),
'Deepl Usage',
sprintf($message, $this->formatNumber($usage->character->count), $this->formatNumber($usage->character->limit)),
$title,
$severity,
true
);
Expand All @@ -66,4 +70,37 @@ private function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}

/**
* Make large API limits easier to read
*
* @param int $number Any large integer - 5000000
* @return string Formated, better readable string variant of the integer - 5.000.000
*/
private function formatNumber(int $number): string
{
return number_format($number, 0, ',', '.');
}

/**
* Calculate the message severity based on the quota usage rate
*
* @param int $characterCount Already translated characters in the current billing period
* @param int $characterLimit Total character limit in the current billing period
* @return int Severity level
*/
private function determineSeverity(int $characterCount, int $characterLimit): int
{
$quotaUtilization = ($characterCount / $characterLimit) * 100;
if ($quotaUtilization >= 100) {
return FlashMessage::ERROR;
}
if ($quotaUtilization >= 98) {
return FlashMessage::WARNING;
}
if ($quotaUtilization >= 90) {
return FlashMessage::INFO;
}
return FlashMessage::NOTICE;
}
}
2 changes: 1 addition & 1 deletion Configuration/Services.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@
'title' => 'LLL:EXT:wv_deepltranslate/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.title',
'description' => 'LLL:EXT:wv_deepltranslate/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.description',
'iconIdentifier' => 'content-widget-list',
'height' => 'medium',
'height' => 'small',
'width' => 'small',
])
;
Expand Down
21 changes: 15 additions & 6 deletions Resources/Private/Backend/Templates/Widget/UsageWidget.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,23 @@
<f:for as="item" each="{usages}" >
<div class="mb-3">
<h4>{item.label}</h4>
<f:variable name="count" value="{item.usage.count -> f:format.number(thousandsSeparator: '.', decimalSeparator: '', decimals: 0)}" />
<f:variable name="limit" value="{item.usage.limit -> f:format.number(thousandsSeparator: '.', decimalSeparator: '', decimals: 0)}" />
<f:variable name="percentage">{item.usage.count / item.usage.limit * 100}</f:variable>
<f:if condition="{percentage} >= 98">
<f:variable name="severity" value="warning" />
</f:if>
<f:if condition="{percentage} >= 100">
<f:variable name="severity" value="danger" />
</f:if>
<p>
<b>{f:translate(key: 'LLL:EXT:wv_deepltranslate/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.count')}</b>: {item.usage.count -> f:format.number(thousandsSeparator: '.', decimalSeparator: '', decimals: 0)}
<br>
<b>{f:translate(key: 'LLL:EXT:wv_deepltranslate/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.limit')}</b>: {item.usage.limit -> f:format.number(thousandsSeparator: '.', decimalSeparator: '', decimals: 0)}
<f:translate
key="LLL:EXT:wv_deepltranslate/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.message"
arguments="{0: count, 1: limit}"
/>
</p>
<f:variable name="procss">{item.usage.count / item.usage.limit * 100}</f:variable>
<div class="progress" role="progressbar" aria-label="Usage" aria-valuenow="{procss}" aria-valuemin="0" aria-valuemax="100" style="height: 50%">
<div class="progress-bar" style="width: {procss}%">{item.usage.count -> f:format.number(thousandsSeparator: '.', decimalSeparator: '', decimals: 0)}</div>
<div class="progress-bar" style="width: {percentage}%; --bs-progress-bar-bg: var(--bs-{severity -> f:or(alternative: 'info')});">&nbsp;</div>
</div>
</div>
</f:for>
Expand All @@ -25,4 +34,4 @@ <h4>{item.label}</h4>
<f:render partial="Widget/Button" arguments="{button: button}"/>
</f:section>

</html>
</html>
28 changes: 18 additions & 10 deletions Resources/Private/Language/de.locallang.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -199,34 +199,42 @@
</trans-unit>

<trans-unit id="usages.toolbar-label">
<source>DeepL Translate Limit</source>
<source>DeepL Translate Quota</source>
<target>DeepL Übersetzung Limit</target>
</trans-unit>
<trans-unit id="usages.toolbar.message">
<source>%s / %s</source>
<target>%s / %s</target>
</trans-unit>
<trans-unit id="usages.toolbar-information">
<source>Information not available</source>
<target>Information nicht verfügbar</target>
</trans-unit>
<trans-unit id="usages.flashmassage.title">
<source>DeepL usage and quota</source>
<target>DeepL Nutzung und Limits</target>
</trans-unit>
<trans-unit id="usages.flashmassage.limit.description">
<source>DeepL translations for current billing period: %s of %s characters</source>
<target>DeepL Übersetzungen für den aktuellen Abrechnungszeitraum: %s von %s Zeichen</target>
</trans-unit>

<!-- Widget -->
<trans-unit id="widgets.deepltranslate.widget.useswidget.title">
<source>DeepL Usage</source>
<target>DeepL Verwendung</target>
</trans-unit>
<trans-unit id="widgets.deepltranslate.widget.useswidget.description">
<source></source>
<target></target>
<source>Show a DeepL usage bar</source>
<target>Zeige einen Fortschrittsbalken für die DeepL Nutzung</target>
</trans-unit>
<trans-unit id="widgets.deepltranslate.widget.useswidget.character">
<source>Character</source>
<target>Zeichen</target>
</trans-unit>
<trans-unit id="widgets.deepltranslate.widget.useswidget.count">
<source>Count</source>
<target>Zähler</target>
</trans-unit>
<trans-unit id="widgets.deepltranslate.widget.useswidget.limit">
<source>Limit</source>
<target>Begrenzung</target>
<trans-unit id="widgets.deepltranslate.widget.useswidget.message">
<source>DeepL translations for current billing period: %s of %s characters</source>
<target>DeepL Übersetzungen für aktuellen Abrechnungszeitraum: %s von %s Zeichen</target>
</trans-unit>
</body>
</file>
Expand Down
18 changes: 9 additions & 9 deletions Resources/Private/Language/locallang.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,19 @@
</trans-unit>

<trans-unit id="usages.toolbar-label">
<source>DeepL Translate Limit</source>
<source>DeepL Translate Quota</source>
</trans-unit>
<trans-unit id="usages.toolbar.message">
<source>%s / %s</source>
</trans-unit>
<trans-unit id="usages.toolbar-information">
<source>Information not available</source>
</trans-unit>
<trans-unit id="usages.flashmassage.title">
<source>DeepL Translate </source>
<source>DeepL usage and quota</source>
</trans-unit>
<trans-unit id="usages.flashmassage.limit.description">
<source>DeepL Translate Limit %s / %s</source>
<source>DeepL translations for current billing period: %s of %s characters</source>
</trans-unit>

<!-- Translation Access | be_groups -->
Expand All @@ -208,16 +211,13 @@
<source>DeepL Usage</source>
</trans-unit>
<trans-unit id="widgets.deepltranslate.widget.useswidget.description">
<source></source>
<source>Show a DeepL usage bar</source>
</trans-unit>
<trans-unit id="widgets.deepltranslate.widget.useswidget.character">
<source>Character</source>
</trans-unit>
<trans-unit id="widgets.deepltranslate.widget.useswidget.count">
<source>Count</source>
</trans-unit>
<trans-unit id="widgets.deepltranslate.widget.useswidget.limit">
<source>Limit</source>
<trans-unit id="widgets.deepltranslate.widget.useswidget.message">
<source>DeepL translations for current billing period: %s of %s characters</source>
</trans-unit>
</body>
</file>
Expand Down
17 changes: 4 additions & 13 deletions Resources/Public/Icons/actions-localize-deepl.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 000df87

Please sign in to comment.