-
-
Notifications
You must be signed in to change notification settings - Fork 287
feature: add bulk update #3695
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
Open
Nevelito
wants to merge
65
commits into
avo-hq:main
Choose a base branch
from
Nevelito:add_bulk_update
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
feature: add bulk update #3695
Changes from all commits
Commits
Show all changes
65 commits
Select commit
Hold shift + click to select a range
0185150
WIP
Nevelito 633f97d
implement bulk update
Nevelito 83e2247
Merge branch 'main' into add_bulk_update
Nevelito 0f85794
optymalize code
Nevelito fa8c558
fix standardeb errors
Nevelito 7a67ccd
rubocop changes in bulk update
Nevelito 7d35c46
fix next rubocop errors
Nevelito ade1422
small changes with rubocop and locales
Nevelito a2be7fb
small changes
Nevelito 0278fca
codeclimate fix
Nevelito 750dd25
fix codeclimate bugs
Nevelito ec17628
fix bugs
Nevelito 3d3b87d
fix errors
Nevelito 669edce
fix standardrb errors
Nevelito 154b062
add locales
Nevelito fd56fe0
normilize locales
Nevelito 182c522
changes locales, add specs, optymalize code
Nevelito c8f635a
fix bugs
Nevelito b7f529b
fix bugs
Nevelito aaa324e
fix bulk update controller
Nevelito 095bacd
Merge branch 'main' into add_bulk_update
Nevelito 4166a5f
Merge branch 'main' into add_bulk_update
Nevelito 859296e
fix complexity
Nevelito d8213a8
fix too many returns
Nevelito 9a74b8a
new idea changing back path def
Nevelito 0fa296b
change case to if conditions
Nevelito 94bfe9a
fix bugs
Nevelito 8321f59
change complexity od function
Nevelito 40af2d8
Merge branch 'main' into add_bulk_update
Nevelito 1764142
fix bugs
Nevelito 9ae1366
request changes
Nevelito f40706d
fix bulg upade select field issue
Nevelito 2146fbd
route bulk update as put instead post
Paul-Bob b0ea750
rm unused method
Paul-Bob c675317
Merge branch 'main' into add_bulk_update
Paul-Bob 04fae6b
Request changes
Nevelito 4739bec
Update app/components/avo/views/resource_index_component.rb
Paul-Bob 19eb3fb
delete unnecessary code
Nevelito d6faf95
Merge branch 'main' into add_bulk_update
Nevelito 6710069
optymalize code
Nevelito 8686622
optymalize code
Nevelito 589cf6d
fix codeclimate error
Nevelito a9fd0e7
fix errors
Nevelito fb8ec92
changes js controller
Nevelito 69fda6a
Merge branch 'main' into add_bulk_update
Nevelito 017946a
fix spec
Nevelito 385552c
fix
Nevelito 657c5ca
tweaks
Paul-Bob 9553272
add button in correct way
Nevelito 42f5da7
set bulk update button hidden at start
Nevelito f9d828e
fix issue with correct updating
Nevelito d203f7b
fix rubocop errors
Nevelito 88fa6ed
fix codeclimate and rubocop
Nevelito d4a0715
Merge branch 'main' into add_bulk_update
Nevelito 8c9a874
fix bulk update spec
Nevelito 58e9b38
fix rubocop issues
Nevelito 977d046
small change
Nevelito 9d7ef48
fix bugs
Nevelito 495b762
fix bugs
Nevelito e6f1feb
Merge branch 'main' into add_bulk_update
Paul-Bob 65a1524
tweak bulk edit button
Paul-Bob c87da90
request changes
Nevelito 6deb60d
tweak
Nevelito 39070f8
Merge branch 'main' into add_bulk_update
Nevelito d09bbb7
add locales
Nevelito File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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,80 @@ | ||
module Avo | ||
class BulkUpdateController < ResourcesController | ||
before_action :set_query, only: [:edit, :handle] | ||
|
||
def edit | ||
@resource.hydrate(record: @resource.model_class.new(bulk_values)) | ||
|
||
set_component_for :bulk_edit, fallback_view: :edit | ||
end | ||
|
||
def handle | ||
saved = save_records | ||
|
||
if saved | ||
flash[:notice] = t("avo.bulk_update_success") | ||
else | ||
flash[:error] = t("avo.bulk_update_failure") | ||
end | ||
|
||
redirect_to after_bulk_update_path | ||
end | ||
|
||
private | ||
|
||
def update_records | ||
Nevelito marked this conversation as resolved.
Show resolved
Hide resolved
|
||
params_to_apply = params[@resource_name.downcase.to_sym].compact_blank || {} | ||
|
||
@query.each do |record| | ||
@resource.fill_record(record, params_to_apply) | ||
end | ||
end | ||
|
||
def save_records | ||
update_records | ||
|
||
all_saved = true | ||
|
||
ActiveRecord::Base.transaction do | ||
@query.each do |record| | ||
@record = record | ||
save_record | ||
end | ||
rescue ActiveRecord::RecordInvalid => e | ||
all_saved = false | ||
puts "Failed to save #{record.id}: #{e.message}" | ||
raise ActiveRecord::Rollback | ||
end | ||
|
||
all_saved | ||
end | ||
|
||
# This method returns a hash of the attributes of the model and their values | ||
# If all the records have the same value for an attribute, the value is assigned to the attribute, otherwise nil is assigned | ||
def bulk_values | ||
@resource.model_class.attribute_names.map do |attribute_key| | ||
values = @query.map { _1.public_send(attribute_key) }.uniq | ||
value_to_assign = (values.size == 1) ? values.first : nil | ||
|
||
[attribute_key, value_to_assign] | ||
end.to_h | ||
end | ||
|
||
def set_query | ||
Nevelito marked this conversation as resolved.
Show resolved
Hide resolved
|
||
resource_ids = params[:fields]&.dig(:avo_resource_ids)&.split(",") || [] | ||
@query = decrypted_query || (resource_ids.any? ? @resource.find_record(resource_ids, params: params) : []) | ||
end | ||
|
||
def decrypted_query | ||
encrypted_query = params[:fields]&.dig(:avo_selected_query) || params[:query] | ||
|
||
return if encrypted_query.blank? | ||
|
||
Avo::Services::EncryptionService.decrypt(message: encrypted_query, purpose: :select_all, serializer: Marshal) | ||
end | ||
|
||
def after_bulk_update_path | ||
resources_path(resource: @resource) | ||
end | ||
end | ||
end |
This file contains hidden or 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 hidden or 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 |
---|---|---|
|
@@ -19,6 +19,7 @@ export default class extends Controller { | |
this.resourceName = this.element.dataset.resourceName | ||
this.selectedResourcesObserver = new AttributeObserver(this.element, 'data-selected-resources', this) | ||
this.selectedResourcesObserver.start() | ||
this.updateBulkEditLinkVisibility() | ||
} | ||
|
||
elementAttributeValueChanged(element) { | ||
|
@@ -39,6 +40,7 @@ export default class extends Controller { | |
// If some are selected, mark the checkbox as indeterminate. | ||
this.checkboxTarget.indeterminate = true | ||
} | ||
this.updateBulkEditLinkVisibility() | ||
} | ||
|
||
disconnect() { | ||
|
@@ -71,6 +73,7 @@ export default class extends Controller { | |
} | ||
|
||
this.updateLinks('resourceIds') | ||
this.updateBulkEditLink('resourceIds') | ||
} | ||
|
||
selectAll(event) { | ||
|
@@ -88,32 +91,67 @@ export default class extends Controller { | |
} | ||
|
||
updateLinks(param) { | ||
const actionButtons = document.querySelectorAll(`a[data-actions-picker-target][data-resource-name="${this.resourceName}"]`) | ||
actionButtons.forEach((link) => { | ||
try { | ||
const url = new URL(link.href) | ||
|
||
Array.from(url.searchParams.keys()) | ||
.filter((key) => key.startsWith('fields[')) | ||
.forEach((key) => url.searchParams.delete(key)) | ||
|
||
if (param === 'resourceIds') { | ||
const resourceIds = JSON.parse(this.element.dataset.selectedResources).join(',') | ||
url.searchParams.set('fields[avo_resource_ids]', resourceIds) | ||
url.searchParams.set('fields[avo_selected_all]', 'false') | ||
} else if (param === 'selectedQuery') { | ||
const selectedQuery = this.element.dataset.itemSelectAllSelectedAllQueryValue | ||
url.searchParams.set('fields[avo_index_query]', selectedQuery) | ||
url.searchParams.set('fields[avo_selected_all]', 'true') | ||
} | ||
this.updateActionLinks(param, '[data-target="actions-list"] > a') | ||
} | ||
|
||
updateBulkEditLink(param) { | ||
this.updateActionLinks(param, 'a[href*="/admin/bulk_update/edit"]') | ||
this.updateBulkEditLinkVisibility() | ||
} | ||
|
||
updateActionLinks(param, selector) { | ||
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. Function |
||
const selectedResourcesArray = JSON.parse(this.element.dataset.selectedResources) | ||
const selectedResources = selectedResourcesArray.join(',') | ||
const selectedQuery = this.element.dataset.itemSelectAllSelectedAllQueryValue | ||
|
||
document.querySelectorAll(selector).forEach((link) => { | ||
try { | ||
const url = this.buildUpdatedUrl(link, param, selectedResources, selectedQuery) | ||
link.href = url.toString() | ||
} catch (error) { | ||
console.error('Error updating link:', link, error) | ||
} | ||
}) | ||
} | ||
|
||
buildUpdatedUrl(link, param, selectedResources, selectedQuery) { | ||
const url = new URL(link.href) | ||
|
||
// Remove old field parameters | ||
Array.from(url.searchParams.keys()) | ||
.filter((key) => key.startsWith('fields[')) | ||
.forEach((key) => url.searchParams.delete(key)) | ||
|
||
const isBulkUpdate = url.pathname.includes('/admin/bulk_update/edit') | ||
const resourceIdsKey = 'fields[avo_resource_ids]' | ||
const selectedQueryKey = isBulkUpdate ? 'fields[avo_selected_query]' : 'fields[avo_index_query]' | ||
const selectedAllKey = 'fields[avo_selected_all]' | ||
|
||
if (param === 'resourceIds') { | ||
Nevelito marked this conversation as resolved.
Show resolved
Hide resolved
|
||
url.searchParams.set(resourceIdsKey, selectedResources) | ||
url.searchParams.set(selectedAllKey, 'false') | ||
} else if (param === 'selectedQuery') { | ||
url.searchParams.set(selectedQueryKey, selectedQuery) | ||
url.searchParams.set(selectedAllKey, 'true') | ||
} | ||
|
||
return url | ||
} | ||
|
||
updateBulkEditLinkVisibility() { | ||
const bulkUpdateLink = document.querySelector('a[href*="/admin/bulk_update/edit"]') | ||
if (!bulkUpdateLink) return | ||
|
||
const selectedResourcesArray = JSON.parse(this.element.dataset.selectedResources) | ||
const resourceCount = selectedResourcesArray.length | ||
|
||
if (resourceCount >= 2) { | ||
bulkUpdateLink.classList.remove('hidden') | ||
} else { | ||
bulkUpdateLink.classList.add('hidden') | ||
} | ||
} | ||
|
||
resetUnselected() { | ||
this.selectedAllValue = false | ||
this.unselectedMessageTarget.classList.remove('hidden') | ||
|
This file contains hidden or 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 hidden or 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 hidden or 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,16 @@ | ||
module Avo | ||
module Resources | ||
module Controls | ||
class BulkEditButton < BaseControl | ||
def initialize(**args) | ||
super(**args) | ||
|
||
@label = args[:label] || I18n.t("avo.bulk_edit").capitalize | ||
@icon = args[:icon] || "avo/edit" | ||
@style = args[:style] || :primary | ||
@color = args[:color] || :primary | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.