diff --git a/app/assets/stylesheets/utils/_margins.scss b/app/assets/stylesheets/utils/_margins.scss index 83151d1..1461cc8 100644 --- a/app/assets/stylesheets/utils/_margins.scss +++ b/app/assets/stylesheets/utils/_margins.scss @@ -10,3 +10,6 @@ .mt-10 { margin-top: 10px; } +.mt-20 { + margin-top: 20px; +} diff --git a/app/controllers/usage_controller.rb b/app/controllers/usage_controller.rb index a469ee9..005b1f3 100644 --- a/app/controllers/usage_controller.rb +++ b/app/controllers/usage_controller.rb @@ -15,6 +15,7 @@ total_users(args: min_max_dates(args: args)) #TODO: pull this in from branding.yml @separators = [",", "|", "#"] + @funder = current_user.org.funder? end # POST /usage_plans_by_template diff --git a/app/helpers/usage_helper.rb b/app/helpers/usage_helper.rb index b38edc6..806c609 100644 --- a/app/helpers/usage_helper.rb +++ b/app/helpers/usage_helper.rb @@ -15,7 +15,7 @@ # appropriately by passing along the labels for the Y axis and the datasets # for the X axis # rubocop:disable Metrics/AbcSize, Metrics/MethodLength - def prep_data_for_template_plans_chart(data:) + def prep_data_for_template_plans_chart(data:, subset: "by_template") last_month = Date.today.last_month.end_of_month.strftime('%b-%y') return { labels: [last_month], datasets: [] }.to_json if data.blank? || data.empty? @@ -29,7 +29,7 @@ # Loop through the data and organize the datasets by template instead of date data.each do |rec| date = prep_date_for_charts(date: rec["date"]) - rec["by_template"].each do |template| + rec[subset].each do |template| # We need a placeholder for each month/year - template combo. The # default is to assume that there are zero plans for that month/year + template dflt = { diff --git a/app/javascript/views/usage/index.js b/app/javascript/views/usage/index.js index d596af6..8967dd8 100644 --- a/app/javascript/views/usage/index.js +++ b/app/javascript/views/usage/index.js @@ -37,25 +37,40 @@ // TODO: Most of these event listeners would not be necessary if JQuery and // all other JS libraries were available to the js.erb files. Reevaluate // this JS once we move to Rails 5 and properly configure webpacker - let drawnChart = null; - const monthlyPlanTemplatesChart = document.getElementById('monthly_template_plans'); + let drawnChartByTemplate = null; + const monthlyPlanTemplatesChart = document.getElementById('monthly_plans_by_template'); // Add event listeners that draw and destroy the chart monthlyPlanTemplatesChart.addEventListener('renderChart', (e) => { - drawnChart = drawHorizontalBar($('#monthly_template_plans'), e.detail); + drawnChartByTemplate = drawHorizontalBar($('#monthly_plans_by_template'), e.detail); // Assigning the chart to a window variable here so that we can fire // the events from the js.erb - window.templatePlansChart = document.getElementById('monthly_template_plans'); + window.templatePlansChart = document.getElementById('monthly_plans_by_template'); }); monthlyPlanTemplatesChart.addEventListener('destroyChart', () => { - if (drawnChart) { - drawnChart.destroy(); + if (drawnChartByTemplate) { + drawnChartByTemplate.destroy(); } }); + const monthlyPlanUsingTemplatesChart = document.getElementById('monthly_plans_using_template'); + // Add event listeners that draw the chart if it exists + if (isObject(monthlyPlanUsingTemplatesChart)) { + monthlyPlanUsingTemplatesChart.addEventListener('renderChart', (e) => { + drawHorizontalBar($('#monthly_plans_using_template'), e.detail); + }); + } + // Create the initial Plans per template chart const templatePlansData = JSON.parse($('#plans_by_template').val()); if (isObject(templatePlansData)) { - const draw = new CustomEvent('renderChart', { detail: templatePlansData }); - document.getElementById('monthly_template_plans').dispatchEvent(draw); + const drawPer = new CustomEvent('renderChart', { detail: templatePlansData }); + document.getElementById('monthly_plans_by_template').dispatchEvent(drawPer); + } + + // Create the initial Plans using template chart if the chart exists + if (isObject(monthlyPlanUsingTemplatesChart)) { + const usingTemplatePlansData = JSON.parse($('#plans_using_template').val()); + const drawUsing = new CustomEvent('renderChart', { detail: usingTemplatePlansData }); + document.getElementById('monthly_plans_using_template').dispatchEvent(drawUsing); } }); diff --git a/app/models/stat_created_plan.rb b/app/models/stat_created_plan.rb index 4d4bdf8..75b645d 100644 --- a/app/models/stat_created_plan.rb +++ b/app/models/stat_created_plan.rb @@ -21,14 +21,21 @@ serialize :details, JSON def by_template - return [] unless details.present? + parse_details.fetch("by_template", []) + end - json = details.is_a?(String) ? JSON.parse(details) : details - json.fetch("by_template", []) + def using_template + parse_details.fetch("using_template", []) end def to_json(options = nil) - super(methods: :by_template) + super(methods: [:by_template, :using_template]) + end + + def parse_details + return JSON.parse({}) unless details.present? + + json = details.is_a?(String) ? JSON.parse(details) : details end class << self diff --git a/app/models/stat_created_plan/create_or_update.rb b/app/models/stat_created_plan/create_or_update.rb index 8802105..ece95dc 100644 --- a/app/models/stat_created_plan/create_or_update.rb +++ b/app/models/stat_created_plan/create_or_update.rb @@ -8,12 +8,13 @@ def do(start_date:, end_date:, org:) count = count_plans(start_date: start_date, end_date: end_date, org: org) - by_template = by_template(start_date: start_date, end_date: end_date, org: org) + by_template = plan_statistics(start_date: start_date, end_date: end_date, org: org) + using_template = plan_statistics(start_date: start_date, end_date: end_date, org: org, own_templates: true) attrs = { date: end_date.to_date, org_id: org.id, count: count, - details: { by_template: by_template } + details: { by_template: by_template, using_template: using_template } } stat_created_plan = StatCreatedPlan.find_by( date: attrs[:date], @@ -37,6 +38,10 @@ Plan.where(plans: { created_at: start_date..end_date }) end + def own_template_plans(org) + Plan.joins(:template).where(templates: { org_id: org.id }) + end + def count_plans(start_date:, end_date:, org:) Role.joins(:plan, :user) .administrator @@ -47,13 +52,16 @@ .count end - def by_template(start_date:, end_date:, org:) - roleable_plan_ids = Role.joins([:plan, :user]) + def plan_statistics(start_date:, end_date:, org:, own_templates: false) + roleable_plans = Role.joins([:plan, :user]) .administrator - .merge(users(org)) .merge(plans(start_date: start_date, end_date: end_date)) - .pluck(:plan_id) - .uniq + if own_templates + roleable_plans = roleable_plans.merge(own_template_plans(org)) + else + roleable_plans = roleable_plans.merge(users(org)) + end + roleable_plan_ids = roleable_plans.pluck(:plan_id).uniq template_counts = Plan.joins(:template).where(id: roleable_plan_ids) .group("templates.family_id").count diff --git a/app/views/usage/_filter.html.erb b/app/views/usage/_filter.html.erb index c1de3f2..7a5f6c3 100644 --- a/app/views/usage/_filter.html.erb +++ b/app/views/usage/_filter.html.erb @@ -2,16 +2,16 @@
<%= _('Use the filters to generate organisational usage statistics for a custom date range. The graphs display new users and plans for your organisation over the past year. You can download a CSV report for each graph.') %>
+<%= _('Use the filters to run organisational usage statistics for a custom date range.') %>
<%= user_count.to_i %> Total users
<%= plan_count.to_i %> Total plans
* <%= _('Move the mouse pointer over the bars of a chart to see numbers.') %>
-<%= _('No. users joined during last year') %>
-<%= _('No. plans during last year') %>
-<%= _('No. plans by template') %>
-