Skip to content
Open
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
0185150
WIP
Nevelito Feb 26, 2025
633f97d
implement bulk update
Nevelito Mar 4, 2025
83e2247
Merge branch 'main' into add_bulk_update
Nevelito Mar 4, 2025
0f85794
optymalize code
Nevelito Mar 5, 2025
fa8c558
fix standardeb errors
Nevelito Mar 10, 2025
7a67ccd
rubocop changes in bulk update
Nevelito Mar 10, 2025
7d35c46
fix next rubocop errors
Nevelito Mar 10, 2025
ade1422
small changes with rubocop and locales
Nevelito Mar 10, 2025
a2be7fb
small changes
Nevelito Mar 10, 2025
0278fca
codeclimate fix
Nevelito Mar 10, 2025
750dd25
fix codeclimate bugs
Nevelito Mar 11, 2025
ec17628
fix bugs
Nevelito Mar 11, 2025
3d3b87d
fix errors
Nevelito Mar 11, 2025
669edce
fix standardrb errors
Nevelito Mar 11, 2025
154b062
add locales
Nevelito Mar 11, 2025
fd56fe0
normilize locales
Nevelito Mar 11, 2025
182c522
changes locales, add specs, optymalize code
Nevelito Mar 12, 2025
c8f635a
fix bugs
Nevelito Mar 12, 2025
b7f529b
fix bugs
Nevelito Mar 12, 2025
aaa324e
fix bulk update controller
Nevelito Mar 12, 2025
095bacd
Merge branch 'main' into add_bulk_update
Nevelito Apr 28, 2025
4166a5f
Merge branch 'main' into add_bulk_update
Nevelito Apr 28, 2025
859296e
fix complexity
Nevelito Apr 28, 2025
d8213a8
fix too many returns
Nevelito Apr 28, 2025
9a74b8a
new idea changing back path def
Nevelito Apr 28, 2025
0fa296b
change case to if conditions
Nevelito Apr 28, 2025
94bfe9a
fix bugs
Nevelito Apr 28, 2025
8321f59
change complexity od function
Nevelito Apr 29, 2025
40af2d8
Merge branch 'main' into add_bulk_update
Nevelito Apr 29, 2025
1764142
fix bugs
Nevelito Apr 29, 2025
9ae1366
request changes
Nevelito Apr 30, 2025
f40706d
fix bulg upade select field issue
Nevelito May 5, 2025
2146fbd
route bulk update as put instead post
Paul-Bob May 6, 2025
b0ea750
rm unused method
Paul-Bob May 6, 2025
c675317
Merge branch 'main' into add_bulk_update
Paul-Bob May 6, 2025
04fae6b
Request changes
Nevelito May 6, 2025
4739bec
Update app/components/avo/views/resource_index_component.rb
Paul-Bob May 7, 2025
19eb3fb
delete unnecessary code
Nevelito May 12, 2025
d6faf95
Merge branch 'main' into add_bulk_update
Nevelito May 16, 2025
6710069
optymalize code
Nevelito May 16, 2025
8686622
optymalize code
Nevelito May 16, 2025
589cf6d
fix codeclimate error
Nevelito May 16, 2025
a9fd0e7
fix errors
Nevelito May 16, 2025
fb8ec92
changes js controller
Nevelito May 21, 2025
69fda6a
Merge branch 'main' into add_bulk_update
Nevelito May 21, 2025
017946a
fix spec
Nevelito May 21, 2025
385552c
fix
Nevelito May 21, 2025
657c5ca
tweaks
Paul-Bob May 22, 2025
9553272
add button in correct way
Nevelito Jun 3, 2025
42f5da7
set bulk update button hidden at start
Nevelito Jun 3, 2025
f9d828e
fix issue with correct updating
Nevelito Jun 16, 2025
d203f7b
fix rubocop errors
Nevelito Jun 16, 2025
88fa6ed
fix codeclimate and rubocop
Nevelito Jun 16, 2025
d4a0715
Merge branch 'main' into add_bulk_update
Nevelito Jun 16, 2025
8c9a874
fix bulk update spec
Nevelito Jun 16, 2025
58e9b38
fix rubocop issues
Nevelito Jun 16, 2025
977d046
small change
Nevelito Jun 16, 2025
9d7ef48
fix bugs
Nevelito Jun 16, 2025
495b762
fix bugs
Nevelito Jun 16, 2025
e6f1feb
Merge branch 'main' into add_bulk_update
Paul-Bob Jun 17, 2025
65a1524
tweak bulk edit button
Paul-Bob Jun 17, 2025
c87da90
request changes
Nevelito Jun 17, 2025
6deb60d
tweak
Nevelito Jun 17, 2025
39070f8
Merge branch 'main' into add_bulk_update
Nevelito Jun 30, 2025
d09bbb7
add locales
Nevelito Jun 30, 2025
d3026a8
Merge branch 'main' into add_bulk_update
Paul-Bob Aug 13, 2025
a1b4323
Merge branch 'main' into add_bulk_update
Paul-Bob Sep 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<%= field_wrapper(**field_wrapper_args) do %>
<%= @form.select @field.id, options_for_select(@field.options_for_select, selected: @field.value), {
include_blank: @field.include_blank
include_blank: (params[:controller] == "avo/bulk_update") || @field.include_blank
},
multiple: @field.multiple,
aria: {
Expand Down
11 changes: 11 additions & 0 deletions app/components/avo/resource_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,17 @@
end
end

def render_bulk_edit_button(control)
a_link bulk_edit_path,
style: :primary,

Check failure on line 151 in app/components/avo/resource_component.rb

View workflow job for this annotation

GitHub Actions / lint / runner / standardrb

[rubocop] reported by reviewdog 🐶 [Corrected] Layout/ArgumentAlignment: Use one level of indentation for arguments following the first line of a multi-line method call. Raw Output: app/components/avo/resource_component.rb:151:12: C: [Corrected] Layout/ArgumentAlignment: Use one level of indentation for arguments following the first line of a multi-line method call. style: :primary, ^^^^^^^^^^^^^^^
color: :primary,

Check failure on line 152 in app/components/avo/resource_component.rb

View workflow job for this annotation

GitHub Actions / lint / runner / standardrb

[rubocop] reported by reviewdog 🐶 [Corrected] Layout/ArgumentAlignment: Use one level of indentation for arguments following the first line of a multi-line method call. Raw Output: app/components/avo/resource_component.rb:152:12: C: [Corrected] Layout/ArgumentAlignment: Use one level of indentation for arguments following the first line of a multi-line method call. color: :primary, ^^^^^^^^^^^^^^^
icon: "avo/edit",

Check failure on line 153 in app/components/avo/resource_component.rb

View workflow job for this annotation

GitHub Actions / lint / runner / standardrb

[rubocop] reported by reviewdog 🐶 [Corrected] Layout/ArgumentAlignment: Use one level of indentation for arguments following the first line of a multi-line method call. Raw Output: app/components/avo/resource_component.rb:153:12: C: [Corrected] Layout/ArgumentAlignment: Use one level of indentation for arguments following the first line of a multi-line method call. icon: "avo/edit", ^^^^^^^^^^^^^^^^
class: "hidden",

Check failure on line 154 in app/components/avo/resource_component.rb

View workflow job for this annotation

GitHub Actions / lint / runner / standardrb

[rubocop] reported by reviewdog 🐶 [Corrected] Layout/ArgumentAlignment: Use one level of indentation for arguments following the first line of a multi-line method call. Raw Output: app/components/avo/resource_component.rb:154:12: C: [Corrected] Layout/ArgumentAlignment: Use one level of indentation for arguments following the first line of a multi-line method call. class: "hidden", ^^^^^^^^^^^^^^^
form_class: "flex flex-col sm:flex-row sm:inline-flex" do

Check failure on line 155 in app/components/avo/resource_component.rb

View workflow job for this annotation

GitHub Actions / lint / runner / standardrb

[rubocop] reported by reviewdog 🐶 [Corrected] Layout/ArgumentAlignment: Use one level of indentation for arguments following the first line of a multi-line method call. Raw Output: app/components/avo/resource_component.rb:155:12: C: [Corrected] Layout/ArgumentAlignment: Use one level of indentation for arguments following the first line of a multi-line method call. form_class: "flex flex-col sm:flex-row sm:inline-flex" do ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
control.label
end
end

def render_actions_list(actions_list)
return unless can_see_the_actions_button?

Expand Down
5 changes: 4 additions & 1 deletion app/components/avo/views/resource_edit_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
prop :actions, default: [].freeze
prop :view, default: Avo::ViewInquirer.new(:edit).freeze
prop :display_breadcrumbs, default: true, reader: :public
prop :query

def after_initialize
@display_breadcrumbs = @reflection.blank? && display_breadcrumbs
Expand Down Expand Up @@ -77,7 +78,9 @@ def form_method
end

def form_url
if is_edit?
if params[:controller] == "avo/bulk_update"
helpers.handle_bulk_update_path(resource_name: @resource.name, query: @query)
elsif is_edit?
helpers.resource_path(
record: @resource.record,
resource: @resource
Expand Down
14 changes: 14 additions & 0 deletions app/components/avo/views/resource_index_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ def title
end
end

def bulk_edit_path
# Add the `view` param to let Avo know where to redirect back when the user clicks the `Cancel` button.
args = {via_view: "index"}

if @parent_record.present?
args = {
via_resource_class: @parent_resource.class.to_s,
via_record_id: @parent_record.to_param
}
end

helpers.edit_bulk_update_path(resource_name: @resource.name, **args)
end

# The Create button is dependent on the new? policy method.
# The create? should be called only when the user clicks the Save button so the developers gets access to the params from the form.
def can_see_the_create_button?
Expand Down
20 changes: 15 additions & 5 deletions app/controllers/avo/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class BaseController < ApplicationController
before_action :set_resource_name
before_action :set_resource
before_action :set_applied_filters, only: :index
before_action :set_record, only: [:show, :edit, :destroy, :update, :preview]
before_action :set_record, only: [:show, :edit, :destroy, :update, :preview], if: -> { controller_name != "bulk_update" }
before_action :set_record_to_fill, only: [:new, :edit, :create, :update]
before_action :detect_fields
before_action :set_edit_title_and_breadcrumbs, only: [:edit, :update]
Expand Down Expand Up @@ -406,8 +406,10 @@ def filters_to_be_applied
end

def set_edit_title_and_breadcrumbs
@resource = @resource.hydrate(record: @record, view: Avo::ViewInquirer.new(:edit), user: _current_user)
@page_title = @resource.default_panel_name.to_s
if params[:controller] != "avo/bulk_update"
@resource = @resource.hydrate(record: @record, view: Avo::ViewInquirer.new(:edit), user: _current_user)
@page_title = @resource.default_panel_name.to_s
end

last_crumb_args = {}
# If we're accessing this resource via another resource add the parent to the breadcrumbs.
Expand All @@ -428,8 +430,16 @@ def set_edit_title_and_breadcrumbs
add_breadcrumb @resource.plural_name.humanize, resources_path(resource: @resource)
end

add_breadcrumb @resource.record_title, resource_path(record: @resource.record, resource: @resource, **last_crumb_args)
add_breadcrumb t("avo.edit").humanize
help_add_breadcrumb(last_crumb_args)
end

def help_add_breadcrumb(last_crumb_args)
if params[:controller] != "avo/bulk_update"
add_breadcrumb @resource.record_title, resource_path(record: @resource.record, resource: @resource, **last_crumb_args) if params[:controller] != "avo/bulk_update"
add_breadcrumb t("avo.edit").humanize
else
add_breadcrumb t("avo.bulk_edit")
end
end

def create_success_action
Expand Down
87 changes: 87 additions & 0 deletions app/controllers/avo/bulk_update_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
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
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

[attribute_key, values.size == 1 ? values.first : nil]

Check failure on line 58 in app/controllers/avo/bulk_update_controller.rb

View workflow job for this annotation

GitHub Actions / lint / runner / standardrb

[rubocop] reported by reviewdog 🐶 [Corrected] Style/TernaryParentheses: Use parentheses for ternary expressions with complex conditions. Raw Output: app/controllers/avo/bulk_update_controller.rb:58:25: C: [Corrected] Style/TernaryParentheses: Use parentheses for ternary expressions with complex conditions. [attribute_key, values.size == 1 ? values.first : nil] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
end.to_h
end

def set_query
@query = if params[:query].present?
@resource.find_record(params[:query], params: params)
else
find_records_by_resource_ids
end
end

def find_records_by_resource_ids
resource_ids = params[:fields]&.dig(:avo_resource_ids)&.split(",") || []
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
8 changes: 8 additions & 0 deletions app/helpers/avo/url_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ def edit_resource_path(resource:, record: nil, resource_id: nil, **args)
avo.send :"edit_resources_#{resource.singular_route_key}_path", record || resource_id, **args
end

def edit_bulk_update_path(resource_name:, id:, **args)
avo.send :edit_bulk_update_path, resource_name, id, **args
end

def handle_bulk_update_path(resource_name:, query:, **args)
avo.send :handle_bulk_update_path, resource_name, query, **args
end

def resource_attach_path(resource, record_id, related_name, related_id = nil)
helpers.avo.resources_associations_new_path(resource.singular_route_key, record_id, related_name)
end
Expand Down
37 changes: 29 additions & 8 deletions app/javascript/js/controllers/item_select_all_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export default class extends Controller {
}

this.updateLinks('resourceIds')
this.updateBulkEditLink('resourceIds')
}

selectAll(event) {
Expand All @@ -88,23 +89,43 @@ export default class extends Controller {
}

updateLinks(param) {
const actionButtons = document.querySelectorAll(`a[data-actions-picker-target][data-resource-name="${this.resourceName}"]`)
actionButtons.forEach((link) => {
this.updateActionLinks(param, '[data-target="actions-list"] > a')
}

updateBulkEditLink(param) {
this.updateActionLinks(param, 'a[href*="/admin/bulk_update/edit"]')
}

updateActionLinks(param, selector) {

Choose a reason for hiding this comment

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

Function updateActionLinks has 30 lines of code (exceeds 25 allowed). Consider refactoring.

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 = new URL(link.href)

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') {
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')
url.searchParams.set(resourceIdsKey, selectedResources)
url.searchParams.set(selectedAllKey, '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')
url.searchParams.set(selectedQueryKey, selectedQuery)
url.searchParams.set(selectedAllKey, 'true')
}

if (selectedResourcesArray.length >= 2 && isBulkUpdate) {
link.classList.remove('hidden')
} else {
link.classList.add('hidden')
}

link.href = url.toString()
Expand Down
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
get "resources", to: redirect(Avo.configuration.root_path), as: :avo_resources_redirect
get "dashboards", to: redirect(Avo.configuration.root_path), as: :avo_dashboards_redirect

get "/bulk_update/edit", to: "bulk_update#edit", as: "edit_bulk_update"
put "/bulk_update/handle", to: "bulk_update#handle", as: "handle_bulk_update"

resources :media_library, only: [:index, :show, :update, :destroy], path: "media-library"
get "attach-media", to: "media_library#attach"

Expand Down
2 changes: 1 addition & 1 deletion lib/avo/concerns/has_controls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def render_edit_controls
end

def render_index_controls(item:)
[BackButton.new, AttachButton.new(item: item), ActionsList.new(as_index_control: true), CreateButton.new(item: item)]
[BackButton.new, AttachButton.new(item: item), BulkEditButton.new, ActionsList.new(as_index_control: true), CreateButton.new(item: item)]
end

def render_row_controls(item:)
Expand Down
17 changes: 17 additions & 0 deletions lib/avo/resources/controls/bulk_edit_button.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Avo
module Resources
module Controls
class BulkEditButton < BaseControl
def initialize(**args)
super(**args)

@label = args[:label] || I18n.t("avo.bulk_update").capitalize
@title = args[:title] || I18n.t("avo.bulk_update_items").humanize
@icon = args[:icon] || "avo/edit"
@style = args[:style] || :primary
@color = args[:color] || :primary
end
end
end
end
end
5 changes: 5 additions & 0 deletions lib/generators/avo/templates/locales/avo.ar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ ar:
attachment_class_detached: "%{attachment_class} تم فصل"
attachment_destroyed: تم حذف المرفق
attachment_failed: فشل في إرفاق %{attachment_class}
bulk_edit: تحرير جماعي
bulk_update: تحديث جماعي
bulk_update_failure: فشل في تحديث السجلات.
bulk_update_no_records: لا يمكن تنفيذ التحديث الجماعي بدون سجلات.
bulk_update_success: تم تنفيذ العملية الجماعية بنجاح.
cancel: إلغاء
choose_a_country: اختر دولة
choose_an_option: اختر خيارًا
Expand Down
5 changes: 5 additions & 0 deletions lib/generators/avo/templates/locales/avo.de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ de:
attachment_class_detached: "%{attachment_class} abgehängt."
attachment_destroyed: Anhang gelöscht
attachment_failed: "%{attachment_class} konnte nicht angehängt werden"
bulk_edit: Massenbearbeitung
bulk_update: Massenaktualisierung
bulk_update_failure: Aktualisierung der Datensätze fehlgeschlagen.
bulk_update_no_records: Bulk-Aktualisierung kann ohne Datensätze nicht durchgeführt werden.
bulk_update_success: Massenaktion erfolgreich ausgeführt.
cancel: Abbrechen
choose_a_country: Land auswählen
choose_an_option: Option auswählen
Expand Down
5 changes: 5 additions & 0 deletions lib/generators/avo/templates/locales/avo.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ en:
attachment_class_detached: "%{attachment_class} detached."
attachment_destroyed: Attachment destroyed
attachment_failed: Failed to attach %{attachment_class}
bulk_edit: Bulk edit
bulk_update: Bulk update
bulk_update_failure: Failed to update records.
bulk_update_no_records: Bulk update cannot be performed without records.
bulk_update_success: Bulk action run successfully.
cancel: Cancel
choose_a_country: Choose a country
choose_an_option: Choose an option
Expand Down
5 changes: 5 additions & 0 deletions lib/generators/avo/templates/locales/avo.es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ es:
attachment_class_detached: "%{attachment_class} adjuntado/a."
attachment_destroyed: Adjunto eliminado
attachment_failed: No se pudo adjuntar %{attachment_class}
bulk_edit: Edición masiva
bulk_update: Actualización masiva
bulk_update_failure: Error al actualizar los registros.
bulk_update_no_records: La actualización masiva no se puede realizar sin registros.
bulk_update_success: Acción masiva ejecutada con éxito.
cancel: Cancelar
choose_a_country: Elige un país
choose_an_option: Elige una opción
Expand Down
5 changes: 5 additions & 0 deletions lib/generators/avo/templates/locales/avo.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ fr:
attachment_class_detached: "%{attachment_class} détaché."
attachment_destroyed: Pièce jointe détruite
attachment_failed: Échec de l'ajout de %{attachment_class}
bulk_edit: Modification en masse
bulk_update: Mise à jour en masse
bulk_update_failure: Échec de la mise à jour des enregistrements.
bulk_update_no_records: La mise à jour en masse ne peut pas être effectuée sans enregistrements.
bulk_update_success: Action en masse exécutée avec succès.
cancel: Annuler
choose_a_country: Sélectionnez un pays
choose_an_option: Sélectionnez une option
Expand Down
5 changes: 5 additions & 0 deletions lib/generators/avo/templates/locales/avo.it.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ it:
attachment_class_detached: "%{attachment_class} staccato."
attachment_destroyed: Allegato distrutto
attachment_failed: Impossibile allegare %{attachment_class}
bulk_edit: Modifica di massa
bulk_update: Aggiornamento di massa
bulk_update_failure: Aggiornamento dei record fallito.
bulk_update_no_records: L'aggiornamento di massa non può essere eseguito senza record.
bulk_update_success: Azione di massa eseguita con successo.
cancel: Annulla
choose_a_country: Scegli un paese
choose_an_option: Scegli un'opzione
Expand Down
5 changes: 5 additions & 0 deletions lib/generators/avo/templates/locales/avo.ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ ja:
attachment_class_detached: "%{attachment_class}をデタッチしました。"
attachment_destroyed: アタッチは削除されました
attachment_failed: "%{attachment_class}の添付に失敗しました"
bulk_edit: 一括編集
bulk_update: 一括更新
bulk_update_failure: レコードの更新に失敗しました。
bulk_update_no_records: レコードがない場合、バルク更新を実行できません。
bulk_update_success: 一括処理が正常に実行されました。
cancel: キャンセル
choose_a_country: 国を選択
choose_an_option: オプションを選択
Expand Down
Loading
Loading