Skip to content

Commit af32540

Browse files
welcoMatticNyholm
authored andcommitted
Improve UI/UX in Profiler (#105)
* Allow to select/deselect all translation keys at once * Add loaders during ajax requests * Add line in changelog
1 parent 13f5c56 commit af32540

File tree

4 files changed

+98
-17
lines changed

4 files changed

+98
-17
lines changed

Changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
44

5+
## 0.3.6
6+
7+
### Added
8+
9+
- Improve UI/UX in Profiler (loader during AJAX requests, select/deselect all messages)
10+
511
## 0.3.5
612

713
### Fixed
Lines changed: 33 additions & 0 deletions
Loading

Resources/public/js/symfonyProfiler.js

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ function clearState(key) {
1616
}
1717

1818
function syncMessage(key) {
19+
var el = document.getElementById(key).getElementsByClassName("translation");
20+
el[0].innerHTML = getLoaderHTML();
21+
1922
Sfjs.request(
2023
translationSyncUrl,
2124
function(xhr) {
2225
// Success
23-
var el = document.getElementById(key).getElementsByClassName("translation");
2426
el[0].innerHTML = xhr.responseText;
2527

2628
if (xhr.responseText !== "") {
@@ -29,53 +31,58 @@ function syncMessage(key) {
2931
},
3032
function(xhr) {
3133
// Error
32-
console.log("Syncing message "+key + " - Error");
34+
el[0].innerHTML = "<span style='color:red;'>Error - Syncing message " + key + "</span>";
3335
},
3436
serializeQueryString({message_id: key}),
3537
{ method: 'POST' }
3638
);
3739
}
40+
3841
function syncAll() {
42+
var el = document.getElementById("top-result-area");
43+
el[0].innerHTML = getLoaderHTML();
44+
3945
Sfjs.request(
4046
translationSyncAllUrl,
4147
function(xhr) {
4248
// Success
43-
var el = document.getElementById("top-result-area");
4449
el.innerHTML = xhr.responseText;
4550
},
4651
function(xhr) {
4752
// Error
48-
console.log("Syncing message "+key + " - Error");
53+
el[0].innerHTML = "<span style='color:red;'>Error - Syncing all messages</span>";
4954
},
5055
{},
5156
{ method: 'POST' }
5257
);
5358
}
5459

5560
function getEditForm(key) {
61+
var el = document.getElementById(key).getElementsByClassName("translation");
62+
el[0].innerHTML = getLoaderHTML();
5663

5764
Sfjs.request(
5865
translationEditUrl + "?" + serializeQueryString({message_id: key}),
5966
function(xhr) {
6067
// Success
61-
var el = document.getElementById(key).getElementsByClassName("translation");
6268
el[0].innerHTML = xhr.responseText;
6369
},
6470
function(xhr) {
6571
// Error
66-
console.log("Getting edit form "+key+" - Error");
72+
el[0].innerHTML = "<span style='color:red;'>Error - Getting edit form " + key + "</span>";
6773
},
6874
{ method: 'GET' }
6975
);
7076
}
7177

7278
function saveEditForm(key, translation) {
79+
var el = document.getElementById(key).getElementsByClassName("translation");
80+
el[0].innerHTML = getLoaderHTML();
7381

7482
Sfjs.request(
7583
translationEditUrl,
7684
function(xhr) {
7785
// Success
78-
var el = document.getElementById(key).getElementsByClassName("translation");
7986
el[0].innerHTML = xhr.responseText;
8087

8188
if (xhr.responseText !== "") {
@@ -84,7 +91,7 @@ function saveEditForm(key, translation) {
8491
},
8592
function(xhr) {
8693
// Error
87-
console.log("Saving edit form "+key +" - Error");
94+
el[0].innerHTML = "<span style='color:red;'>Error - Saving edit form " + key + "</span>";
8895
},
8996
serializeQueryString({message_id: key, translation:translation}),
9097
{ method: 'POST' }
@@ -98,6 +105,20 @@ function cancelEditForm(key, orgMessage) {
98105
el[0].innerHTML = orgMessage;
99106
}
100107

108+
function toggleCheckAll(controller) {
109+
var checkboxes = document.querySelectorAll('.translation-key-checkbox');
110+
111+
for (var i = 0; i < checkboxes.length; i++) {
112+
checkboxes[i].checked = controller.checked;
113+
}
114+
}
115+
116+
function getLoaderHTML() {
117+
var loader = document.getElementById('svg-loader');
118+
119+
return loader.outerHTML;
120+
}
121+
101122
var serializeQueryString = function(obj, prefix) {
102123
var str = [];
103124
for(var p in obj) {
@@ -122,11 +143,14 @@ var serializeQueryString = function(obj, prefix) {
122143

123144
var saveTranslations = function(form) {
124145
"use strict";
146+
125147
if (typeof(form.translationKey) === 'undefined') {
126148
return false;
127149
}
150+
128151
var inputs = form.translationKey;
129152
var selected = [];
153+
130154
if (!inputs.value) {
131155
for (var val in inputs) {
132156
if (inputs.hasOwnProperty(val) && inputs[val].value) {
@@ -138,15 +162,26 @@ var saveTranslations = function(form) {
138162
} else if (inputs.checked) {
139163
selected.push(inputs.value);
140164
}
165+
166+
var el = document.getElementById('translationResult');
167+
el.innerHTML = getLoaderHTML();
168+
el.classList.remove('label');
169+
el.classList.remove('status-error');
170+
el.classList.remove('status-success');
171+
141172
Sfjs.request(
142173
form.action,
143174
function(xhr) {
144175
// Success
145-
document.getElementById('translationResult').innerHTML = xhr.responseText;
176+
el.classList.add('label');
177+
el.classList.add('status-success');
178+
el.innerHTML = xhr.responseText;
146179
},
147180
function(xhr) {
148181
// Error
149-
document.getElementById('translationResult').innerHTML = xhr.responseText;
182+
el.classList.add('label');
183+
el.classList.add('status-error');
184+
el.innerHTML = xhr.responseText;
150185
},
151186
serializeQueryString({selected: selected}),
152187
{ method: 'POST' }

Resources/views/SymfonyProfiler/translation.html.twig

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747

4848
<form action="{{ path('php_translation_profiler_translation_create_assets', {'token': token}) }}" method="post"
4949
id="translations-list" onSubmit="return saveTranslations(this);" >
50+
<span class="hidden">
51+
<img src="{{ asset("bundles/translation/css/images/loader.svg") }}" width="60" id="svg-loader">
52+
</span>
5053

5154
<div class="sf-tabs">
5255
<div class="tab">
@@ -101,27 +104,29 @@
101104
<p>There are no messages of this category.</p>
102105
</div>
103106
{% else %}
104-
{{ translation_helper.render_table(messages_missing) }}
107+
{{ translation_helper.render_table(messages_missing, true) }}
105108
{% endif %}
106109
</div>
107110
</div>
108111
</div>
109112

113+
<p class="full-width" id="translationResult"></p>
114+
110115
<button type="submit" class="btn">
111116
Send selected translations to SaaS
112117
</button>
113118

114-
<div id="translationResult"></div>
115-
116119
</form>
117120
{% include "@Translation/SymfonyProfiler/javascripts.html.twig" %}
118121
{% endblock %}
119122

120-
{% macro render_table(messages) %}
123+
{% macro render_table(messages, checkedByDefault = false) %}
121124
<table>
122125
<thead>
123126
<tr>
124-
<th></th>
127+
<th>
128+
<input type="checkbox" id="check-all-control" onchange="toggleCheckAll(this)" {% if checkedByDefault %}checked="checked"{% endif %}>
129+
</th>
125130
<th>Locale</th>
126131
<th>Domain</th>
127132
<th>Times used</th>
@@ -135,7 +140,7 @@
135140
<tr id="{{ key }}">
136141
<td>
137142
{% if message.state == constant('Symfony\\Component\\Translation\\DataCollectorTranslator::MESSAGE_MISSING') %}
138-
<input type="checkbox" name="translationKey" value="{{ key }}" checked="checked">
143+
<input type="checkbox" name="translationKey" value="{{ key }}" checked="checked" class="translation-key-checkbox">
139144
{% else %}
140145
<input type="checkbox" disabled="disabled">
141146
{% endif %}
@@ -161,7 +166,9 @@
161166
</div>
162167
{% endif %}
163168
</td>
164-
<td class="translation">{{ message.translation }}</td>
169+
<td class="translation">
170+
{{ message.translation }}
171+
</td>
165172
<td width="155px">
166173
{% spaceless %}
167174
<a class="edit" href="javascript:void(0);" onclick='getEditForm("{{ key }}")'>Edit</a>

0 commit comments

Comments
 (0)