Skip to content
Snippets Groups Projects
Commit bcdfe145 authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms
Browse files

always store the whole order of widgets, fixes #2821

Closes #2821

Merge request studip/studip!1902
parent f37775ce
No related branches found
No related tags found
No related merge requests found
...@@ -255,16 +255,17 @@ class StartController extends AuthenticatedController ...@@ -255,16 +255,17 @@ class StartController extends AuthenticatedController
/** /**
* Action to store the widget placements * Action to store the widget placements
*
* @return void
*/ */
public function storeNewOrder_action() public function storeNewOrder_action(): void
{ {
WidgetHelper::storeNewPositions( if (!Request::isPost()) {
Request::get('widget'), throw new MethodNotAllowedException();
Request::get('position'), }
Request::get('column')
); $lanes = Request::getArray('lanes');
WidgetHelper::storeNewPositions($lanes);
$this->render_nothing(); $this->render_nothing();
} }
......
...@@ -63,37 +63,48 @@ class WidgetHelper ...@@ -63,37 +63,48 @@ class WidgetHelper
/** /**
* storeNewPositions - stores new Widget positions for a given user * storeNewPositions - stores new Widget positions for a given user
* *
* @param array ids of widgets to be stored * @param array $lanes array with column as index and ids array as value
* *
* @return void * @return void
*/ */
public static function storeNewPositions($widget, $position, $column) public static function storeNewPositions(array $lanes): void
{ {
$db = DBManager::get(); // Query not displayed widgets to sort them to the bottom of a lane
$oldWidget = $db->fetchOne("SELECT position,col FROM widget_user WHERE id = ? AND range_id = ?", [$widget, $GLOBALS['user']->id]); $query = "SELECT `col`, `id`
if ($oldWidget) { FROM `widget_user`
WHERE `range_id` = ?
if ($oldWidget['col'] == $column) { AND `id` NOT IN (?)
// Insert element ORDER BY `col`, `position`";
$db->execute("UPDATE widget_user SET position = ? WHERE id = ? ", [$position, $widget]); $undisplayed = DBManager::get()->fetchGrouped($query, [
if ($oldWidget['position'] < $position) { User::findCurrent()->id,
//Move back items BETWEEN old and new position array_merge(...$lanes)
$db->execute("UPDATE widget_user SET position = position - 1 WHERE col = ? AND range_id = ? AND position > ? AND position <= ? AND id <> ?", [$oldWidget['col'], $GLOBALS['user']->id, $oldWidget['position'], $position, $widget]); ], function ($row) {
} else { return array_column($row, 'id');
//Move forward items BETWEEN old and new position });
$db->execute("UPDATE widget_user SET position = position + 1 WHERE col = ? AND range_id = ? AND position < ? AND position >= ? AND id <> ?", [$oldWidget['col'], $GLOBALS['user']->id, $oldWidget['position'], $position, $widget]);
} // Set new positions
} else { $query = "UPDATE `widget_user`
// Push all entries in the new column one position away SET `col` = :column,
$db->execute("UPDATE widget_user SET position = position + 1 WHERE range_id = ? AND col = ? AND position >= ?", [$GLOBALS['user']->id, $column, $position]); `position` = :position
WHERE `id` = :id
AND `range_id` = :user_id";
$statement = DBManager::get()->prepare($query);
$statement->bindValue(':user_id', User::findCurrent()->id);
// Insert element foreach ([0, 1] as $column) {
$db->execute("UPDATE widget_user SET position = ?, col = ? WHERE id = ? ", [$position, $column, $widget]); $statement->bindValue(':column', $column);
// Move positions in old column $ids = array_merge(
$db->execute("UPDATE widget_user SET position = position - 1 WHERE col = ? AND range_id = ? AND position > ?", [$oldWidget['col'], $GLOBALS['user']->id, $oldWidget['position']]); $lanes[$column] ?? [],
} $undisplayed[$column] ?? []
);
$position = 0;
foreach ($ids as $id) {
$statement->bindValue(':position', $position++);
$statement->bindValue(':id', $id);
$statement->execute();
}
} }
} }
......
const startpage = { const startpage = {
init: function() { init() {
$('.start-widgetcontainer .portal-widget-list').sortable({ $('.start-widgetcontainer .portal-widget-list').sortable({
handle: '.widget-header', handle: '.widget-header',
connectWith: 'ul.portal-widget-list', connectWith: 'ul.portal-widget-list',
start: function() { start() {
$(this) $(this)
.closest('.start-widgetcontainer') .closest('.start-widgetcontainer')
.find('.portal-widget-list') .find('.portal-widget-list')
.addClass('ui-sortable move'); .addClass('move');
}, },
stop: function(event, ui) { update(event, ui) {
$.get(STUDIP.ABSOLUTE_URI_STUDIP + 'dispatch.php/start/storeNewOrder', { let lanes = [];
widget: $(ui.item).attr('id'), $(this)
position: $(ui.item).index(), .closest('.start-widgetcontainer')
column: $(ui.item) .children('.portal-widget-list')
.parent() .each((index, element) => {
.index() lanes[index] = $('.studip-widget-wrapper', element)
}); .map((i, el) => el.getAttribute('id'))
.get(); // Ensure we have an array
});
$.post(
STUDIP.URLHelper.getURL('dispatch.php/start/storeNewOrder'),
{lanes}
);
},
stop() {
$(this) $(this)
.closest('.start-widgetcontainer') .closest('.start-widgetcontainer')
.find('.portal-widget-list') .find('.portal-widget-list')
...@@ -25,7 +34,7 @@ const startpage = { ...@@ -25,7 +34,7 @@ const startpage = {
}); });
}, },
init_edit: function(perm) { init_edit(perm) {
$('.edit-widgetcontainer .portal-widget-list').sortable({ $('.edit-widgetcontainer .portal-widget-list').sortable({
handle: '.widget-header', handle: '.widget-header',
connectWith: '.edit-widgetcontainer .portal-widget-list', connectWith: '.edit-widgetcontainer .portal-widget-list',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment