summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/menu_items_controller.rb10
-rw-r--r--app/views/menu_items/index.html.erb49
-rw-r--r--config/locales/de.yml4
-rw-r--r--config/locales/en.yml4
-rw-r--r--config/routes.rb2
-rw-r--r--public/javascripts/admin_interface.js13
-rw-r--r--public/stylesheets/admin.css144
7 files changed, 196 insertions, 30 deletions
diff --git a/app/controllers/menu_items_controller.rb b/app/controllers/menu_items_controller.rb
index 48018800..f169e0ca 100644
--- a/app/controllers/menu_items_controller.rb
+++ b/app/controllers/menu_items_controller.rb
@@ -54,6 +54,16 @@ class MenuItemsController < ApplicationController
54 head :ok 54 head :ok
55 end 55 end
56 56
57 def move_up
58 MenuItem.find(params[:id]).move_higher
59 redirect_to menu_items_path
60 end
61
62 def move_down
63 MenuItem.find(params[:id]).move_lower
64 redirect_to menu_items_path
65 end
66
57 private 67 private
58 68
59 def menu_item_params 69 def menu_item_params
diff --git a/app/views/menu_items/index.html.erb b/app/views/menu_items/index.html.erb
index cdc60c63..0eacc34a 100644
--- a/app/views/menu_items/index.html.erb
+++ b/app/views/menu_items/index.html.erb
@@ -4,18 +4,55 @@
4 <%= icon("plus", library: "tabler", "aria-hidden": true) %> <%= t(".create_item") %> 4 <%= icon("plus", library: "tabler", "aria-hidden": true) %> <%= t(".create_item") %>
5<% end %> 5<% end %>
6 6
7<p class="field_hint"><%= t(".reorder_hint") %></p>
8
7<table id="menu_item_list"> 9<table id="menu_item_list">
8 <% @menu_items.each do |menu_item| %> 10 <% @menu_items.each do |menu_item| %>
9 <tr id="menu_items-<%= menu_item.id %>"> 11 <tr id="menu_items-<%= menu_item.id %>">
10 <td class="menu_sort_handle"> 12 <td class="menu_sort_handle">
11 <div></div> 13 <span class="menu_grip"><%= icon("grip-vertical", library: "tabler", "aria-hidden": true) %></span>
14
15 <%= button_to move_up_menu_item_path(menu_item), method: :post,
16 disabled: menu_item.first?,
17 form: { class: "button_to menu_move" },
18 "aria-label" => t(".move_up"), title: t(".move_up") do %>
19 <%= icon("chevron-up", library: "tabler", "aria-hidden": true) %>
20 <% end %>
21
22 <%= button_to move_down_menu_item_path(menu_item), method: :post,
23 disabled: menu_item.last?,
24 form: { class: "button_to menu_move" },
25 "aria-label" => t(".move_down"), title: t(".move_down") do %>
26 <%= icon("chevron-down", library: "tabler", "aria-hidden": true) %>
27 <% end %>
28 </td>
29 <td class="menu_item_title">
30 <%= menu_item.title %>
31 <% (I18n.available_locales - [:root, I18n.default_locale]).each do |locale| %>
32 <% translated = menu_item.translations.find_by(:locale => locale)&.title %>
33 <span class="menu_item_translation">
34 <span class="menu_item_translation_locale"><%= locale.to_s.upcase %></span>
35 <% if translated.present? %>
36 <%= translated %>
37 <% else %>
38 <span class="menu_item_translation_absent"><%= t(".falls_back") %></span>
39 <% end %>
40 </span>
41 <% end %>
42 </td>
43 <td class="menu_item_action">
44 <%= link_to edit_menu_item_path(menu_item),
45 "aria-label" => t("admin.common.edit"),
46 title: t("admin.common.edit") do %>
47 <%= icon("edit", library: "tabler", "aria-hidden": true) %>
48 <% end %>
12 </td> 49 </td>
13 <td class="menu_item_title"><%= menu_item.title %></td> 50 <td class="menu_item_action">
14 <td><%= link_to t("admin.common.edit"), edit_menu_item_path(menu_item) %></td>
15 <td>
16 <%= button_to menu_item_path(menu_item), method: :delete, 51 <%= button_to menu_item_path(menu_item), method: :delete,
17 form: { data: { confirm: t(".confirm_destroy") }, class: 'button_to destructive' } do %> 52 form: { data: { confirm: t(".confirm_destroy") }, class: 'button_to destructive' },
18 <%= icon("trash", library: "tabler", "aria-hidden": true) %> <%= t("admin.common.destroy") %> 53 "aria-label" => t("admin.common.destroy"),
54 title: t("admin.common.destroy") do %>
55 <%= icon("trash", library: "tabler", "aria-hidden": true) %>
19 <% end %> 56 <% end %>
20 </td> 57 </td>
21 </tr> 58 </tr>
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 647caf57..2d5e9685 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -669,6 +669,10 @@ de:
669 title: "Menüeinträge" 669 title: "Menüeinträge"
670 create_item: "Menüeintrag anlegen" 670 create_item: "Menüeintrag anlegen"
671 confirm_destroy: "Diesen Menüeintrag wirklich löschen?" 671 confirm_destroy: "Diesen Menüeintrag wirklich löschen?"
672 reorder_hint: "Die Einträge im Navi-Menü kann man draggen"
673 falls_back: "… Fallback auf deutsch"
674 move_up: "Nach oben"
675 move_down: "Nach unten"
672 new: 676 new:
673 title: "Menüeintrag hinzufügen" 677 title: "Menüeintrag hinzufügen"
674 edit: 678 edit:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 1b112e3d..da8282cf 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -481,6 +481,10 @@ en:
481 title: "Menu Items" 481 title: "Menu Items"
482 create_item: "Create menu item" 482 create_item: "Create menu item"
483 confirm_destroy: "Do you really want to destroy the menu entry?" 483 confirm_destroy: "Do you really want to destroy the menu entry?"
484 reorder_hint: "Drag the handles to change the order"
485 falls_back: "… falls back to German"
486 move_up: "Move up"
487 move_down: "Move down"
484 new: 488 new:
485 title: "Add Menu Item" 489 title: "Add Menu Item"
486 edit: 490 edit:
diff --git a/config/routes.rb b/config/routes.rb
index 9793c6a6..4b5d15c9 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -108,6 +108,8 @@ Cccms::Application.routes.draw do
108 resources :menu_items, :except => :show do 108 resources :menu_items, :except => :show do
109 member do 109 member do
110 post :sort 110 post :sort
111 post :move_up
112 post :move_down
111 end 113 end
112 end 114 end
113 115
diff --git a/public/javascripts/admin_interface.js b/public/javascripts/admin_interface.js
index ee0b34cd..d94fb623 100644
--- a/public/javascripts/admin_interface.js
+++ b/public/javascripts/admin_interface.js
@@ -386,9 +386,16 @@ menu_item_sorter = {
386 type: "POST", 386 type: "POST",
387 url: "/menu_items/0/sort", 387 url: "/menu_items/0/sort",
388 data: $(this).sortable("serialize"), 388 data: $(this).sortable("serialize"),
389 dataType: "json", 389 success : function() {
390 success : function(results) { 390 // The controller answers head :ok, so there is nothing to parse
391 alert(results); 391 // and dataType: "json" would send every success down the error
392 // path. Reload rather than patch the DOM: first?/last? decide the
393 // disabled chevrons server-side, and after a drag they describe
394 // the old order.
395 window.location.reload();
396 },
397 error : function() {
398 alert("Reihenfolge konnte nicht gespeichert werden.");
392 } 399 }
393 }); 400 });
394 } 401 }
diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css
index 49e2362b..1d39dd6c 100644
--- a/public/stylesheets/admin.css
+++ b/public/stylesheets/admin.css
@@ -9,7 +9,6 @@
9 --hairline: color-mix(in srgb, CanvasText, Canvas 91%); /* #e8e8e8 */ 9 --hairline: color-mix(in srgb, CanvasText, Canvas 91%); /* #e8e8e8 */
10 --hairline-faint: color-mix(in srgb, CanvasText, Canvas 94%); /* #f1f1f1 */ 10 --hairline-faint: color-mix(in srgb, CanvasText, Canvas 94%); /* #f1f1f1 */
11 --border: color-mix(in srgb, CanvasText, Canvas 87%); /* #ddd */ 11 --border: color-mix(in srgb, CanvasText, Canvas 87%); /* #ddd */
12 --frame-fill: color-mix(in srgb, CanvasText, Canvas 83%); /* lightgrey */
13 --field-border: color-mix(in srgb, CanvasText, Canvas 60%); /* #989898 */ 12 --field-border: color-mix(in srgb, CanvasText, Canvas 60%); /* #989898 */
14 --handle-fill: color-mix(in srgb, CanvasText, Canvas 60%); /* #989898 as fill */ 13 --handle-fill: color-mix(in srgb, CanvasText, Canvas 60%); /* #989898 as fill */
15 --link-underline: color-mix(in srgb, CanvasText, Canvas 69%); /* #b0b0b0 */ 14 --link-underline: color-mix(in srgb, CanvasText, Canvas 69%); /* #b0b0b0 */
@@ -1295,11 +1294,15 @@ input#menu_item_title {
1295 ============================================================ */ 1294 ============================================================ */
1296 1295
1297#menu_item_list { 1296#menu_item_list {
1298 border-collapse: collapse; 1297 border-collapse: separate;
1299 padding: 5px 5px 5px 5px; 1298 border-spacing: 0;
1300 border: solid 5px var(--frame-fill); 1299 width: 100%;
1301 background-color: var(--frame-fill); 1300 max-width: 44rem;
1302 border-radius: 5px; 1301
1302 border: 1px solid var(--hairline);
1303 border-radius: var(--radius);
1304
1305 padding: 0.5rem;
1303} 1306}
1304 1307
1305#menu_item_list tr:hover { 1308#menu_item_list tr:hover {
@@ -1307,33 +1310,132 @@ input#menu_item_title {
1307} 1310}
1308 1311
1309#menu_item_list td { 1312#menu_item_list td {
1310 height: 20px; 1313 padding: 0.4rem 0.5rem;
1314 border-bottom: 1px solid var(--hairline);
1315}
1316
1317#menu_item_list tr:last-child td {
1318 border-bottom: none;
1311} 1319}
1312 1320
1313#menu_item_list td.menu_item_title { 1321#menu_item_list td.menu_item_title {
1314 width: 200px; 1322 width: 100%;
1323}
1324
1325.menu_item_translation {
1326 display: block;
1327 font-size: 0.85rem;
1328 color: var(--text-muted);
1315} 1329}
1316 1330
1317#menu_item_list td.menu_sort_handle div { 1331.menu_item_translation_locale {
1318 background-color: var(--handle-fill); 1332 font-variant: all-small-caps;
1319 height: 26px; 1333 letter-spacing: 0.04em;
1320 width: 26px; 1334 margin-right: 0.35rem;
1321} 1335}
1322 1336
1323#menu_item_list td.menu_sort_handle div:before { 1337.menu_item_translation_absent {
1324 content: "⇳"; 1338 font-style: italic;
1325 font-size: 20px; 1339}
1326 font-weight: bold; 1340
1341#menu_item_list td.menu_item_action {
1342 width: 1px;
1343 white-space: nowrap;
1327 text-align: center; 1344 text-align: center;
1328 vertical-align: center;
1329} 1345}
1330 1346
1331#menu_item_list td.menu_sort_handle div:hover { 1347#menu_item_list td.menu_item_action a {
1332 cursor: grab; 1348 text-decoration: none;
1333} 1349}
1334 1350
1335.ui-state-highlight td { 1351#menu_item_list td.menu_item_action svg {
1336 height: 20px; 1352 width: 1.25rem;
1353 height: 1.25rem;
1354 vertical-align: middle;
1355}
1356
1357#menu_item_list td.menu_sort_handle {
1358 width: 1px;
1359 white-space: nowrap;
1360 color: var(--text-muted);
1361}
1362
1363/* jQuery UI sortable binds mouse events, so drag never works on touch.
1364 Below the desktop breakpoint the grip would advertise something that
1365 cannot happen, and the width is better spent on the chevrons. */
1366#menu_item_list .menu_grip {
1367 display: none;
1368}
1369
1370@media (min-width: 1016px) {
1371 #menu_item_list .menu_grip {
1372 display: inline-block;
1373 cursor: grab;
1374 vertical-align: middle;
1375 }
1376
1377 #menu_item_list td.menu_sort_handle:active .menu_grip {
1378 cursor: grabbing;
1379 }
1380}
1381
1382#menu_item_list form.menu_move {
1383 display: inline-block;
1384 margin: 0;
1385}
1386
1387#menu_item_list form.menu_move button[type="submit"] {
1388 padding: 0.15rem 0.2rem;
1389 border: 1px solid transparent;
1390 background-color: transparent;
1391 color: var(--text-muted);
1392 line-height: 1;
1393}
1394
1395#menu_item_list form.menu_move button[type="submit"]:hover {
1396 color: var(--text);
1397 background-color: var(--surface-tint);
1398}
1399
1400#menu_item_list form.menu_move button[type="submit"]:disabled {
1401 opacity: 0.35;
1402 cursor: default;
1403 background-color: transparent;
1404 color: var(--text-muted);
1405}
1406
1407#menu_item_list td.menu_sort_handle svg {
1408 width: 1.1rem;
1409 height: 1.1rem;
1410 vertical-align: middle;
1411}
1412
1413#menu_item_list td.menu_sort_handle:active {
1414 cursor: grabbing;
1415}
1416
1417#menu_item_list td.menu_sort_handle svg {
1418 width: 1.25rem;
1419 height: 1.25rem;
1420 vertical-align: middle;
1421}
1422
1423#menu_item_list tr.ui-state-highlight td {
1424 height: 2.5rem;
1425 background-color: var(--accent-surface);
1426 border: 1px dashed var(--accent);
1427}
1428
1429#menu_item_list form.button_to.destructive input[type="submit"],
1430#menu_item_list form.button_to.destructive button[type="submit"] {
1431 color: var(--danger);
1432 background-color: transparent;
1433}
1434
1435#menu_item_list form.button_to.destructive input[type="submit"]:hover,
1436#menu_item_list form.button_to.destructive button[type="submit"]:hover {
1437 color: var(--on-solid);
1438 background-color: var(--danger-solid);
1337} 1439}
1338 1440
1339/* ============================================================ 1441/* ============================================================