module PgEngine module Resource def self.included(clazz) # clazz.before_action :authenticate_user! clazz.helper_method :atributos_para_listar clazz.helper_method :atributos_para_mostrar clazz.helper_method :current_page_size clazz.helper_method :show_filters? end # Public endpoints def abrir_modal pg_respond_abrir_modal end def buscar pg_respond_buscar end def index @collection = filtros_y_policy atributos_para_buscar shared_context = Ransack::Context.for(clase_modelo) @q = @clase_modelo.ransack(params[:q], context: shared_context) # @collection = @q.result(distinct: true) @collection = @collection.joins(shared_context.join_sources) vis = Ransack::Visitor.new.accept(@q.base) @collection = @collection.where(vis) @collection = sort_collection(@collection) pg_respond_index end def show add_breadcrumb instancia_modelo.to_s_short, instancia_modelo.target_object pg_respond_show end def new add_breadcrumb instancia_modelo.submit_default_value end def edit add_breadcrumb instancia_modelo.to_s_short, instancia_modelo.target_object add_breadcrumb 'Editando' end def create pg_respond_create end def update pg_respond_update end def destroy pg_respond_destroy(instancia_modelo, params[:redirect_to]) end # End public endpoints protected def show_filters? cur_route = pg_current_route idtf = cur_route[:controller] + '#' + cur_route[:action] + '#open-filters' if params[:ocultar_filtros] session[idtf] = nil elsif params[:mostrar_filtros] session[idtf] = true end session[idtf] end def current_page_size if params[:page_size].present? session[:page_size] = params[:page_size] params[:page_size].to_i else default_page_size end end def default_page_size session[:page_size].present? ? session[:page_size].to_i : 10 end def pg_respond_update object = instancia_modelo respond_to do |format| if (@saved = object.save) format.html { redirect_to object.decorate.target_object } format.json { render json: object.decorate } else # TODO: esto solucionaría el problema? # self.instancia_modelo = instancia_modelo.decorate format.html { render :edit, status: :unprocessable_entity } format.json { render json: object.errors, status: :unprocessable_entity } end end end def pg_respond_create object = instancia_modelo respond_to do |format| if (@saved = object.save) # TODO: 'asociable' lo cambiaría por 'in_modal' o algo así if params[:asociable] format.turbo_stream do render turbo_stream: turbo_stream.update_all('.modal.show .pg-associable-form', <<~HTML
HTML ) # FIXME: handlear json # render json: object.decorate, content_type: 'application/json' end end format.html do if params[:save_and_next] == 'true' new_path = "#{url_for(@clase_modelo)}/new" redirect_to new_path, notice: "#{@clase_modelo.nombre_singular} creado." else redirect_to object.decorate.target_object end end format.json { render json: object.decorate } else # TODO: esto solucionaría el problema? # self.instancia_modelo = instancia_modelo.decorate if params[:asociable] format.turbo_stream do # FIXME: agregar , status: :unprocessable_entity render turbo_stream: turbo_stream.update_all('.modal.show .pg-associable-form', partial: 'form', locals: { asociable: true }) end end format.html { render :new, status: :unprocessable_entity } format.json { render json: object.errors.full_messages, status: :unprocessable_entity } end end end def pg_respond_index respond_to do |format| format.json { render json: @collection } format.html { render_listing } format.xlsx do render xlsx: 'download', filename: "#{@clase_modelo.nombre_plural.gsub(' ', '-').downcase}" \ "-#{Time.zone.now.strftime('%Y-%m-%d-%H.%M.%S')}.xlsx" end end end def pg_respond_show(object = nil) object ||= instancia_modelo if params[:modal].present? render turbo_stream: turbo_stream.append_all('body', partial: 'pg_layout/modal_show', locals: { object: }) else respond_to do |format| format.json { render json: object } format.html end end end def pg_respond_destroy(model, redirect_url = nil) if destroy_model(model) msg = "#{model.model_name.human} #{model.gender == 'f' ? 'borrada' : 'borrado'}" respond_to do |format| if redirect_url.present? format.html do redirect_to redirect_url, notice: msg, status: :see_other end else format.turbo_stream do # Esto no es totalmente limpio pero funciona tanto en los listados como en los # modal show render turbo_stream: turbo_stream.remove(model) + turbo_stream.remove_all('.modal') end format.html do redirect_back(fallback_location: root_path, notice: msg, status: 303) end format.json { head :no_content } end end else respond_to do |format| format.html do if model.respond_to?(:associated_elements) && model.associated_elements.present? @model = model render destroy_error_details_view else flash[:alert] = @error_message redirect_back(fallback_location: root_path, status: 303) end end format.json { render json: { error: @error_message }, status: :unprocessable_entity } end end end # TODO: crear esta vista en pg_rails def destroy_error_details_view 'destroy_error_details' end def destroy_model(model) @error_message = 'No se pudo eliminar el registro' begin destroy_method = model.respond_to?(:discard) ? :discard : :destroy return true if model.send(destroy_method) @error_message = model.errors.full_messages.join(', ') false rescue ActiveRecord::InvalidForeignKey => e # class_name = /from table \"(?