Skip to content

Commit

Permalink
Dynamically render Dashboard stats from CSV data
Browse files Browse the repository at this point in the history
  • Loading branch information
odlp committed Sep 28, 2020
1 parent eb25063 commit 198867f
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 41 deletions.
12 changes: 11 additions & 1 deletion config.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'govuk_tech_docs'
require 'lib/api_catalogue'
require 'lib/dashboard_stats'
require 'lib/url_helpers'

GovukTechDocs.configure(self)
Expand All @@ -11,7 +12,9 @@
helpers UrlHelpers

csv_path = File.expand_path("data/inputs/apic.csv", __dir__)
ApiCatalogue.from_csv(csv_path).organisations_apis.each do |organisation, apis|
api_catalogue = ApiCatalogue.from_csv(csv_path)

api_catalogue.organisations_apis.each do |organisation, apis|
proxy(
UrlHelpers.organisation_path(organisation),
"organisation_index.html",
Expand All @@ -30,3 +33,10 @@
)
end
end

proxy(
"/dashboard/index.html",
"dashboard.html",
locals: { dashboard_stats: DashboardStats.new(api_catalogue) },
ignore: true,
)
8 changes: 3 additions & 5 deletions lib/api_catalogue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ def self.from_csv(csv_path)
new(data)
end

def initialize(data)
@data = data
end
attr_reader :organisations_apis

def organisations_apis
data.each
def initialize(organisations_apis)
@organisations_apis = organisations_apis
end

private
Expand Down
44 changes: 44 additions & 0 deletions lib/dashboard_stats.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class DashboardStats
OrganisationStats = Struct.new(
:organisation, :api_count, :first_added, :last_updated, keyword_init: true
)

def initialize(api_catalogue)
@api_catalogue = api_catalogue
end

def total_apis
api_catalogue.organisations_apis.sum do |_, apis|
apis.count
end
end

def total_organisations
api_catalogue.organisations_apis.count
end

def by_organisation
@_by_organsation ||= calculate_stats_by_organisation
end

private

attr_reader :api_catalogue

def calculate_stats_by_organisation
api_catalogue
.organisations_apis
.map(&method(:build_organisation_stats))
.sort_by(&:api_count)
.reverse
end

def build_organisation_stats(organisation, apis)
OrganisationStats.new(
organisation: organisation,
api_count: apis.count,
first_added: apis.min_by(&:date_added)&.date_added,
last_updated: apis.max_by(&:date_updated)&.date_updated,
)
end
end
47 changes: 47 additions & 0 deletions source/dashboard.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: API Catalogue Contents
weight: 1000
hide_in_navigation: true
---

<h2>API Catalogue Contents</h2>

<table>
<thead>
<tr>
<th>Total APIs:</th>
<th>Departments Represented:</th>
</tr>
</thead>

<tbody>
<tr>
<td><%= dashboard_stats.total_apis %></td>
<td><%= dashboard_stats.total_organisations %></td>
</tr>
</tbody>
</table>

<table>
<thead>
<tr>
<th>Department:</th>
<th>Number of APIs:</th>
<th>First Added:</th>
<th>Last Update:</th>
<th>Link:</th>
</tr>
</thead>

<tbody>
<% dashboard_stats.by_organisation.each do |stats| %>
<tr>
<td><%= stats.organisation.name %></td>
<td><%= stats.api_count %></td>
<td><%= stats.first_added&.to_formatted_s(:iso8601) %></td>
<td><%= stats.last_updated&.to_formatted_s(:iso8601) %></td>
<td><%= link_to(stats.organisation.alternate_name, organisation_path(stats.organisation)) %></td>
</tr>
<% end %>
</tbody>
</table>
35 changes: 0 additions & 35 deletions source/dashboard/index.html.md

This file was deleted.

43 changes: 43 additions & 0 deletions spec/lib/dashboard_stats_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
require "api_catalogue"
require "dashboard_stats"

RSpec.describe DashboardStats do
let(:csv_path) { File.expand_path("../../data/inputs/apic.csv", __dir__) }
let(:api_catalogue) { ApiCatalogue.from_csv(csv_path) }

subject { described_class.new(api_catalogue) }

describe "#total_apis" do
it "sums the APIs across each organisation" do
expect(subject.total_apis).to be > 100
end
end

describe "#total_organisations" do
it "sums the number of organisations" do
expect(subject.total_organisations).to be > 10
expect(subject.total_organisations).to be < subject.total_apis
end
end

describe "#by_organisation" do
it "provides stats per organisation" do
nhs_stats = subject.by_organisation.detect do |stats|
stats.organisation.name.casecmp?("National Health Service")
end

expect(nhs_stats).to have_attributes(
organisation: have_attributes(name: "National Health Service"),
api_count: (a_value > 30),
first_added: be_a(Date),
last_updated: be_a(Date),
)
end

it "orders the organisations by number of APIs" do
subject.by_organisation.each_cons(2) do |org1, org2|
expect(org1.api_count).to be >= org2.api_count
end
end
end
end

0 comments on commit 198867f

Please sign in to comment.