diff --git a/app/controllers/gobierto_admin/gobierto_dashboards/dashboards_controller.rb b/app/controllers/gobierto_admin/gobierto_dashboards/dashboards_controller.rb deleted file mode 100644 index 966103f5fb..0000000000 --- a/app/controllers/gobierto_admin/gobierto_dashboards/dashboards_controller.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module GobiertoAdmin - module GobiertoDashboards - class DashboardsController < GobiertoAdmin::BaseController - before_action { module_enabled!(current_site, "GobiertoDashboards") } - before_action -> { module_allowed_action!(current_admin, "GobiertoPlans", [:manage_dashboards, :view_dashboards]) } - - layout false - - def modal; end - end - end -end diff --git a/app/controllers/gobierto_admin/gobierto_plans/projects_controller.rb b/app/controllers/gobierto_admin/gobierto_plans/projects_controller.rb index 8aa99f1bc9..d4cbce0c06 100644 --- a/app/controllers/gobierto_admin/gobierto_plans/projects_controller.rb +++ b/app/controllers/gobierto_admin/gobierto_plans/projects_controller.rb @@ -200,7 +200,7 @@ def find_versioned_project end def set_dashboards_list_path - return unless current_site.configuration.gobierto_dashboards_enabled? && + return unless current_site.configuration.available_module?("GobiertoDashboards") && current_admin.module_allowed_action?(current_admin_module, current_site, :manage_dashboards) @dashboards_list_path ||= list_admin_plans_plan_dashboards_path(@plan) diff --git a/app/controllers/gobierto_admin/sites_controller.rb b/app/controllers/gobierto_admin/sites_controller.rb index 0a6cd60be7..22858f8b20 100644 --- a/app/controllers/gobierto_admin/sites_controller.rb +++ b/app/controllers/gobierto_admin/sites_controller.rb @@ -115,7 +115,7 @@ def find_site end def get_site_modules - APP_CONFIG[:site_modules].map { |site_module| OpenStruct.new(site_module) } + APP_CONFIG[:site_modules].union(Rails.configuration.engine_modules).map { |site_module| OpenStruct.new(site_module) } end def set_auth_modules diff --git a/app/controllers/gobierto_dashboards/api/v1/base_controller.rb b/app/controllers/gobierto_dashboards/api/v1/base_controller.rb deleted file mode 100644 index 60675508cf..0000000000 --- a/app/controllers/gobierto_dashboards/api/v1/base_controller.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module GobiertoDashboards - module Api - module V1 - class BaseController < ApiBaseController - include ActionController::MimeResponds - - before_action { module_enabled!(current_site, "GobiertoDashboards", false) } - end - end - end -end diff --git a/app/controllers/gobierto_dashboards/api/v1/dashboards_controller.rb b/app/controllers/gobierto_dashboards/api/v1/dashboards_controller.rb deleted file mode 100644 index 74d6a8986d..0000000000 --- a/app/controllers/gobierto_dashboards/api/v1/dashboards_controller.rb +++ /dev/null @@ -1,152 +0,0 @@ -# frozen_string_literal: true - -module GobiertoDashboards - module Api - module V1 - class DashboardsController < BaseController - include ::GobiertoCommon::SecuredWithAdminToken - - skip_before_action :set_admin_with_token, only: [:index, :show, :data, :dashboard_data] - before_action :check_manage_dashboards, except: [:index, :show, :data, :dashboard_data] - - # GET /api/v1/dashboards - # GET /api/v1/dashboards.json - def index - render( - json: filtered_relation.active, - adapter: :json_api - ) - end - - # GET /api/v1/dashboards/1 - # GET /api/v1/dashboards/1.json - def show - find_active_resource - - render( - json: @resource, - adapter: :json_api - ) - end - - # GET /api/v1/dashboard_data?context=GobiertoPlans::Plan/1&data_pipe=project_metrics - # GET /api/v1/dashboard_data?context=GobiertoPlans::Plan/1&data_pipe=project_metrics.json - def dashboard_data - data = context_resource.present? && data_pipe.present? ? data_pipe.new(context_resource, site: current_site).output_data : [] - - render( - json: data - ) - end - - # GET /api/v1/dashboards/1/data - # GET /api/v1/dashboards/1/data.json - def data - find_active_resource - - render( - json: @resource, - serializer: ::GobiertoDashboards::DashboardDataSerializer, - adapter: :json_api - ) - end - - # GET /api/v1/dashboards/new - # GET /api/v1/dashboards/new.json - def new - render( - json: base_relation.active.new, - adapter: :json_api - ) - end - - # POST /api/v1/dashboards - # POST /api/v1/dashboards.json - def create - @form = form_class.new(resource_params.merge(site_id: current_site.id, admin_id: current_admin.id)) - - if @form.save - render( - json: @form.resource, - status: :created, - adapter: :json - ) - else - api_errors_render(@form, adapter: :json_api) - end - end - - # PATCH/PUT /api/v1/dashboards/1 - # PATCH/PUT /api/v1/dashboards/1.json - def update - find_resource - - @form = form_class.new(resource_params.merge(site_id: current_site.id, admin_id: current_admin.id, id: @resource.id)) - - if @form.save - render( - json: @form.resource, - adapter: :json - ) - else - api_errors_render(@form, adapter: :json_api) - end - end - - # DELETE /api/v1/dashboards/1 - # DELETE /api/v1/dashboards/1.json - def destroy - find_resource - - @resource.destroy - - head :no_content - end - - private - - def find_active_resource - @resource = (current_admin.present? ? base_relation : base_relation.active).find(params[:id]) - end - - def find_resource - @resource = base_relation.find(params[:id]) - end - - def data_pipe - return if params[:data_pipe].blank? - - "GobiertoDashboards::DataPipes::#{ params[:data_pipe].camelize }".constantize - rescue NameError - nil - end - - def context_resource - @context_resource ||= GobiertoCommon::ContextService.new(params[:context]) - end - - def base_relation - current_site.dashboards - end - - def filtered_relation - params[:context].present? ? base_relation.where(context: context_resource.context) : base_relation - end - - def form_class - DashboardForm - end - - def resource_params - ActiveModelSerializers::Deserialization.jsonapi_parse(params, only: [:title_translations, :title, :context, :widgets_configuration, :visibility_level]) - end - - def check_manage_dashboards - return if current_admin.manager? || current_admin.permissions.can?(:manage_dashboards) - - render(json: { message: "Unauthorized" }, status: :unauthorized, adapter: :json_api) - end - end - end - end -end diff --git a/app/controllers/gobierto_plans/plan_types_controller.rb b/app/controllers/gobierto_plans/plan_types_controller.rb index d8fe9bb38e..f56f6f5431 100644 --- a/app/controllers/gobierto_plans/plan_types_controller.rb +++ b/app/controllers/gobierto_plans/plan_types_controller.rb @@ -42,7 +42,7 @@ def sdg private def dashboards_enabled? - @dashboards_enabled ||= module_enabled?("GobiertoDashboards") && current_site.dashboards.active.for_context(@plan).exists? + @dashboards_enabled ||= module_enabled?("GobiertoDashboards") && defined?(GobiertoDashboards::Dashboard) && current_site.dashboards.active.for_context(@plan).exists? end def find_plan_type diff --git a/app/forms/gobierto_dashboards/dashboard_form.rb b/app/forms/gobierto_dashboards/dashboard_form.rb deleted file mode 100644 index 271f5cccb1..0000000000 --- a/app/forms/gobierto_dashboards/dashboard_form.rb +++ /dev/null @@ -1,118 +0,0 @@ -# frozen_string_literal: true - -module GobiertoDashboards - class DashboardForm < BaseForm - include ::GobiertoCore::TranslationsHelpers - include ActiveModel::Serialization - - attr_accessor( - :site_id, - :admin_id, - :widgets_configuration, - :context - ) - - attr_writer( - :id, - :title_translations, - :title, - :visibility_level - ) - - validate :context_presence - validates :title, :visibility_level, :site, presence: true - validates :title_translations, translated_attribute_presence: true - validates :visibility_level, inclusion: { in: Dashboard.visibility_levels.keys } - validate :widgets_configuration_json_format - - delegate :persisted?, to: :resource - - def resource - @resource ||= resource_class.find_by(id: @id) || build_resource - end - alias dashboard resource - - def site - @site ||= Site.find_by(id: site_id) - end - - def id - @id ||= resource.id - end - - def title_translations - @title_translations ||= (resource.title_translations || available_locales_blank_translations).tap do |translations| - translations[I18n.locale] = @title if @title.present? - end - end - - def title - title_translations.with_indifferent_access[I18n.locale].presence || title_translations.values.find(&:present?) - end - - def visibility_level - @visibility_level ||= resource.visibility_level || :draft - end - - def context_service - @context_service ||= GobiertoCommon::ContextService.new(context) - end - - def save - save_resource if valid? - end - - def available_visibility_levels - Dashboard.visibility_levels - end - - private - - def widgets_configuration_json_format - return if widgets_configuration.blank? || widgets_configuration.is_a?(Enumerable) - - @widgets_configuration = JSON.parse(widgets_configuration) - rescue JSON::ParserError - errors.add :widgets_configuration, I18n.t("errors.messages.invalid") - end - - def transformed_widgets_configuration - return if widgets_configuration.blank? - - widgets_configuration_json_format if widgets_configuration.is_a?(String) - - @widgets_configuration.map do |widget_configuration| - widget_configuration.merge(widget_configuration.slice("x", "y", "w", "h").transform_values(&:to_i)) - end - end - - def context_presence - errors.add(:context, I18n.t("errors.messages.not_found")) unless context_service.present? - end - - def build_resource - resource_class.new - end - - def resource_class - Dashboard - end - - def save_resource - @resource = resource.tap do |attributes| - attributes.site_id = site.id - attributes.title_translations = title_translations - attributes.context = context_service.context - attributes.visibility_level = visibility_level - attributes.widgets_configuration = transformed_widgets_configuration - end - - if @resource.save - @resource - else - promote_errors(@resource.errors) - false - end - end - end -end diff --git a/app/models/gobierto_dashboards/dashboard.rb b/app/models/gobierto_dashboards/dashboard.rb deleted file mode 100644 index 5c2861b94a..0000000000 --- a/app/models/gobierto_dashboards/dashboard.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require_relative "../gobierto_dashboards" - -module GobiertoDashboards - class Dashboard < ApplicationRecord - belongs_to :site - - scope :sorted, -> { order(data_updated_at: :desc) } - scope :for_context, ->(resource) { where(context: resource.is_a?(String) ? GobiertoCommon::ContextService.new(resource).context : resource.to_global_id.to_s) } - - translates :title - - enum visibility_level: { draft: 0, active: 1 } - - validates :site, presence: true - - def custom_fields - site.custom_fields.where(uid: custom_field_uids) - end - - def custom_field_records - if context_resource.present? && site.custom_fields.where(instance: context_resource).exists? - site.custom_field_records.where(custom_fields: { uid: custom_fields_uids, instance: context_resource }) - else - site.custom_field_records.where(item: context_resource, custom_fields: { uid: custom_fields_uids }) - end - end - - def custom_fields_uids - widgets_configuration.map { |widget| widget["indicator"] }.compact - end - - def context_resource - @context_resource ||= GobiertoCommon::ContextService.new(context).resource - end - end -end diff --git a/app/models/gobierto_dashboards/data_pipes/base.rb b/app/models/gobierto_dashboards/data_pipes/base.rb deleted file mode 100644 index 88b6ced5ff..0000000000 --- a/app/models/gobierto_dashboards/data_pipes/base.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require_relative "../../gobierto_dashboards" - -module GobiertoDashboards - module DataPipes - class Base - class NotImplementedError < StandardError; end - - attr_reader :site, :context - - def initialize(context, opts = {}) - @context = context.is_a?(GobiertoCommon::ContextService) ? context : GobiertoCommon::ContextService.new(:context) - @site = @context.present? && context.resource.respond_to?(:site) ? @context.resource.site : opts[:site] - end - - def output_data - raise NotImplementedError, "Override this with a method returning an ActiveRecord::Relation of a class with sortable concern" - end - end - end -end diff --git a/app/models/gobierto_dashboards/data_pipes/project_metrics.rb b/app/models/gobierto_dashboards/data_pipes/project_metrics.rb deleted file mode 100644 index 02d7c3dda4..0000000000 --- a/app/models/gobierto_dashboards/data_pipes/project_metrics.rb +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true - -require_relative "../../gobierto_dashboards" - -module GobiertoDashboards - module DataPipes - class ProjectMetrics < Base - delegate :safe_parameterize, to: :class - - def output_data - { - data: indicator_names_disambiguation(custom_field_records.map { |record| indicators(record) }.compact.flatten) - }.to_json - end - - def self.safe_parameterize(text) - ActiveSupport::Inflector.transliterate(text).parameterize - end - - private - - def custom_fields - site.custom_fields.find_by(**custom_field_condition) - end - - def custom_field_records - site.custom_field_records.where(custom_fields: custom_field_condition) - end - - def custom_field_condition - @custom_field_condition ||= { instance: @context.resource, uid: "project-metrics" } - end - - def indicators(record) - published_version = record.item.published_version - return unless published_version.present? - - published_value = ::GobiertoCommon::CustomFieldFunctions::Indicator.new(record, version: published_version).value - return unless published_value.is_a? Array - - published_project = ::GobiertoPlans::ProjectDecorator.new(record.item, opts: { plan: @context.resource }).at_current_version - project = published_project.to_global_id.to_s - project_name = published_project.name - grouped_values(published_value).map do |key, values| - { - name: values.first["indicator"].strip.squeeze(" "), - id: key, - project: project, - project_name: project_name, - values: values.map { |value| value.except("indicator") } - } - end - end - - def indicator_names_disambiguation(data) - names = data.map { |indicator| indicator[:name] } - duplicated_names = names.group_by(&:itself).select { |_, v| v.size > 1 }.map(&:first) - - data.map do |indicator| - next indicator unless duplicated_names.include? indicator[:name] - - indicator.merge(name: "#{indicator[:project_name]} - #{indicator[:name]}") - end - end - - def grouped_values(values) - values.group_by do |row| - safe_parameterize(row["indicator"]) - end - end - end - end -end diff --git a/app/serializers/gobierto_dashboards/base_serializer.rb b/app/serializers/gobierto_dashboards/base_serializer.rb deleted file mode 100644 index 9a0961ff51..0000000000 --- a/app/serializers/gobierto_dashboards/base_serializer.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module GobiertoDashboards - class BaseSerializer < ActiveModel::Serializer - def current_site - object.site - end - - def exclude_links? - instance_options[:exclude_links] - end - - def exclude_relationships? - instance_options[:exclude_relationships] - end - - def with_translations? - instance_options[:with_translations] - end - - def include_draft? - instance_options[:include_draft] - end - end -end diff --git a/app/serializers/gobierto_dashboards/custom_field_record_data_serializer.rb b/app/serializers/gobierto_dashboards/custom_field_record_data_serializer.rb deleted file mode 100644 index 8ee68a41ba..0000000000 --- a/app/serializers/gobierto_dashboards/custom_field_record_data_serializer.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -module GobiertoDashboards - class CustomFieldRecordDataSerializer < BaseSerializer - attribute :name do - object.custom_field.uid - end - - attribute :item do - next unless object.item.present? - - object.item.to_global_id.to_s - end - - attribute :values do - object.value - end - end -end diff --git a/app/serializers/gobierto_dashboards/dashboard_data_serializer.rb b/app/serializers/gobierto_dashboards/dashboard_data_serializer.rb deleted file mode 100644 index d81bfb7ecc..0000000000 --- a/app/serializers/gobierto_dashboards/dashboard_data_serializer.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module GobiertoDashboards - class DashboardDataSerializer < BaseSerializer - attribute :values - - def values - object.custom_field_records.map do |record| - { - name: record.custom_field.uid, - item: record.item.to_global_id.to_s, - values: record.value - } - end - end - end -end diff --git a/app/serializers/gobierto_dashboards/dashboard_serializer.rb b/app/serializers/gobierto_dashboards/dashboard_serializer.rb deleted file mode 100644 index 0821e94381..0000000000 --- a/app/serializers/gobierto_dashboards/dashboard_serializer.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module GobiertoDashboards - class DashboardSerializer < BaseSerializer - include Rails.application.routes.url_helpers - - attribute :title, unless: :with_translations? - attribute :title_translations, if: :with_translations? - attributes :visibility_level, :context, :widgets_configuration - end -end diff --git a/app/views/gobierto_admin/gobierto_dashboards/dashboards/list_modal.html.erb b/app/views/gobierto_admin/gobierto_dashboards/dashboards/list_modal.html.erb deleted file mode 100644 index a6f5bc46f7..0000000000 --- a/app/views/gobierto_admin/gobierto_dashboards/dashboards/list_modal.html.erb +++ /dev/null @@ -1,51 +0,0 @@ - diff --git a/app/views/gobierto_admin/gobierto_dashboards/dashboards/modal.html.erb b/app/views/gobierto_admin/gobierto_dashboards/dashboards/modal.html.erb deleted file mode 100644 index 64d5ea651f..0000000000 --- a/app/views/gobierto_admin/gobierto_dashboards/dashboards/modal.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -