-
Notifications
You must be signed in to change notification settings - Fork 356
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
GOD's button group can have buttons assign/unassign during create/edit #4913
Changes from 20 commits
831bda5
2dce5ab
0879c47
41de4b1
d7475ec
e84e54a
be2cacb
99bef04
e88642a
1a15728
67628cf
b0f132a
e31ea87
5ac2c05
f5face0
e30e46c
9b0cf63
0955e0a
3f926f3
59fafce
0f8c328
03d6c5f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* globals move */ | ||
|
||
ManageIQ.angular.app.component('assignButtons', { | ||
bindings: { | ||
assignedButtons: '<', | ||
unassignedButtons: '<', | ||
updateButtons: '<', | ||
}, | ||
require: { | ||
parent: '^^mainCustomButtonGroupForm', | ||
}, | ||
controllerAs: 'vm', | ||
controller: assignButtonsController, | ||
templateUrl: '/static/generic_object/assign-buttons.html.haml', | ||
}); | ||
|
||
|
||
// move comes from app/javascript/helpers/move.js | ||
function assignButtonsController() { | ||
var vm = this; | ||
|
||
vm.model = { | ||
selectedAssignedButtons: [], | ||
selectedUnassignedButtons: [], | ||
}; | ||
|
||
vm.leftButtonClicked = function() { | ||
var ret = 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 = 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(move.top); | ||
vm.bottomButtonClicked = wrap(move.bottom); | ||
|
||
vm.upButtonClicked = wrap(move.up); | ||
vm.downButtonClicked = wrap(move.down); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,9 +9,9 @@ ManageIQ.angular.app.component('mainCustomButtonGroupForm', { | |
templateUrl: '/static/generic_object/main_custom_button_group_form.html.haml', | ||
}); | ||
|
||
mainCustomButtonGroupFormController.$inject = ['API', 'miqService']; | ||
mainCustomButtonGroupFormController.$inject = ['API', 'miqService', '$http']; | ||
|
||
function mainCustomButtonGroupFormController(API, miqService) { | ||
function mainCustomButtonGroupFormController(API, miqService, $http) { | ||
var vm = this; | ||
|
||
vm.$onInit = function() { | ||
|
@@ -26,20 +26,35 @@ function mainCustomButtonGroupFormController(API, miqService) { | |
button_icon: '', | ||
button_color: '#4d5258', | ||
set_data: {}, | ||
assigned_buttons: [], | ||
unassigned_buttons: [], | ||
}; | ||
|
||
if (vm.customButtonGroupRecordId) { | ||
vm.newRecord = false; | ||
miqService.sparkleOn(); | ||
API.get('/api/custom_button_sets/' + vm.customButtonGroupRecordId) | ||
.then(getCustomButtonGroupFormData) | ||
.catch(miqService.handleFailure); | ||
} else { | ||
vm.newRecord = true; | ||
$http.get('/generic_object_definition/custom_buttons_in_set/?custom_button_set_id=' + vm.customButtonGroupRecordId + '&generic_object_definition_id=' + vm.genericObjectDefnRecordId) | ||
.then(function(response) { | ||
Object.assign(vm.customButtonGroupModel, response.data); | ||
if (vm.customButtonGroupRecordId) { | ||
vm.newRecord = false; | ||
miqService.sparkleOn(); | ||
API.get('/api/custom_button_sets/' + vm.customButtonGroupRecordId) | ||
.then(getCustomButtonGroupFormData) | ||
.catch(miqService.handleFailure); | ||
} else { | ||
vm.newRecord = true; | ||
|
||
API.get('/api/custom_button_sets?expand=resources&attributes=set_data') | ||
.then(getCustomButtonSetGroupIndex) | ||
.catch(miqService.handleFailure); | ||
} | ||
}) | ||
.catch(miqService.handleFailure); | ||
}; | ||
|
||
vm.updateButtons = function(assignedButtons, unassignedButtons) { | ||
vm.customButtonGroupModel.assigned_buttons = assignedButtons; | ||
|
||
API.get('/api/custom_button_sets?expand=resources&attributes=set_data') | ||
.then(getCustomButtonSetGroupIndex) | ||
.catch(miqService.handleFailure); | ||
if (unassignedButtons) { | ||
vm.customButtonGroupModel.unassigned_buttons = unassignedButtons; | ||
} | ||
}; | ||
|
||
|
@@ -53,7 +68,7 @@ function mainCustomButtonGroupFormController(API, miqService) { | |
}; | ||
|
||
vm.resetClicked = function(angularForm) { | ||
vm.customButtonGroupModel = Object.assign({}, vm.modelCopy); | ||
vm.customButtonGroupModel = _.cloneDeep(vm.modelCopy); | ||
|
||
angularForm.$setUntouched(true); | ||
angularForm.$setPristine(true); | ||
|
@@ -71,11 +86,19 @@ function mainCustomButtonGroupFormController(API, miqService) { | |
vm.saveWithAPI('post', '/api/custom_button_sets/', vm.prepSaveObject(), saveMsg); | ||
}; | ||
|
||
vm.buttonOrder = function() { | ||
var orderedButtons = []; | ||
vm.customButtonGroupModel.assigned_buttons.forEach(function(button) { | ||
orderedButtons.push(button.id); | ||
}); | ||
return orderedButtons; | ||
}; | ||
|
||
vm.prepSaveObject = function() { | ||
vm.customButtonGroupModel.set_data = { | ||
button_icon: vm.customButtonGroupModel.button_icon, | ||
button_color: vm.customButtonGroupModel.button_color, | ||
button_order: vm.customButtonGroupModel.button_order, | ||
button_order: vm.buttonOrder(), | ||
display: vm.customButtonGroupModel.display, | ||
applies_to_class: 'GenericObjectDefinition', | ||
applies_to_id: parseInt(vm.genericObjectDefnRecordId, 10), | ||
|
@@ -94,7 +117,17 @@ function mainCustomButtonGroupFormController(API, miqService) { | |
vm.saveWithAPI = function(method, url, saveObject, saveMsg) { | ||
miqService.sparkleOn(); | ||
API[method](url, saveObject) | ||
.then(miqService.redirectBack.bind(vm, saveMsg, 'success', vm.redirectUrl)) | ||
// TODO remove once API supports adding/removing buttons from button set | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is done in ManageIQ/manageiq#18368 |
||
.then(function() { | ||
$http.post('/generic_object_definition/add_custom_buttons_in_set', { | ||
custom_button_set_id: vm.customButtonGroupRecordId, | ||
assigned_custom_buttons: vm.customButtonGroupModel.assigned_buttons, | ||
}) | ||
.then(function() { | ||
miqService.redirectBack(saveMsg, 'success', vm.redirectUrl); | ||
}) | ||
.catch(miqService.handleFailure); | ||
}) | ||
.catch(miqService.handleFailure); | ||
}; | ||
|
||
|
@@ -112,7 +145,8 @@ function mainCustomButtonGroupFormController(API, miqService) { | |
|
||
vm.customButtonGroupModel.set_data = {}; | ||
|
||
vm.modelCopy = Object.assign({}, vm.customButtonGroupModel); | ||
vm.modelCopy = _.cloneDeep(vm.customButtonGroupModel); | ||
|
||
vm.afterGet = true; | ||
miqService.sparkleOff(); | ||
} | ||
|
@@ -123,6 +157,6 @@ function mainCustomButtonGroupFormController(API, miqService) { | |
return setData.applies_to_class === 'GenericObject'; | ||
}).length; | ||
vm.customButtonGroupModel.group_index = currentGroupIndex + 1; | ||
vm.modelCopy = angular.copy( vm.customButtonGroupModel ); | ||
vm.modelCopy = _.cloneDeep(vm.customButtonGroupModel); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,6 +106,7 @@ def custom_button_group_edit | |
assert_privileges('ab_group_edit') | ||
@custom_button_group = CustomButtonSet.find(params[:id]) | ||
@right_cell_text = _("Edit Custom Button Group '%{name}'") % {:name => @custom_button_group.name} | ||
@generic_object_definition = GenericObjectDefinition.find(@custom_button_group.set_data[:applies_to_id]) | ||
render_form(@right_cell_text, 'custom_button_group_form') | ||
end | ||
|
||
|
@@ -148,6 +149,28 @@ def add_button_in_group | |
custom_button_set.save! | ||
end | ||
|
||
def add_custom_buttons_in_set | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (probably not needed - the API now does it too) |
||
custom_button_set = CustomButtonSet.find(params[:custom_button_set_id]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
custom_buttons = params[:assigned_custom_buttons].pluck(:id).map { |id| CustomButton.find_by(:id => id) } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
custom_button_set.replace_children(custom_buttons) | ||
custom_button_set.save! | ||
render :json => {:status => 200} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
end | ||
|
||
def custom_buttons_in_set | ||
assigned_buttons = if params[:custom_button_set_id].present? | ||
button_set = CustomButtonSet.find(params[:custom_button_set_id]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. find_record_with_rbac |
||
button_set.custom_buttons | ||
else | ||
[] | ||
end | ||
generic_object_definition = GenericObjectDefinition.find(params[:generic_object_definition_id]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rbac |
||
unassigned_buttons = generic_object_definition.custom_buttons | ||
assigned_buttons.map! { |button| {:name => button.name, :id => button.id} } | ||
unassigned_buttons.map! { |button| {:name => button.name, :id => button.id} } | ||
render :json => {:assigned_buttons => assigned_buttons, :unassigned_buttons => unassigned_buttons} | ||
end | ||
|
||
private | ||
|
||
def node_type(node) | ||
|
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; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no longer needed