Skip to content

Commit

Permalink
#22 i18n. Supported static language switching for web UI
Browse files Browse the repository at this point in the history
This is actually not an i18n solution but a quick fix until next
frontend refactoring
  • Loading branch information
Toparvion committed Jun 10, 2019
1 parent b81c7f1 commit 036ac5f
Show file tree
Hide file tree
Showing 34 changed files with 1,864 additions and 65 deletions.
6 changes: 5 additions & 1 deletion config/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ server:
address: localhost
spring:
mvc:
locale: en # as of v0.12 supported locales are: en, ru
locale: en # as of v0.12 supported locales are: en, ru
# Uncomment following 3 lines if the above locale is set to 'ru'
# resources:
# static-locations:
# - 'classpath:/static/ru'

nodes:
this:
Expand Down
18 changes: 9 additions & 9 deletions src/main/resources/static/download/download.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@ function DownloadController($scope, $element, $attrs, $log, $http) {
app.filter('sizeFormatter', function() {
return function(bytes) {
if (!bytes)
return '[н/д]';
return '[n/a]';
if (bytes === 0)
return '0 Байт';
return '0 Bytes';
let k = 1024,
dm = /*decimals ||*/ 2,
sizes = ['Байт', 'КБ', 'МБ', 'ГБ', 'ТБ', 'ПБ', 'ЭБ', 'ЗБ', 'YB'],
sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
};
Expand All @@ -133,9 +133,9 @@ app.filter('sizeFormatter', function() {
app.filter('dateFormatter', function () {
return function (utcDateString) {
if (!utcDateString)
return '[н/д]';
return '[n/a]';
let parsedDate = new Date(Date.parse(utcDateString));
return parsedDate.toLocaleString("ru-RU");
return parsedDate.toLocaleString("en-US");
}
});

Expand All @@ -146,16 +146,16 @@ app.filter('errorFormatter', function () {
let text;
switch (error.status) {
case 404:
text = 'не найден';
text = 'not found';
break;
case 403:
text = 'запрещён для загрузки';
text = 'access denied';
break;
case 503:
text = 'временно не доступен';
text = 'temporarily unavailable';
break;
default:
text = 'не может быть получен';
text = 'can not be downloaded';
}
text += (' ' + '(HTTP ' + error.status);
if (error.message)
Expand Down
28 changes: 14 additions & 14 deletions src/main/resources/static/download/download.template.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<div>
<button class="btn btn-default navbar-btn navbar-last-item" title="Скачать выбранный лог"
<button class="btn btn-default navbar-btn navbar-last-item" title="Download selected log"
ng-click="$ctrl.toggleDialog()" ng-show="$ctrl.isShowingButton">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true"></span>
</button>

<div class="panel panel-default" ng-show="$ctrl.isShowingDialog">
<div class="panel-body">
<div class="dialog-header">
<h4>Контрольная сводка</h4>
<h4>Download Summary</h4>
<div ng-switch="$ctrl.isLoading">
<div ng-switch-when="true">
<div class="loader"></div>
Expand All @@ -30,15 +30,15 @@ <h4>Контрольная сводка</h4>
</tr>
<tr ng-show="$ctrl.allMembers.length == 1">
<!-- node may not be specified if selected log is set manually through browser location bar -->
<th scope="row">Узел</th><td>{{$ctrl.file2Download.node || 'текущий'}}</td>
<th scope="row">Node</th><td>{{$ctrl.file2Download.node || 'current'}}</td>
</tr><tr>
<th scope="row">Путь</th><td>{{$ctrl.file2Download.path}}</td>
<th scope="row">Path</th><td>{{$ctrl.file2Download.path}}</td>
</tr><tr>
<th scope="row">Изменен</th><td>{{$ctrl.lastModified | dateFormatter}}</td>
<th scope="row">Changed</th><td>{{$ctrl.lastModified | dateFormatter}}</td>
</tr><tr>
<th scope="row">Размер</th><td>{{$ctrl.currentSize | sizeFormatter}}</td>
<th scope="row">Size</th><td>{{$ctrl.currentSize | sizeFormatter}}</td>
</tr><tr ng-show="$ctrl.lastError">
<th scope="row">Статус</th><td class="text-danger">{{$ctrl.lastError | errorFormatter}}</td>
<th scope="row">Status</th><td class="text-danger">{{$ctrl.lastError | errorFormatter}}</td>
</tr>
</tbody>
</table>
Expand All @@ -47,25 +47,25 @@ <h4>Контрольная сводка</h4>
<a ng-href="{{$ctrl.downloadLink}}"
ng-disabled="$ctrl.lastError || $ctrl.isLoading"
ng-click="$ctrl.onDownloadClick()"
class="btn btn-primary" download>Скачать целиком</a>
class="btn btn-primary" download>Download Fully</a>
<a href ng-disabled="$ctrl.lastError || $ctrl.isLoading || ($ctrl.currentSize < 1024*50)"
class="btn btn-primary dropdown-toggle"
data-toggle="dropdown"><span class="caret"></span></a>
<ul class="dropdown-menu">
<li ng-show="$ctrl.currentSize>1024*50" ng-click="$ctrl.closeDialog()">
<a ng-href="{{$ctrl.downloadLink+'&last-kbytes=50'}}" download>Последние 50 КБ</a></li>
<a ng-href="{{$ctrl.downloadLink+'&last-kbytes=50'}}" download>Last 50 KB</a></li>
<li ng-show="$ctrl.currentSize>1024*500" ng-click="$ctrl.closeDialog()">
<a ng-href="{{$ctrl.downloadLink+'&last-kbytes=500'}}" download>Последние 500 КБ</a></li>
<a ng-href="{{$ctrl.downloadLink+'&last-kbytes=500'}}" download>Last 500 KB</a></li>
<li ng-show="$ctrl.currentSize>1024*5120" ng-click="$ctrl.closeDialog()">
<a ng-href="{{$ctrl.downloadLink+'&last-kbytes=5120'}}" download>Последние 5 МБ</a></li>
<a ng-href="{{$ctrl.downloadLink+'&last-kbytes=5120'}}" download>Last 5 MB</a></li>
<li ng-show="$ctrl.currentSize>1024*51200" ng-click="$ctrl.closeDialog()">
<a ng-href="{{$ctrl.downloadLink+'&last-kbytes=51200'}}" download>Последние 50 МБ</a></li>
<a ng-href="{{$ctrl.downloadLink+'&last-kbytes=51200'}}" download>Last 50 MB</a></li>
<li class="divider" ng-show="$ctrl.currentSize>1024*204800"></li>
<li ng-show="$ctrl.currentSize>1024*204800" ng-click="$ctrl.closeDialog()">
<a ng-href="{{$ctrl.downloadLink+'&last-kbytes=204800'}}" download>Последние 200 МБ</a></li>
<a ng-href="{{$ctrl.downloadLink+'&last-kbytes=204800'}}" download>Last 200 MB</a></li>
</ul>
</div>
<a ng-click="$ctrl.closeDialog()" href class="card-link cancel">Отмена</a>
<a ng-click="$ctrl.closeDialog()" href class="card-link cancel">Cancel</a>
</div>
</div>
</div>
2 changes: 1 addition & 1 deletion src/main/resources/static/general/js/choice-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function ChoicesService($http, $location, $log, $rootScope) {
$log.log("Proposed log is unknown among server choices and hence will be added as separate group.");
let logType = detectLogType(proposedLogId);
selectedChoice = {
group: "Указан через URL",
group: "Specified via URL",
title: extractFileName(proposedLogId),
type: logType,
id: proposedLogId
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/static/general/js/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
app.constant('config', {
general: {
appTitle: 'АнаЛ&oacute;г'
appTitle: 'AnaL&oacute;g'
},

rendering: {
Expand Down
14 changes: 7 additions & 7 deletions src/main/resources/static/general/js/main-controller.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
app = angular.module("AnaLog", ['ngSanitize', 'ngAnimate', 'ui.select']);

app.run(function ($rootScope, watchingService) {
$rootScope.watchingLog = "АнаЛ&oacute;г v0.11 (загрузка...)";
$rootScope.watchingLog = "AnaL&oacute;g v0.12 (loading...)";
watchingService.connect();
});

Expand Down Expand Up @@ -102,19 +102,19 @@ app.filter('logTypeDetector', function () {
return function (logChoice) {
switch (logChoice.type) {
case 'LOCAL_FILE':
return 'локальный файл';
return 'local file';
case 'NODE':
return 'удалённый файл на узле {node}'.format(logChoice);
return 'remote file on {node} node'.format(logChoice);
case 'COMPOSITE':
return 'композит из {size} {logs}'.format({size: logChoice.includes.length,
return 'composite of {size} {logs}'.format({size: logChoice.includes.length,
logs: quantify(logChoice.includes.length)});
case 'DOCKER':
return 'контейнер в Docker';
return 'Docker container';
case 'KUBERNETES':
case 'K8S':
return 'ресурс в Kubernetes';
return 'Kubernetes resource';
default:
return '[неизвестный тип лога]';
return '[unknown log type]';
}
}
});
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/static/general/js/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ function arePathsEqual(path1, path2) {

function quantify(count) {
if (count > 1) {
return 'логов';
return 'logs';
} else {
return 'лога';
return 'log';
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/main/resources/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title ng-bind-html="watchingLog">АнаЛ&oacute;г v0.11</title>
<title ng-bind-html="watchingLog">AnaL&oacute;g v0.12</title>

<script type="text/javascript" src="webjars/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="webjars/jquery.scrollto/2.1.2/jquery.scrollTo.min.js"></script>
Expand Down Expand Up @@ -47,17 +47,17 @@
<!-- Brand -->
<div class="navbar-header">
<div class="navbar-brand">
<img alt="АнаЛ&oacute;г v0.11" title="АнаЛ&oacute;г v0.11" src="general/img/logo-20-20.png">
<img alt="AnaL&oacute;g v0.12" title="AnaL&oacute;g v0.12" src="general/img/logo-20-20.png">
</div>
</div>
<!-- Watching toggle control -->
<label class="checkbox-inline navbar-text"><input type="checkbox" ng-model="ctrl.onAir">
Отслеживать лог
Follow
</label>
<!-- Choices field-->
<div class="navbar-form navbar-left form-group">
<ui-select ng-model="ctrl.selectedLog" on-select="ctrl.onLogChange()">
<ui-select-match allow-clear="false" placeholder="Имя лога, путь, группа, ...">
<ui-select-match allow-clear="false" placeholder="Log name, path, group, etc.">
<span ng-bind-html="$select.selected.title"></span>
</ui-select-match>
<ui-select-choices group-by="'group'"
Expand All @@ -80,11 +80,11 @@
<div class="nav navbar-nav navbar-right">
<!-- Text wrapping control -->
<label class="checkbox-inline navbar-text">
<input type="checkbox" ng-model="ctrl.textWrap">Перенос строк
<input type="checkbox" ng-model="ctrl.textWrap">Wrap Lines
</label>
<!--<p class="navbar-text">Выбран лог: "{{ctrl.selectedLog.title}}"</p>-->
<!--<p class="navbar-text">Selected Log: "{{ctrl.selectedLog.title}}"</p>-->
<!-- Clear button -->
<button class="btn btn-default navbar-btn navbar-last-item" ng-click="ctrl.clear()">Очистить</button>
<button class="btn btn-default navbar-btn navbar-last-item" ng-click="ctrl.clear()">Clear</button>
</div>
</div><!-- /.container-fluid -->
</nav>
Expand All @@ -104,7 +104,7 @@

<!-- Scroll down button (auto-hiding) -->
<button type="button" class="btn btn-primary scroll-down-btn ng-hide" hide-upon-auto-scroll
title="Промотать в самый вниз" ng-click="ctrl.scrollDown()">
title="Scroll to bottom" ng-click="ctrl.scrollDown()">
<span class="glyphicon glyphicon-arrow-down" aria-hidden="true"></span>
</button>

Expand Down
45 changes: 23 additions & 22 deletions src/main/resources/static/notification/notification.constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,63 @@ app.constant('notifications', {
//<editor-fold desc="Server Events">
serverConnected: {
level: 'success',
title: 'Сервер снова доступен',
text: 'Связь восстановлена, можно работать.'
title: 'Server Is Available',
text: 'Connection restored, we can go on working.'
},
serverDisconnected: {
level: 'warning',
title: 'Нет связи с сервером',
text: 'При необходимости слежение продолжится автоматически после восстановления связи.'
title: 'No Connection With Server',
text: 'Log tracking will continue (if necessary) after connection restore.'
},
//</editor-fold>

//<editor-fold desc="Tail Events">
logNotFound: {
level: 'info',
title: 'Лог не найден',
text: "Лог <span class='highlight'>{logPath}</span> не найден. Ожидаю его появления..."
title: 'Log Not Found',
text: "Log <span class='highlight'>{logPath}</span> not found. Waiting for it to appear..."
},
logAppeared: {
level: 'success',
title: 'Лог обнаружен',
text: "Лог <span class='highlight'>{logPath}</span> появился. Отслеживаю его изменения."
title: 'Log Detected',
text: "Log <span class='highlight'>{logPath}</span> has appeared. Following it..."
},
logRotated: {
level: 'info',
title: 'Ротация лога',
text: "Лог <span class='highlight'>{logPath}</span> начал писаться с начала. " +
"Предыдущие записи, вероятно, перенесены в другой лог."
title: 'Log Rotation',
text: "Log <span class='highlight'>{logPath}</span> started to write from scratch. " +
"Perhaps previous records have been moved to another file."
},
logDisappeared: {
level: 'info',
title: 'Лог потерян',
text: "Лог <span class='highlight'>{logPath}</span> пропал. Продолжу отслеживание, когда появится."
title: 'Log Lost',
text: "Log <span class='highlight'>{logPath}</span> has disappeared. The tracking will continue" +
" automatically when the log is back."
},
logTruncated: {
level: 'danger',
title: 'Лог сократился',
text: "Лог <span class='highlight'>{logPath}</span> сократился в размере.<br/>" +
"Дальнейшее отслеживание может быть ошибочным.<br/>В этом случае лучше начать его заново."
title: 'Log Reduced',
text: "Log <span class='highlight'>{logPath}</span> has become shorter.<br/>" +
"Current tracking can become incorrect. Restart it if necessary."
},
unrecognized: {
level: 'warning',
title: 'Сообщение о слежении',
text: "При слежении за логом <span class='highlight'>{logPath}</span> получено сообщение:<br/>" +
title: 'Tracking Notification',
text: "Log <span class='highlight'>{logPath}</span> produced a message:<br/>" +
"<span class='tracking-message'>{message}</span>"
},
//</editor-fold>

//<editor-fold desc="Server Fault(s)">
serverFailure: {
level: 'danger',
title: 'Сообщение от сервера',
text: "Отслеживание прекращено из-за ошибки:<br/><span class='failure-message'>{message}</span>"
title: 'Server Message',
text: "Tracking has been stopped because of error:<br/><span class='failure-message'>{message}</span>"
},
choicesNotFound: {
level: 'danger',
title: 'Сбой на сервере',
text: "Не удалось получить варианты логов из-за ошибки:<br/>" +
title: 'Server Failure',
text: "Couldn't fetch log choices because of error:<br/>" +
"<span class='failure-message'>{message}</span>"
}
//</editor-fold>
Expand Down
Loading

0 comments on commit 036ac5f

Please sign in to comment.