-
Notifications
You must be signed in to change notification settings - Fork 356
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4913 from ZitaNemeckova/god_buttons
GOD's button group can have buttons assign/unassign during create/edit
- Loading branch information
Showing
11 changed files
with
448 additions
and
19 deletions.
There are no files selected for viewing
59 changes: 59 additions & 0 deletions
59
app/assets/javascripts/components/generic_object/assign-buttons.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
ManageIQ.angular.app.component('assignButtons', { | ||
bindings: { | ||
assignedButtons: '<', | ||
unassignedButtons: '<', | ||
updateButtons: '<', | ||
}, | ||
require: { | ||
parent: '^^mainCustomButtonGroupForm', | ||
}, | ||
controllerAs: 'vm', | ||
controller: assignButtonsController, | ||
templateUrl: '/static/generic_object/assign-buttons.html.haml', | ||
}); | ||
|
||
function assignButtonsController() { | ||
var vm = this; | ||
|
||
vm.model = { | ||
selectedAssignedButtons: [], | ||
selectedUnassignedButtons: [], | ||
}; | ||
|
||
vm.leftButtonClicked = function() { | ||
var ret = ManageIQ.move.between({ | ||
from: [].concat(vm.assignedButtons), | ||
to: [].concat(vm.unassignedButtons), | ||
selected: vm.model.selectedAssignedButtons, | ||
}); | ||
|
||
vm.updateButtons(ret.from, ret.to); | ||
}; | ||
|
||
vm.rightButtonClicked = function() { | ||
var ret = ManageIQ.move.between({ | ||
from: [].concat(vm.unassignedButtons), | ||
to: [].concat(vm.assignedButtons), | ||
selected: vm.model.selectedUnassignedButtons, | ||
}); | ||
|
||
vm.updateButtons(ret.to, ret.from); | ||
}; | ||
|
||
function wrap(fn) { | ||
return function() { | ||
var assigned = fn({ | ||
array: [].concat(vm.assignedButtons), | ||
selected: vm.model.selectedAssignedButtons, | ||
}); | ||
|
||
vm.updateButtons(assigned); | ||
}; | ||
} | ||
|
||
vm.topButtonClicked = wrap(ManageIQ.move.top); | ||
vm.bottomButtonClicked = wrap(ManageIQ.move.bottom); | ||
|
||
vm.upButtonClicked = wrap(ManageIQ.move.up); | ||
vm.downButtonClicked = wrap(ManageIQ.move.down); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { find, findIndex, some, reject } from 'lodash'; | ||
|
||
// [{id: 123}], [123] => [0] | ||
function idsToElements(arr, ids) { | ||
return ids.map((id) => find(arr, { id })); | ||
} | ||
|
||
function idsToIndexes(arr, ids) { | ||
return ids.map((id) => findIndex(arr, { id })); | ||
} | ||
|
||
function removeElements(arr, elements) { | ||
return reject(arr, (elem) => some(elements, elem)); | ||
} | ||
|
||
function filterIndexes(indexes) { | ||
if (indexes[0] !== 0) { | ||
return indexes; | ||
} | ||
var previous = 0; | ||
var filteredIndexes = []; | ||
indexes.forEach(function(index) { | ||
if (index !== 0 && index - 1 !== previous) { | ||
filteredIndexes.push(index); | ||
} else { | ||
previous = index; | ||
} | ||
}); | ||
return filteredIndexes; | ||
} | ||
|
||
function filterReverseIndexes(indexes, endIndex) { | ||
if (indexes[0] !== endIndex) { | ||
return indexes; | ||
} | ||
var previous = endIndex; | ||
var filteredIndexes = []; | ||
indexes.forEach(function(index) { | ||
if (index !== endIndex && index + 1 !== previous) { | ||
filteredIndexes.push(index); | ||
} else { | ||
previous = index; | ||
} | ||
}); | ||
return filteredIndexes; | ||
} | ||
|
||
function stepUp(array, index) { | ||
if (index < 1) { | ||
return; | ||
} | ||
|
||
[array[index], array[index - 1]] = [array[index - 1], array[index]]; | ||
} | ||
|
||
function stepDown(array, index) { | ||
if ((index < 0) || (index >= array.length - 1)) { | ||
return; | ||
} | ||
|
||
[array[index], array[index + 1]] = [array[index + 1], array[index]]; | ||
} | ||
|
||
|
||
// move selected elements between two arrays | ||
export function between({from, to, selected}) { | ||
var moved = idsToElements(from, selected); | ||
|
||
return { | ||
from: removeElements(from, moved), | ||
to: to.concat(moved), | ||
}; | ||
} | ||
|
||
// move selected elements to the top of the array | ||
export function top({array, selected}) { | ||
var moved = idsToElements(array, selected); | ||
array = removeElements(array, moved); | ||
|
||
return moved.concat(array); | ||
} | ||
|
||
// move selected elements to the bottom of the array | ||
export function bottom({array, selected}) { | ||
var moved = idsToElements(array, selected); | ||
array = removeElements(array, moved); | ||
|
||
return array.concat(moved); | ||
} | ||
|
||
// move selected elements one position up | ||
export function up({array, selected}) { | ||
var indexes = idsToIndexes(array, selected); | ||
indexes = filterIndexes(indexes); | ||
|
||
indexes.forEach((index) => stepUp(array, index)); | ||
|
||
return array; | ||
} | ||
|
||
// move selected elements one position up | ||
export function down({array, selected}) { | ||
var indexes = idsToIndexes(array, selected).reverse(); | ||
indexes = filterReverseIndexes(indexes, array.length - 1); | ||
|
||
indexes.forEach((index) => stepDown(array, index)); | ||
|
||
return array; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
.form-horizontal | ||
%hr | ||
%h3 | ||
= _('Assign Buttons') | ||
#column_lists | ||
.col-md-5 | ||
= _('Unassigned:') | ||
%select.form-control{:name => 'unassigned_buttons', | ||
"ng-model" => "vm.model.selectedUnassignedButtons", | ||
"ng-options" => "item.id as item.name for item in vm.unassignedButtons", | ||
:multiple => true, | ||
:style => "overflow-x: scroll;", | ||
:size => 8, | ||
:id => "available_fields"} | ||
.col-md-1{:style => "padding: 10px"} | ||
.spacer | ||
.spacer | ||
%button.btn.btn-default.btn-block{:title => _("Move selected fields right"), | ||
"ng-click" => "vm.rightButtonClicked()"} | ||
%i.fa.fa-angle-right.fa-lg.hidden-xs.hidden-sm | ||
%i.fa.fa-lg.fa-angle-right.fa-rotate-90.hidden-md.hidden-lg | ||
%button.btn.btn-default.btn-block{:title => _("Move selected fields left"), | ||
"ng-click" => "vm.leftButtonClicked()"} | ||
%i.fa.fa-angle-left.fa-lg.hidden-xs.hidden-sm | ||
%i.fa.fa-lg.fa-angle-left.fa-rotate-90.hidden-md.hidden-lg | ||
.spacer | ||
.col-md-5 | ||
= _('Selected:') | ||
%select.form-control{:name => 'assigned_buttons', | ||
"ng-model" => "vm.model.selectedAssignedButtons", | ||
"ng-options" => "item.id as item.name for item in vm.assignedButtons", | ||
:multiple => true, | ||
:style => "overflow-x: scroll;", | ||
:size => 8, | ||
:id => "selected_fields"} | ||
.col-md-1{:style => "padding: 10px"} | ||
.spacer | ||
.spacer | ||
%button.btn.btn-default.btn-block{:title => _("Move selected fields to top"), | ||
"ng-enabled" => "vm.moveButtonsEnabled()", | ||
"ng-click" => "vm.topButtonClicked()"} | ||
%i.fa.fa-angle-double-up.fa-lg | ||
%button.btn.btn-default.btn-block{:title => _("Move selected fields up"), | ||
:enabled => "vm.moveButtonsEnabled()", | ||
"ng-click" => "vm.upButtonClicked()"} | ||
%i.fa.fa-angle-up.fa-lg | ||
%button.btn.btn-default.btn-block{:title => _("Move selected fields down"), | ||
"ng-enabled" => "vm.moveButtonsEnabled()", | ||
"ng-click" => "vm.downButtonClicked()"} | ||
%i.fa.fa-angle-down.fa-lg | ||
%button.btn.btn-default.btn-block{:title => _("Move selected fields to bottom"), | ||
"ng-enabled" => "vm.moveButtonsEnabled()", | ||
"ng-click" => "vm.bottomButtonClicked()"} | ||
%i.fa.fa-angle-double-down | ||
.spacer |
Oops, something went wrong.