From 9abdc8698acd7bf6719d36158f1c2942b520f4a9 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 9 Nov 2023 16:58:20 +0100 Subject: [PATCH] Refactor label templates backend [SCI-9676] --- app/controllers/application_controller.rb | 10 +++ app/controllers/label_templates_controller.rb | 10 +-- app/datatables/custom_datatable_v2.rb | 71 --------------- app/datatables/label_template_datatable.rb | 87 ------------------- app/javascript/vue/label_template/table.vue | 7 +- app/javascript/vue/shared/datatable/table.vue | 7 +- .../lists/label_template_serializer.rb | 45 ++++++++++ app/services/lists/base_service.rb | 39 +++++++++ app/services/lists/label_templates_service.rb | 47 ++++++++++ app/views/label_templates/index.html.erb | 2 +- 10 files changed, 152 insertions(+), 173 deletions(-) delete mode 100644 app/datatables/custom_datatable_v2.rb delete mode 100644 app/datatables/label_template_datatable.rb create mode 100644 app/serializers/lists/label_template_serializer.rb create mode 100644 app/services/lists/base_service.rb create mode 100644 app/services/lists/label_templates_service.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index acbfdd4d9..49fde23a6 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -113,4 +113,14 @@ class ApplicationController < ActionController::Base ensure I18n.backend.date_format = nil end + + def pagination_dict(object) + { + current_page: object.current_page, + next_page: object.next_page, + prev_page: object.prev_page, + total_pages: object.total_pages, + total_count: object.total_count + } + end end diff --git a/app/controllers/label_templates_controller.rb b/app/controllers/label_templates_controller.rb index c9b94a0b4..7b242dcf5 100644 --- a/app/controllers/label_templates_controller.rb +++ b/app/controllers/label_templates_controller.rb @@ -16,7 +16,8 @@ class LabelTemplatesController < ApplicationController def index respond_to do |format| format.json do - render json: @label_templates, each_serializer: LabelTemplateSerializer, user: current_user + label_templates = Lists::LabelTemplatesService.new(@label_templates, params).call + render json: label_templates, each_serializer: Lists::LabelTemplateSerializer, user: current_user, meta: pagination_dict(label_templates) end format.html do unless LabelTemplate.enabled? @@ -28,13 +29,6 @@ class LabelTemplatesController < ApplicationController end end - def datatable - render json: ::LabelTemplateDatatable.new( - view_context, - @label_templates - ) - end - def show respond_to do |format| format.json { render json: @label_template, serializer: LabelTemplateSerializer, user: current_user } diff --git a/app/datatables/custom_datatable_v2.rb b/app/datatables/custom_datatable_v2.rb deleted file mode 100644 index 6d55810ef..000000000 --- a/app/datatables/custom_datatable_v2.rb +++ /dev/null @@ -1,71 +0,0 @@ -# frozen_string_literal: true - -class CustomDatatableV2 - attr_reader :params, :options - - def initialize(view, raw_data, options = {}) - @raw_data = raw_data - @params = view.params - @options = options - end - - def as_json(_options = {}) - { - data: data, - pageTotal: records.total_pages - } - end - - def records - @records ||= fetch_records - end - - private - - def order_params - @order_params ||= - params.require(:order).permit(:column, :dir).to_h - end - - def fetch_records - records = get_raw_records - records = sort_records(records) if params[:order].present? - records = paginate_records(records) if params[:page].present? - records = filter_records(records) if params[:search].present? - records - end - - def paginate_records(records) - records.page(params[:page]).per(params[:per_page]) - end - - def sort_direction(order_params) - order_params[:dir] == 'asc' ? 'ASC' : 'DESC' - end - - def sort_records(records) - sort_by = "#{sortable_columns[order_params[:column].to_sym]} #{sort_direction(order_params)}" - records.order(sort_by) - end - - def generate_sortable_displayed_columns - @sortable_displayed_columns = [] - columns_params.each_value do |col| - @sortable_displayed_columns << col[:data] if col[:orderable] == 'true' - end - @sortable_displayed_columns - end - - def formated_date - f_date = I18n.backend.date_format.dup - f_date.gsub!(/%-d/, 'FMDD') - f_date.gsub!(/%d/, 'DD') - f_date.gsub!(/%-m/, 'FMMM') - f_date.gsub!(/%m/, 'MM') - f_date.gsub!(/%b/, 'Mon') - f_date.gsub!(/%B/, 'Month') - f_date.gsub!('%Y', 'YYYY') - f_date += ' HH24:MI' - f_date - end -end diff --git a/app/datatables/label_template_datatable.rb b/app/datatables/label_template_datatable.rb deleted file mode 100644 index 83d67cfea..000000000 --- a/app/datatables/label_template_datatable.rb +++ /dev/null @@ -1,87 +0,0 @@ -# frozen_string_literal: true - -class LabelTemplateDatatable < CustomDatatableV2 - include InputSanitizeHelper - include Rails.application.routes.url_helpers - - TABLE_COLUMNS = { - default: 'label_templates.default', - name: 'label_templates.name', - format: 'label_templates.type', - description: 'label_templates.description', - modified_by: 'label_templates.modified_by', - updated_at: 'label_templates.updated_at', - created_by: 'label_templates.created_by_user', - created_at: 'label_templates.created_at' - }.freeze - - def sortable_columns - @sortable_columns ||= TABLE_COLUMNS - end - - def searchable_columns - @searchable_columns ||= TABLE_COLUMNS - end - - private - - def order_params - @order_params ||= - params.require(:order).permit(:column, :dir).to_h - end - - def data - records.map do |record| - { - id: record.id, - default: record.default, - name: append_format_icon(record), - format: escape_input(record.label_format), - description: escape_input(record.description), - modified_by: escape_input(record.modified_by), - updated_at: I18n.l(record.updated_at, format: :full), - created_by: escape_input(record.created_by_user), - created_at: I18n.l(record.created_at, format: :full), - attributes: { - edit_url: label_template_path(record) - } - } - end - end - - def append_format_icon(record) - { - icon_image_tag: - ActionController::Base.helpers.image_tag( - "label_template_icons/#{record.icon}.svg", - class: 'label-template-icon' - ), - name: escape_input(record.name) - } - end - - def get_raw_records - res = @raw_data.joins( - 'LEFT OUTER JOIN users AS creators ' \ - 'ON label_templates.created_by_id = creators.id' - ).joins( - 'LEFT OUTER JOIN users AS modifiers '\ - 'ON label_templates.last_modified_by_id = modifiers.id' - ).select('label_templates.* AS label_templates') - .select('creators.full_name AS created_by_user') - .select('modifiers.full_name AS modified_by') - .select( - "('#{Extends::LABEL_TEMPLATE_FORMAT_MAP.to_json}'::jsonb -> label_templates.type)::text "\ - "AS label_format" - ) - LabelTemplate.from(res, :label_templates) - end - - def filter_records(records) - records.where_attributes_like( - ['label_templates.name', 'label_templates.label_format', 'label_templates.description', - 'label_templates.modified_by', 'label_templates.created_by_user'], - params[:search] - ) - end -end diff --git a/app/javascript/vue/label_template/table.vue b/app/javascript/vue/label_template/table.vue index 275fd8ee6..ccf14d683 100644 --- a/app/javascript/vue/label_template/table.vue +++ b/app/javascript/vue/label_template/table.vue @@ -97,11 +97,10 @@ export default { }, methods: { labelNameRenderer(params) { - let name = params.data.name; - let editUrl = params.data.attributes.edit_url; + let editUrl = params.data.urls.show; return ` - ${name.icon_image_tag} - ${name.name} + ${params.data.icon_url} + ${params.data.name} ` }, defaultRenderer(params) { diff --git a/app/javascript/vue/shared/datatable/table.vue b/app/javascript/vue/shared/datatable/table.vue index 69a478326..c88cc75e9 100644 --- a/app/javascript/vue/shared/datatable/table.vue +++ b/app/javascript/vue/shared/datatable/table.vue @@ -158,6 +158,9 @@ export default { window.removeEventListener('resize', this.resize); }, methods: { + formatData(data) { + return data.map( (item) => Object.assign({}, item.attributes, { id: item.id }) ); + }, resize() { if (this.tableState) return; @@ -175,8 +178,8 @@ export default { }) .then((response) => { this.selectedRows = []; - this.gridApi.setRowData(response.data.data); - this.totalPage = response.data.pageTotal; + this.gridApi.setRowData(this.formatData(response.data.data)); + this.totalPage = response.data.meta.total_pages; this.$emit('tableReloaded'); }) }, diff --git a/app/serializers/lists/label_template_serializer.rb b/app/serializers/lists/label_template_serializer.rb new file mode 100644 index 000000000..096303bda --- /dev/null +++ b/app/serializers/lists/label_template_serializer.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Lists + class LabelTemplateSerializer < ActiveModel::Serializer + include Canaid::Helpers::PermissionsHelper + include Rails.application.routes.url_helpers + + attributes :name, :language_type, :urls, :type, + :default, :format, :modified_by, :created_by, + :created_at, :updated_at, :id, :icon_url, :description + + def icon_url + ActionController::Base.helpers.image_tag( + "label_template_icons/#{object.icon}.svg", + class: 'label-template-icon' + ) + end + + delegate :modified_by, to: :object + + def format + object.label_format + end + + def created_by + object.created_by_user + end + + def created_at + I18n.l(object.created_at, format: :full) + end + + def updated_at + I18n.l(object.updated_at, format: :full) + end + + def urls + return {} unless can_manage_label_templates?(object.team) + + { + show: label_template_path(object) + } + end + end +end diff --git a/app/services/lists/base_service.rb b/app/services/lists/base_service.rb new file mode 100644 index 000000000..db9127984 --- /dev/null +++ b/app/services/lists/base_service.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module Lists + class BaseService + def initialize(raw_data, params, user: nil) + @raw_data = raw_data + @params = params + @user = user + end + + def call + records = fetch_records + records = filter_records(records) + records = sort_records(records) + paginate_records(records) + end + + private + + def order_params + @order_params ||= @params.require(:order).permit(:column, :dir).to_h + end + + def paginate_records(records) + records.page(@params[:page]).per(@params[:per_page]) + end + + def sort_direction(order_params) + order_params[:dir] == 'asc' ? 'ASC' : 'DESC' + end + + def sort_records(records) + return records unless @params[:order] + + sort_by = "#{sortable_columns[order_params[:column].to_sym]} #{sort_direction(order_params)}" + records.order(sort_by) + end + end +end diff --git a/app/services/lists/label_templates_service.rb b/app/services/lists/label_templates_service.rb new file mode 100644 index 000000000..d2948ec21 --- /dev/null +++ b/app/services/lists/label_templates_service.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Lists + class LabelTemplatesService < BaseService + private + + def fetch_records + res = @raw_data.joins( + 'LEFT OUTER JOIN users AS creators ' \ + 'ON label_templates.created_by_id = creators.id' + ).joins( + 'LEFT OUTER JOIN users AS modifiers ' \ + 'ON label_templates.last_modified_by_id = modifiers.id' + ).select('label_templates.* AS label_templates') + .select('creators.full_name AS created_by_user') + .select('modifiers.full_name AS modified_by') + .select( + "('#{Extends::LABEL_TEMPLATE_FORMAT_MAP.to_json}'::jsonb -> label_templates.type)::text " \ + "AS label_format" + ) + LabelTemplate.from(res, :label_templates) + end + + def filter_records(records) + return records unless @params[:search] + + records.where_attributes_like( + ['label_templates.name', 'label_templates.label_format', 'label_templates.description', + 'label_templates.modified_by', 'label_templates.created_by_user'], + @params[:search] + ) + end + + def sortable_columns + @sortable_columns ||= { + default: 'label_templates.default', + name: 'label_templates.name', + format: 'label_templates.type', + description: 'label_templates.description', + modified_by: 'label_templates.modified_by', + updated_at: 'label_templates.updated_at', + created_by: 'label_templates.created_by_user', + created_at: 'label_templates.created_at' + } + end + end +end diff --git a/app/views/label_templates/index.html.erb b/app/views/label_templates/index.html.erb index 29646202b..445fc4fee 100644 --- a/app/views/label_templates/index.html.erb +++ b/app/views/label_templates/index.html.erb @@ -13,7 +13,7 @@ >