Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow updates, sorting for new row #714

Merged
merged 10 commits into from May 11, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/ngrest/plugins/Sortable.php
Expand Up @@ -23,8 +23,9 @@ class Sortable extends Plugin
public function renderList($id, $ngModel)
{
return [
$this->createTag('i', 'keyboard_arrow_up', ['ng-init' => '$first ? changeOrder(\''.$this->name.'\', \'+\') : null', 'ng-click' => 'sortableUp($index, item, \''.$this->name.'\')', 'ng-class' => '{\'sortable-up-first\' : $first}', 'class' => 'material-icons btn btn-outline-secondary btn-symbol']),
$this->createTag('i', 'keyboard_arrow_down', ['ng-click' => 'sortableDown($index, item, \''.$this->name.'\')', 'ng-class' => '{\'sortable-up-last\' : $last}', 'class' => 'material-icons btn btn-outline-secondary btn-symbol'])
$this->createTag('i', 'keyboard_arrow_up', ['ng-init' => '$first ? changeOrder(\''.$this->name.'\', \'+\') : null', 'ng-click' => 'sortableUp($index, item, \''.$this->name.'\')', 'ng-class' => '{\'sortable-up-first\' : $first && pager.currentPage == 1}', 'class' => 'material-icons btn btn-outline-secondary btn-symbol']),
$this->createTag('i', 'keyboard_arrow_down', ['ng-click' => 'sortableDown($index, item, \''.$this->name.'\')', 'ng-class' => '{\'sortable-up-last\' : $last && pager.currentPage == pager.pageCount}', 'class' => 'material-icons btn btn-outline-secondary btn-symbol']),
$this->createTag('span', '{{'.$ngModel.'}}', ['class' => 'badge badge-light'])
];
}

Expand All @@ -33,7 +34,7 @@ public function renderList($id, $ngModel)
*/
public function renderCreate($id, $ngModel)
{
return $this->createFormTag('zaa-number', $id, $ngModel);
return $this->createFormTag('zaa-number', $id, $ngModel, ['min' => 1]);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/resources/dist/main.js

Large diffs are not rendered by default.

25 changes: 16 additions & 9 deletions src/resources/js/controllers.js
Expand Up @@ -569,29 +569,36 @@
/**** SORTABLE PLUGIN ****/

$scope.sortableUp = function(index, row, fieldName) {
var switchWith = $scope.data.listArray[index-1];
$scope.data.listArray[index-1] = row;
$scope.data.listArray[index] = switchWith;
$scope.updateSortableIndexPositions(fieldName);
var newPost = parseInt(row[fieldName]) - 1
$scope.updateSortableIndexPosition(row, fieldName, newPost);
};

$scope.sortableDown = function(index, row, fieldName) {
var switchWith = $scope.data.listArray[index+1];
$scope.data.listArray[index+1] = row;
$scope.data.listArray[index] = switchWith;
$scope.updateSortableIndexPositions(fieldName);
var newPost = parseInt(row[fieldName]) + 1
$scope.updateSortableIndexPosition(row, fieldName, newPost);
};

$scope.updateSortableIndexPosition = function(row, fieldName, newPosition) {
var json = {};
json[fieldName] = newPosition;
var pk = $scope.getRowPrimaryValue(row);
$http.put($scope.config.apiEndpoint + '/' + pk +'?ngrestCallType=update&fields='+fieldName, angular.toJson(json, true)).then(() => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar blocks of code found in 2 locations. Consider refactoring.

$scope.loadList();
})
};

/*
$scope.updateSortableIndexPositions = function(fieldName) {
angular.forEach($scope.data.listArray, function(value, key) {
var json = {};
json[fieldName] = key;
var pk = $scope.getRowPrimaryValue(value);
$http.put($scope.config.apiEndpoint + '/' + pk +'?ngrestCallType=update&fields='+fieldName, angular.toJson(json, true), {
ignoreLoadingBar: true
ignoreLoadingBar: true
});
});
};
*/

/***** LIST LOADERS ********/

Expand Down
5 changes: 3 additions & 2 deletions src/resources/js/formdirectives.js
Expand Up @@ -737,7 +737,8 @@ zaa.directive("zaaNumber", function () {
"i18n": "@",
"id": "@fieldid",
"placeholder": "@",
"initvalue": "@"
"initvalue": "@",
"min": "@"
},
template: function () {
return '' +
Expand All @@ -746,7 +747,7 @@ zaa.directive("zaaNumber", function () {
'<label for="{{id}}">{{label}}</label>' +
'</div>' +
'<div class="form-side">' +
'<luya-number ng-model="model" fieldid="{{id}}" min="0" placeholder="{{placeholder}}" initvalue="{{initvalue}}"></luya-number>' +
'<luya-number ng-model="model" fieldid="{{id}}" min="{{min}}" placeholder="{{placeholder}}" initvalue="{{initvalue}}"></luya-number>' +
'</div>' +
'</div>';
}
Expand Down
84 changes: 84 additions & 0 deletions src/traits/SortableTrait.php
Expand Up @@ -2,6 +2,10 @@

namespace luya\admin\traits;

use luya\admin\ngrest\base\NgRestModel;
use Yii;
use yii\db\AfterSaveEvent;

/**
* Sortable Trait provides orderBy clause.
*
Expand All @@ -23,6 +27,86 @@
*/
trait SortableTrait
{
public function init()
{
parent::init();
$this->on(NgRestModel::EVENT_AFTER_INSERT, [$this, 'swapIndex']);
$this->on(NgRestModel::EVENT_AFTER_UPDATE, [$this, 'swapIndex']);
}

public function swapIndex(AfterSaveEvent $event)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method swapIndex has 55 lines of code (exceeds 25 allowed). Consider refactoring.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function swapIndex has a Cognitive Complexity of 28 (exceeds 5 allowed). Consider refactoring.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method swapIndex has 65 lines of code (exceeds 25 allowed). Consider refactoring.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function swapIndex has a Cognitive Complexity of 30 (exceeds 5 allowed). Consider refactoring.

{
$attributeName = self::sortableField();
$oldPosition = array_key_exists($attributeName, $event->changedAttributes) ? $event->changedAttributes[$attributeName] : false;
$newPosition = $event->sender[$attributeName];

// nothing has changed, skip further updates
if ($oldPosition == $newPosition) {
return;
}

$pkName = current($event->sender->primaryKey());

if (!$oldPosition && empty($newPosition)) {
Yii::debug('set max value for new record', __METHOD__);
// no index has been set, set max value (last position)
$event->sender->updateAttributes([$attributeName => $event->sender::find()->max($attributeName) + 1]);
} else if ($oldPosition && $newPosition && $oldPosition != $newPosition) {
if ($newPosition > $oldPosition) {
// wenn neue position grösser als alte position: = (alte position – 1)+ *1
// find alle einträge
$q = $event->sender->find()->andWhere([
'and',
['!=', $pkName, $event->sender->primaryKey],
['>', $attributeName, $oldPosition],
['<=', $attributeName, $newPosition]
])->all();

$i = 1;
foreach ($q as $item) {
$item->updateAttributes([$attributeName => ($oldPosition - 1) + $i]);
$i++;
}
} else {
// wenn neue position kleiner als alte position = (neue position + *1)
$q = $event->sender->find()->andWhere([
'and',
['!=', $pkName, $event->sender->primaryKey],
['>=', $attributeName, $newPosition],
['<', $attributeName, $oldPosition]
])->all();

$i = 1;
foreach ($q as $item) {
$item->updateAttributes([$attributeName => $newPosition + $i]);
$i++;
}
}
} else if (!empty($newPosition) && empty($oldPosition)) {
Yii::debug('new record with user input, move all other indexes', __METHOD__);
// its a new record where the user entered a position, lets move all the other higher indexes
$q = $event->sender->find()->andWhere([
'and',
['!=', $pkName, $event->sender->primaryKey],
['>=', $attributeName, $newPosition],
])->all();

$i = 1;
foreach ($q as $item) {
$item->updateAttributes([$attributeName => $newPosition + $i]);
$i++;
}
}

$q = $event->sender->find()->asArray()->all();

$i = 1;
foreach ($q as $item) {
$event->sender->updateAll([$attributeName => $i], [$pkName => $item[$pkName]]);
$i++;
}
}

/**
* The field which should by used to sort.
*
Expand Down